diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-01-26 06:36:39 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-01-26 06:36:39 +0100 |
| commit | e4003114860fef6d2eaa56c394dbfe7e4bff0db2 (patch) | |
| tree | aa83abea2ffd9c72cf431ba78cfc889d2fcb71a0 | |
| parent | 626797b61db2467e4c6e8f5f180130e94d50c964 (diff) | |
| parent | 8c2ae804e386d0e8e49233d23ce35469316eea52 (diff) | |
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: https://github.com/rust-lang/rust/blob/cd6d8f2a04528f827ad3d399581c0f3502b15a72/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```
| -rw-r--r-- | compiler/rustc_resolve/src/late.rs | 29 | ||||
| -rw-r--r-- | tests/ui/async-await/async-closures/higher-ranked.rs | 12 | ||||
| -rw-r--r-- | tests/ui/async-await/async-closures/higher-ranked.stderr | 17 |
3 files changed, 29 insertions, 29 deletions
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index abd724a6cc2..18926463d6b 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -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 }, diff --git a/tests/ui/async-await/async-closures/higher-ranked.rs b/tests/ui/async-await/async-closures/higher-ranked.rs new file mode 100644 index 00000000000..f0bdcf691ae --- /dev/null +++ b/tests/ui/async-await/async-closures/higher-ranked.rs @@ -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}"); + }; +} diff --git a/tests/ui/async-await/async-closures/higher-ranked.stderr b/tests/ui/async-await/async-closures/higher-ranked.stderr new file mode 100644 index 00000000000..fb02a15b079 --- /dev/null +++ b/tests/ui/async-await/async-closures/higher-ranked.stderr @@ -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 + |
