Skip to content

Commit b0950ca

Browse files
Report AsyncFn traits in async closure lifetime note
1 parent aa31d6d commit b0950ca

2 files changed

Lines changed: 25 additions & 20 deletions

File tree

compiler/rustc_borrowck/src/diagnostics/region_name.rs

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,12 @@ impl RegionName {
111111
| RegionNameSource::NamedEarlyParamRegion(span) => {
112112
diag.span_label(*span, format!("lifetime `{self}` defined here"));
113113
}
114-
RegionNameSource::SynthesizedFreeEnvRegion(span, note) => {
114+
RegionNameSource::SynthesizedFreeEnvRegion(span, closure_trait) => {
115115
diag.span_label(*span, format!("lifetime `{self}` represents this closure's body"));
116-
diag.note(*note);
116+
diag.note(format!(
117+
"closure implements `{closure_trait}`, so references to captured variables \
118+
can't escape the closure"
119+
));
117120
}
118121
RegionNameSource::AnonRegionFromArgument(RegionNameHighlight::CannotMatchHirTy(
119122
span,
@@ -326,9 +329,15 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
326329
ty::LateParamRegionKind::ClosureEnv => {
327330
let def_ty = self.regioncx.universal_regions().defining_ty;
328331

329-
let closure_kind = match def_ty {
330-
DefiningTy::Closure(_, args) => args.as_closure().kind(),
331-
DefiningTy::CoroutineClosure(_, args) => args.as_coroutine_closure().kind(),
332+
let (is_lending_coroutine_closure, closure_kind) = match def_ty {
333+
DefiningTy::Closure(_, args) => (false, args.as_closure().kind()),
334+
DefiningTy::CoroutineClosure(_, args) => {
335+
let args = args.as_coroutine_closure();
336+
(
337+
!args.tupled_upvars_ty().is_ty_var() && args.has_self_borrows(),
338+
args.kind(),
339+
)
340+
}
332341
_ => {
333342
// Can't have BrEnv in functions, constants or coroutines.
334343
bug!("BrEnv outside of closure.");
@@ -340,23 +349,19 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
340349
bug!("Closure is not defined by a closure expr");
341350
};
342351
let region_name = self.synthesize_region_name();
343-
let note = match closure_kind {
344-
ty::ClosureKind::Fn => {
345-
"closure implements `Fn`, so references to captured variables \
346-
can't escape the closure"
347-
}
348-
ty::ClosureKind::FnMut => {
349-
"closure implements `FnMut`, so references to captured variables \
350-
can't escape the closure"
351-
}
352-
ty::ClosureKind::FnOnce => {
353-
bug!("BrEnv in a `FnOnce` closure");
354-
}
352+
let closure_trait = match (is_lending_coroutine_closure, closure_kind) {
353+
(false, kind) => kind.as_str(),
354+
(true, ty::ClosureKind::Fn) => "AsyncFn",
355+
(true, ty::ClosureKind::FnMut) => "AsyncFnMut",
356+
(true, ty::ClosureKind::FnOnce) => "AsyncFnOnce",
355357
};
356358

357359
Some(RegionName {
358360
name: region_name,
359-
source: RegionNameSource::SynthesizedFreeEnvRegion(fn_decl_span, note),
361+
source: RegionNameSource::SynthesizedFreeEnvRegion(
362+
fn_decl_span,
363+
closure_trait,
364+
),
360365
})
361366
}
362367

tests/ui/async-await/async-closures/not-lending.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | let x = async move || -> &String { &s };
77
| | return type of async closure `{async closure body@$DIR/not-lending.rs:12:42: 12:48}` contains a lifetime `'2`
88
| lifetime `'1` represents this closure's body
99
|
10-
= note: closure implements `Fn`, so references to captured variables can't escape the closure
10+
= note: closure implements `AsyncFn`, so references to captured variables can't escape the closure
1111

1212
error: lifetime may not live long enough
1313
--> $DIR/not-lending.rs:16:31
@@ -18,7 +18,7 @@ LL | let x = async move || { &s };
1818
| | return type of async closure `{async closure body@$DIR/not-lending.rs:16:31: 16:37}` contains a lifetime `'2`
1919
| lifetime `'1` represents this closure's body
2020
|
21-
= note: closure implements `Fn`, so references to captured variables can't escape the closure
21+
= note: closure implements `AsyncFn`, so references to captured variables can't escape the closure
2222

2323
error: aborting due to 2 previous errors
2424

0 commit comments

Comments
 (0)