about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSantiago Pastorino <spastorino@gmail.com>2020-12-02 12:19:38 -0300
committerSantiago Pastorino <spastorino@gmail.com>2020-12-02 12:19:38 -0300
commit37354ebc9794b0eb14b08c02177e3094c8fe91cd (patch)
treebc9a0e3278d1415afae16c30b375f4bae4f38e22
parentb7ebc6b0c1ba3c27ebb17c0b496ece778ef11e18 (diff)
downloadrust-37354ebc9794b0eb14b08c02177e3094c8fe91cd.tar.gz
rust-37354ebc9794b0eb14b08c02177e3094c8fe91cd.zip
Revert "Auto merge of #79209 - spastorino:trait-inheritance-self, r=nikomatsakis"
This reverts commit 349b3b324dade7ca638091db93ba08bbc443c63d, reversing
changes made to b776d1c3e3db8befabb123ebb1e46c3531eaed46.
-rw-r--r--compiler/rustc_infer/src/traits/util.rs34
-rw-r--r--compiler/rustc_middle/src/query/mod.rs15
-rw-r--r--compiler/rustc_middle/src/ty/context.rs38
-rw-r--r--compiler/rustc_middle/src/ty/query/keys.rs24
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs3
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs68
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/mod.rs8
-rw-r--r--compiler/rustc_typeck/src/collect.rs184
-rw-r--r--compiler/rustc_typeck/src/collect/item_bounds.rs4
-rw-r--r--src/test/incremental/cyclic-trait-hierarchy.rs10
-rw-r--r--src/test/ui/associated-type-bounds/ambiguous-associated-type2.rs12
-rw-r--r--src/test/ui/associated-type-bounds/ambiguous-associated-type2.stderr16
-rw-r--r--src/test/ui/associated-type-bounds/associated-item-through-where-clause.rs21
-rw-r--r--src/test/ui/associated-type-bounds/handle-predicates-that-can-define-assoc-type.rs10
-rw-r--r--src/test/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.rs10
-rw-r--r--src/test/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.stderr16
-rw-r--r--src/test/ui/associated-type-bounds/super-trait-referencing-self.rs12
-rw-r--r--src/test/ui/associated-type-bounds/super-trait-referencing.rs19
-rw-r--r--src/test/ui/associated-type-bounds/super-trait-where-referencing-self.rs27
-rw-r--r--src/test/ui/cycle-projection-based-on-where-clause.rs24
-rw-r--r--src/test/ui/cycle-projection-based-on-where-clause.stderr16
-rw-r--r--src/test/ui/cycle-trait/cycle-trait-supertrait-direct.stderr11
-rw-r--r--src/test/ui/cycle-trait/cycle-trait-supertrait-indirect.stderr18
-rw-r--r--src/test/ui/issues/issue-12511.stderr16
-rw-r--r--src/test/ui/issues/issue-20772.stderr6
-rw-r--r--src/test/ui/issues/issue-20825.stderr6
-rw-r--r--src/test/ui/issues/issue-22673.rs5
-rw-r--r--src/test/ui/issues/issue-22673.stderr16
28 files changed, 151 insertions, 498 deletions
diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs
index 93863ef1d50..8273c2d291d 100644
--- a/compiler/rustc_infer/src/traits/util.rs
+++ b/compiler/rustc_infer/src/traits/util.rs
@@ -1,10 +1,9 @@
 use smallvec::smallvec;
 
 use crate::traits::{Obligation, ObligationCause, PredicateObligation};
-use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
+use rustc_data_structures::fx::FxHashSet;
 use rustc_middle::ty::outlives::Component;
 use rustc_middle::ty::{self, ToPredicate, TyCtxt, WithConstness};
-use rustc_span::symbol::Ident;
 
 pub fn anonymize_predicate<'tcx>(
     tcx: TyCtxt<'tcx>,
@@ -288,37 +287,6 @@ pub fn transitive_bounds<'tcx>(
     elaborate_trait_refs(tcx, bounds).filter_to_traits()
 }
 
-/// A specialized variant of `elaborate_trait_refs` that only elaborates trait references that may
-/// define the given associated type `assoc_name`. It uses the
-/// `super_predicates_that_define_assoc_type` query to avoid enumerating super-predicates that
-/// aren't related to `assoc_item`.  This is used when resolving types like `Self::Item` or
-/// `T::Item` and helps to avoid cycle errors (see e.g. #35237).
-pub fn transitive_bounds_that_define_assoc_type<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    bounds: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
-    assoc_name: Ident,
-) -> FxIndexSet<ty::PolyTraitRef<'tcx>> {
-    let mut stack: Vec<_> = bounds.collect();
-    let mut trait_refs = FxIndexSet::default();
-
-    while let Some(trait_ref) = stack.pop() {
-        if trait_refs.insert(trait_ref) {
-            let super_predicates =
-                tcx.super_predicates_that_define_assoc_type((trait_ref.def_id(), Some(assoc_name)));
-            for (super_predicate, _) in super_predicates.predicates {
-                let bound_predicate = super_predicate.bound_atom();
-                let subst_predicate = super_predicate
-                    .subst_supertrait(tcx, &bound_predicate.rebind(trait_ref.skip_binder()));
-                if let Some(binder) = subst_predicate.to_opt_poly_trait_ref() {
-                    stack.push(binder.value);
-                }
-            }
-        }
-    }
-
-    trait_refs
-}
-
 ///////////////////////////////////////////////////////////////////////////
 // Other
 ///////////////////////////////////////////////////////////////////////////
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index b516810205f..7822ecc2c1f 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -433,23 +433,12 @@ rustc_queries! {
         /// full predicates are available (note that supertraits have
         /// additional acyclicity requirements).
         query super_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> {
-            desc { |tcx| "computing the super predicates of `{}`", tcx.def_path_str(key) }
-        }
-
-        /// The `Option<Ident>` is the name of an associated type. If it is `None`, then this query
-        /// returns the full set of predicates. If `Some<Ident>`, then the query returns only the
-        /// subset of super-predicates that reference traits that define the given associated type.
-        /// This is used to avoid cycles in resolving types like `T::Item`.
-        query super_predicates_that_define_assoc_type(key: (DefId, Option<rustc_span::symbol::Ident>)) -> ty::GenericPredicates<'tcx> {
-            desc { |tcx| "computing the super traits of `{}`{}",
-                tcx.def_path_str(key.0),
-                if let Some(assoc_name) = key.1 { format!(" with associated type name `{}`", assoc_name) } else { "".to_string() },
-            }
+            desc { |tcx| "computing the supertraits of `{}`", tcx.def_path_str(key) }
         }
 
         /// To avoid cycles within the predicates of a single item we compute
         /// per-type-parameter predicates for resolving `T::AssocTy`.
-        query type_param_predicates(key: (DefId, LocalDefId, rustc_span::symbol::Ident)) -> ty::GenericPredicates<'tcx> {
+        query type_param_predicates(key: (DefId, LocalDefId)) -> ty::GenericPredicates<'tcx> {
             desc { |tcx| "computing the bounds for type parameter `{}`", {
                 let id = tcx.hir().local_def_id_to_hir_id(key.1);
                 tcx.hir().ty_param_name(id)
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 744aa39b96c..7207e5a179e 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -51,7 +51,7 @@ use rustc_session::config::{BorrowckMode, CrateType, OutputFilenames};
 use rustc_session::lint::{Level, Lint};
 use rustc_session::Session;
 use rustc_span::source_map::MultiSpan;
-use rustc_span::symbol::{kw, sym, Ident, Symbol};
+use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 use rustc_target::abi::{Layout, TargetDataLayout, VariantIdx};
 use rustc_target::spec::abi;
@@ -2085,42 +2085,6 @@ impl<'tcx> TyCtxt<'tcx> {
         self.mk_fn_ptr(sig.map_bound(|sig| ty::FnSig { unsafety: hir::Unsafety::Unsafe, ..sig }))
     }
 
-    /// Given the def_id of a Trait `trait_def_id` and the name of an associated item `assoc_name`
-    /// returns true if the `trait_def_id` defines an associated item of name `assoc_name`.
-    pub fn trait_may_define_assoc_type(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
-        self.super_traits_of(trait_def_id).any(|trait_did| {
-            self.associated_items(trait_did)
-                .find_by_name_and_kind(self, assoc_name, ty::AssocKind::Type, trait_did)
-                .is_some()
-        })
-    }
-
-    /// Computes the def-ids of the transitive super-traits of `trait_def_id`. This (intentionally)
-    /// does not compute the full elaborated super-predicates but just the set of def-ids. It is used
-    /// to identify which traits may define a given associated type to help avoid cycle errors.
-    /// Returns a `DefId` iterator.
-    fn super_traits_of(self, trait_def_id: DefId) -> impl Iterator<Item = DefId> + 'tcx {
-        let mut set = FxHashSet::default();
-        let mut stack = vec![trait_def_id];
-
-        set.insert(trait_def_id);
-
-        iter::from_fn(move || -> Option<DefId> {
-            let trait_did = stack.pop()?;
-            let generic_predicates = self.super_predicates_of(trait_did);
-
-            for (predicate, _) in generic_predicates.predicates {
-                if let ty::PredicateAtom::Trait(data, _) = predicate.skip_binders() {
-                    if set.insert(data.def_id()) {
-                        stack.push(data.def_id());
-                    }
-                }
-            }
-
-            Some(trait_did)
-        })
-    }
-
     /// Given a closure signature, returns an equivalent fn signature. Detuples
     /// and so forth -- so e.g., if we have a sig with `Fn<(u32, i32)>` then
     /// you would get a `fn(u32, i32)`.
diff --git a/compiler/rustc_middle/src/ty/query/keys.rs b/compiler/rustc_middle/src/ty/query/keys.rs
index 3949c303f72..a005990264c 100644
--- a/compiler/rustc_middle/src/ty/query/keys.rs
+++ b/compiler/rustc_middle/src/ty/query/keys.rs
@@ -7,7 +7,7 @@ use crate::ty::subst::{GenericArg, SubstsRef};
 use crate::ty::{self, Ty, TyCtxt};
 use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
 use rustc_query_system::query::DefaultCacheSelector;
-use rustc_span::symbol::{Ident, Symbol};
+use rustc_span::symbol::Symbol;
 use rustc_span::{Span, DUMMY_SP};
 
 /// The `Key` trait controls what types can legally be used as the key
@@ -149,28 +149,6 @@ impl Key for (LocalDefId, DefId) {
     }
 }
 
