Skip to content

Commit

Permalink
Auto merge of #119328 - estebank:might_coerce_eq_typo, r=compiler-errors
Browse files Browse the repository at this point in the history
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 {}
   |             +
```
  • Loading branch information
bors committed Dec 27, 2023
2 parents 2df6406 + dc30eb1 commit eee93d8
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 3 deletions.
21 changes: 19 additions & 2 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1131,8 +1131,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut err = self.demand_suptype_diag(expr.span, expected_ty, actual_ty).unwrap();
let lhs_ty = self.check_expr(lhs);
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) {
(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(
Spanned { node: hir::BinOpKind::And | hir::BinOpKind::Or, .. },
_,
Expand All @@ -1142,7 +1151,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// if x == 1 && y == 2 { .. }
// +
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(
Spanned { node: hir::BinOpKind::And | hir::BinOpKind::Or, .. },
lhs_expr,
Expand All @@ -1152,7 +1165,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// if x == 1 && y == 2 { .. }
// +
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 {
(Applicability::MaybeIncorrect, false)
};
Expand Down
5 changes: 5 additions & 0 deletions tests/ui/type/type-check/assignment-expected-bool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,9 @@ fn main() {
let _: usize = 0 = 0;
//~^ ERROR mismatched types [E0308]
//~| ERROR invalid left-hand side of assignment [E0070]

let foo = &String::new();
let bar = "";
if foo = bar {}
//~^ ERROR mismatched types [E0308]
}
13 changes: 12 additions & 1 deletion tests/ui/type/type-check/assignment-expected-bool.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,18 @@ LL | let _: usize = 0 = 0;
| |
| 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.
For more information about an error, try `rustc --explain E0070`.

0 comments on commit eee93d8

Please sign in to comment.