Misleading "captured variable cannot escape FnMut closure body" diagnostic, should be "can't mutable borrow more than once" #140875
Labels
A-diagnostics
Area: Messages for errors, warnings, and lints
T-compiler
Relevant to the compiler team, which will review and decide on the PR/issue.
Code
https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=8f47967d049435bc0f84cb62a057a3eb
Current output
Desired output
The issue with this code is that the compiler can't statically guarantee that each
id
accesses a unique HashMap item. We know this to be true due to the definition of HashMap, but that's hard to prove with generic key and hasher types.The standard "cannot borrow
strs
as mutable more than once at a time" error would be much more helpful here. An error about accessing a collection item as mutable more than once at a time would be even more useful.Ideally, the compiler could encourage the user towards a working implementation like this:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=6242cd4dbc29ca60773cf4c674ece882
Rationale and extra context
The type of the closure is not explicit in this code, and the user doesn't have much influence over the inferred type. Even if the inferred type is changed, it doesn't really help the user understand why the problem is happening.
Other cases
This is similar to other issues about FnMut closures, but the solution and desired diagnostic output is different:
#99279
It's most similar to the diagnostic suggested here:
#44611 (comment)
Most online answers suggest using
Mutex
orRefCell
, which is completely unnecessary in this situation, and can lead to poorer performance, or runtime panics (if implemented incorrectly):https://www.reddit.com/r/rust/comments/qotdo1/comment/hjphkp7/
https://stackoverflow.com/a/62563511
The last one is actually closest, suggesting
fold
.Rust Version
(whatever environment is on play.rust-lang.org, but this isn't specific to the OS or commit)
Anything else?
This came up in real-world code when trying to create a mutable iterator across futures with associated data.
The implementation ensures each future has exactly one associated data item, so it is sound to return
(&mut Fut, &mut Data)
. And the user can't get at the futures or data without this method.thomaseizinger/rust-futures-bounded@008af99
The text was updated successfully, but these errors were encountered: