Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
lcnr opened this issue Dec 20, 2024 · 0 comments
Open

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

lcnr opened this issue Dec 20, 2024 · 0 comments
Labels
A-auto-traits Area: auto traits (e.g., `auto trait Send {}`) A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ I-types-nominated Nominated for discussion during a types team meeting. T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@lcnr
Copy link
Contributor

lcnr commented Dec 20, 2024

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.

@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Dec 20, 2024
@lcnr lcnr added I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. T-types Relevant to the types team, which will review and decide on the PR/issue. I-types-nominated Nominated for discussion during a types team meeting. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Dec 20, 2024
@fmease fmease added the A-auto-traits Area: auto traits (e.g., `auto trait Send {}`) label Dec 21, 2024
@workingjubilee workingjubilee added the C-bug Category: This is a bug. label Feb 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-auto-traits Area: auto traits (e.g., `auto trait Send {}`) A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ I-types-nominated Nominated for discussion during a types team meeting. T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants