Suggest deref non-lvalue mutable reference
This commit is contained in:
parent
4c5f6e6277
commit
a5c4f4cc4b
@ -836,6 +836,7 @@ pub(crate) fn check_lhs_assignable(
|
||||
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 @@ pub(crate) fn check_lhs_assignable(
|
||||
);
|
||||
});
|
||||
|
||||
adjust_err(&mut err);
|
||||
|
||||
err.emit();
|
||||
}
|
||||
|
||||
@ -1050,9 +1053,24 @@ fn check_expr_assign(
|
||||
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);
|
||||
|
@ -41,7 +41,7 @@ pub fn check_binop_assign(
|
||||
return_ty
|
||||
};
|
||||
|
||||
self.check_lhs_assignable(lhs, "E0067", op.span);
|
||||
self.check_lhs_assignable(lhs, "E0067", op.span, |_| {});
|
||||
|
||||
ty
|
||||
}
|
||||
|
7
src/test/ui/typeck/assign-non-lval-mut-ref.fixed
Normal file
7
src/test/ui/typeck/assign-non-lval-mut-ref.fixed
Normal 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
|
||||
}
|
7
src/test/ui/typeck/assign-non-lval-mut-ref.rs
Normal file
7
src/test/ui/typeck/assign-non-lval-mut-ref.rs
Normal 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
|
||||
}
|
16
src/test/ui/typeck/assign-non-lval-mut-ref.stderr
Normal file
16
src/test/ui/typeck/assign-non-lval-mut-ref.stderr
Normal 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`.
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user