Skip to content

Commit

Permalink
Auto merge of rust-lang#71896 - spastorino:existential-assoc-types-va…
Browse files Browse the repository at this point in the history
…riance, r=nikomatsakis

Relate existential associated types with variance Invariant

Fixes rust-lang#71550 rust-lang#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.
  • Loading branch information
bors committed Jun 11, 2020
2 parents e93cb96 + c99164e commit 3ddf480
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 5 deletions.
4 changes: 2 additions & 2 deletions src/librustc_middle/ty/relate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 })
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/coercion/coerce-expect-unsized-ascribed.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/issues/issue-20605.stderr
Original file line number Diff line number Diff line change
@@ -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`

Expand Down
12 changes: 12 additions & 0 deletions src/test/ui/variance/variance-associated-types2.nll.stderr
Original file line number Diff line number Diff line change
@@ -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

17 changes: 17 additions & 0 deletions src/test/ui/variance/variance-associated-types2.rs
Original file line number Diff line number Diff line change
@@ -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() {}
18 changes: 18 additions & 0 deletions src/test/ui/variance/variance-associated-types2.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 3ddf480

Please sign in to comment.