// check-pass // edition:2018 #![feature(async_await)] #![feature(type_alias_impl_trait)] #![feature(impl_trait_in_bindings)] //~^ WARNING the feature `impl_trait_in_bindings` is incomplete // See issue 60414 ///////////////////////////////////////////// // Reduction to `impl Trait` struct Foo(T); trait FooLike { type Output; } impl FooLike for Foo { type Output = T; } mod impl_trait { use super::*; trait Trait { type Assoc; } /// `T::Assoc` should be normalized to `()` here. fn foo_pass>() -> impl FooLike { 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>::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>::Assoc> + 'a { Foo(&()) } } ///////////////////////////////////////////// // Reduction using `impl Trait` in bindings mod impl_trait_in_bindings { struct Foo; trait FooLike { type Output; } impl FooLike for Foo { type Output = u32; } trait Trait { type Assoc; } fn foo>() { let _: impl FooLike = Foo; } } ///////////////////////////////////////////// // The same applied to `existential type`s mod existential_types { trait Implemented { type Assoc; } impl Implemented for T { type Assoc = u8; } trait Trait { type Out; } impl Trait for () { type Out = u8; } type Ex = impl Trait::Assoc>; fn define() -> Ex { () } } fn main() {}