Skip to content

RPITITs may imply unsound outlives for late-bound args in signature #133427

Closed

Description

@compiler-errors

I tried this code:

use std::sync::Mutex;

static MUTEX: Mutex<Option<&'static str>> = Mutex::new(None);

trait Foo {
    fn foo<'a: 'static>(&self) -> impl Sized;
}

impl Foo for str {
    fn foo<'a: 'static>(&'a self) -> impl Sized + 'a {
        *MUTEX.lock().unwrap() = Some(self);
    }
}

fn call_foo<T: Foo + ?Sized>(s: &T) {
    s.foo();
}

fn main() {
    let s = String::from("hello, world");
    call_foo(s.as_str());
    drop(s);
    println!("> {}", MUTEX.lock().unwrap().unwrap());
}

I expected to see this happen: Compilation failure.

Instead, this happened: Segfault due to UAF

Why?

See comment below.

Meta

rustc --version --verbose:

2024-11-24

Not present on beta or stable.

Activity

  1. added
    A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.
    C-bugCategory: This is a bug.
    I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness
    T-typesRelevant to the types team, which will review and decide on the PR/issue.
    on Nov 24, 2024
  2. added
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    on Nov 24, 2024
  3. added
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Nov 24, 2024
  4. compiler-errors commented on Nov 24, 2024

    @compiler-errors
    ContributorAuthor

    While it may seem from bisection that this is due to:

    It's actually only uncovered by that PR because it flipped the order that we listed opaque lifetimes (which changes what regions we end up remapping in the collect_return_position_impl_trait_in_trait_tys query). Instead, this is due to my stupidity in:

  5. compiler-errors commented on Nov 24, 2024

    @compiler-errors
    ContributorAuthor

    Actually, here's an unsoundness that is on stable.

    trait MkStatic {
        fn mk_static(self) -> &'static str;
    }
    
    impl MkStatic for &'static str {
        fn mk_static(self) -> &'static str { self }
    }
    
    trait Foo {
        fn foo<'a: 'static, 'late>(&'late self) -> impl MkStatic;
    }
    
    impl Foo for str {
        fn foo<'a: 'static>(&'a self) -> impl MkStatic + 'static {
            self
        }
    }
    
    fn call_foo<T: Foo + ?Sized>(t: &T) -> &'static str {
        t.foo().mk_static()
    }
    
    fn main() {
        let s = call_foo(String::from("hello, world").as_str());
        println!("> {s}");
    }
  6. removed
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Nov 25, 2024
  7. apiraino commented on Nov 25, 2024

    @apiraino
    Contributor

    WG-prioritization assigning priority (Zulip discussion).

    @rustbot label -I-prioritize +P-high

  8. added
    P-highHigh priority
    and removed
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    on Nov 25, 2024
  9. added a commit that references this issue on Nov 28, 2024
    3e095e8
  10. added a commit that references this issue on Nov 28, 2024
    dbed79a
  11. moved this to Completed in T-types unsound issueson Mar 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.C-bugCategory: This is a bug.F-return_position_impl_trait_in_trait`#![feature(return_position_impl_trait_in_trait)]`I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-highHigh priorityT-typesRelevant to the types team, which will review and decide on the PR/issue.

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions