From 0d744ec6eca622aa63bb89f02e819e4270fa5794 Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Fri, 16 Nov 2018 08:25:46 -0500
Subject: [PATCH 1/2] improve debug output related to bound calculation

---
 src/librustc/traits/mod.rs                     |  7 ++++++-
 src/librustc_typeck/collect.rs                 | 11 +++++++++++
 src/librustc_typeck/outlives/implicit_infer.rs | 17 +++++++++++++----
 src/librustc_typeck/outlives/mod.rs            |  3 +++
 4 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index 33b689c60a118..8c3cd5e6612b9 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -700,7 +700,12 @@ fn do_normalize_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                      predicates: Vec<ty::Predicate<'tcx>>)
                                      -> Result<Vec<ty::Predicate<'tcx>>, ErrorReported>
 {
-    debug!("do_normalize_predicates({:?})", predicates);
+    debug!(
+        "do_normalize_predicates(predicates={:?}, region_context={:?}, cause={:?})",
+        predicates,
+        region_context,
+        cause,
+    );
     let span = cause.span;
     tcx.infer_ctxt().enter(|infcx| {
         // FIXME. We should really... do something with these region
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 6ef09d96fd153..f3c570e84009b 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -1608,10 +1608,21 @@ fn predicates_defined_on<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     def_id: DefId,
 ) -> Lrc<ty::GenericPredicates<'tcx>> {
+    debug!("predicates_defined_on({:?})", def_id);
     let mut result = tcx.explicit_predicates_of(def_id);
+    debug!(
+        "predicates_defined_on: explicit_predicates_of({:?}) = {:?}",
+        def_id,
+        result,
+    );
     let inferred_outlives = tcx.inferred_outlives_of(def_id);
     if !inferred_outlives.is_empty() {
         let span = tcx.def_span(def_id);
+        debug!(
+            "predicates_defined_on: inferred_outlives_of({:?}) = {:?}",
+            def_id,
+            inferred_outlives,
+        );
         Lrc::make_mut(&mut result)
             .predicates
             .extend(inferred_outlives.iter().map(|&p| (p, span)));
diff --git a/src/librustc_typeck/outlives/implicit_infer.rs b/src/librustc_typeck/outlives/implicit_infer.rs
index 132da8f5cea8d..101edac04c7d4 100644
--- a/src/librustc_typeck/outlives/implicit_infer.rs
+++ b/src/librustc_typeck/outlives/implicit_infer.rs
@@ -245,6 +245,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
     }
 }
 
+#[derive(Debug)]
 pub struct IgnoreSelfTy(bool);
 
 /// We also have to check the explicit predicates
@@ -270,10 +271,18 @@ pub fn check_explicit_predicates<'tcx>(
     explicit_map: &mut ExplicitPredicatesMap<'tcx>,
     ignore_self_ty: IgnoreSelfTy,
 ) {
-    debug!("def_id = {:?}", &def_id);
-    debug!("substs = {:?}", &substs);
-    debug!("explicit_map =  {:?}", explicit_map);
-    debug!("required_predicates = {:?}", required_predicates);
+    debug!(
+        "check_explicit_predicates(def_id={:?}, \
+         substs={:?}, \
+         explicit_map={:?}, \
+         required_predicates={:?}, \
+         ignore_self_ty={:?})",
+        def_id,
+        substs,
+        explicit_map,
+        required_predicates,
+        ignore_self_ty,
+    );
     let explicit_predicates = explicit_map.explicit_predicates_of(tcx, *def_id);
 
     for outlives_predicate in explicit_predicates.iter() {
diff --git a/src/librustc_typeck/outlives/mod.rs b/src/librustc_typeck/outlives/mod.rs
index cca77b20d9b30..1eb53ffc730f6 100644
--- a/src/librustc_typeck/outlives/mod.rs
+++ b/src/librustc_typeck/outlives/mod.rs
@@ -67,6 +67,9 @@ fn inferred_outlives_of<'a, 'tcx>(
                     }
                     err.emit();
                 }
+
+                debug!("inferred_outlives_of({:?}) = {:?}", item_def_id, predicates);
+
                 predicates
             }
 

