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
Tweak error message when reborrowing &mut self
as mut
#47818
Conversation
r? @eddyb (rust_highfive has picked a reviewer for you, use r? to override) |
Why do I keep getting these?! Can we blacklist "error" and "suggest" for me in @rust-highfive? |
Sorry @eddyb, I'll make sure to set a reviewer going forward. I believe you were picked because you have substantial contributions to |
@@ -1,6 +1,8 @@ | |||
error[E0596]: cannot borrow immutable argument `self` as mutable | |||
--> $DIR/issue-31424.rs:17:15 | |||
| | |||
16 | fn foo(&mut self) { | |||
| --------- given this existing mutable borrow... |
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 agree the existing message is confusing, but this doesn't seem quite right. The problem is that &mut self
desugars to self: &mut Self
, and hence the variable self
itself is immutable and can't be borrowed mutably. I find pointing out the "existing mutable borrow" somewhat misleading, since it suggests that this is a problem of a borrow conflicting with another action, but that's not right right.
For example, this code compiles:
struct Foo {
u :u32,
}
impl Foo {
fn foo(mut self: &mut Self) {
|| {
let r = &mut self;
r.u += 1;
};
}
//~^^^^^ ERROR closure cannot assign to immutable argument `self` [E0595]
}
fn main() {}
I have to wonder -- rather than improve the diagnostics here, maybe we should make &mut self
desugar to mut self: &mut Self
so that these code snippets work?
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 agree that &mut self
should desugar to mut self
and should probably be accepted. That being said, I would like to keep the label to other cases like TestEnum::Item(ref mut x)
.
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 wonder if they should all desugar the same way? It seems like the error message is equally misleading here (or at least I find it misleading). The problem is that the binding is not mutable -- but why isn't it, anyway? I feel like we've been moving towards a place where it's ok to &mut
borrow an &mut
-- thanks to deref coercions etc -- and I wonder if we should just embrace it.
Not sure how to make this decision. Feels like a thin RFC, but still a highly visible change in some sense, certainly would want at least FCP!
cc @rust-lang/lang -- thoughts? The context is that &mut self
and ref mut foo
both desugar to an immutable binding, but people sometimes stub their toe writing &mut self
or &mut foo
, which results in an error (where &mut *self
and &mut *foo
would work).
@estebank -- that reminds me, the suggestion to remove &mut
(instead of adding *
) is not necessarily a good one. Removing &mut
can result in moves, where adding *
would work more often and be closer to the existing "intent" of the code, I think.
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.
Changing the semantics to accept this in all cases sounds eminently reasonable to me. I know I found it confusing at first, even though I'm now used to 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.
Interestingly, this also resolved something with match desugarings. I kind of forget the details now, but there was a minor inconsistency that centered about ref mut
not being mut
... maybe @cramertj remembers?
@estebank you want to try implementing those changes? Maybe we should open up an issue on it. |
@nikomatsakis can you create the ticket with any pitfalls on the new semantic that we should avoid? I believe I can take this up probably during the weekend. |
Closing in light of the conversation. |
&mut self
inside a closure, the error message doesn't point at the reborrow statement but at the closure signature (Confusing error message with closures #47774). While we should fix the span itself, in the meantime mention the binding being reborrowed in the span label.