-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Explain move errors that occur due to method calls involving self
#72389
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
r? @nikomatsakis for review or reassignment |
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.
Skimming the code, it seems reasonable so far
80c1359
to
334d559
Compare
self
self
I'm happy with the current output of 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.
This is really nice, I think it's going to be a big improvement. I left some comments where it seems like the output could be further improved -- thoughts?
cc @estebank, I suspect you'd like to see this |
334d559
to
9f2eab1
Compare
This PR ended up accreting some non-diagnostic changes (serializing |
@Aaron1011 I think that would be good |
@nikomatsakis: I've split out the metadata and desguaring changes locally, but I don't see a way of testing them without this PR. Do you still want me to split them out, or would it be better to merge them with PR where they actually get tested? |
Fixes rust-lang#69977 When we parse a chain of method calls like `foo.a().b().c()`, each `MethodCallExpr` gets assigned a span that starts at the beginning of the call chain (`foo`). While this is useful for diagnostics, it means that `Location::caller` will return the same location for every call in a call chain. This PR makes us separately record the span of the function name and arguments for a method call (e.g. `b()` in `foo.a().b().c()`). This `Span` is passed through HIR lowering and MIR building to `TerminatorKind::Call`, where it is used in preference to `Terminator.source_info.span` when determining `Location::caller`. This new span is also useful for diagnostics where we want to emphasize a particular method call - for an example, see rust-lang#72389 (comment)
@Aaron1011 you mean that you split them out into distinct commits? I think if they can't be tested, they should probably stay in this PR. |
Rollup of 10 pull requests Successful merges: - rust-lang#71824 (Check for live drops in constants after drop elaboration) - rust-lang#72389 (Explain move errors that occur due to method calls involving `self`) - rust-lang#72556 (Fix trait alias inherent impl resolution) - rust-lang#72584 (Stabilize vec::Drain::as_slice) - rust-lang#72598 (Display information about captured variable in `FnMut` error) - rust-lang#73336 (Group `Pattern::strip_*` method together) - rust-lang#73341 (_match.rs: fix module doc comment) - rust-lang#73342 (Fix iterator copied() documentation example code) - rust-lang#73351 (Update E0446.md) - rust-lang#73353 (structural_match: non-structural-match ty closures) Failed merges: r? @ghost
@@ -237,6 +239,7 @@ impl<'hir> LoweringContext<'_, 'hir> { | |||
} | |||
|
|||
fn lower_binop(&mut self, b: BinOp) -> hir::BinOp { | |||
let span = self.mark_span_with_reason(DesugaringKind::Operator, b.span, None); |
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.
Uh this destroyed Clippy (23 UI tests suddenly failed) and send me on a multiple hour bisecting adventure. We need to enforce test-pass for Clippy ASAP 😄
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.
D'oh! Now that we are able to refactor clippy "in situ" that might be more reasonable, not sure. It'd be nice if we could at least get an "advisory" warning perhaps that clippy is affected.
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.
@nikomatsakis Normally rustc gates on clippy tests iirc, right now due to some temporary toolstate changes they don't.
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.
Given that this PR breaks the ability to understand if something comes from a macro desugaring or not, which is used in both clippy and rustc for diagnostics, I'm inclined to revert this until a solution that can preserve macro desugaring info is found.
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.
@Aaron1011 is also working on a fix that resurfaces that, i'm down to landing that as well, but as it currently stands I consider this a rustc bug
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.
Given that this PR breaks the ability to understand if something comes from a macro desugaring or not,
Nit: This was already broken any time we created an ExpnKind::Desugaring
span. However, DesugaringKind::Operator
is created much more frequently that other DesugaringKind
s (or it overlaps with macros/lint-able code in more cases), so it's more of an issue.
Following PR rust-lang#72389, we create many more spans with `ExpnKind::Desugaring`. This exposed a latent bug in Clippy - only the top-most `ExpnData` is considered when checking if code is the result of a macro expansion. If code emitted by a macro expansion gets annotated with an `ExpnKind::Desugaring` (e.g. an operator or a for loop), Clippy will incorrectly act as though this code is not the result of a macro expansion. This PR introduces the `ClosestAstOrMacro` enum, which allows linting code to quickly determine if a given `Span` is the result of a macro expansion. For any `ExpnId`, we keep track of closest `ExpnKind::Macro` or `ExpnKind::AstPass` in the `call_site` chain. This is determined when the `ExpnData` is set for an `ExpnId`, which allows us to avoid walking the entire chain in Clippy.
See rust-lang#73468 (comment) This removes the immediate need for PR rust-lang#73468, since Clippy will no longer be confused by the precense of a new `ExpnId` 'on top of' a macro expansion `ExpnId`. This makes some of the 'self move diagnostics' added by PR rust-lang#72389 slightly worse. I've left the operator-related diagnostics code in place, so it should be easy for a followup PR to plug in a new way of detecting desugared operators.
…r=petrochenkov Revert PR rust-lang#72389 - "Explain move errors that occur due to method calls involving `self" r? @petrochenkov
…Manishearth Revert PR rust-lang#72389 - "Explain move errors that occur due to method calls involving `self" r? @petrochenkov
This is a re-attempt of rust-lang#72389 (which was reverted in rust-lang#73594) Instead of using `ExpnKind::Desugaring` to represent operators, this PR checks the lang item directly.
This is a re-attempt of rust-lang#72389 (which was reverted in rust-lang#73594) Instead of using `ExpnKind::Desugaring` to represent operators, this PR checks the lang item directly.
…lf-msg, r=davidtwco Explain move errors that occur due to method calls involving `self` (take two) This is a re-attempt of rust-lang#72389 (which was reverted in rust-lang#73594) Instead of using `ExpnKind::Desugaring` to represent operators, this PR checks the lang item directly.
When calling a method that takes
self
(e.g.vec.into_iter()
), the method receiver is moved out of. If the method receiver is used again, a move error will be emitted::emits
However, the error message doesn't make it clear that the move is caused by the call to
into_iter
.This PR adds additional messages to move errors when the move is caused by using a value as the receiver of a
self
method::TODO:
FnOnce/FnMut/Fn
- we probably don't want to point at the unstable trait methodsShr::shr
) when the call was generated using the operator syntax (e.g.a >> b
)