Rollup merge of #120322 - compiler-errors:higher-ranked-async-closures, r=oli-obk
Don't manually resolve async closures in `rustc_resolve`
There's a comment here that talks about doing this "[so] closure [args] are detected as upvars rather than normal closure arg usages", but we do upvar analysis on the HIR now:
cd6d8f2a04/compiler/rustc_passes/src/upvars.rs (L21-L29)
Removing this ad-hoc logic makes it so that `async |x: &str|` now introduces an implicit binder, like regular closures.
r? ```@oli-obk```
This commit is contained in:
commit
e400311486
@ -4424,35 +4424,6 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
ExprKind::Type(ref _type_expr, ref _ty) => {
|
||||
visit::walk_expr(self, expr);
|
||||
}
|
||||
// `async |x| ...` gets desugared to `|x| async {...}`, so we need to
|
||||
// resolve the arguments within the proper scopes so that usages of them inside the
|
||||
// closure are detected as upvars rather than normal closure arg usages.
|
||||
//
|
||||
// Similarly, `gen |x| ...` gets desugared to `|x| gen {...}`, so we handle that too.
|
||||
ExprKind::Closure(box ast::Closure {
|
||||
coroutine_kind: Some(_),
|
||||
ref fn_decl,
|
||||
ref body,
|
||||
..
|
||||
}) => {
|
||||
self.with_rib(ValueNS, RibKind::Normal, |this| {
|
||||
this.with_label_rib(RibKind::FnOrCoroutine, |this| {
|
||||
// Resolve arguments:
|
||||
this.resolve_params(&fn_decl.inputs);
|
||||
// No need to resolve return type --
|
||||
// the outer closure return type is `FnRetTy::Default`.
|
||||
|
||||
// Now resolve the inner closure
|
||||
{
|
||||
// No need to resolve arguments: the inner closure has none.
|
||||
// Resolve the return type:
|
||||
visit::walk_fn_ret_ty(this, &fn_decl.output);
|
||||
// Resolve the body
|
||||
this.visit_expr(body);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
// For closures, RibKind::FnOrCoroutine is added in visit_fn
|
||||
ExprKind::Closure(box ast::Closure {
|
||||
binder: ClosureBinder::For { ref generic_params, span },
|
||||
|
12
tests/ui/async-await/async-closures/higher-ranked.rs
Normal file
12
tests/ui/async-await/async-closures/higher-ranked.rs
Normal file
@ -0,0 +1,12 @@
|
||||
// edition:2021
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
fn main() {
|
||||
let x = async move |x: &str| {
|
||||
//~^ ERROR lifetime may not live long enough
|
||||
// This error is proof that the `&str` type is higher-ranked.
|
||||
// This won't work until async closures are fully impl'd.
|
||||
println!("{x}");
|
||||
};
|
||||
}
|
17
tests/ui/async-await/async-closures/higher-ranked.stderr
Normal file
17
tests/ui/async-await/async-closures/higher-ranked.stderr
Normal file
@ -0,0 +1,17 @@
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/higher-ranked.rs:6:34
|
||||
|
|
||||
LL | let x = async move |x: &str| {
|
||||
| ____________________________-___-_^
|
||||
| | | |
|
||||
| | | return type of closure `{async closure body@$DIR/higher-ranked.rs:6:34: 11:6}` contains a lifetime `'2`
|
||||
| | let's call the lifetime of this reference `'1`
|
||||
LL | |
|
||||
LL | | // This error is proof that the `&str` type is higher-ranked.
|
||||
LL | | // This won't work until async closures are fully impl'd.
|
||||
LL | | println!("{x}");
|
||||
LL | | };
|
||||
| |_____^ returning this value requires that `'1` must outlive `'2`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
Loading…
x
Reference in New Issue
Block a user