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
Opaque impl Trait
return types unsoundly ignoring lifetime constraints
#84305
Comments
Error: Label Please let |
impl Trait
return types ignoring lifetime constraints unsoundnessimpl Trait
return types unsoundly ignoring lifetime constraints
Error: Label Please let |
So the code example compiles since
before that, you’ll get
|
I guess that lifetime bounds aren’t the only problem. Here’s an unsound example that doesn’t need any use std::marker::PhantomData;
trait Foo<T: ?Sized> {
fn fun(f: &dyn Fn(PhantomData<&Self>) -> &Self) -> &dyn Fn(PhantomData<&T>) -> &T;
}
impl<T: ?Sized> Foo<T> for T {
fn fun(f: &dyn Fn(PhantomData<&Self>) -> &Self) -> &dyn Fn(PhantomData<&T>) -> &T {
f
}
}
fn extend_lifetime<'a, T: ?Sized>(x: &T) -> &'a T {
Foo::fun(&|_| impl_foo(x))(PhantomData)
}
fn impl_foo<T: ?Sized>(x: &T) -> &(impl ?Sized + Foo<T> + '_) {
x
}
fn main() {
let r;
{
let x = String::from("Hello World?");
r = extend_lifetime(&x);
}
println!("{}", r);
}
In fn extend_lifetime<'a, 'b, T: ?Sized>(x: &'a T) -> &'b T {
Foo::fun(&|_| impl_foo(x))(PhantomData)
} produces this warning
Weirdly, from Edit: That’s interesting… changing it to fn extend_lifetime<'a, 'b, T: ?Sized>(x: &'a T) -> &'b T {
let y = impl_foo(x);
Foo::fun(&|_| y)(PhantomData)
} moves the regression back up to |
So, the code above but with fn extend_lifetime<'a, 'b, T: ?Sized>(x: &'a T) -> &'b T {
Foo::fun(&|_| impl_foo(x))(PhantomData)
} stops producing the warning about “potential undefined behavior” at
looking through the description of these PRs, the point of regression (where the warning disappeared) might be #58347 The warning first appeared in Edit: Ah, the choice of edition explains the different godbolt behavior, its errors are probably due to NNL not being available on edition 2015 or something like that. |
I’m more and more getting the feeling that this issue might be about how closures interact with opaque |
Assigning priority as discussed as part of the Prioritization Working Group procedure and removing @rustbot label -I-prioritize +P-high |
To be clear: on further thought, I don’t think that the It all becomes a bit more explicit and visible when we use #![feature(min_type_alias_impl_trait)]
type WithLifetime<'a> = impl Equals<SelfType = ()>;
fn _defining_use<'a>() -> WithLifetime<'a> {}
trait Convert<'a> {
type Witness;
fn convert<'b, T: ?Sized>(_proof: &'b Self::Witness, x: &'a T) -> &'b T;
}
impl<'a> Convert<'a> for () {
type Witness = WithLifetime<'a>;
fn convert<'b, T: ?Sized>(_proof: &'b WithLifetime<'a>, x: &'a T) -> &'b T {
// compiler thinks it gets to assume 'a: 'b here because of the `&'b WithLifetime<'a>` argument
x
}
}
fn extend_lifetime<'a, 'b, T: ?Sized>(x: &'a T) -> &'b T {
WithLifetime::<'a>::convert_helper::<(), T>(&(), x)
}
trait Equals {
type SelfType;
fn convert_helper<'a, 'b, W: Convert<'a, Witness = Self>, T: ?Sized>(
proof: &'b Self::SelfType,
x: &'a T,
) -> &'b T;
}
impl<S> Equals for S {
type SelfType = Self;
fn convert_helper<'a, 'b, W: Convert<'a, Witness = Self>, T: ?Sized>(
proof: &'b Self,
x: &'a T,
) -> &'b T {
W::convert(proof, x)
}
}
fn main() {
let r;
{
let x = String::from("Hello World?");
r = extend_lifetime(&x);
}
println!("{}", r);
} The important thing that has to change IMO is that a |
Neither require nor imply lifetime bounds on opaque type for well formedness The actual hidden type can live arbitrarily longer than any individual lifetime and arbitrarily shorter than all but one of the lifetimes. fixes rust-lang#84305 fixes rust-lang#86218 (as a side effect, cc `@jackh726)` cc `@eddyb` opaque types need the same hack as functions, but out of a different reason. This is a **breaking change** but it is a necessary soundness fix
Neither require nor imply lifetime bounds on opaque type for well formedness The actual hidden type can live arbitrarily longer than any individual lifetime and arbitrarily shorter than all but one of the lifetimes. fixes rust-lang#84305 cc `@eddyb` opaque types need the same hack as functions, but out of a different reason. This is a **breaking change** but it is a necessary soundness fix
Neither require nor imply lifetime bounds on opaque type for well formedness The actual hidden type can live arbitrarily longer than any individual lifetime and arbitrarily shorter than all but one of the lifetimes. fixes rust-lang#84305 cc `@eddyb` opaque types need the same hack as functions, but out of a different reason. This is a **breaking change** but it is a necessary soundness fix
Neither require nor imply lifetime bounds on opaque type for well formedness The actual hidden type can live arbitrarily longer than any individual lifetime and arbitrarily shorter than all but one of the lifetimes. fixes rust-lang#84305 cc `@eddyb` opaque types need the same hack as functions, but out of a different reason. This is a **breaking change** but it is a necessary soundness fix
Neither require nor imply lifetime bounds on opaque type for well formedness The actual hidden type can live arbitrarily longer than any individual lifetime and arbitrarily shorter than all but one of the lifetimes. fixes rust-lang#84305 This is a **breaking change** but it is a necessary soundness fix
Neither require nor imply lifetime bounds on opaque type for well formedness The actual hidden type can live arbitrarily longer than any individual lifetime and arbitrarily shorter than all but one of the lifetimes. fixes rust-lang#84305 This is a **breaking change** but it is a necessary soundness fix
(playground)
So IMO the biggest problem in the code above is that the opaque type returned by
into_impl
implementsStaticDefaultRef
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
The text was updated successfully, but these errors were encountered: