Skip to content

Commit 1e00e1b

Browse files
committed
upcasting traits requires only that things become more general
Revert the code that states that upcasting traits requires full equality and change to require that the source type is a subtype of the target type, as one would expect. As the comment states, this was an old bug that we didn't want to fix yet as it interacted poorly with the old leak-check. This fixes the old-lub-glb-object test, which was previously reporting too many errors (i.e., in the previous commit).
1 parent 5a7a850 commit 1e00e1b

File tree

4 files changed

+12
-40
lines changed

4 files changed

+12
-40
lines changed

src/librustc_trait_selection/traits/select/confirmation.rs

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -612,24 +612,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
612612

613613
// Require that the traits involved in this upcast are **equal**;
614614
// only the **lifetime bound** is changed.
615-
//
616-
// FIXME: This condition is arguably too strong -- it would
617-
// suffice for the source trait to be a *subtype* of the target
618-
// trait. In particular, changing from something like
619-
// `for<'a, 'b> Foo<'a, 'b>` to `for<'a> Foo<'a, 'a>` should be
620-
// permitted. And, indeed, in the in commit
621-
// 904a0bde93f0348f69914ee90b1f8b6e4e0d7cbc, this
622-
// condition was loosened. However, when the leak check was
623-
// added back, using subtype here actually guides the coercion
624-
// code in such a way that it accepts `old-lub-glb-object.rs`.
625-
// This is probably a good thing, but I've modified this to `.eq`
626-
// because I want to continue rejecting that test (as we have
627-
// done for quite some time) before we are firmly comfortable
628-
// with what our behavior should be there. -nikomatsakis
629615
let InferOk { obligations, .. } = self
630616
.infcx
631617
.at(&obligation.cause, obligation.param_env)
632-
.eq(target, source_trait) // FIXME -- see below
618+
.sup(target, source_trait)
633619
.map_err(|_| Unimplemented)?;
634620
nested.extend(obligations);
635621

src/test/mir-opt/address-of/rustc.address_of_reborrow.SimplifyCfg-initial.after.mir

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
| 8: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) } at $DIR/address-of.rs:16:12: 16:24
1313
| 9: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) } at $DIR/address-of.rs:16:12: 16:24
1414
| 10: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) } at $DIR/address-of.rs:18:5: 18:18
15-
| 11: Canonical { max_universe: U3, variables: [CanonicalVarInfo { kind: Region(U3) }], value: Ty(*const dyn std::marker::Send) } at $DIR/address-of.rs:20:5: 20:25
15+
| 11: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) } at $DIR/address-of.rs:20:5: 20:25
1616
| 12: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) } at $DIR/address-of.rs:23:12: 23:20
1717
| 13: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) } at $DIR/address-of.rs:23:12: 23:20
1818
| 14: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) } at $DIR/address-of.rs:24:12: 24:28
@@ -22,7 +22,7 @@
2222
| 18: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) } at $DIR/address-of.rs:26:12: 26:24
2323
| 19: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) } at $DIR/address-of.rs:26:12: 26:24
2424
| 20: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) } at $DIR/address-of.rs:28:5: 28:16
25-
| 21: Canonical { max_universe: U6, variables: [CanonicalVarInfo { kind: Region(U6) }], value: Ty(*mut dyn std::marker::Send) } at $DIR/address-of.rs:30:5: 30:23
25+
| 21: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) } at $DIR/address-of.rs:30:5: 30:23
2626
| 22: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) } at $DIR/address-of.rs:33:12: 33:18
2727
| 23: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) } at $DIR/address-of.rs:33:12: 33:18
2828
| 24: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32; 10]) } at $DIR/address-of.rs:34:12: 34:26
Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,22 @@
11
// Test that we give a note when the old LUB/GLB algorithm would have
22
// succeeded but the new code (which is stricter) gives an error.
33

4-
trait Foo<T, U> { }
4+
trait Foo<T, U> {}
55

6-
fn foo(
7-
x: &dyn for<'a, 'b> Foo<&'a u8, &'b u8>,
8-
y: &dyn for<'a> Foo<&'a u8, &'a u8>,
9-
) {
6+
fn foo(x: &dyn for<'a, 'b> Foo<&'a u8, &'b u8>, y: &dyn for<'a> Foo<&'a u8, &'a u8>) {
107
let z = match 22 {
8+
//~^ ERROR mismatched types
119
0 => x,
12-
_ => y, //~ ERROR `match` arms have incompatible types
10+
_ => y,
1311
};
1412
}
1513

16-
fn bar(
17-
x: &dyn for<'a, 'b> Foo<&'a u8, &'b u8>,
18-
y: &dyn for<'a> Foo<&'a u8, &'a u8>,
19-
) {
14+
fn bar(x: &dyn for<'a, 'b> Foo<&'a u8, &'b u8>, y: &dyn for<'a> Foo<&'a u8, &'a u8>) {
2015
// Accepted with explicit case:
2116
let z = match 22 {
2217
0 => x as &dyn for<'a> Foo<&'a u8, &'a u8>,
2318
_ => y,
2419
};
2520
}
2621

27-
fn main() {
28-
}
22+
fn main() {}
Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
error[E0308]: mismatched types
2-
--> $DIR/old-lub-glb-object.rs:10:13
2+
--> $DIR/old-lub-glb-object.rs:7:13
33
|
44
LL | let z = match 22 {
55
| _____________^
6+
LL | |
67
LL | | 0 => x,
78
LL | | _ => y,
89
LL | | };
@@ -11,15 +12,6 @@ LL | | };
1112
= note: expected trait object `dyn for<'a, 'b> Foo<&'a u8, &'b u8>`
1213
found trait object `dyn for<'a> Foo<&'a u8, &'a u8>`
1314

14-
error[E0308]: mismatched types
15-
--> $DIR/old-lub-glb-object.rs:22:14
16-
|
17-
LL | 0 => x as &dyn for<'a> Foo<&'a u8, &'a u8>,
18-
| ^ one type is more general than the other
19-
|
20-
= note: expected trait object `dyn for<'a> Foo<&'a u8, &'a u8>`
21-
found trait object `dyn for<'a, 'b> Foo<&'a u8, &'b u8>`
22-
23-
error: aborting due to 2 previous errors
15+
error: aborting due to previous error
2416

2517
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)