diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 9a2f242ec4e15..76d1b27e7e39b 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -961,7 +961,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Check if the expression that could not be assigned to was a typoed expression that - fn check_for_missing_semi(&self, expr: &'tcx hir::Expr<'tcx>, err: &mut Diagnostic) { + pub fn check_for_missing_semi( + &self, + expr: &'tcx hir::Expr<'tcx>, + err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, + ) -> bool { if let hir::ExprKind::Binary(binop, lhs, rhs) = expr.kind && let hir::BinOpKind::Mul = binop.node && self.tcx.sess.source_map().is_multiline(lhs.span.between(rhs.span)) @@ -977,7 +981,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ";".to_string(), Applicability::MachineApplicable, ); + return true; } + false } // Check if an expression `original_expr_id` comes from the condition of a while loop, diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index 92075c7832a97..f40406c67265a 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -379,21 +379,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (err, output_def_id) } }; - if self.tcx.sess.source_map().is_multiline(lhs_expr.span.between(rhs_expr.span)) - && let IsAssign::No = is_assign - && let hir::BinOpKind::Mul = op.node - && rhs_expr.is_syntactic_place_expr() + if self.check_for_missing_semi(expr, &mut err) + && let hir::Node::Expr(expr) = self.tcx.hir().get_parent(expr.hir_id) + && let hir::ExprKind::Assign(..) = expr.kind { - // v missing semicolon here - // foo() - // *bar = baz; - // (#80446). - err.span_suggestion_verbose( - lhs_expr.span.shrink_to_hi(), - "you might have meant to write a semicolon here", - ";".to_string(), - Applicability::MaybeIncorrect, - ); + // We defer to the later error produced by `check_lhs_assignable`. + err.delay_as_bug(); } let suggest_deref_binop = diff --git a/tests/ui/binop/false-binop-caused-by-missing-semi.fixed b/tests/ui/binop/false-binop-caused-by-missing-semi.fixed new file mode 100644 index 0000000000000..b47372c906486 --- /dev/null +++ b/tests/ui/binop/false-binop-caused-by-missing-semi.fixed @@ -0,0 +1,10 @@ +// run-rustfix +fn foo() {} +fn main() { + let mut y = 42; + let x = &mut y; + foo(); + *x = 0; //~ ERROR invalid left-hand side of assignment + let _ = x; + println!("{y}"); +} diff --git a/tests/ui/binop/false-binop-caused-by-missing-semi.rs b/tests/ui/binop/false-binop-caused-by-missing-semi.rs index 9cd32e1db500c..14671de7e5111 100644 --- a/tests/ui/binop/false-binop-caused-by-missing-semi.rs +++ b/tests/ui/binop/false-binop-caused-by-missing-semi.rs @@ -1,9 +1,10 @@ +// run-rustfix fn foo() {} fn main() { let mut y = 42; let x = &mut y; foo() *x = 0; //~ ERROR invalid left-hand side of assignment - //~^ ERROR cannot multiply `()` by `&mut {integer}` + let _ = x; println!("{y}"); } diff --git a/tests/ui/binop/false-binop-caused-by-missing-semi.stderr b/tests/ui/binop/false-binop-caused-by-missing-semi.stderr index 8d0f15fe2ea16..fca042b1c57d2 100644 --- a/tests/ui/binop/false-binop-caused-by-missing-semi.stderr +++ b/tests/ui/binop/false-binop-caused-by-missing-semi.stderr @@ -1,18 +1,5 @@ -error[E0369]: cannot multiply `()` by `&mut {integer}` - --> $DIR/false-binop-caused-by-missing-semi.rs:6:5 - | -LL | foo() - | ----- () -LL | *x = 0; - | ^- &mut {integer} - | -help: you might have meant to write a semicolon here - | -LL | foo(); - | + - error[E0070]: invalid left-hand side of assignment - --> $DIR/false-binop-caused-by-missing-semi.rs:6:8 + --> $DIR/false-binop-caused-by-missing-semi.rs:7:8 | LL | / foo() LL | | *x = 0; @@ -25,7 +12,6 @@ help: you might have meant to write a semicolon here LL | foo(); | + -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0070, E0369. -For more information about an error, try `rustc --explain E0070`. +For more information about this error, try `rustc --explain E0070`.