Auto merge of #119328 - estebank:might_coerce_eq_typo, r=compiler-errors

Suggest `=` to `==` in more cases, even in the face of reference mismatch

Given `foo: &String` and `bar: str`, suggest `==` when given `if foo = bar {}`:

```
error[E0308]: mismatched types
  --> $DIR/assignment-expected-bool.rs:37:8
   |
LL |     if foo = bar {}
   |        ^^^^^^^^^ expected `bool`, found `()`
   |
help: you might have meant to compare for equality
   |
LL |     if foo == bar {}
   |             +
```
This commit is contained in:
bors 2023-12-27 00:22:27 +00:00
commit eee93d8396
3 changed files with 36 additions and 3 deletions

View File

@ -1131,8 +1131,17 @@ fn check_expr_assign(
let mut err = self.demand_suptype_diag(expr.span, expected_ty, actual_ty).unwrap(); let mut err = self.demand_suptype_diag(expr.span, expected_ty, actual_ty).unwrap();
let lhs_ty = self.check_expr(lhs); let lhs_ty = self.check_expr(lhs);
let rhs_ty = self.check_expr(rhs); let rhs_ty = self.check_expr(rhs);
let refs_can_coerce = |lhs: Ty<'tcx>, rhs: Ty<'tcx>| {
let lhs = Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, lhs.peel_refs());
let rhs = Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, rhs.peel_refs());
self.can_coerce(rhs, lhs)
};
let (applicability, eq) = if self.can_coerce(rhs_ty, lhs_ty) { let (applicability, eq) = if self.can_coerce(rhs_ty, lhs_ty) {
(Applicability::MachineApplicable, true) (Applicability::MachineApplicable, true)
} else if refs_can_coerce(rhs_ty, lhs_ty) {
// The lhs and rhs are likely missing some references in either side. Subsequent
// suggestions will show up.
(Applicability::MaybeIncorrect, true)
} else if let ExprKind::Binary( } else if let ExprKind::Binary(
Spanned { node: hir::BinOpKind::And | hir::BinOpKind::Or, .. }, Spanned { node: hir::BinOpKind::And | hir::BinOpKind::Or, .. },
_, _,
@ -1142,7 +1151,11 @@ fn check_expr_assign(
// if x == 1 && y == 2 { .. } // if x == 1 && y == 2 { .. }
// + // +
let actual_lhs_ty = self.check_expr(rhs_expr); let actual_lhs_ty = self.check_expr(rhs_expr);
(Applicability::MaybeIncorrect, self.can_coerce(rhs_ty, actual_lhs_ty)) (
Applicability::MaybeIncorrect,
self.can_coerce(rhs_ty, actual_lhs_ty)
|| refs_can_coerce(rhs_ty, actual_lhs_ty),
)
} else if let ExprKind::Binary( } else if let ExprKind::Binary(
Spanned { node: hir::BinOpKind::And | hir::BinOpKind::Or, .. }, Spanned { node: hir::BinOpKind::And | hir::BinOpKind::Or, .. },
lhs_expr, lhs_expr,
@ -1152,7 +1165,11 @@ fn check_expr_assign(
// if x == 1 && y == 2 { .. } // if x == 1 && y == 2 { .. }
// + // +
let actual_rhs_ty = self.check_expr(lhs_expr); let actual_rhs_ty = self.check_expr(lhs_expr);
(Applicability::MaybeIncorrect, self.can_coerce(actual_rhs_ty, lhs_ty)) (
Applicability::MaybeIncorrect,
self.can_coerce(actual_rhs_ty, lhs_ty)
|| refs_can_coerce(actual_rhs_ty, lhs_ty),
)
} else { } else {
(Applicability::MaybeIncorrect, false) (Applicability::MaybeIncorrect, false)
}; };

View File

@ -31,4 +31,9 @@ fn main() {
let _: usize = 0 = 0; let _: usize = 0 = 0;
//~^ ERROR mismatched types [E0308] //~^ ERROR mismatched types [E0308]
//~| ERROR invalid left-hand side of assignment [E0070] //~| ERROR invalid left-hand side of assignment [E0070]
let foo = &String::new();
let bar = "";
if foo = bar {}
//~^ ERROR mismatched types [E0308]
} }

View File

@ -135,7 +135,18 @@ LL | let _: usize = 0 = 0;
| | | |
| expected due to this | expected due to this
error: aborting due to 13 previous errors error[E0308]: mismatched types
--> $DIR/assignment-expected-bool.rs:37:8
|
LL | if foo = bar {}
| ^^^^^^^^^ expected `bool`, found `()`
|
help: you might have meant to compare for equality
|
LL | if foo == bar {}
| +
error: aborting due to 14 previous errors
Some errors have detailed explanations: E0070, E0308. Some errors have detailed explanations: E0070, E0308.
For more information about an error, try `rustc --explain E0070`. For more information about an error, try `rustc --explain E0070`.