rustc_borrowck: fix async closure error note to report FnOnce rather than Fn#148713
rustc_borrowck: fix async closure error note to report FnOnce rather than Fn#148713InvalidPathException wants to merge 1 commit intorust-lang:mainfrom
Conversation
df041f8 to
fb3af1b
Compare
| "closure implements `FnOnce`, so references to captured variables \ | ||
| can't escape the closure" | ||
| } | ||
| }; |
There was a problem hiding this comment.
Any way this can look like
let note = format!("closure implements `{}`, so references to captured variables can't escape the closure", closure_kind.as_str());There was a problem hiding this comment.
I did think about this. Correct me if I'm wrong, RegionNameSource stores these as &'static str but format! gives String, so we cannot really get around it (at least in this way). If we do refactor then it might be a lot of diff for something we do not touch for years.
| DefiningTy::CoroutineClosure(_, args) => args.as_coroutine_closure().kind(), | ||
| DefiningTy::CoroutineClosure(_, args) => { | ||
| match args.as_coroutine_closure().kind() { | ||
| ty::ClosureKind::Fn => ty::ClosureKind::FnOnce, |
There was a problem hiding this comment.
didn't look into this myself, but this seems... quite suboptimal.
Why are we not properly updating the kind for coroutine closures instead so that we don't have to deal with this weird behavior here?
There was a problem hiding this comment.
rust/compiler/rustc_hir_typeck/src/closure.rs
Lines 206 to 252 in a7b3715
It is marked as
Fn at line 212, I don't know if I am wording it correctly but my understanding is the existing code conflates calling capability with the actual type/behavior. This is the root cause.rust/compiler/rustc_hir_typeck/src/upvar.rs
Lines 251 to 261 in a7b3715
This fixme seems related. It could be a way larger refactor and I am not sure if we want to have the right behavior first, or do the refactor as well. It probably warrants more discussion.
rust/src/doc/rustc-dev-guide/src/coroutine-closures.md
Lines 269 to 287 in a7b3715
Might need to update the docs too if we do that.
|
|
|
I feel like mentioning The closure kind is actually correct, just somewhat confusingly named... just because kind is This is to support the future which has been returned by calling the async closure borrowing from the closure itself, see #132706. We should instead change this diagnostic to talk about |
| ty::ClosureKind::Fn => ty::ClosureKind::FnOnce, | ||
| kind => kind, | ||
| } | ||
| } |
There was a problem hiding this comment.
so the fix here would be to check whether args.has_self_borrows and if so, talk about AsyncFn(Mut) instead
Fixes #148391
Root cause:
asyncclosures are treated like plainFnclosures because we never updated their kind after adding the async coroutine path.Symptom:
The compiler note tells users
closure implements Fn…, which is wrong for async closures and made the error message confusing. NotablyFnMutdoes not suffer from this issue.Fix:
With this fix we treat coroutine closures as FnOnce when building that note.
Testing:
Updated a UI test stderr file to reflect the correct wording. It also clearly demonstrates what was wrong.