Code change:
With the following code: comes the following error: However, this function compiles correctly without the keyword.
cc
You can trigger this without async/await using : cc
Some more reduction in genericity and clearing up a few things: The problem is that is not know in impl trait items. It's also not related to the return position, but refers to any impl trait in the function. Outside of impl trait can be resolved without a problem, so it must be something related to the way impl trait reuses the generics of its parent.
It seems to be a missing normalization, most likely.
I have a local fix for reduction above, but is making this rather difficult as it makes output not work properly.
This also happens for definitions: My fix only seems to turn this into a cycle error for some reason. EDIT: Nevermind I just broke existential types in general lol
Marking as blocking, although I think there's minimal future compat risk. If push came to shove I personally would be ok with removing this from the blocking list. But then it looks like already fixed it =)
I think the problem is on this line of code: in particular, we "instantiate" the predicates -- meaning, substitute in the values for their type parameters -- but we never normalize them. We should be able to invoke the methods. Note that in this code we do have an available, as well, in . I think we should be able to invoke: this returns an  value, which contains obligations that must be pushed into .
Hmm, that code is only invoked if is true, which I think wouldn't be the case here since there are no region bounds at all (right?). I also noticed that does not exist in this context ( is an ), and there's no nearby either. However, another place where is called without normalizing the result is here, further down in the same file: there does exist (as does ). Quick testing shows that normalizing there fixes this issue as well, and as a bonus also fixes the issue with without ICEs!
good catch -- actually I think the lines you found are the ones I meant to direct you to in the first place. I see you have some other problems on the PR, looking now.

Related discussion:
text: <ins> // check-pass // edition:2018 #![feature(async_await)] #![feature(existential_type)] #![feature(impl_trait_in_bindings)] //~^ WARNING the feature `impl_trait_in_bindings` is incomplete // 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(&()) } } ///////////////////////////////////////////// // 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<T: Trait<Assoc=u32>>() { let _: impl FooLike<Output=T::Assoc> = Foo; } } ///////////////////////////////////////////// // The same applied to `existential type`s mod existential_types { trait Implemented { type Assoc; } impl<T> Implemented for T { type Assoc = u8; } trait Trait { type Out; } impl Trait for () { type Out = u8; } existential type Ex: Trait<Out = <() as Implemented>::Assoc>; fn define() -> Ex { () } } fn main() {} </ins>