diff options
| author | bors <bors@rust-lang.org> | 2020-06-11 04:58:48 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-06-11 04:58:48 +0000 |
| commit | 3ddf48053e83f4949d00dcaf6eb8d9e28fc6bb95 (patch) | |
| tree | 77896eb87d9a6d0986920cd169e4468003ee3938 | |
| parent | e93cb961ba67c73815401291ab42b81e3e5733ae (diff) | |
| parent | c99164e7a13d7b2451464f3c0c066be9c7516a2b (diff) | |
| download | rust-3ddf48053e83f4949d00dcaf6eb8d9e28fc6bb95.tar.gz rust-3ddf48053e83f4949d00dcaf6eb8d9e28fc6bb95.zip | |
Auto merge of #71896 - spastorino:existential-assoc-types-variance, r=nikomatsakis
Relate existential associated types with variance Invariant
Fixes #71550 #72315
r? @nikomatsakis
The test case reported in that issue now errors with the following message ...
```
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'a in function call due to conflicting requirements
--> /tmp/test.rs:25:5
|
25 | bad(&Bar(PhantomData), x)
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 24:11...
--> /tmp/test.rs:24:11
|
24 | fn extend<'a, T>(x: &'a T) -> &'static T {
| ^^
note: ...so that reference does not outlive borrowed content
--> /tmp/test.rs:25:28
|
25 | bad(&Bar(PhantomData), x)
| ^
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the types are compatible
--> /tmp/test.rs:25:9
|
25 | bad(&Bar(PhantomData), x)
| ^^^^^^^^^^^^^^^^^
= note: expected `&'static T`
found `&T`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0495`.
```
I could also add that test case if we want to have a weaponized one too.
| -rw-r--r-- | src/librustc_middle/ty/relate.rs | 4 | ||||
| -rw-r--r-- | src/test/ui/coercion/coerce-expect-unsized-ascribed.stderr | 2 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-20605.stderr | 4 | ||||
| -rw-r--r-- | src/test/ui/variance/variance-associated-types2.nll.stderr | 12 | ||||
| -rw-r--r-- | src/test/ui/variance/variance-associated-types2.rs | 17 | ||||
| -rw-r--r-- | src/test/ui/variance/variance-associated-types2.stderr | 18 |
6 files changed, 52 insertions, 5 deletions
diff --git a/src/librustc_middle/ty/relate.rs b/src/librustc_middle/ty/relate.rs index d507fcbc194..67426b87c24 100644 --- a/src/librustc_middle/ty/relate.rs +++ b/src/librustc_middle/ty/relate.rs @@ -250,8 +250,8 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialProjection<'tcx> { &b.item_def_id, ))) } else { - let ty = relation.relate(&a.ty, &b.ty)?; - let substs = relation.relate(&a.substs, &b.substs)?; + let ty = relation.relate_with_variance(ty::Invariant, &a.ty, &b.ty)?; + let substs = relation.relate_with_variance(ty::Invariant, &a.substs, &b.substs)?; Ok(ty::ExistentialProjection { item_def_id: a.item_def_id, substs, ty }) } } diff --git a/src/test/ui/coercion/coerce-expect-unsized-ascribed.stderr b/src/test/ui/coercion/coerce-expect-unsized-ascribed.stderr index 44e5c6a99f7..93e16bac13b 100644 --- a/src/test/ui/coercion/coerce-expect-unsized-ascribed.stderr +++ b/src/test/ui/coercion/coerce-expect-unsized-ascribed.stderr @@ -121,7 +121,7 @@ error[E0308]: mismatched types LL | let _ = Box::new(|x| (x as u8)): Box<dyn Fn(i32) -> _>; | ^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn std::ops::Fn`, found closure | - = note: expected struct `std::boxed::Box<dyn std::ops::Fn(i32) -> _>` + = note: expected struct `std::boxed::Box<dyn std::ops::Fn(i32) -> u8>` found struct `std::boxed::Box<[closure@$DIR/coerce-expect-unsized-ascribed.rs:26:22: 26:35]>` error: aborting due to 14 previous errors diff --git a/src/test/ui/issues/issue-20605.stderr b/src/test/ui/issues/issue-20605.stderr index 89df58dd2dc..5e050f27ac5 100644 --- a/src/test/ui/issues/issue-20605.stderr +++ b/src/test/ui/issues/issue-20605.stderr @@ -1,10 +1,10 @@ -error[E0277]: the size for values of type `dyn std::iter::Iterator<Item = &mut u8>` cannot be known at compilation time +error[E0277]: the size for values of type `dyn std::iter::Iterator<Item = &'a mut u8>` cannot be known at compilation time --> $DIR/issue-20605.rs:2:17 | LL | for item in *things { *item = 0 } | ^^^^^^^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `dyn std::iter::Iterator<Item = &mut u8>` + = help: the trait `std::marker::Sized` is not implemented for `dyn std::iter::Iterator<Item = &'a mut u8>` = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait> = note: required by `std::iter::IntoIterator::into_iter` diff --git a/src/test/ui/variance/variance-associated-types2.nll.stderr b/src/test/ui/variance/variance-associated-types2.nll.stderr new file mode 100644 index 00000000000..27d1e184416 --- /dev/null +++ b/src/test/ui/variance/variance-associated-types2.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/variance-associated-types2.rs:13:12 + | +LL | fn take<'a>(_: &'a u32) { + | -- lifetime `'a` defined here +LL | let _: Box<dyn Foo<Bar = &'a u32>> = make(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + | + = help: consider replacing `'a` with `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/variance/variance-associated-types2.rs b/src/test/ui/variance/variance-associated-types2.rs new file mode 100644 index 00000000000..6a095fce7ab --- /dev/null +++ b/src/test/ui/variance/variance-associated-types2.rs @@ -0,0 +1,17 @@ +// Test that dyn Foo<Bar = T> is invariant with respect to T. +// Failure to enforce invariance here can be weaponized, see #71550 for details. + +trait Foo { + type Bar; +} + +fn make() -> Box<dyn Foo<Bar = &'static u32>> { + panic!() +} + +fn take<'a>(_: &'a u32) { + let _: Box<dyn Foo<Bar = &'a u32>> = make(); + //~^ ERROR mismatched types [E0308] +} + +fn main() {} diff --git a/src/test/ui/variance/variance-associated-types2.stderr b/src/test/ui/variance/variance-associated-types2.stderr new file mode 100644 index 00000000000..52cdd6493b0 --- /dev/null +++ b/src/test/ui/variance/variance-associated-types2.stderr @@ -0,0 +1,18 @@ +error[E0308]: mismatched types + --> $DIR/variance-associated-types2.rs:13:42 + | +LL | let _: Box<dyn Foo<Bar = &'a u32>> = make(); + | ^^^^^^ lifetime mismatch + | + = note: expected trait object `dyn Foo<Bar = &'a u32>` + found trait object `dyn Foo<Bar = &'static u32>` +note: the lifetime `'a` as defined on the function body at 12:9... + --> $DIR/variance-associated-types2.rs:12:9 + | +LL | fn take<'a>(_: &'a u32) { + | ^^ + = note: ...does not necessarily outlive the static lifetime + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. |
