Suggest deref non-lvalue mutable reference

This commit is contained in:
Michael Goulet 2022-03-04 21:59:13 -08:00
parent 4c5f6e6277
commit a5c4f4cc4b
6 changed files with 56 additions and 3 deletions

View file

@ -836,6 +836,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
lhs: &'tcx hir::Expr<'tcx>,
err_code: &'static str,
op_span: Span,
adjust_err: impl FnOnce(&mut DiagnosticBuilder<'tcx, ErrorGuaranteed>),
) {
if lhs.is_syntactic_place_expr() {
return;
@ -858,6 +859,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
});
adjust_err(&mut err);
err.emit();
}
@ -1050,9 +1053,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return self.tcx.ty_error();
}
self.check_lhs_assignable(lhs, "E0070", span);
let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
self.check_lhs_assignable(lhs, "E0070", span, |err| {
let rhs_ty = self.check_expr(&rhs);
if let ty::Ref(_, lhs_inner_ty, hir::Mutability::Mut) = lhs_ty.kind() {
if self.can_coerce(rhs_ty, *lhs_inner_ty) {
err.span_suggestion_verbose(
lhs.span.shrink_to_lo(),
"consider dereferencing here to assign to the mutable \
borrowed piece of memory",
"*".to_string(),
Applicability::MachineApplicable,
);
}
}
});
let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty, Some(lhs));
self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);

View file

@ -41,7 +41,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return_ty
};
self.check_lhs_assignable(lhs, "E0067", op.span);
self.check_lhs_assignable(lhs, "E0067", op.span, |_| {});
ty
}

View file

@ -0,0 +1,7 @@
// run-rustfix
fn main() {
let mut x = vec![1usize];
*x.last_mut().unwrap() = 2usize;
//~^ ERROR invalid left-hand side of assignment
}

View file

@ -0,0 +1,7 @@
// run-rustfix
fn main() {
let mut x = vec![1usize];
x.last_mut().unwrap() = 2usize;
//~^ ERROR invalid left-hand side of assignment
}

View file

@ -0,0 +1,16 @@
error[E0070]: invalid left-hand side of assignment
--> $DIR/assign-non-lval-mut-ref.rs:5:27
|
LL | x.last_mut().unwrap() = 2usize;
| --------------------- ^
| |
| cannot assign to this expression
|
help: consider dereferencing here to assign to the mutable borrowed piece of memory
|
LL | *x.last_mut().unwrap() = 2usize;
| +
error: aborting due to previous error
For more information about this error, try `rustc --explain E0070`.

View file

@ -5,6 +5,11 @@ LL | vec![].last_mut().unwrap() = 3_u8;
| -------------------------- ^
| |
| cannot assign to this expression
|
help: consider dereferencing here to assign to the mutable borrowed piece of memory
|
LL | *vec![].last_mut().unwrap() = 3_u8;
| +
error: aborting due to previous error