diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index c7e0c35436afb..c3f3baf9d3d47 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -468,21 +468,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.predicates
.into_iter()
{
- if let ty::PredicateKind::Trait(..) = super_trait.kind().skip_binder() {
- let normalized_super_trait = normalize_with_depth_to(
- self,
- obligation.param_env,
- obligation.cause.clone(),
- obligation.recursion_depth + 1,
- super_trait,
- &mut nested,
- );
- nested.push(Obligation::new(
- obligation.cause.clone(),
- obligation.param_env,
- normalized_super_trait,
- ));
- }
+ let normalized_super_trait = normalize_with_depth_to(
+ self,
+ obligation.param_env,
+ obligation.cause.clone(),
+ obligation.recursion_depth + 1,
+ super_trait,
+ &mut nested,
+ );
+ nested.push(Obligation::new(
+ obligation.cause.clone(),
+ obligation.param_env,
+ normalized_super_trait,
+ ));
}
let assoc_types: Vec<_> = tcx
diff --git a/src/test/ui/traits/object/enforce-supertrait-projection.rs b/src/test/ui/traits/object/enforce-supertrait-projection.rs
new file mode 100644
index 0000000000000..0ea944ec2df55
--- /dev/null
+++ b/src/test/ui/traits/object/enforce-supertrait-projection.rs
@@ -0,0 +1,24 @@
+trait SuperTrait {
+ type A;
+ type B;
+}
+
+trait Trait: SuperTrait::B> {}
+
+fn transmute(x: A) -> B {
+ foo::>(x)
+ //~^ ERROR type mismatch resolving ` as SuperTrait>::A == B`
+}
+
+fn foo(x: T::A) -> B
+where
+ T: Trait,
+{
+ x
+}
+
+static X: u8 = 0;
+fn main() {
+ let x = transmute::<&u8, &[u8; 1_000_000]>(&X);
+ println!("{:?}", x[100_000]);
+}
diff --git a/src/test/ui/traits/object/enforce-supertrait-projection.stderr b/src/test/ui/traits/object/enforce-supertrait-projection.stderr
new file mode 100644
index 0000000000000..a3d17fabbe47f
--- /dev/null
+++ b/src/test/ui/traits/object/enforce-supertrait-projection.stderr
@@ -0,0 +1,26 @@
+error[E0271]: type mismatch resolving ` as SuperTrait>::A == B`
+ --> $DIR/enforce-supertrait-projection.rs:9:5
+ |
+LL | fn transmute(x: A) -> B {
+ | - - expected type parameter
+ | |
+ | found type parameter
+LL | foo::>(x)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `B`, found type parameter `A`
+ |
+ = note: expected type parameter `B`
+ found type parameter `A`
+ = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+ = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
+note: required by a bound in `foo`
+ --> $DIR/enforce-supertrait-projection.rs:15:8
+ |
+LL | fn foo(x: T::A) -> B
+ | --- required by a bound in this
+LL | where
+LL | T: Trait,
+ | ^^^^^^^^^^^^ required by this bound in `foo`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/traits/object/supertrait-lifetime-bound.nll.stderr b/src/test/ui/traits/object/supertrait-lifetime-bound.nll.stderr
new file mode 100644
index 0000000000000..ed2f8624357bb
--- /dev/null
+++ b/src/test/ui/traits/object/supertrait-lifetime-bound.nll.stderr
@@ -0,0 +1,11 @@
+error: lifetime may not live long enough
+ --> $DIR/supertrait-lifetime-bound.rs:10:5
+ |
+LL | fn test2<'a>() {
+ | -- lifetime `'a` defined here
+...
+LL | test1::, _>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/traits/object/supertrait-lifetime-bound.rs b/src/test/ui/traits/object/supertrait-lifetime-bound.rs
index 9d834727a4a1b..5349771693a2a 100644
--- a/src/test/ui/traits/object/supertrait-lifetime-bound.rs
+++ b/src/test/ui/traits/object/supertrait-lifetime-bound.rs
@@ -1,16 +1,14 @@
-// check-pass
+trait Foo: 'static { }
-use std::any::Any;
+trait Bar: Foo { }
-trait A: Any {
- fn m(&self) {}
-}
-
-impl A for T {}
+fn test1, S>() { }
-fn call_obj<'a>() {
- let obj: &dyn A<&'a ()> = &();
- obj.m();
+fn test2<'a>() {
+ // Here: the type `dyn Bar<&'a u32>` references `'a`,
+ // and so it does not outlive `'static`.
+ test1::, _>();
+ //~^ ERROR the type `(dyn Bar<&'a u32> + 'static)` does not fulfill the required lifetime
}
-fn main() {}
+fn main() { }
diff --git a/src/test/ui/traits/object/supertrait-lifetime-bound.stderr b/src/test/ui/traits/object/supertrait-lifetime-bound.stderr
new file mode 100644
index 0000000000000..c3d7f8cd0c1cd
--- /dev/null
+++ b/src/test/ui/traits/object/supertrait-lifetime-bound.stderr
@@ -0,0 +1,15 @@
+error[E0477]: the type `(dyn Bar<&'a u32> + 'static)` does not fulfill the required lifetime
+ --> $DIR/supertrait-lifetime-bound.rs:10:5
+ |
+LL | test1::, _>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: type must satisfy the static lifetime as required by this binding
+ --> $DIR/supertrait-lifetime-bound.rs:5:22
+ |
+LL | fn test1, S>() { }
+ | ^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0477`.