Skip to content

Commit

Permalink
Rollup merge of rust-lang#120322 - compiler-errors:higher-ranked-asyn…
Browse files Browse the repository at this point in the history
…c-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``
  • Loading branch information
matthiaskrgr committed Jan 26, 2024
2 parents 5fbd7fa + 8c2ae80 commit 0e1097e
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 29 deletions.
29 changes: 0 additions & 29 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
Expand Down
12 changes: 12 additions & 0 deletions tests/ui/async-await/async-closures/higher-ranked.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 17 additions & 0 deletions tests/ui/async-await/async-closures/higher-ranked.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 0e1097e

Please sign in to comment.