Skip to content

Opaque impl Trait return types unsoundly ignoring lifetime constraints #84305

Closed

Description

trait StaticDefaultRef: 'static {
    fn default_ref() -> &'static Self;
}

impl StaticDefaultRef for str {
    fn default_ref() -> &'static str {
        ""
    }
}

fn into_impl(x: &str) -> &(impl ?Sized + AsRef<str> + StaticDefaultRef + '_) {
    x
}

fn extend_lifetime<'a>(x: &'a str) -> &'static str {
    let t = into_impl(x);
    helper(|_| t)
}

fn helper<T: ?Sized + AsRef<str> + StaticDefaultRef>(f: impl FnOnce(&T) -> &T) -> &'static str {
    f(T::default_ref()).as_ref()
}

fn main() {
    let r;
    {
        let x = String::from("Hello World?");
        r = extend_lifetime(&x);
    }
    println!("{}", r);
}

(playground)

�j��0V�

So IMO the biggest problem in the code above is that the opaque type returned by into_impl implements StaticDefaultRef even though its lifetime is '_, i.e. not 'static.

This particular code only compiles since 1.45, so this might be a regression.

@rustbot modify labels: T-compiler, A-impl-trait, A-lifetimes, A-typesystem
and someone please add “I-unsound 💥”.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

A-closuresArea: Closures (`|…| { … }`)A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.A-lifetimesArea: Lifetimes / regionsA-typesystemArea: The type systemC-bugCategory: This is a bug.F-type_alias_impl_trait`#[feature(type_alias_impl_trait)]`I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

Type

No type

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions