Skip to content

auto trait leakage can be used to leak arbitrary types #134578

Open
@lcnr

Description

@lcnr

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-auto-traitsArea: auto traits (e.g., `auto trait Send {}`)A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.C-bugCategory: This is a bug.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️I-types-nominatedNominated for discussion during a types team meeting.T-typesRelevant to the types team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions