-
Notifications
You must be signed in to change notification settings - Fork 13.3k
For move errors, suggest match ergonomics instead of ref
#53147
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
r? @cramertj (rust_highfive has picked a reviewer for you, use r? to override) |
There are still tests to fix and bless, but I figured I'd see if this is the right idea before I start on that. |
9c4ca2d
to
0ff2dea
Compare
This comment has been minimized.
This comment has been minimized.
} | ||
err.span_suggestion( | ||
pat_span, |
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.
Can you change this span to point at the span of the &
/&mut
rather than the whole pattern? I think it would make it more clear exactly what you're suggesting to remove.
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.
Although that would mean that the "suggestion" now points at the wrong place, meaning that the applicability would need to indicate that it was intended to be read and performed by a human. Perhaps leaving as-is but making the change to the error message I suggested below would be better?
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.
Yeah, changing the help message looks like it would be clear enough. Good call.
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.
We could synthesize a new span from pat_span
by looking at it's string constents and remove the leading &
, whitespace, mut
(when appropriate) and any further whitespace. Once we've done that, we can create a new span that points at sp.lo()~sp.hi()-snippet.len()
. (I don't think that this is something urgent to do in this PR.)
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.
Ooh, thanks for reminding me about the whitespace between &
and mut
.
} | ||
err.span_suggestion( | ||
pat_span, | ||
"consider removing this borrow operator", |
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.
Nit: perhaps "consider removing the &
" / "consider removing the &mut
" would be clearer than "consider removing this borrow operator"?
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.
With the suggestion next to it it works as an introduction to the jargon that is sadly used in other places. The suggestion code should be enough to make it clear what we're telling the user to do, despite the jargon. That being said, the text could be "consider not borrowing here".
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.
IMO "consider removing this borrow operator: Foo::Bar(..)
" looks confusing, since "this" makes it sound like it's referring to Foo::Bar(..)
as a "borrow operator", which isn't what's going on. I personally find "consider removing the &
: Foo::Bar(...)
" easier to read.
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.
In the (probably rare) case where the pattern is a double reference (&&Foo::Bar(..)
), "consider not borrowing" would be sorta imprecise. But that might not be worth worrying about.
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.
Although, now that I think about it, I guess we could strip all the leading &
/&mut
instead of just the first one.
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.
That is if we don't change the span either. If we do, this could look like this:
error[E0507]: cannot move out of borrowed content
--> $DIR/dont-suggest-ref.rs:103:18
|
LL | let &X(_t) = s;
| - -- ^ cannot move out of borrowed content
| | |
| | data moved here
| | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
| help: consider removing this borrow
This looks great to me so far! Thanks so much for doing this-- I'm really excited about these new errors.
It seems like they're
I think it seems reasonable to make a note about |
_ => false, | ||
}, | ||
|
||
err.span_note( |
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.
This one
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.
Is there any particular applicability I should set on those suggestions?
The examples seem to be machine applicable. That being said, I am slightly worried about knock on effects on code after this error that is expecting a mutable borrow, for example. After applying the changes you will see new errors. This is fine most of the time, but it is less than ideal. I would go for MachineApplicable
for now.
err.span_note( | ||
binding_span, | ||
&format!( | ||
"move occurs because {} has type `{}`, \ |
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.
move occurs because `{}`
} | ||
err.span_suggestion( | ||
pat_span, | ||
"consider removing this borrow operator", |
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.
With the suggestion next to it it works as an introduction to the jargon that is sadly used in other places. The suggestion code should be enough to make it clear what we're telling the user to do, despite the jargon. That being said, the text could be "consider not borrowing here".
} | ||
err.span_suggestion( | ||
pat_span, |
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.
We could synthesize a new span from pat_span
by looking at it's string constents and remove the leading &
, whitespace, mut
(when appropriate) and any further whitespace. Once we've done that, we can create a new span that points at sp.lo()~sp.hi()-snippet.len()
. (I don't think that this is something urgent to do in this PR.)
Just realized that when destructuring a tuple, array, or struct, you end up with duplicate suggestions. Here's an example: #![feature(nll)]
struct X {
a: String,
b: String,
}
fn main() {
let x = X {
a: String::new(),
b: String::new(),
};
let &X { a, b } = &x;
}
I'm guessing I should probably collect them together and dedup them based on their span? |
That would be a great idea, and also present:
|
Also it turns out I messed up the logic for derefs that don't start with Edit: fixed. |
r? @estebank -- they know diagnostics better than I, and I've given what feedback I had to offer. |
@cramertj Thanks for your help! |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
8ddc3d6
to
2562312
Compare
This comment has been minimized.
This comment has been minimized.
60b3e5e
to
76d40fc
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
So I'm a little worried about combining the
It might also be nice to add a label on each variable showing its type, but I guess that would end up being verbose again. |
e1e7064
to
f4229b8
Compare
@bors r+ |
📌 Commit f4229b8 has been approved by |
⌛ Testing commit f4229b8 with merge 894c01f23b458da53696ae5bef2213d44ac208f3... |
💔 Test failed - status-travis |
@bors r+ |
📌 Commit 0023dd9 has been approved by |
For move errors, suggest match ergonomics instead of `ref` Partially fixes issue #52423. Also makes errors and suggestions more consistent between move-from-place and move-from-value errors. Limitations: - Only the first pattern in a match arm can have a "consider removing this borrow operator" suggestion. - Suggestions don't always compile as-is (see the TODOs in the test for details). Sorry for the really long test. I wanted to make sure I handled every case I could think of, and it turned out there were a lot of them. Questions: - Is there any particular applicability I should set on those suggestions? - Are the notes about the `Copy` trait excessive?
☀️ Test successful - status-appveyor, status-travis |
Partially fixes issue #52423. Also makes errors and suggestions more consistent between move-from-place and move-from-value errors.
Limitations:
Sorry for the really long test. I wanted to make sure I handled every case I could think of, and it turned out there were a lot of them.
Questions:
Copy
trait excessive?