-impl Key for (DefId, Option<Ident>) {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        self.0.krate
-    }
-    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
-        tcx.def_span(self.0)
-    }
-}
-
-impl Key for (DefId, LocalDefId, Ident) {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        self.0.krate
-    }
-    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
-        self.1.default_span(tcx)
-    }
-}
-
 impl Key for (CrateNum, DefId) {
     type CacheSelector = DefaultCacheSelector;
 
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index d6048d092b1..2fb9b3cd5d3 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -65,8 +65,7 @@ pub use self::util::{
     get_vtable_index_of_object_method, impl_item_is_final, predicate_for_trait_def, upcast_choices,
 };
 pub use self::util::{
-    supertrait_def_ids, supertraits, transitive_bounds, transitive_bounds_that_define_assoc_type,
-    SupertraitDefIds, Supertraits,
+    supertrait_def_ids, supertraits, transitive_bounds, SupertraitDefIds, Supertraits,
 };
 
 pub use self::chalk_fulfill::FulfillmentContext as ChalkFulfillmentContext;
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 915a15fd245..7888cb1b9f5 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -49,10 +49,9 @@ pub trait AstConv<'tcx> {
 
     fn default_constness_for_trait_bounds(&self) -> Constness;
 
-    /// Returns predicates in scope of the form `X: Foo<T>`, where `X`
-    /// is a type parameter `X` with the given id `def_id` and T
-    /// matches `assoc_name`. This is a subset of the full set of
-    /// predicates.
+    /// Returns predicates in scope of the form `X: Foo`, where `X` is
+    /// a type parameter `X` with the given id `def_id`. This is a
+    /// subset of the full set of predicates.
     ///
     /// This is used for one specific purpose: resolving "short-hand"
     /// associated type references like `T::Item`. In principle, we
@@ -61,12 +60,7 @@ pub trait AstConv<'tcx> {
     /// but this can lead to cycle errors. The problem is that we have
     /// to do this resolution *in order to create the predicates in
     /// the first place*. Hence, we have this "special pass".
-    fn get_type_parameter_bounds(
-        &self,
-        span: Span,
-        def_id: DefId,
-        assoc_name: Ident,
-    ) -> ty::GenericPredicates<'tcx>;
+    fn get_type_parameter_bounds(&self, span: Span, def_id: DefId) -> ty::GenericPredicates<'tcx>;
 
     /// Returns the lifetime to use when a lifetime is omitted (and not elided).
     fn re_infer(&self, param: Option<&ty::GenericParamDef>, span: Span)
@@ -768,7 +762,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
     }
 
     // Returns `true` if a bounds list includes `?Sized`.
-    pub fn is_unsized(&self, ast_bounds: &[&hir::GenericBound<'_>], span: Span) -> bool {
+    pub fn is_unsized(&self, ast_bounds: &[hir::GenericBound<'_>], span: Span) -> bool {
         let tcx = self.tcx();
 
         // Try to find an unbound in bounds.
@@ -826,7 +820,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
     fn add_bounds(
         &self,
         param_ty: Ty<'tcx>,
-        ast_bounds: &[&hir::GenericBound<'_>],
+        ast_bounds: &[hir::GenericBound<'_>],
         bounds: &mut Bounds<'tcx>,
     ) {
         let constness = self.default_constness_for_trait_bounds();
@@ -841,7 +835,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe) => {}
                 hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => self
                     .instantiate_lang_item_trait_ref(
-                        *lang_item, *span, *hir_id, args, param_ty, bounds,
+                        lang_item, span, hir_id, args, param_ty, bounds,
                     ),
                 hir::GenericBound::Outlives(ref l) => {
                     bounds.region_bounds.push((self.ast_region_to_region(l, None), l.span))
@@ -873,42 +867,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         sized_by_default: SizedByDefault,
         span: Span,
     ) -> Bounds<'tcx> {
-        let ast_bounds: Vec<_> = ast_bounds.iter().collect();
-        self.compute_bounds_inner(param_ty, &ast_bounds, sized_by_default, span)
-    }
-
-    /// Convert the bounds in `ast_bounds` that refer to traits which define an associated type
-    /// named `assoc_name` into ty::Bounds. Ignore the rest.
-    pub fn compute_bounds_that_match_assoc_type(
-        &self,
-        param_ty: Ty<'tcx>,
-        ast_bounds: &[hir::GenericBound<'_>],
-        sized_by_default: SizedByDefault,
-        span: Span,
-        assoc_name: Ident,
-    ) -> Bounds<'tcx> {
-        let mut result = Vec::new();
-
-        for ast_bound in ast_bounds {
-            if let Some(trait_ref) = ast_bound.trait_ref() {
-                if let Some(trait_did) = trait_ref.trait_def_id() {
-                    if self.tcx().trait_may_define_assoc_type(trait_did, assoc_name) {
-                        result.push(ast_bound);
-                    }
-                }
-            }
-        }
-
-        self.compute_bounds_inner(param_ty, &result, sized_by_default, span)
-    }
-
-    fn compute_bounds_inner(
-        &self,
-        param_ty: Ty<'tcx>,
-        ast_bounds: &[&hir::GenericBound<'_>],
-        sized_by_default: SizedByDefault,
-        span: Span,
-    ) -> Bounds<'tcx> {
         let mut bounds = Bounds::default();
 
         self.add_bounds(param_ty, ast_bounds, &mut bounds);
@@ -1077,8 +1035,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 // Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty`
                 // parameter to have a skipped binder.
                 let param_ty = tcx.mk_projection(assoc_ty.def_id, candidate.skip_binder().substs);
-                let ast_bounds: Vec<_> = ast_bounds.iter().collect();
-                self.add_bounds(param_ty, &ast_bounds, bounds);
+                self.add_bounds(param_ty, ast_bounds, bounds);
             }
         }
         Ok(())
@@ -1395,9 +1352,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             ty_param_def_id, assoc_name, span,
         );
 
-        let predicates = &self
-            .get_type_parameter_bounds(span, ty_param_def_id.to_def_id(), assoc_name)
-            .predicates;
+        let predicates =
+            &self.get_type_parameter_bounds(span, ty_param_def_id.to_def_id()).predicates;
 
         debug!("find_bound_for_assoc_item: predicates={:#?}", predicates);
 
@@ -1405,14 +1361,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         let param_name = tcx.hir().ty_param_name(param_hir_id);
         self.one_bound_for_assoc_type(
             || {
-                traits::transitive_bounds_that_define_assoc_type(
+                traits::transitive_bounds(
                     tcx,
                     predicates.iter().filter_map(|(p, _)| {
                         p.to_opt_poly_trait_ref().map(|trait_ref| trait_ref.value)
                     }),
-                    assoc_name,
                 )
-                .into_iter()
             },
             || param_name.to_string(),
             assoc_name,
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs
index 20c639a0031..f635e0b6f93 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs
@@ -20,7 +20,6 @@ use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::subst::GenericArgKind;
 use rustc_middle::ty::{self, Const, Ty, TyCtxt};
 use rustc_session::Session;
-use rustc_span::symbol::Ident;
 use rustc_span::{self, Span};
 use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode};
 
@@ -184,12 +183,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
         }
     }
 
-    fn get_type_parameter_bounds(
-        &self,
-        _: Span,
-        def_id: DefId,
-        _: Ident,
-    ) -> ty::GenericPredicates<'tcx> {
+    fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
         let tcx = self.tcx;
         let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
         let item_id = tcx.hir().ty_param_owner(hir_id);
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index f8b7ccb2cd6..0ff10abb60a 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -1,4 +1,3 @@
-// ignore-tidy-filelength
 //! "Collection" is the process of determining the type and other external
 //! details of each item in Rust. Collection is specifically concerned
 //! with *inter-procedural* things -- for example, for a function
@@ -80,7 +79,6 @@ pub fn provide(providers: &mut Providers) {
         projection_ty_from_predicates,
         explicit_predicates_of,
         super_predicates_of,
-        super_predicates_that_define_assoc_type,
         trait_explicit_predicates_and_bounds,
         type_param_predicates,
         trait_def,
@@ -312,17 +310,8 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
         }
     }
 
-    fn get_type_parameter_bounds(
-        &self,
-        span: Span,
-        def_id: DefId,
-        assoc_name: Ident,
-    ) -> ty::GenericPredicates<'tcx> {
-        self.tcx.at(span).type_param_predicates((
-            self.item_def_id,
-            def_id.expect_local(),
-            assoc_name,
-        ))
+    fn get_type_parameter_bounds(&self, span: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
+        self.tcx.at(span).type_param_predicates((self.item_def_id, def_id.expect_local()))
     }
 
     fn re_infer(&self, _: Option<&ty::GenericParamDef>, _: Span) -> Option<ty::Region<'tcx>> {
@@ -503,7 +492,7 @@ fn get_new_lifetime_name<'tcx>(
 /// `X: Foo` where `X` is the type parameter `def_id`.
 fn type_param_predicates(
     tcx: TyCtxt<'_>,
-    (item_def_id, def_id, assoc_name): (DefId, LocalDefId, Ident),
+    (item_def_id, def_id): (DefId, LocalDefId),
 ) -> ty::GenericPredicates<'_> {
     use rustc_hir::*;
 
@@ -528,7 +517,7 @@ fn type_param_predicates(
     let mut result = parent
         .map(|parent| {
             let icx = ItemCtxt::new(tcx, parent);
-            icx.get_type_parameter_bounds(DUMMY_SP, def_id.to_def_id(), assoc_name)
+            icx.get_type_parameter_bounds(DUMMY_SP, def_id.to_def_id())
         })
         .unwrap_or_default();
     let mut extend = None;
@@ -571,18 +560,12 @@ fn type_param_predicates(
 
     let icx = ItemCtxt::new(tcx, item_def_id);
     let extra_predicates = extend.into_iter().chain(
-        icx.type_parameter_bounds_in_generics(
-            ast_generics,
-            param_id,
-            ty,
-            OnlySelfBounds(true),
-            Some(assoc_name),
-        )
-        .into_iter()
-        .filter(|(predicate, _)| match predicate.skip_binders() {
-            ty::PredicateAtom::Trait(data, _) => data.self_ty().is_param(index),
-            _ => false,
-        }),
+        icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty, OnlySelfBounds(true))
+            .into_iter()
+            .filter(|(predicate, _)| match predicate.skip_binders() {
+                ty::PredicateAtom::Trait(data, _) => data.self_ty().is_param(index),
+                _ => false,
+            }),
     );
     result.predicates =
         tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(extra_predicates));
@@ -600,7 +583,6 @@ impl ItemCtxt<'tcx> {
         param_id: hir::HirId,
         ty: Ty<'tcx>,
         only_self_bounds: OnlySelfBounds,
-        assoc_name: Option<Ident>,
     ) -> Vec<(ty::Predicate<'tcx>, Span)> {
         let constness = self.default_constness_for_trait_bounds();
         let from_ty_params = ast_generics
@@ -611,10 +593,6 @@ impl ItemCtxt<'tcx> {
                 _ => None,
             })
             .flat_map(|bounds| bounds.iter())
