mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Detect misparsed binop caused by missing semi
When encountering ```rust foo() *bar = baz; ``` We currently emit potentially two errors, one for the return type of `foo` not being multiplyiable by the type of `bar`, and another for `foo() * bar` not being assignable. We now check for this case and suggest adding a semicolon in the right place. Fix #80446.
This commit is contained in:
parent
6f65201659
commit
231f93524d
@ -953,12 +953,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
});
|
||||
self.check_for_missing_semi(lhs, &mut err);
|
||||
|
||||
adjust_err(&mut err);
|
||||
|
||||
err.emit();
|
||||
}
|
||||
|
||||
/// 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) {
|
||||
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))
|
||||
&& rhs.is_syntactic_place_expr()
|
||||
{
|
||||
// v missing semicolon here
|
||||
// foo()
|
||||
// *bar = baz;
|
||||
// (#80446).
|
||||
err.span_suggestion_verbose(
|
||||
lhs.span.shrink_to_hi(),
|
||||
"you might have meant to write a semicolon here",
|
||||
";".to_string(),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if an expression `original_expr_id` comes from the condition of a while loop,
|
||||
/// as opposed from the body of a while loop, which we can naively check by iterating
|
||||
/// parents until we find a loop...
|
||||
|
@ -379,6 +379,22 @@ 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()
|
||||
{
|
||||
// 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,
|
||||
);
|
||||
}
|
||||
|
||||
let suggest_deref_binop =
|
||||
|err: &mut DiagnosticBuilder<'_, _>, lhs_deref_ty: Ty<'tcx>| {
|
||||
|
9
tests/ui/binop/false-binop-caused-by-missing-semi.rs
Normal file
9
tests/ui/binop/false-binop-caused-by-missing-semi.rs
Normal file
@ -0,0 +1,9 @@
|
||||
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}`
|
||||
println!("{y}");
|
||||
}
|
31
tests/ui/binop/false-binop-caused-by-missing-semi.stderr
Normal file
31
tests/ui/binop/false-binop-caused-by-missing-semi.stderr
Normal file
@ -0,0 +1,31 @@
|
||||
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
|
||||
|
|
||||
LL | / foo()
|
||||
LL | | *x = 0;
|
||||
| | - ^
|
||||
| |______|
|
||||
| cannot assign to this expression
|
||||
|
|
||||
help: you might have meant to write a semicolon here
|
||||
|
|
||||
LL | foo();
|
||||
| +
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0070, E0369.
|
||||
For more information about an error, try `rustc --explain E0070`.
|
Loading…
Reference in New Issue
Block a user