about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthew Jasper <mjjasper1@gmail.com>2020-08-15 12:29:23 +0100
committerMatthew Jasper <mjjasper1@gmail.com>2020-10-06 11:19:32 +0100
commite42c97919cd5a7fe856865cfd1034dfe14206ceb (patch)
tree2480b6702640fd050134e7969534c164a4680bc6
parente674cf0200347c5e58f8a3867657187b12e7b496 (diff)
downloadrust-e42c97919cd5a7fe856865cfd1034dfe14206ceb.tar.gz
rust-e42c97919cd5a7fe856865cfd1034dfe14206ceb.zip
Don't require lifetime super-bounds on traits apply to trait objects of that trait
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs31
-rw-r--r--src/test/ui/traits/trait-object-supertrait-lifetime-bound.rs16
2 files changed, 33 insertions, 14 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 8c58d4191c5..7f9525c842a 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -439,26 +439,29 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         let upcast_trait_ref = upcast_trait_ref.unwrap();
 
-        // Check supertraits hold
+        // Check supertraits hold. This is so that their associated type bounds
+        // will be checked in the code below.
         for super_trait in tcx
             .super_predicates_of(trait_predicate.def_id())
             .instantiate(tcx, trait_predicate.trait_ref.substs)
             .predicates
             .into_iter()
         {
-            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.clone(),
-                normalized_super_trait,
-            ));
+            if let ty::PredicateAtom::Trait(..) = super_trait.skip_binders() {
+                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.clone(),
+                    normalized_super_trait,
+                ));
+            }
         }
 
         let assoc_types: Vec<_> = tcx
diff --git a/src/test/ui/traits/trait-object-supertrait-lifetime-bound.rs b/src/test/ui/traits/trait-object-supertrait-lifetime-bound.rs
new file mode 100644
index 00000000000..9d834727a4a
--- /dev/null
+++ b/src/test/ui/traits/trait-object-supertrait-lifetime-bound.rs
@@ -0,0 +1,16 @@
+// check-pass
+
+use std::any::Any;
+
+trait A<T>: Any {
+    fn m(&self) {}
+}
+
+impl<S, T: 'static> A<S> for T {}
+
+fn call_obj<'a>() {
+    let obj: &dyn A<&'a ()> = &();
+    obj.m();
+}
+
+fn main() {}