-            .filter(|b| match assoc_name {
-                Some(assoc_name) => self.bound_defines_assoc_item(b, assoc_name),
-                None => true,
-            })
             .flat_map(|b| predicates_from_bound(self, ty, b, constness));
 
         let from_where_clauses = ast_generics
@@ -633,34 +611,12 @@ impl ItemCtxt<'tcx> {
                 } else {
                     None
                 };
-                bp.bounds
-                    .iter()
-                    .filter(|b| match assoc_name {
-                        Some(assoc_name) => self.bound_defines_assoc_item(b, assoc_name),
-                        None => true,
-                    })
-                    .filter_map(move |b| bt.map(|bt| (bt, b)))
+                bp.bounds.iter().filter_map(move |b| bt.map(|bt| (bt, b)))
             })
             .flat_map(|(bt, b)| predicates_from_bound(self, bt, b, constness));
 
         from_ty_params.chain(from_where_clauses).collect()
     }
-
-    fn bound_defines_assoc_item(&self, b: &hir::GenericBound<'_>, assoc_name: Ident) -> bool {
-        debug!("bound_defines_assoc_item(b={:?}, assoc_name={:?})", b, assoc_name);
-
-        match b {
-            hir::GenericBound::Trait(poly_trait_ref, _) => {
-                let trait_ref = &poly_trait_ref.trait_ref;
-                if let Some(trait_did) = trait_ref.trait_def_id() {
-                    self.tcx.trait_may_define_assoc_type(trait_did, assoc_name)
-                } else {
-                    false
-                }
-            }
-            _ => false,
-        }
-    }
 }
 
 /// Tests whether this is the AST for a reference to the type
