-
Notifications
You must be signed in to change notification settings - Fork 13k
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
NLL fails to suggest "try removing &mut
here"
#54720
Conversation
This comment has been minimized.
This comment has been minimized.
r=me but the incremental tests are unhappy. Looks like the test just needs to be updated though. You probably just need to change #[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
trait TraitChangeModeSelfOwnToMut: Sized {
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
fn method(mut self) {}
} to #[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
trait TraitChangeModeSelfOwnToMut: Sized {
#[rustc_dirty(label="Hir", cfg="cfail2")] // changed!
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
fn method(mut self) {}
} In particular, in the old system, the |
This commit adds an `ImplicitSelfKind` to the HIR and the MIR that keeps track of whether a implicit self argument is immutable by-value, mutable by-value, immutable reference or mutable reference so that the addition of the `mut` keyword can be suggested for the immutable by-value case.
This commit improves mutability error suggestions by suggesting the removal of `&mut` where a mutable borrow is being taken of a `&mut self` or a `self: &mut Self`.
} => | ||
{ | ||
err.span_label(span, format!("cannot {ACT}", ACT = act)); | ||
err.span_label(span, "try removing `&mut` 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.
I believe that if we use local_decl.source_info.span
here it would point at &mut self
instead of (&mut self)
, which would let you make it a machine applicable suggestion instead of a label. Changing this will likely require you to change the above condition, but marginally so.
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 might be misunderstanding but, wouldn't local_decl.source_info.span
point to the argument not the use of it as span
does?
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 believe you're right, I misread the code. It'd be nice to get the actual span to get the behavior I wanted, but it might be too hard to do in this case. Don't let it be a blocker.
@bors r+ |
📌 Commit 2be3069 has been approved by |
NLL fails to suggest "try removing `&mut` here" Fixes #51191. This PR adds ``try removing `&mut` here`` suggestions to functions where a mutable borrow is being taken of a `&mut self` or a `self: &mut Self`. This PR also enables the suggestion for adding a `mut` pattern to by-value implicit self arguments without `mut` patterns already. r? @nikomatsakis
☀️ Test successful - status-appveyor, status-travis |
/// (but not a `self: Xxx` one). | ||
pub has_implicit_self: bool, | ||
/// Does the function have an implicit self? | ||
pub implicit_self: ImplicitSelfKind, |
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 a bit sad, I was hoping this could stay out of the HIR permanently.
@@ -583,11 +583,27 @@ pub enum BindingForm<'tcx> { | |||
/// This is a binding for a non-`self` binding, or a `self` that has an explicit type. | |||
Var(VarBindingForm<'tcx>), | |||
/// Binding for a `self`/`&self`/`&mut self` binding where the type is implicit. | |||
ImplicitSelf, | |||
ImplicitSelf(ImplicitSelfKind), | |||
/// Reference used in a guard expression to ensure immutability. | |||
RefForGuard, | |||
} |
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 guess the ideal of lowering away pattern-matching completely is too naive in the face of diagnostics 😭
/// Represents a `fn x(self);`. | ||
Imm, | ||
/// Represents a `fn x(mut self);`. | ||
Mut, |
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't these two be distinguished by binding_mode
?
/// Represents a `fn x(&self);`. | ||
ImmRef, | ||
/// Represents a `fn x(&mut self);`. | ||
MutRef, |
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't these two be distinguished by type? (maybe even distinguish &self
from self
by type?)
Suggest removing `&mut` from a `&mut borrow` Modify the code added in rust-lang#54720. Closes rust-lang#75871
Fixes #51191.
This PR adds
try removing `&mut` here
suggestions to functions where a mutable borrow is being taken of a&mut self
or aself: &mut Self
. This PR also enables the suggestion for adding amut
pattern to by-value implicit self arguments withoutmut
patterns already.r? @nikomatsakis