mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 06:51:58 +00:00
Rollup merge of #93221 - alyssaverkade:fix-93093, r=wesleywiser
[borrowck] Fix help on mutating &self in async fns Previously, when rustc was provided an async function that tried to mutate through a shared reference to an implicit self (as shown in the ui test), rustc would suggest modifying the parameter signature to `&mut` + the fully qualified name of the ty (in the case of the repro `S`). If a user modified their code to match the suggestion, the compiler would not accept it. This commit modifies the suggestion so that when rustc is provided the ui test that is also attached in this commit, it suggests (correctly) `&mut self`. We try to be careful about distinguishing between implicit and explicit self annotations, since the latter seem to be handled correctly already. This is my first PR here so I'm pretty sure I probably missed something/could use better terminology. I also didn't try to make the match exhaustive since implicit self is the only real special case that I need to handle (that I'm aware of), and I'm pretty sure there's a cleaner way to do this so any advice would be greatly appreciated! (I'm also not terribly confident about how I wrote the ui tests) here is your cc as requested `@compiler-errors` This is an attempt to fix #93093
This commit is contained in:
commit
b622552e10
@ -488,12 +488,32 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||||||
// don't create labels for compiler-generated spans
|
// don't create labels for compiler-generated spans
|
||||||
Some(_) => None,
|
Some(_) => None,
|
||||||
None => {
|
None => {
|
||||||
let (span, suggestion) = suggest_ampmut(
|
let (span, suggestion) = if name != kw::SelfLower {
|
||||||
self.infcx.tcx,
|
suggest_ampmut(
|
||||||
local_decl,
|
self.infcx.tcx,
|
||||||
opt_assignment_rhs_span,
|
local_decl,
|
||||||
*opt_ty_info,
|
opt_assignment_rhs_span,
|
||||||
);
|
*opt_ty_info,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
match local_decl.local_info.as_deref() {
|
||||||
|
Some(LocalInfo::User(ClearCrossCrate::Set(
|
||||||
|
mir::BindingForm::Var(mir::VarBindingForm {
|
||||||
|
opt_ty_info: None,
|
||||||
|
..
|
||||||
|
}),
|
||||||
|
))) => {
|
||||||
|
suggest_ampmut_self(self.infcx.tcx, local_decl)
|
||||||
|
}
|
||||||
|
// explicit self (eg `self: &'a Self`)
|
||||||
|
_ => suggest_ampmut(
|
||||||
|
self.infcx.tcx,
|
||||||
|
local_decl,
|
||||||
|
opt_assignment_rhs_span,
|
||||||
|
*opt_ty_info,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
};
|
||||||
Some((true, span, suggestion))
|
Some((true, span, suggestion))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
14
src/test/ui/borrowck/issue-93093.rs
Normal file
14
src/test/ui/borrowck/issue-93093.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// edition:2018
|
||||||
|
struct S {
|
||||||
|
foo: usize,
|
||||||
|
}
|
||||||
|
impl S {
|
||||||
|
async fn bar(&self) { //~ HELP consider changing this to be a mutable reference
|
||||||
|
//~| SUGGESTION &mut self
|
||||||
|
self.foo += 1; //~ ERROR cannot assign to `self.foo`, which is behind a `&` reference [E0594]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
S { foo: 1 }.bar();
|
||||||
|
}
|
12
src/test/ui/borrowck/issue-93093.stderr
Normal file
12
src/test/ui/borrowck/issue-93093.stderr
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
error[E0594]: cannot assign to `self.foo`, which is behind a `&` reference
|
||||||
|
--> $DIR/issue-93093.rs:8:9
|
||||||
|
|
|
||||||
|
LL | async fn bar(&self) {
|
||||||
|
| ----- help: consider changing this to be a mutable reference: `&mut self`
|
||||||
|
LL |
|
||||||
|
LL | self.foo += 1;
|
||||||
|
| ^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0594`.
|
Loading…
Reference in New Issue
Block a user