Skip to content

Commit 72b1d15

Browse files
committed
Require that if the new type and LUB can coerce to each other, that they the coerced types must be the same.
1 parent 8b8ef10 commit 72b1d15

4 files changed

Lines changed: 81 additions & 7 deletions

File tree

compiler/rustc_hir_typeck/src/coercion.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -454,10 +454,22 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
454454

455455
let result = self.commit_if_ok(|_| coerce_inner(new_ty, prev_ty));
456456
let first_error = match result {
457-
Ok(_) => {
458-
return result.map(|r| InferOk {
459-
obligations: r.obligations,
460-
value: (r.value.0, r.value.1, CoerceDirection::ToPrev),
457+
Ok(forwd_result) => {
458+
let prev_ty = self.resolve_vars_if_possible(prev_ty);
459+
let new_ty = self.resolve_vars_if_possible(new_ty);
460+
let rev_result = self.commit_if_ok(|_| coerce_inner(prev_ty, new_ty));
461+
if let Ok(rev_result) = rev_result {
462+
let forwd_ty = self.resolve_vars_if_possible(forwd_result.value.1);
463+
let rev_ty = self.resolve_vars_if_possible(rev_result.value.1);
464+
let res = self.unify(forwd_ty, rev_ty, ForceLeakCheck::No);
465+
if let Err(e) = res {
466+
return Err(e);
467+
}
468+
}
469+
470+
return Ok(InferOk {
471+
obligations: forwd_result.obligations,
472+
value: (forwd_result.value.0, forwd_result.value.1, CoerceDirection::ToPrev),
461473
});
462474
}
463475
Err(e) => e,

tests/ui/coercion/multistep3.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//@ run-pass
1+
//@ check-fail
22

33
#![feature(unsize, coerce_unsized)]
44
#![allow(static_mut_refs)]
@@ -73,6 +73,7 @@ assert_arms(
7373
0 => &Wrap3(Inner) as &I,
7474
1 => &Wrap3(Inner) as &J,
7575
2 => &Wrap3(Inner) as &K,
76+
//~^ ERROR `match` arms have incompatible types
7677
_ => loop {},
7778
}.complete(),
7879
&[
@@ -87,6 +88,7 @@ assert_arms(
8788
0 => &Wrap3(Inner) as &I,
8889
1 => &Wrap3(Inner) as &K,
8990
2 => &Wrap3(Inner) as &J,
91+
//~^ ERROR `match` arms have incompatible types
9092
_ => loop {},
9193
}.complete(),
9294
&[
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
error[E0308]: `match` arms have incompatible types
2+
--> $DIR/multistep3.rs:75:18
3+
|
4+
LL | |i| match i {
5+
| _____________-
6+
LL | | 0 => &Wrap3(Inner) as &I,
7+
| | ------------------------ this is found to be of type `&Wrap3<dyn Dynable + Send>`
8+
LL | | 1 => &Wrap3(Inner) as &J,
9+
| | ------------------------ this is found to be of type `&Wrap3<dyn Dynable + Send>`
10+
LL | | 2 => &Wrap3(Inner) as &K,
11+
| | ^^^^^^^^^^^^^^^^^^^^^^^^ expected trait `Dynable`, found trait `Dynable + Send`
12+
LL | |
13+
LL | | _ => loop {},
14+
LL | | }.complete(),
15+
| |_________- `match` arms have incompatible types
16+
|
17+
= note: expected reference `&Wrap3<dyn Dynable + Send>`
18+
found reference `&Wrap3<(dyn Dynable + 'static)>`
19+
20+
error[E0308]: `match` arms have incompatible types
21+
--> $DIR/multistep3.rs:90:18
22+
|
23+
LL | |i| match i {
24+
| _____________-
25+
LL | | 0 => &Wrap3(Inner) as &I,
26+
| | ------------------------ this is found to be of type `&Wrap3<dyn Dynable>`
27+
LL | | 1 => &Wrap3(Inner) as &K,
28+
| | ------------------------ this is found to be of type `&Wrap3<dyn Dynable>`
29+
LL | | 2 => &Wrap3(Inner) as &J,
30+
| | ^^^^^^^^^^^^^^^^^^^^^^^^ expected trait `Dynable + Send`, found trait `Dynable`
31+
LL | |
32+
LL | | _ => loop {},
33+
LL | | }.complete(),
34+
| |_________- `match` arms have incompatible types
35+
|
36+
= note: expected reference `&Wrap3<dyn Dynable>`
37+
found reference `&Wrap3<(dyn Dynable + Send + 'static)>`
38+
39+
error: aborting due to 2 previous errors
40+
41+
For more information about this error, try `rustc --explain E0308`.

tests/ui/coercion/multistep5.stderr

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,25 @@ LL | 1 => &P as &P,
66
|
77
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`multistep5`)
88

9-
error: aborting due to 1 previous error
9+
error[E0308]: `match` arms have incompatible types
10+
--> $DIR/multistep5.rs:84:14
11+
|
12+
LL | let _a = match 0 {
13+
| ______________-
14+
LL | | 0 => &O as &O,
15+
| | ------------- this is found to be of type `&P`
16+
LL | | 1 => &P as &P,
17+
| | ------------- this is found to be of type `&P`
18+
LL | | 2 => &Q as &Q,
19+
| | ^^^^^^^^^^^^^ expected `&P`, found `&Q`
20+
LL | | _ => loop {},
21+
LL | | };
22+
| |_____- `match` arms have incompatible types
23+
|
24+
= note: expected reference `&P`
25+
found reference `&Q`
26+
27+
error: aborting due to 2 previous errors
1028

11-
For more information about this error, try `rustc --explain E0055`.
29+
Some errors have detailed explanations: E0055, E0308.
30+
For more information about an error, try `rustc --explain E0055`.

0 commit comments

Comments
 (0)