[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.

Fixes rust-lang/rust#93093
This commit is contained in:
Alyssa Verkade
2022-01-22 15:35:09 -08:00
parent ecf72996ed
commit b885700c7b
3 changed files with 52 additions and 6 deletions

View File

@@ -488,12 +488,32 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
// don't create labels for compiler-generated spans
Some(_) => None,
None => {
let (span, suggestion) = suggest_ampmut(
self.infcx.tcx,
local_decl,
opt_assignment_rhs_span,
*opt_ty_info,
);
let (span, suggestion) = if name != kw::SelfLower {
suggest_ampmut(
self.infcx.tcx,
local_decl,
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))
}
}