@@ -1029,90 +985,54 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::AdtDef {
 /// the transitive super-predicates are converted.
 fn super_predicates_of(tcx: TyCtxt<'_>, trait_def_id: DefId) -> ty::GenericPredicates<'_> {
     debug!("super_predicates(trait_def_id={:?})", trait_def_id);
-    tcx.super_predicates_that_define_assoc_type((trait_def_id, None))
-}
-
-/// Ensures that the super-predicates of the trait with a `DefId`
-/// of `trait_def_id` are converted and stored. This also ensures that
-/// the transitive super-predicates are converted.
-fn super_predicates_that_define_assoc_type(
-    tcx: TyCtxt<'_>,
-    (trait_def_id, assoc_name): (DefId, Option<Ident>),
-) -> ty::GenericPredicates<'_> {
-    debug!(
-        "super_predicates_that_define_assoc_type(trait_def_id={:?}, assoc_name={:?})",
-        trait_def_id, assoc_name
-    );
-    if trait_def_id.is_local() {
-        debug!("super_predicates_that_define_assoc_type: local trait_def_id={:?}", trait_def_id);
-        let trait_hir_id = tcx.hir().local_def_id_to_hir_id(trait_def_id.expect_local());
-
-        let item = match tcx.hir().get(trait_hir_id) {
-            Node::Item(item) => item,
-            _ => bug!("trait_node_id {} is not an item", trait_hir_id),
-        };
+    let trait_hir_id = tcx.hir().local_def_id_to_hir_id(trait_def_id.expect_local());
 
-        let (generics, bounds) = match item.kind {
-            hir::ItemKind::Trait(.., ref generics, ref supertraits, _) => (generics, supertraits),
-            hir::ItemKind::TraitAlias(ref generics, ref supertraits) => (generics, supertraits),
-            _ => span_bug!(item.span, "super_predicates invoked on non-trait"),
-        };
-
-        let icx = ItemCtxt::new(tcx, trait_def_id);
+    let item = match tcx.hir().get(trait_hir_id) {
+        Node::Item(item) => item,
+        _ => bug!("trait_node_id {} is not an item", trait_hir_id),
+    };
 
-        // Convert the bounds that follow the colon, e.g., `Bar + Zed` in `trait Foo: Bar + Zed`.
-        let self_param_ty = tcx.types.self_param;
-        let superbounds1 = if let Some(assoc_name) = assoc_name {
-            AstConv::compute_bounds_that_match_assoc_type(
-                &icx,
-                self_param_ty,
-                &bounds,
-                SizedByDefault::No,
-                item.span,
-                assoc_name,
-            )
-        } else {
-            AstConv::compute_bounds(&icx, self_param_ty, &bounds, SizedByDefault::No, item.span)
-        };
+    let (generics, bounds) = match item.kind {
+        hir::ItemKind::Trait(.., ref generics, ref supertraits, _) => (generics, supertraits),
+        hir::ItemKind::TraitAlias(ref generics, ref supertraits) => (generics, supertraits),
+        _ => span_bug!(item.span, "super_predicates invoked on non-trait"),
+    };
 
-        let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
+    let icx = ItemCtxt::new(tcx, trait_def_id);
+
+    // Convert the bounds that follow the colon, e.g., `Bar + Zed` in `trait Foo: Bar + Zed`.
+    let self_param_ty = tcx.types.self_param;
+    let superbounds1 =
+        AstConv::compute_bounds(&icx, self_param_ty, bounds, SizedByDefault::No, item.span);
+
+    let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
+
+    // Convert any explicit superbounds in the where-clause,
+    // e.g., `trait Foo where Self: Bar`.
+    // In the case of trait aliases, however, we include all bounds in the where-clause,
+    // so e.g., `trait Foo = where u32: PartialEq<Self>` would include `u32: PartialEq<Self>`
+    // as one of its "superpredicates".
+    let is_trait_alias = tcx.is_trait_alias(trait_def_id);
+    let superbounds2 = icx.type_parameter_bounds_in_generics(
+        generics,
+        item.hir_id,
+        self_param_ty,
+        OnlySelfBounds(!is_trait_alias),
+    );
 
-        // Convert any explicit superbounds in the where-clause,
-        // e.g., `trait Foo where Self: Bar`.
-        // In the case of trait aliases, however, we include all bounds in the where-clause,
-        // so e.g., `trait Foo = where u32: PartialEq<Self>` would include `u32: PartialEq<Self>`
-        // as one of its "superpredicates".
-        let is_trait_alias = tcx.is_trait_alias(trait_def_id);
-        let superbounds2 = icx.type_parameter_bounds_in_generics(
-            generics,
-            item.hir_id,
-            self_param_ty,
-            OnlySelfBounds(!is_trait_alias),
-            assoc_name,
-        );
+    // Combine the two lists to form the complete set of superbounds:
+    let superbounds = &*tcx.arena.alloc_from_iter(superbounds1.into_iter().chain(superbounds2));
 
-        // Combine the two lists to form the complete set of superbounds:
-        let superbounds = &*tcx.arena.alloc_from_iter(superbounds1.into_iter().chain(superbounds2));
-
-        // Now require that immediate supertraits are converted,
-        // which will, in turn, reach indirect supertraits.
-        if assoc_name.is_none() {
-            // FIXME: move this into the `super_predicates_of` query
-            for &(pred, span) in superbounds {
-                debug!("superbound: {:?}", pred);
-                if let ty::PredicateAtom::Trait(bound, _) = pred.skip_binders() {
-                    tcx.at(span).super_predicates_of(bound.def_id());
-                }
-            }
+    // Now require that immediate supertraits are converted,
+    // which will, in turn, reach indirect supertraits.
+    for &(pred, span) in superbounds {
+        debug!("superbound: {:?}", pred);
+        if let ty::PredicateAtom::Trait(bound, _) = pred.skip_binders() {
+            tcx.at(span).super_predicates_of(bound.def_id());
         }
-
-        ty::GenericPredicates { parent: None, predicates: superbounds }
-    } else {
-        // if `assoc_name` is None, then the query should've been redirected to an
-        // external provider
-        assert!(assoc_name.is_some());
-        tcx.super_predicates_of(trait_def_id)
     }
+
+    ty::GenericPredicates { parent: None, predicates: superbounds }
 }
 
 fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef {
diff --git a/compiler/rustc_typeck/src/collect/item_bounds.rs b/compiler/rustc_typeck/src/collect/item_bounds.rs
index dd1da7d9cff..e596dd1a396 100644
--- a/compiler/rustc_typeck/src/collect/item_bounds.rs
+++ b/compiler/rustc_typeck/src/collect/item_bounds.rs
@@ -28,7 +28,7 @@ fn associated_type_bounds<'tcx>(
     let bounds = AstConv::compute_bounds(
         &ItemCtxt::new(tcx, assoc_item_def_id),
         item_ty,
-        &bounds,
+        bounds,
         SizedByDefault::Yes,
         span,
     );
@@ -68,7 +68,7 @@ fn opaque_type_bounds<'tcx>(
         let bounds = AstConv::compute_bounds(
             &ItemCtxt::new(tcx, opaque_def_id),
             item_ty,
-            &bounds,
+            bounds,
             SizedByDefault::Yes,
             span,
         )
diff --git a/src/test/incremental/cyclic-trait-hierarchy.rs b/src/test/incremental/cyclic-trait-hierarchy.rs
index b502e7207d5..03bb5eea765 100644
--- a/src/test/incremental/cyclic-trait-hierarchy.rs
+++ b/src/test/incremental/cyclic-trait-hierarchy.rs
@@ -3,11 +3,11 @@
 // revisions: rpass1 cfail2
 
 #[cfg(rpass1)]
-pub trait T2 {}
+pub trait T2 { }
 #[cfg(cfail2)]
-pub trait T2: T1 {}
-//[cfail2]~^ ERROR cycle detected when computing the super predicates of `T2`
+pub trait T2: T1 { }
+//[cfail2]~^ ERROR cycle detected when computing the supertraits of `T2`
 
-pub trait T1: T2 {}
+pub trait T1: T2 { }
 
-fn main() {}
+fn main() { }
diff --git a/src/test/ui/associated-type-bounds/ambiguous-associated-type2.rs b/src/test/ui/associated-type-bounds/ambiguous-associated-type2.rs
deleted file mode 100644
index 1b6d6d0ff59..00000000000
--- a/src/test/ui/associated-type-bounds/ambiguous-associated-type2.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-// ignore-tidy-linelength
-
-trait Foo {
-    type Item;
-}
-trait Bar<T> {
-    type Item;
-}
-trait Baz: Foo + Bar<Self::Item> {}
-//~^ ERROR cycle detected when computing the super traits of `Baz` with associated type name `Item` [E0391]
-
-fn main() {}
diff --git a/src/test/ui/associated-type-bounds/ambiguous-associated-type2.stderr b/src/test/ui/associated-type-bounds/ambiguous-associated-type2.stderr
deleted file mode 100644
index bda1debeac0..00000000000
--- a/src/test/ui/associated-type-bounds/ambiguous-associated-type2.stderr
+++ /dev/null
@@ -1,16 +0,0 @@
-error[E0391]: cycle detected when computing the super traits of `Baz` with associated type name `Item`
-  --> $DIR/ambiguous-associated-type2.rs:9:1
-   |
-LL | trait Baz: Foo + Bar<Self::Item> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: ...which again requires computing the super traits of `Baz` with associated type name `Item`, completing the cycle
-note: cycle used when computing the super traits of `Baz`
-  --> $DIR/ambiguous-associated-type2.rs:9:1
-   |
-LL | trait Baz: Foo + Bar<Self::Item> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0391`.
diff --git a/src/test/ui/associated-type-bounds/associated-item-through-where-clause.rs b/src/test/ui/associated-type-bounds/associated-item-through-where-clause.rs
deleted file mode 100644
index 3eb50ab5547..00000000000
--- a/src/test/ui/associated-type-bounds/associated-item-through-where-clause.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-// check-pass
-
-trait Foo {
-    type Item;
-}
-
-trait Bar
-where
-    Self: Foo,
-{
-}
-
-#[allow(dead_code)]
-fn foo<M>(_m: M)
-where
-    M: Bar,
-    M::Item: Send,
-{
-}
-
-fn main() {}
diff --git a/src/test/ui/associated-type-bounds/handle-predicates-that-can-define-assoc-type.rs b/src/test/ui/associated-type-bounds/handle-predicates-that-can-define-assoc-type.rs
deleted file mode 100644
index b1e54ec0449..00000000000
--- a/src/test/ui/associated-type-bounds/handle-predicates-that-can-define-assoc-type.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-// check-pass
-
-trait Foo<T> {}
-trait Bar {
-    type A;
-    type B;
-}
-trait Baz: Bar<B = u32> + Foo<Self::A> {}
-
-fn main() {}
diff --git a/src/test/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.rs b/src/test/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.rs
deleted file mode 100644
index 07d0f8f8769..00000000000
--- a/src/test/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-#[allow(dead_code)]
-fn foo<M>(_m: M)
-where
-    M::Item: Temp,
-    //~^ ERROR cannot find trait `Temp` in this scope [E0405]
-    //~| ERROR associated type `Item` not found for `M` [E0220]
-{
-}
-
-fn main() {}
diff --git a/src/test/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.stderr b/src/test/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.stderr
deleted file mode 100644
index bc2807b0396..00000000000
--- a/src/test/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.stderr
+++ /dev/null
@@ -1,16 +0,0 @@
-error[E0405]: cannot find trait `Temp` in this scope
-  --> $DIR/missing-trait-bound-for-assoc-fails.rs:4:14
-   |
-LL |     M::Item: Temp,
-   |              ^^^^ not found in this scope
-
-error[E0220]: associated type `Item` not found for `M`
-  --> $DIR/missing-trait-bound-for-assoc-fails.rs:4:8
-   |
-LL |     M::Item: Temp,
-   |        ^^^^ associated type `Item` not found
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0220, E0405.
-For more information about an error, try `rustc --explain E0220`.
diff --git a/src/test/ui/associated-type-bounds/super-trait-referencing-self.rs b/src/test/ui/associated-type-bounds/super-trait-referencing-self.rs
deleted file mode 100644
index c82ec01f4d6..00000000000
--- a/src/test/ui/associated-type-bounds/super-trait-referencing-self.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-// check-pass
-trait Foo {
-    type Bar;
-}
-trait Qux: Foo + AsRef<Self::Bar> {}
-trait Foo2 {}
-
-trait Qux2: Foo2 + AsRef<Self::Bar> {
-    type Bar;
-}
-
-fn main() {}
diff --git a/src/test/ui/associated-type-bounds/super-trait-referencing.rs b/src/test/ui/associated-type-bounds/super-trait-referencing.rs
deleted file mode 100644
index 2e97535157f..00000000000
--- a/src/test/ui/associated-type-bounds/super-trait-referencing.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-// check-pass
-
-// The goal of this test is to ensure that T: Bar<T::Item>
-// in the where clause does not cycle
-
-trait Foo {
-    type Item;
-}
-
-trait Bar<T> {}
-
-fn baz<T>()
-where
-    T: Foo,
-    T: Bar<T::Item>,
-{
-}
-
-fn main() {}
diff --git a/src/test/ui/associated-type-bounds/super-trait-where-referencing-self.rs b/src/test/ui/associated-type-bounds/super-trait-where-referencing-self.rs
deleted file mode 100644
index 72a6be9ffc3..00000000000
--- a/src/test/ui/associated-type-bounds/super-trait-where-referencing-self.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-// check-pass
-
-// Test that we do not get a cycle due to
-// resolving `Self::Bar` in the where clauses
-// on a trait definition (in particular, in
-// a where clause that is defining a superpredicate).
-
-trait Foo {
-    type Bar;
-}
-trait Qux
-where
-    Self: Foo,
-    Self: AsRef<Self::Bar>,
-{
-}
-trait Foo2 {}
-
-trait Qux2
-where
-    Self: Foo2,
-    Self: AsRef<Self::Bar>,
-{
-    type Bar;
-}
-
-fn main() {}
diff --git a/src/test/ui/cycle-projection-based-on-where-clause.rs b/src/test/ui/cycle-projection-based-on-where-clause.rs
new file mode 100644
index 00000000000..d3609acfdff
--- /dev/null
+++ b/src/test/ui/cycle-projection-based-on-where-clause.rs
@@ -0,0 +1,24 @@
+// Example cycle where a bound on `T` uses a shorthand for `T`. This
+// creates a cycle because we have to know the bounds on `T` to figure
+// out what trait defines `Item`, but we can't know the bounds on `T`
+// without knowing how to handle `T::Item`.
+//
+// Note that in the future cases like this could perhaps become legal,
+// if we got more fine-grained about our cycle detection or changed
+// how we handle `T::Item` resolution.
+
+use std::ops::Add;
+
+// Preamble.
+trait Trait { type Item; }
+
+struct A<T>
+    where T : Trait,
+          T : Add<T::Item>
+    //~^ ERROR cycle detected
+{
+    data: T
+}
+
+fn main() {
+}
diff --git a/src/test/ui/cycle-projection-based-on-where-clause.stderr b/src/test/ui/cycle-projection-based-on-where-clause.stderr
new file mode 100644
index 00000000000..2c337cc6bf9
--- /dev/null
+++ b/src/test/ui/cycle-projection-based-on-where-clause.stderr
@@ -0,0 +1,16 @@
+error[E0391]: cycle detected when computing the bounds for type parameter `T`
+  --> $DIR/cycle-projection-based-on-where-clause.rs:17:19
+   |
+LL |           T : Add<T::Item>
+   |                   ^^^^^^^
+   |
+   = note: ...which again requires computing the bounds for type parameter `T`, completing the cycle
+note: cycle used when computing explicit predicates of `A`
+  --> $DIR/cycle-projection-based-on-where-clause.rs:17:19
+   |
+LL |           T : Add<T::Item>
+   |                   ^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0391`.
diff --git a/src/test/ui/cycle-trait/cycle-trait-supertrait-direct.stderr b/src/test/ui/cycle-trait/cycle-trait-supertrait-direct.stderr
index ee54b2fd151..8aa3ac8abf5 100644
--- a/src/test/ui/cycle-trait/cycle-trait-supertrait-direct.stderr
+++ b/src/test/ui/cycle-trait/cycle-trait-supertrait-direct.stderr
@@ -1,15 +1,10 @@
-error[E0391]: cycle detected when computing the super predicates of `Chromosome`
-  --> $DIR/cycle-trait-supertrait-direct.rs:3:1
-   |
-LL | trait Chromosome: Chromosome {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: ...which requires computing the super traits of `Chromosome`...
+error[E0391]: cycle detected when computing the supertraits of `Chromosome`
   --> $DIR/cycle-trait-supertrait-direct.rs:3:19
    |
 LL | trait Chromosome: Chromosome {
    |                   ^^^^^^^^^^
-   = note: ...which again requires computing the super predicates of `Chromosome`, completing the cycle
+   |
+   = note: ...which again requires computing the supertraits of `Chromosome`, completing the cycle
 note: cycle used when collecting item types in top-level module
   --> $DIR/cycle-trait-supertrait-direct.rs:3:1
    |
diff --git a/src/test/ui/cycle-trait/cycle-trait-supertrait-indirect.stderr b/src/test/ui/cycle-trait/cycle-trait-supertrait-indirect.stderr
index 0a2284e0efb..9740f43a4ba 100644
--- a/src/test/ui/cycle-trait/cycle-trait-supertrait-indirect.stderr
+++ b/src/test/ui/cycle-trait/cycle-trait-supertrait-indirect.stderr
@@ -1,26 +1,16 @@
-error[E0391]: cycle detected when computing the super predicates of `B`
-  --> $DIR/cycle-trait-supertrait-indirect.rs:7:1
-   |
-LL | trait B: C {
-   | ^^^^^^^^^^
-   |
-note: ...which requires computing the super traits of `B`...
+error[E0391]: cycle detected when computing the supertraits of `B`
   --> $DIR/cycle-trait-supertrait-indirect.rs:7:10
    |
 LL | trait B: C {
    |          ^
-note: ...which requires computing the super predicates of `C`...
-  --> $DIR/cycle-trait-supertrait-indirect.rs:11:1
    |
-LL | trait C: B { }
-   | ^^^^^^^^^^
-note: ...which requires computing the super traits of `C`...
+note: ...which requires computing the supertraits of `C`...
   --> $DIR/cycle-trait-supertrait-indirect.rs:11:10
    |
 LL | trait C: B { }
    |          ^
-   = note: ...which again requires computing the super predicates of `B`, completing the cycle
-note: cycle used when computing the super traits of `A`
+   = note: ...which again requires computing the supertraits of `B`, completing the cycle
+note: cycle used when computing the supertraits of `A`
   --> $DIR/cycle-trait-supertrait-indirect.rs:4:10
    |
 LL | trait A: B {
diff --git a/src/test/ui/issues/issue-12511.stderr b/src/test/ui/issues/issue-12511.stderr
index 5f2b98c5237..37e38ff60ae 100644
--- a/src/test/ui/issues/issue-12511.stderr
+++ b/src/test/ui/issues/issue-12511.stderr
@@ -1,25 +1,15 @@
-error[E0391]: cycle detected when computing the super predicates of `T1`
-  --> $DIR/issue-12511.rs:1:1
-   |
-LL | trait T1 : T2 {
-   | ^^^^^^^^^^^^^
-   |
-note: ...which requires computing the super traits of `T1`...
+error[E0391]: cycle detected when computing the supertraits of `T1`
   --> $DIR/issue-12511.rs:1:12
    |
 LL | trait T1 : T2 {
    |            ^^
-note: ...which requires computing the super predicates of `T2`...
-  --> $DIR/issue-12511.rs:5:1
    |
-LL | trait T2 : T1 {
-   | ^^^^^^^^^^^^^
-note: ...which requires computing the super traits of `T2`...
+note: ...which requires computing the supertraits of `T2`...
   --> $DIR/issue-12511.rs:5:12
    |
 LL | trait T2 : T1 {
    |            ^^
-   = note: ...which again requires computing the super predicates of `T1`, completing the cycle
+   = note: ...which again requires computing the supertraits of `T1`, completing the cycle
 note: cycle used when collecting item types in top-level module
   --> $DIR/issue-12511.rs:1:1
    |
diff --git a/src/test/ui/issues/issue-20772.stderr b/src/test/ui/issues/issue-20772.stderr
index 4aecc7eab46..d64636310a3 100644
--- a/src/test/ui/issues/issue-20772.stderr
+++ b/src/test/ui/issues/issue-20772.stderr
@@ -1,4 +1,4 @@
-error[E0391]: cycle detected when computing the super traits of `T` with associated type name `Item`
+error[E0391]: cycle detected when computing the supertraits of `T`
   --> $DIR/issue-20772.rs:1:1
    |
 LL | / trait T : Iterator<Item=Self::Item>
@@ -6,8 +6,8 @@ LL | |
 LL | | {}
    | |__^
    |
-   = note: ...which again requires computing the super traits of `T` with associated type name `Item`, completing the cycle
-note: cycle used when computing the super traits of `T`
+   = note: ...which again requires computing the supertraits of `T`, completing the cycle
+note: cycle used when collecting item types in top-level module
   --> $DIR/issue-20772.rs:1:1
    |
 LL | / trait T : Iterator<Item=Self::Item>
diff --git a/src/test/ui/issues/issue-20825.stderr b/src/test/ui/issues/issue-20825.stderr
index ccbe06d9c0d..5f9709d1c64 100644
--- a/src/test/ui/issues/issue-20825.stderr
+++ b/src/test/ui/issues/issue-20825.stderr
@@ -1,11 +1,11 @@
-error[E0391]: cycle detected when computing the super traits of `Processor` with associated type name `Input`
+error[E0391]: cycle detected when computing the supertraits of `Processor`
   --> $DIR/issue-20825.rs:5:1
    |
 LL | pub trait Processor: Subscriber<Input = Self::Input> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: ...which again requires computing the super traits of `Processor` with associated type name `Input`, completing the cycle
-note: cycle used when computing the super traits of `Processor`
+   = note: ...which again requires computing the supertraits of `Processor`, completing the cycle
+note: cycle used when collecting item types in top-level module
   --> $DIR/issue-20825.rs:5:1
    |
 LL | pub trait Processor: Subscriber<Input = Self::Input> {
diff --git a/src/test/ui/issues/issue-22673.rs b/src/test/ui/issues/issue-22673.rs
index 4b9b4d6b23d..ba8057b684d 100644
--- a/src/test/ui/issues/issue-22673.rs
+++ b/src/test/ui/issues/issue-22673.rs
@@ -1,6 +1,5 @@
-// check-pass
-
-trait Expr: PartialEq<Self::Item> {
+trait Expr : PartialEq<Self::Item> {
+    //~^ ERROR: cycle detected
     type Item;
 }
 
diff --git a/src/test/ui/issues/issue-22673.stderr b/src/test/ui/issues/issue-22673.stderr
new file mode 100644
index 00000000000..9e7e4b218b1
--- /dev/null
+++ b/src/test/ui/issues/issue-22673.stderr
@@ -0,0 +1,16 @@
+error[E0391]: cycle detected when computing the supertraits of `Expr`
+  --> $DIR/issue-22673.rs:1:1
+   |
+LL | trait Expr : PartialEq<Self::Item> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: ...which again requires computing the supertraits of `Expr`, completing the cycle
+note: cycle used when collecting item types in top-level module
+  --> $DIR/issue-22673.rs:1:1
+   |
+LL | trait Expr : PartialEq<Self::Item> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0391`.