When leaking the hidden type of opaques when proving auto traits, we can leak their hidden type to the caller by relying on type inference. See lcnr/random-rust-snippets#13 for minimized examples.
Note that this allows us to access foreign closures during typeck/borrowck. This very easily results in ICE, as this code expects all encountered closures to be local:
// crate dep
struct WaddupGamers<T, U>(Option<T>, U);
impl<T: Leak<Assoc = U>, U> Unpin for WaddupGamers<T, U> {}
pub trait Leak {
type Assoc;
}
impl<T> Leak for T {
type Assoc = T;
}
pub fn define<T>() -> impl Sized {
WaddupGamers(None::<T>, || ())
}
// root
#![feature(type_alias_impl_trait)]
#![allow(unused)]
#![crate_type = "rlib"]
use dep::*;
fn require_auto<T: Unpin>(x: T) -> T { x }
type NameMe<T> = impl Sized;
fn leak<T>() -> NameMe<T>
where
T: Leak<Assoc = NameMe<T>>,
{
// Proving `impl Sized: Unpin` constrains `NameMe<T>` to
// the closure of `define`.
let opaque = require_auto(define::<T>());
let closure;
loop {}
return closure; // This constrains this infer var to that closure
}
results in
thread 'rustc' panicked at compiler/rustc_hir_typeck/src/coercion.rs:1202:62:
DefId::expect_local: `DefId(20:20 ~ dep[6a51]::define::{closure#0})` isn't local
|
self.tcx.upvars_mentioned(closure_def_id.expect_local()).is_some() |
There are a lot of such uses, this was simply the first one i've triggered.
When leaking the hidden type of opaques when proving auto traits, we can leak their hidden type to the caller by relying on type inference. See lcnr/random-rust-snippets#13 for minimized examples.
Note that this allows us to access foreign closures during typeck/borrowck. This very easily results in ICE, as this code expects all encountered closures to be local:
results in
rust/compiler/rustc_hir_typeck/src/coercion.rs
Line 1202 in fcc1615
There are a lot of such uses, this was simply the first one i've triggered.