From 6575988d8e383fedd3d5579577c05ef23e77913b Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Fri, 16 Nov 2018 08:58:55 -0500
Subject: [PATCH 2/2] handle trait objects formed from traits with `Self::Foo:
 'a` clauses

---
 .../outlives/implicit_infer.rs                | 21 ++++++++++++++-----
 .../ui/rfc-2093-infer-outlives/issue-54467.rs | 17 +++++++++++++++
 2 files changed, 33 insertions(+), 5 deletions(-)
 create mode 100644 src/test/ui/rfc-2093-infer-outlives/issue-54467.rs

diff --git a/src/librustc_typeck/outlives/implicit_infer.rs b/src/librustc_typeck/outlives/implicit_infer.rs
index 101edac04c7d4..30e304375fe0e 100644
--- a/src/librustc_typeck/outlives/implicit_infer.rs
+++ b/src/librustc_typeck/outlives/implicit_infer.rs
@@ -14,6 +14,7 @@ use rustc::hir::def_id::DefId;
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::ty::subst::{Kind, Subst, UnpackedKind};
 use rustc::ty::{self, Ty, TyCtxt};
+use rustc::ty::fold::TypeFoldable;
 use rustc::util::nodemap::FxHashMap;
 
 use super::explicit::ExplicitPredicatesMap;
@@ -311,13 +312,23 @@ pub fn check_explicit_predicates<'tcx>(
         //
         // Note that we do this check for self **before** applying `substs`. In the
         // case that `substs` come from a `dyn Trait` type, our caller will have
-        // included `Self = dyn Trait<'x, X>` as the value for `Self`. If we were
+        // included `Self = usize` as the value for `Self`. If we were
         // to apply the substs, and not filter this predicate, we might then falsely
         // conclude that e.g. `X: 'x` was a reasonable inferred requirement.
-        if let UnpackedKind::Type(ty) = outlives_predicate.0.unpack() {
-            if ty.is_self() && ignore_self_ty.0 {
-                debug!("skipping self ty = {:?}", &ty);
-                continue;
+        //
+        // Another similar case is where we have a inferred
+        // requirement like `<Self as Trait>::Foo: 'b`. We presently
+        // ignore such requirements as well (cc #54467)-- though
+        // conceivably it might be better if we could extract the `Foo
+        // = X` binding from the object type (there must be such a
+        // binding) and thus infer an outlives requirement that `X:
+        // 'b`.
+        if ignore_self_ty.0 {
+            if let UnpackedKind::Type(ty) = outlives_predicate.0.unpack() {
+                if ty.has_self_ty() {
+                    debug!("skipping self ty = {:?}", &ty);
+                    continue;
+                }
             }
         }
 
diff --git a/src/test/ui/rfc-2093-infer-outlives/issue-54467.rs b/src/test/ui/rfc-2093-infer-outlives/issue-54467.rs
new file mode 100644
index 0000000000000..438923e29246c
--- /dev/null
+++ b/src/test/ui/rfc-2093-infer-outlives/issue-54467.rs
@@ -0,0 +1,17 @@
+// Regression test for #54467:
+//
+// Here, the trait object has an "inferred outlives" requirement that
+// `<Self as MyIterator<'a>>::Item: 'a`; but since we don't know what
+// `Self` is, we were (incorrectly) messing things up, leading to
+// strange errors. This test ensures that we do not give compilation
+// errors.
+//
+// compile-pass
+
+trait MyIterator<'a>: Iterator where Self::Item: 'a { }
+
+struct MyStruct<'a, A> {
+    item: Box<dyn MyIterator<'a, Item = A>>
+}
+
+fn main() { }