coerce_inner: use initial expected_ty
This commit is contained in:
parent
3964a55ba5
commit
f97c37f8ae
@ -1289,8 +1289,20 @@ fn coerce_inner<'a>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Error possibly reported in `check_assign` so avoid emitting error again.
|
// Error possibly reported in `check_assign` so avoid emitting error again.
|
||||||
err.emit_unless(expression.filter(|e| fcx.is_assign_to_bool(e, expected))
|
let assign_to_bool = expression
|
||||||
.is_some());
|
// #67273: Use initial expected type as opposed to `expected`.
|
||||||
|
// Otherwise we end up using prior coercions in e.g. a `match` expression:
|
||||||
|
// ```
|
||||||
|
// match i {
|
||||||
|
// 0 => true, // Because of this...
|
||||||
|
// 1 => i = 1, // ...`expected == bool` now, but not when checking `i = 1`.
|
||||||
|
// _ => (),
|
||||||
|
// };
|
||||||
|
// ```
|
||||||
|
.filter(|e| fcx.is_assign_to_bool(e, self.expected_ty()))
|
||||||
|
.is_some();
|
||||||
|
|
||||||
|
err.emit_unless(assign_to_bool);
|
||||||
|
|
||||||
self.final_ty = Some(fcx.tcx.types.err);
|
self.final_ty = Some(fcx.tcx.types.err);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
fn main() {
|
||||||
|
let mut i: i64;
|
||||||
|
// Expected type is an inference variable `?T`
|
||||||
|
// because the `match` is used as a statement.
|
||||||
|
// This is the "initial" type of the `coercion`.
|
||||||
|
match i {
|
||||||
|
// Add `bool` to the overall `coercion`.
|
||||||
|
0 => true,
|
||||||
|
|
||||||
|
// Necessary to cause the ICE:
|
||||||
|
1 => true,
|
||||||
|
|
||||||
|
// Suppose that we had `let _: bool = match i { ... }`.
|
||||||
|
// In that case, as the expected type would be `bool`,
|
||||||
|
// we would suggest `i == 1` as a fix.
|
||||||
|
//
|
||||||
|
// However, no type error happens when checking `i = 1` because `expected == ?T`,
|
||||||
|
// which will unify with `typeof(i = 1) == ()`.
|
||||||
|
//
|
||||||
|
// However, in #67273, we would delay the unification of this arm with the above
|
||||||
|
// because we used the hitherto accumulated coercion as opposed to the "initial" type.
|
||||||
|
2 => i = 1,
|
||||||
|
//~^ ERROR match arms have incompatible types
|
||||||
|
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
error[E0308]: match arms have incompatible types
|
||||||
|
--> $DIR/issue-67273-assignment-match-prior-arm-bool-expected-unit.rs:22:14
|
||||||
|
|
|
||||||
|
LL | / match i {
|
||||||
|
LL | | // Add `bool` to the overall `coercion`.
|
||||||
|
LL | | 0 => true,
|
||||||
|
| | ---- this is found to be of type `bool`
|
||||||
|
LL | |
|
||||||
|
LL | | // Necessary to cause the ICE:
|
||||||
|
LL | | 1 => true,
|
||||||
|
| | ---- this is found to be of type `bool`
|
||||||
|
... |
|
||||||
|
LL | | 2 => i = 1,
|
||||||
|
| | ^^^^^ expected `bool`, found `()`
|
||||||
|
... |
|
||||||
|
LL | | _ => (),
|
||||||
|
LL | | }
|
||||||
|
| |_____- `match` arms have incompatible types
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Reference in New Issue
Block a user