diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2022-09-04 18:55:45 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-09-04 18:55:45 +0200 |
| commit | dd35e2f79bd19f331ca8a0644400af99e5a598ae (patch) | |
| tree | a257d3ccb7bc15afb23778039df7ed89c0a78813 | |
| parent | 8f8a36d1c2795dcdab29d12a73cc49fd252ecc34 (diff) | |
| parent | 98f4b20abc9ad5ff77874119bbec305f4c7c6226 (diff) | |
| download | rust-dd35e2f79bd19f331ca8a0644400af99e5a598ae.tar.gz rust-dd35e2f79bd19f331ca8a0644400af99e5a598ae.zip | |
Rollup merge of #101388 - compiler-errors:issue-101376, r=fee1-dead
Don't delay invalid LHS bug unless it will be covered by an error in `check_overloaded_binop` Fixes #101376
| -rw-r--r-- | compiler/rustc_typeck/src/check/op.rs | 25 | ||||
| -rw-r--r-- | src/test/ui/typeck/assign-non-lval-needs-deref.rs | 19 | ||||
| -rw-r--r-- | src/test/ui/typeck/assign-non-lval-needs-deref.stderr | 16 |
3 files changed, 57 insertions, 3 deletions
diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs index 952086e898f..0d9dbb5bc11 100644 --- a/compiler/rustc_typeck/src/check/op.rs +++ b/compiler/rustc_typeck/src/check/op.rs @@ -57,9 +57,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) .is_ok() { - // Suppress this error, since we already emitted - // a deref suggestion in check_overloaded_binop - err.downgrade_to_delayed_bug(); + // If LHS += RHS is an error, but *LHS += RHS is successful, then we will have + // emitted a better suggestion during error handling in check_overloaded_binop. + if self + .lookup_op_method( + lhs_ty, + Some(rhs_ty), + Some(rhs), + Op::Binary(op, IsAssign::Yes), + expected, + ) + .is_err() + { + err.downgrade_to_delayed_bug(); + } else { + // Otherwise, it's valid to suggest dereferencing the LHS here. + err.span_suggestion_verbose( + lhs.span.shrink_to_lo(), + "consider dereferencing the left-hand side of this operation", + "*", + Applicability::MaybeIncorrect, + ); + } } } }); diff --git a/src/test/ui/typeck/assign-non-lval-needs-deref.rs b/src/test/ui/typeck/assign-non-lval-needs-deref.rs new file mode 100644 index 00000000000..c979d76b4f4 --- /dev/null +++ b/src/test/ui/typeck/assign-non-lval-needs-deref.rs @@ -0,0 +1,19 @@ +// issue #101376 + +use std::ops::AddAssign; +struct Foo; + +impl AddAssign<()> for Foo { + fn add_assign(&mut self, _: ()) {} +} + +impl AddAssign<()> for &mut Foo { + fn add_assign(&mut self, _: ()) {} +} + +fn main() { + (&mut Foo) += (); + //~^ ERROR invalid left-hand side of assignment + //~| NOTE cannot assign to this expression + //~| HELP consider dereferencing the left-hand side of this operation +} diff --git a/src/test/ui/typeck/assign-non-lval-needs-deref.stderr b/src/test/ui/typeck/assign-non-lval-needs-deref.stderr new file mode 100644 index 00000000000..ee83b145321 --- /dev/null +++ b/src/test/ui/typeck/assign-non-lval-needs-deref.stderr @@ -0,0 +1,16 @@ +error[E0067]: invalid left-hand side of assignment + --> $DIR/assign-non-lval-needs-deref.rs:15:16 + | +LL | (&mut Foo) += (); + | ---------- ^^ + | | + | cannot assign to this expression + | +help: consider dereferencing the left-hand side of this operation + | +LL | *(&mut Foo) += (); + | + + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0067`. |
