Code change:
fn visit_async_fn( &mut self, id: NodeId, <del> async_node_id: NodeId, return_impl_trait_id: NodeId, </del> name: Name, span: Span, <del> visit_fn: impl FnOnce(&mut DefCollector<'a>) </del> <ins> header: &FnHeader, generics: &'a Generics, decl: &'a FnDecl, body: &'a Block, </ins> ) { <ins> let (closure_id, return_impl_trait_id) = match header.asyncness { IsAsync::Async { closure_id, return_impl_trait_id, } => (closure_id, return_impl_trait_id), _ => unreachable!(), }; </ins> // For async functions, we need to create their inner defs inside of a // closure to match their desugared representation. let fn_def_data = DefPathData::ValueNs(name.as_interned_str()); let fn_def = self.create_def(id, fn_def_data, ITEM_LIKE_SPACE, span); return self.with_parent(fn_def, |this| { this.create_def(return_impl_trait_id, DefPathData::ImplTrait, REGULAR_SPACE, span); <del> let closure_def = this.create_def(async_node_id, </del> <ins> visit::walk_generics(this, generics); visit::walk_fn_decl(this, decl); let closure_def = this.create_def(closure_id, </ins> DefPathData::ClosureExpr, REGULAR_SPACE, span); <del> this.with_parent(closure_def, visit_fn) </del> <ins> this.with_parent(closure_def, |this| { visit::walk_block(this, body); }) </ins> }) }

Related discussion:
text: suggested this is because when we lower the async function, we add `), whereas it should be parented as something outside of the impl trait context (as that is how such an expression would be parented, if it actually existing in the AST). I have a bit of code where I'd like to use a reference with a lifetime in an "async" function, which panics the compiler. I tried this code: I expected to see this happen: My understanding was that async functions are allowed to take references as parameters. helped to debug this a little bit and there is a suspicion that named lifetimes are somehow not properly propagated. I stumbled into this because I wanted to have 2 args with references, but if the lifetimes are elided the compiler asks for them to be . Adding them ICEs the compiler. Instead, this happened: I got a compiler panic. Backtrace:
suggested might be related
It would appear one can workaround this by using async blocks manually: I still need to test this does what I expect.
why do you need the immediately invoked closure there,
Yeah, just noticed. I think I also had some other issue / ICE, but I don't remember exactly what it was. Gonna have to check it again. Also, I don't think I knew that on blocks was a thing.
I didn't quite understand why I needed the move. I am trying to fix the original ICE, I think I got some time today tomorrow, hopefully, will make some progress. But compiler newbie, so might not work out.
You need to move to avoid the closure borrowing the references locally. It's the same situation as with I just removed all immeditaly invoked functions from eval :wink:
I am playing around with similar types of borrowing patterns, namely using StreamObj to carry a stream around inside of a struct. I can't seem to use the posted work-arounds: I am taking this working code and I'm refactoring it. Starts as: this works, compiles and runs. Then I try my hand at refactoring to move the stream out of the same scope as the await code pulling out values.