-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Add help message if a FnOnce is moved #41772
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
src/test/ui/fn_once-moved.stderr
Outdated
| ^^^^^^^^^^^^^^^ value used here after move | ||
| | ||
= help: closure was moved because it only implements `FnOnce` | ||
= note: move occurs because `debug_dump_dict` has type `[closure@$DIR/fn_once-moved.rs:15:27: 19:6 dict:std::collections::HashMap<i32, i32>]`, which does not implement the `Copy` trait |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this note be removed (only for this case)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering about this actually...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does actually have some helpful information: std::collections::HashMap<i32, i32> ... Copy
. I don't know if that's intentionally there, though...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should better keep it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, I think it should be removed. I highly doubt anyone will extract much value out of it -- particularly in non-trivial cases with more upvars. It'd be better to extend the upvar inference to track why a move is occurring, I suspect.
@GuillaumeGomez, interested in pursuing that?
21 | debug_dump_dict(); | ||
| ^^^^^^^^^^^^^^^ value used here after move | ||
| | ||
= help: closure was moved because it only implements `FnOnce` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this point at the closure's span? If so, the text should be changed to something along the lines of
error[E0382]: use of moved value: `debug_dump_dict`
--> $DIR/fn_once-moved.rs:21:5
15 | let debug_dump_dict = || {
| --------------- closure only implements `FnOnce` so calling it moves it
...
20 | debug_dump_dict();
| --------------- value moved here
21 | debug_dump_dict();
| ^^^^^^^^^^^^^^^ value used here after move
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point!
ty::TypeVariants::TyClosure(id, _) => { | ||
if let Ok(ty::ClosureKind::FnOnce) = | ||
ty::queries::closure_kind::try_get(self.tcx, DUMMY_SP, id) { | ||
err.help("closure was moved because it only implements `FnOnce`"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. I'm torn. This message is definitely an improvement. I wonder if we can't do better. One thing that would be really nice is if we could show why the closure implements FnOnce
(i.e., because it has a move from the environment, typically).
We would then say something like:
- closure cannot be invoked twice because it moves the variable
dict
out of its environment
Computing this would require modifying upvar.rs
to make the information available. But it seems worthwhile (it's been on my to-do list for a while). Possibly should be deferred to a separate PR, I'm not sure.
src/test/ui/fn_once-moved.stderr
Outdated
| ^^^^^^^^^^^^^^^ value used here after move | ||
| | ||
= help: closure was moved because it only implements `FnOnce` | ||
= note: move occurs because `debug_dump_dict` has type `[closure@$DIR/fn_once-moved.rs:15:27: 19:6 dict:std::collections::HashMap<i32, i32>]`, which does not implement the `Copy` trait |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, I think it should be removed. I highly doubt anyone will extract much value out of it -- particularly in non-trivial cases with more upvars. It'd be better to extend the upvar inference to track why a move is occurring, I suspect.
@GuillaumeGomez, interested in pursuing that?
(To be clear, I'd be happy to mentor those changes.) |
Totally interested in pursuing it. |
@GuillaumeGomez shall we start by landing this PR, or you want to pursue in this PR? The part of the code you have to look at a bit is in We would want to extend it with a span, I think. Then we could extend the We'll also have to change the Question for @eddyb -- is it ok to have a |
|
@nikomatsakis: I think it'll take me quite some time to finish the full changes requested, so better merge this one and I'll open another one once I'll start. It'll allow me to not be bothered by master's changes too much. |
@GuillaumeGomez ok, I opened #42065 and copied mentoring instructions in there. Maybe you or someone else will pick it up. I'd be happy to r+ this, except that I still think we should suppress the |
Ok, I'll remove it so we can move forward. |
a327aff
to
0c0d11b
Compare
Updated. |
@nikomatsakis approving @bors r+ |
📌 Commit 0c0d11b has been approved by |
☀️ Test successful - status-appveyor, status-travis |
Fixes #40855.
r? @eddyb