Skip to content

Commit eee93d8

Browse files
committed
Auto merge of rust-lang#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 {} | + ```
2 parents 2df6406 + dc30eb1 commit eee93d8

File tree

3 files changed

+36
-3
lines changed

3 files changed

+36
-3
lines changed

compiler/rustc_hir_typeck/src/expr.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -1131,8 +1131,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11311131
let mut err = self.demand_suptype_diag(expr.span, expected_ty, actual_ty).unwrap();
11321132
let lhs_ty = self.check_expr(lhs);
11331133
let rhs_ty = self.check_expr(rhs);
1134+
let refs_can_coerce = |lhs: Ty<'tcx>, rhs: Ty<'tcx>| {
1135+
let lhs = Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, lhs.peel_refs());
1136+
let rhs = Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, rhs.peel_refs());
1137+
self.can_coerce(rhs, lhs)
1138+
};
11341139
let (applicability, eq) = if self.can_coerce(rhs_ty, lhs_ty) {
11351140
(Applicability::MachineApplicable, true)
1141+
} else if refs_can_coerce(rhs_ty, lhs_ty) {
1142+
// The lhs and rhs are likely missing some references in either side. Subsequent
1143+
// suggestions will show up.
1144+
(Applicability::MaybeIncorrect, true)
11361145
} else if let ExprKind::Binary(
11371146
Spanned { node: hir::BinOpKind::And | hir::BinOpKind::Or, .. },
11381147
_,
@@ -1142,7 +1151,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11421151
// if x == 1 && y == 2 { .. }
11431152
// +
11441153
let actual_lhs_ty = self.check_expr(rhs_expr);
1145-
(Applicability::MaybeIncorrect, self.can_coerce(rhs_ty, actual_lhs_ty))
1154+
(
1155+
Applicability::MaybeIncorrect,
1156+
self.can_coerce(rhs_ty, actual_lhs_ty)
1157+
|| refs_can_coerce(rhs_ty, actual_lhs_ty),
1158+
)
11461159
} else if let ExprKind::Binary(
11471160
Spanned { node: hir::BinOpKind::And | hir::BinOpKind::Or, .. },
11481161
lhs_expr,
@@ -1152,7 +1165,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11521165
// if x == 1 && y == 2 { .. }
11531166
// +
11541167
let actual_rhs_ty = self.check_expr(lhs_expr);
1155-
(Applicability::MaybeIncorrect, self.can_coerce(actual_rhs_ty, lhs_ty))
1168+
(
1169+
Applicability::MaybeIncorrect,
1170+
self.can_coerce(actual_rhs_ty, lhs_ty)
1171+
|| refs_can_coerce(actual_rhs_ty, lhs_ty),
1172+
)
11561173
} else {
11571174
(Applicability::MaybeIncorrect, false)
11581175
};

tests/ui/type/type-check/assignment-expected-bool.rs

+5
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,9 @@ fn main() {
3131
let _: usize = 0 = 0;
3232
//~^ ERROR mismatched types [E0308]
3333
//~| ERROR invalid left-hand side of assignment [E0070]
34+
35+
let foo = &String::new();
36+
let bar = "";
37+
if foo = bar {}
38+
//~^ ERROR mismatched types [E0308]
3439
}

tests/ui/type/type-check/assignment-expected-bool.stderr

+12-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,18 @@ LL | let _: usize = 0 = 0;
135135
| |
136136
| expected due to this
137137

138-
error: aborting due to 13 previous errors
138+
error[E0308]: mismatched types
139+
--> $DIR/assignment-expected-bool.rs:37:8
140+
|
141+
LL | if foo = bar {}
142+
| ^^^^^^^^^ expected `bool`, found `()`
143+
|
144+
help: you might have meant to compare for equality
145+
|
146+
LL | if foo == bar {}
147+
| +
148+
149+
error: aborting due to 14 previous errors
139150

140151
Some errors have detailed explanations: E0070, E0308.
141152
For more information about an error, try `rustc --explain E0070`.

0 commit comments

Comments
 (0)