| //@ check-pass | |
| //@ edition:2018 | |
| //@ revisions: default sa | |
| #![feature(type_alias_impl_trait)] | |
| // See issue 60414 | |
| // Reduction to `impl Trait` | |
| struct Foo<T>(T); | |
| trait FooLike { | |
| type Output; | |
| } | |
| impl<T> FooLike for Foo<T> { | |
| type Output = T; | |
| } | |
| mod impl_trait { | |
| use super::*; | |
| trait Trait { | |
| type Assoc; | |
| } | |
| /// `T::Assoc` should be normalized to `()` here. | |
| fn foo_pass<T: Trait<Assoc = ()>>() -> impl FooLike<Output = T::Assoc> { | |
| Foo(()) | |
| } | |
| } | |
| // Same with lifetimes in the trait | |
| mod lifetimes { | |
| use super::*; | |
| trait Trait<'a> { | |
| type Assoc; | |
| } | |
| /// Like above. | |
| /// | |
| /// FIXME(#51525) -- the shorter notation `T::Assoc` winds up referencing `'static` here | |
| fn foo2_pass<'a, T: Trait<'a, Assoc = ()> + 'a>() | |
| -> impl FooLike<Output = <T as Trait<'a>>::Assoc> + 'a { | |
| Foo(()) | |
| } | |
| /// Normalization to type containing bound region. | |
| /// | |
| /// FIXME(#51525) -- the shorter notation `T::Assoc` winds up referencing `'static` here | |
| fn foo2_pass2<'a, T: Trait<'a, Assoc = &'a ()> + 'a>() | |
| -> impl FooLike<Output = <T as Trait<'a>>::Assoc> + 'a { | |
| Foo(&()) | |
| } | |
| } | |
| // The same applied to `type Foo = impl Bar`s | |
| mod opaque_types { | |
| trait Implemented { | |
| type Assoc; | |
| } | |
| impl<T> Implemented for T { | |
| type Assoc = u8; | |
| } | |
| trait Trait { | |
| type Out; | |
| } | |
| impl Trait for () { | |
| type Out = u8; | |
| } | |
| type Ex = impl Trait<Out = <() as Implemented>::Assoc>; | |
| #[define_opaque(Ex)] | |
| fn define() -> Ex { | |
| () | |
| } | |
| } | |
| fn main() {} |