From c99164e7a13d7b2451464f3c0c066be9c7516a2b Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 4 May 2020 17:27:09 -0300 Subject: [PATCH] Relate existential associated types with variance Invariant --- src/librustc_middle/ty/relate.rs | 4 ++-- .../coerce-expect-unsized-ascribed.stderr | 2 +- src/test/ui/issues/issue-20605.stderr | 4 ++-- .../variance-associated-types2.nll.stderr | 12 ++++++++++++ .../ui/variance/variance-associated-types2.rs | 17 +++++++++++++++++ .../variance/variance-associated-types2.stderr | 18 ++++++++++++++++++ 6 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/variance/variance-associated-types2.nll.stderr create mode 100644 src/test/ui/variance/variance-associated-types2.rs create mode 100644 src/test/ui/variance/variance-associated-types2.stderr diff --git a/src/librustc_middle/ty/relate.rs b/src/librustc_middle/ty/relate.rs index d507fcbc19404..67426b87c24f7 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 44e5c6a99f727..93e16bac13b87 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 _>; | ^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn std::ops::Fn`, found closure | - = note: expected struct `std::boxed::Box _>` + = note: expected struct `std::boxed::Box 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 89df58dd2dc1b..5e050f27ac546 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` cannot be known at compilation time +error[E0277]: the size for values of type `dyn std::iter::Iterator` 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` + = help: the trait `std::marker::Sized` is not implemented for `dyn std::iter::Iterator` = note: to learn more, visit = 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 0000000000000..27d1e1844167e --- /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> = 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 0000000000000..6a095fce7abfa --- /dev/null +++ b/src/test/ui/variance/variance-associated-types2.rs @@ -0,0 +1,17 @@ +// Test that dyn Foo 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> { + panic!() +} + +fn take<'a>(_: &'a u32) { + let _: Box> = 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 0000000000000..52cdd6493b06d --- /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> = make(); + | ^^^^^^ lifetime mismatch + | + = note: expected trait object `dyn Foo` + found trait object `dyn Foo` +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`.