| // Well-formedness of nested opaque types, i.e. `impl Sized` in | |
| // `type Outer = impl Trait<Assoc = impl Sized>`. We check that | |
| // the nested type is well-formed, even though this would also | |
| // be implied by the item bounds of the opaque being | |
| // well-formed. See the comments below. | |
| #![feature(type_alias_impl_trait)] | |
| struct IsStatic<T: 'static>(T); | |
| trait Trait<In> { | |
| type Out; | |
| fn get(&self) -> Result<Self::Out, ()> { | |
| Err(()) | |
| } | |
| } | |
| impl<T> Trait<&'static T> for () { | |
| type Out = IsStatic<T>; | |
| } | |
| // We could theoretically allow this (and previously did), as even | |
| // though the nested opaque is not well-formed, it can only be | |
| // used by normalizing the projection | |
| // <OuterOpaque1<T> as Trait<&'static T>>::Out | |
| // Assuming that we check that this projection is well-formed, the wf | |
| // of the nested opaque is implied. | |
| type OuterOpaque1<T> = impl Trait<&'static T, Out = impl Sized>; | |
| #[define_opaque(OuterOpaque1)] | |
| fn define<T>() -> OuterOpaque1<T> {} | |
| //~^ ERROR `T` may not live long enough | |
| fn define_rpit<T>() -> impl Trait<&'static T, Out = impl Sized> {} | |
| //~^ ERROR the parameter type `T` may not live long enough | |
| // Similar to `define` but here `impl Sized` can be referenced directly as | |
| // InnerOpaque<T>, so the `'static` bound is definitely required for | |
| // soundness. | |
| type InnerOpaque<T> = impl Sized; | |
| type OuterOpaque2<T> = impl Trait<&'static T, Out = InnerOpaque<T>>; | |
| #[define_opaque(OuterOpaque2)] | |
| fn define_nested_rpit<T>() -> OuterOpaque2<T> {} | |
| //~^ ERROR the parameter type `T` may not live long enough | |
| fn main() {} |