about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs24
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/mod.rs71
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs59
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs52
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs29
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs95
-rw-r--r--tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs32
-rw-r--r--tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr39
-rw-r--r--tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs5
-rw-r--r--tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.stderr26
-rw-r--r--tests/ui/associated-type-bounds/duplicate.rs3
-rw-r--r--tests/ui/associated-type-bounds/duplicate.stderr50
-rw-r--r--tests/ui/associated-type-bounds/higher-ranked.rs17
-rw-r--r--tests/ui/associated-type-bounds/nested-bounds-dont-eliminate-alias-bounds.rs37
-rw-r--r--tests/ui/associated-types/hr-associated-type-bound-object.stderr4
-rw-r--r--tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.current.stderr28
-rw-r--r--tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.next.stderr2
-rw-r--r--tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs5
-rw-r--r--tests/ui/feature-gates/feature-gate-associated_type_bounds.rs1
-rw-r--r--tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr47
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-88460.rs5
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-88460.stderr29
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.rs3
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.stderr29
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.rs3
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr23
26 files changed, 307 insertions, 411 deletions
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index dc427f607f5..4ef9c7607be 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1092,24 +1092,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
                 // Piggy-back on the `impl Trait` context to figure out the correct behavior.
                 let desugar_kind = match itctx {
-                    // We are in the return position:
-                    //
-                    //     fn foo() -> impl Iterator<Item: Debug>
-                    //
-                    // so desugar to
-                    //
-                    //     fn foo() -> impl Iterator<Item = impl Debug>
-                    ImplTraitContext::ReturnPositionOpaqueTy { .. }
-                    | ImplTraitContext::TypeAliasesOpaqueTy { .. } => DesugarKind::ImplTrait,
-
-                    // We are in the argument position, but within a dyn type:
+                    // in an argument, RPIT, or TAIT, if we are within a dyn type:
                     //
                     //     fn foo(x: dyn Iterator<Item: Debug>)
                     //
-                    // so desugar to
+                    // then desugar to:
                     //
                     //     fn foo(x: dyn Iterator<Item = impl Debug>)
-                    ImplTraitContext::Universal if self.is_in_dyn_type => DesugarKind::ImplTrait,
+                    //
+                    // This is because dyn traits must have all of their associated types specified.
+                    ImplTraitContext::ReturnPositionOpaqueTy { .. }
+                    | ImplTraitContext::TypeAliasesOpaqueTy { .. }
+                    | ImplTraitContext::Universal
+                        if self.is_in_dyn_type =>
+                    {
+                        DesugarKind::ImplTrait
+                    }
 
                     ImplTraitContext::Disallowed(position) if self.is_in_dyn_type => {
                         DesugarKind::Error(position)
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
index 3b9515e1670..81c0cfea85a 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
@@ -548,7 +548,27 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         goal: Goal<'tcx, G>,
         candidates: &mut Vec<Candidate<'tcx>>,
     ) {
-        let alias_ty = match goal.predicate.self_ty().kind() {
+        let () = self.probe(|_| ProbeKind::NormalizedSelfTyAssembly).enter(|ecx| {
+            ecx.assemble_alias_bound_candidates_recur(goal.predicate.self_ty(), goal, candidates);
+        });
+    }
+
+    /// For some deeply nested `<T>::A::B::C::D` rigid associated type,
+    /// we should explore the item bounds for all levels, since the
+    /// `associated_type_bounds` feature means that a parent associated
+    /// type may carry bounds for a nested associated type.
+    ///
+    /// If we have a projection, check that its self type is a rigid projection.
+    /// If so, continue searching by recursively calling after normalization.
+    // FIXME: This may recurse infinitely, but I can't seem to trigger it without
+    // hitting another overflow error something. Add a depth parameter needed later.
+    fn assemble_alias_bound_candidates_recur<G: GoalKind<'tcx>>(
+        &mut self,
+        self_ty: Ty<'tcx>,
+        goal: Goal<'tcx, G>,
+        candidates: &mut Vec<Candidate<'tcx>>,
+    ) {
+        let (kind, alias_ty) = match *self_ty.kind() {
             ty::Bool
             | ty::Char
             | ty::Int(_)
@@ -573,13 +593,27 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             | ty::Param(_)
             | ty::Placeholder(..)
             | ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
-            | ty::Alias(ty::Inherent, _)
-            | ty::Alias(ty::Weak, _)
             | ty::Error(_) => return,
-            ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
-            | ty::Bound(..) => bug!("unexpected self type for `{goal:?}`"),
-            // Excluding IATs and type aliases here as they don't have meaningful item bounds.
-            ty::Alias(ty::Projection | ty::Opaque, alias_ty) => alias_ty,
+            ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) | ty::Bound(..) => {
+                bug!("unexpected self type for `{goal:?}`")
+            }
+
+            ty::Infer(ty::TyVar(_)) => {
+                // If we hit infer when normalizing the self type of an alias,
+                // then bail with ambiguity. We should never encounter this on
+                // the *first* iteration of this recursive function.
+                if let Ok(result) =
+                    self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
+                {
+                    candidates.push(Candidate { source: CandidateSource::AliasBound, result });
+                }
+                return;
+            }
+
+            ty::Alias(kind @ (ty::Projection | ty::Opaque), alias_ty) => (kind, alias_ty),
+            ty::Alias(ty::Inherent | ty::Weak, _) => {
+                unreachable!("Weak and Inherent aliases should have been normalized away already")
+            }
         };
 
         for assumption in
@@ -587,9 +621,28 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         {
             match G::consider_alias_bound_candidate(self, goal, assumption) {
                 Ok(result) => {
-                    candidates.push(Candidate { source: CandidateSource::AliasBound, result })
+                    candidates.push(Candidate { source: CandidateSource::AliasBound, result });
+                }
+                Err(NoSolution) => {}
+            }
+        }
+
+        if kind != ty::Projection {
+            return;
+        }
+
+        match self.try_normalize_ty(goal.param_env, alias_ty.self_ty()) {
+            // Recurse on the self type of the projection.
+            Some(next_self_ty) => {
+                self.assemble_alias_bound_candidates_recur(next_self_ty, goal, candidates);
+            }
+            // Bail if we overflow when normalizing, adding an ambiguous candidate.
+            None => {
+                if let Ok(result) =
+                    self.evaluate_added_goals_and_make_canonical_response(Certainty::OVERFLOW)
+                {
+                    candidates.push(Candidate { source: CandidateSource::AliasBound, result });
                 }
-                Err(NoSolution) => (),
             }
         }
     }
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index d271a0ea33b..95f833372fb 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -40,6 +40,7 @@ use rustc_middle::ty::{self, Term, ToPredicate, Ty, TyCtxt};
 use rustc_span::symbol::sym;
 
 use std::collections::BTreeMap;
+use std::ops::ControlFlow;
 
 pub use rustc_middle::traits::Reveal;
 
@@ -1614,32 +1615,44 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
     candidate_set: &mut ProjectionCandidateSet<'tcx>,
 ) {
     debug!("assemble_candidates_from_trait_def(..)");
+    let mut ambiguous = false;
+    selcx.for_each_item_bound(
+        obligation.predicate.self_ty(),
+        |selcx, clause, _| {
+            let Some(clause) = clause.as_projection_clause() else {
+                return ControlFlow::Continue(());
+            };
 
-    let tcx = selcx.tcx();
-    // Check whether the self-type is itself a projection.
-    // If so, extract what we know from the trait and try to come up with a good answer.
-    let bounds = match *obligation.predicate.self_ty().kind() {
-        // Excluding IATs and type aliases here as they don't have meaningful item bounds.
-        ty::Alias(ty::Projection | ty::Opaque, ref data) => {
-            tcx.item_bounds(data.def_id).instantiate(tcx, data.args)
-        }
-        ty::Infer(ty::TyVar(_)) => {
-            // If the self-type is an inference variable, then it MAY wind up
-            // being a projected type, so induce an ambiguity.
-            candidate_set.mark_ambiguous();
-            return;
-        }
-        _ => return,
-    };
+            let is_match =
+                selcx.infcx.probe(|_| selcx.match_projection_projections(obligation, clause, true));
 
-    assemble_candidates_from_predicates(
-        selcx,
-        obligation,
-        candidate_set,
-        ProjectionCandidate::TraitDef,
-        bounds.iter(),
-        true,
+            match is_match {
+                ProjectionMatchesProjection::Yes => {
+                    candidate_set.push_candidate(ProjectionCandidate::TraitDef(clause));
+
+                    if !obligation.predicate.has_non_region_infer() {
+                        // HACK: Pick the first trait def candidate for a fully
+                        // inferred predicate. This is to allow duplicates that
+                        // differ only in normalization.
+                        return ControlFlow::Break(());
+                    }
+                }
+                ProjectionMatchesProjection::Ambiguous => {
+                    candidate_set.mark_ambiguous();
+                }
+                ProjectionMatchesProjection::No => {}
+            }
+
+            ControlFlow::Continue(())
+        },
+        // `ProjectionCandidateSet` is borrowed in the above closure,
+        // so just mark ambiguous outside of the closure.
+        || ambiguous = true,
     );
+
+    if ambiguous {
+        candidate_set.mark_ambiguous();
+    }
 }
 
 /// In the case of a trait object like
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index d056dd51f50..27dbe0351da 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -6,13 +6,16 @@
 //!
 //! [rustc dev guide]:https://rustc-dev-guide.rust-lang.org/traits/resolution.html#candidate-assembly
 
+use std::ops::ControlFlow;
+
 use hir::def_id::DefId;
 use hir::LangItem;
+use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_infer::traits::ObligationCause;
 use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError};
 use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
-use rustc_middle::ty::{self, Ty, TypeVisitableExt};
+use rustc_middle::ty::{self, ToPolyTraitRef, Ty, TypeVisitableExt};
 
 use crate::traits;
 use crate::traits::query::evaluate_obligation::InferCtxtExt;
@@ -158,11 +161,50 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             _ => return,
         }
 
-        let result = self
-            .infcx
-            .probe(|_| self.match_projection_obligation_against_definition_bounds(obligation));
+        self.infcx.probe(|_| {
+            let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate);
+            let placeholder_trait_predicate =
+                self.infcx.enter_forall_and_leak_universe(poly_trait_predicate);
+            debug!(?placeholder_trait_predicate);
+
+            // The bounds returned by `item_bounds` may contain duplicates after
+            // normalization, so try to deduplicate when possible to avoid
+            // unnecessary ambiguity.
+            let mut distinct_normalized_bounds = FxHashSet::default();
+            self.for_each_item_bound::<!>(
+                placeholder_trait_predicate.self_ty(),
+                |selcx, bound, idx| {
+                    let Some(bound) = bound.as_trait_clause() else {
+                        return ControlFlow::Continue(());
+                    };
+                    if bound.polarity() != placeholder_trait_predicate.polarity {
+                        return ControlFlow::Continue(());
+                    }
 
-        candidates.vec.extend(result.into_iter().map(|idx| ProjectionCandidate(idx)));
+                    selcx.infcx.probe(|_| {
+                        match selcx.match_normalize_trait_ref(
+                            obligation,
+                            bound.to_poly_trait_ref(),
+                            placeholder_trait_predicate.trait_ref,
+                        ) {
+                            Ok(None) => {
+                                candidates.vec.push(ProjectionCandidate(idx));
+                            }
+                            Ok(Some(normalized_trait))
+                                if distinct_normalized_bounds.insert(normalized_trait) =>
+                            {
+                                candidates.vec.push(ProjectionCandidate(idx));
+                            }
+                            _ => {}
+                        }
+                    });
+
+                    ControlFlow::Continue(())
+                },
+                // On ambiguity.
+                || candidates.ambiguous = true,
+            );
+        });
     }
 
     /// Given an obligation like `<SomeTrait for T>`, searches the obligations that the caller
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index f0c49253dbd..42074f4a079 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -162,20 +162,26 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             self.infcx.enter_forall_and_leak_universe(trait_predicate).trait_ref;
         let placeholder_self_ty = placeholder_trait_predicate.self_ty();
         let placeholder_trait_predicate = ty::Binder::dummy(placeholder_trait_predicate);
-        let (def_id, args) = match *placeholder_self_ty.kind() {
-            // Excluding IATs and type aliases here as they don't have meaningful item bounds.
-            ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
-                (def_id, args)
-            }
-            _ => bug!("projection candidate for unexpected type: {:?}", placeholder_self_ty),
-        };
 
-        let candidate_predicate =
-            tcx.item_bounds(def_id).map_bound(|i| i[idx]).instantiate(tcx, args);
+        let candidate_predicate = self
+            .for_each_item_bound(
+                placeholder_self_ty,
+                |_, clause, clause_idx| {
+                    if clause_idx == idx {
+                        ControlFlow::Break(clause)
+                    } else {
+                        ControlFlow::Continue(())
+                    }
+                },
+                || unreachable!(),
+            )
+            .break_value()
+            .expect("expected to index into clause that exists");
         let candidate = candidate_predicate
             .as_trait_clause()
             .expect("projection candidate is not a trait predicate")
             .map_bound(|t| t.trait_ref);
+
         let mut obligations = Vec::new();
         let candidate = normalize_with_depth_to(
             self,
@@ -194,8 +200,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 .map_err(|_| Unimplemented)
         })?);
 
-        if let ty::Alias(ty::Projection, ..) = placeholder_self_ty.kind() {
-            let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, args);
+        // FIXME(compiler-errors): I don't think this is needed.
+        if let ty::Alias(ty::Projection, alias_ty) = placeholder_self_ty.kind() {
+            let predicates = tcx.predicates_of(alias_ty.def_id).instantiate_own(tcx, alias_ty.args);
             for (predicate, _) in predicates {
                 let normalized = normalize_with_depth_to(
                     self,
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 5befff5372a..ac6cfcdeb59 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -52,6 +52,7 @@ use std::cell::{Cell, RefCell};
 use std::cmp;
 use std::fmt::{self, Display};
 use std::iter;
+use std::ops::ControlFlow;
 
 pub use rustc_middle::traits::select::*;
 use rustc_middle::ty::print::with_no_trimmed_paths;
@@ -1592,71 +1593,41 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         self.infcx.selection_cache.insert((param_env, pred), dep_node, candidate);
     }
 
-    /// Matches a predicate against the bounds of its self type.
-    ///
-    /// Given an obligation like `<T as Foo>::Bar: Baz` where the self type is
-    /// a projection, look at the bounds of `T::Bar`, see if we can find a
-    /// `Baz` bound. We return indexes into the list returned by
-    /// `tcx.item_bounds` for any applicable bounds.
-    #[instrument(level = "debug", skip(self), ret)]
-    fn match_projection_obligation_against_definition_bounds(
+    /// Looks at the item bounds of the projection or opaque type.
+    /// If this is a nested rigid projection, such as
+    /// `<<T as Tr1>::Assoc as Tr2>::Assoc`, consider the item bounds
+    /// on both `Tr1::Assoc` and `Tr2::Assoc`, since we may encounter
+    /// relative bounds on both via the `associated_type_bounds` feature.
+    pub(super) fn for_each_item_bound<T>(
         &mut self,
-        obligation: &PolyTraitObligation<'tcx>,
-    ) -> smallvec::SmallVec<[usize; 2]> {
-        let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate);
-        let placeholder_trait_predicate =
-            self.infcx.enter_forall_and_leak_universe(poly_trait_predicate);
-        debug!(?placeholder_trait_predicate);
-
-        let tcx = self.infcx.tcx;
-        let (def_id, args) = match *placeholder_trait_predicate.trait_ref.self_ty().kind() {
-            ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
-                (def_id, args)
-            }
-            _ => {
-                span_bug!(
-                    obligation.cause.span,
-                    "match_projection_obligation_against_definition_bounds() called \
-                     but self-ty is not a projection: {:?}",
-                    placeholder_trait_predicate.trait_ref.self_ty()
-                );
-            }
-        };
-        let bounds = tcx.item_bounds(def_id).instantiate(tcx, args);
+        mut self_ty: Ty<'tcx>,
+        mut for_each: impl FnMut(&mut Self, ty::Clause<'tcx>, usize) -> ControlFlow<T, ()>,
+        on_ambiguity: impl FnOnce(),
+    ) -> ControlFlow<T, ()> {
+        let mut idx = 0;
+        loop {
+            let (kind, alias_ty) = match *self_ty.kind() {
+                ty::Alias(kind @ (ty::Projection | ty::Opaque), alias_ty) => (kind, alias_ty),
+                ty::Infer(ty::TyVar(_)) => {
+                    on_ambiguity();
+                    return ControlFlow::Continue(());
+                }
+                _ => return ControlFlow::Continue(()),
+            };
 
-        // The bounds returned by `item_bounds` may contain duplicates after
-        // normalization, so try to deduplicate when possible to avoid
-        // unnecessary ambiguity.
-        let mut distinct_normalized_bounds = FxHashSet::default();
+            for bound in
+                self.tcx().item_bounds(alias_ty.def_id).instantiate(self.tcx(), alias_ty.args)
+            {
+                for_each(self, bound, idx)?;
+                idx += 1;
+            }
 
-        bounds
-            .iter()
-            .enumerate()
-            .filter_map(|(idx, bound)| {
-                let bound_predicate = bound.kind();
-                if let ty::ClauseKind::Trait(pred) = bound_predicate.skip_binder() {
-                    let bound = bound_predicate.rebind(pred.trait_ref);
-                    if self.infcx.probe(|_| {
-                        match self.match_normalize_trait_ref(
-                            obligation,
-                            bound,
-                            placeholder_trait_predicate.trait_ref,
-                        ) {
-                            Ok(None) => true,
-                            Ok(Some(normalized_trait))
-                                if distinct_normalized_bounds.insert(normalized_trait) =>
-                            {
-                                true
-                            }
-                            _ => false,
-                        }
-                    }) {
-                        return Some(idx);
-                    }
-                }
-                None
-            })
-            .collect()
+            if kind == ty::Projection {
+                self_ty = alias_ty.self_ty();
+            } else {
+                return ControlFlow::Continue(());
+            }
+        }
     }
 
     /// Equates the trait in `obligation` with trait bound. If the two traits
diff --git a/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs b/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs
index d180de9be3b..1c48aadecce 100644
--- a/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs
+++ b/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs
@@ -1,5 +1,4 @@
-// NOTE: rustc cannot currently handle bounds of the form `for<'a> <Foo as Bar<'a>>::Assoc: Baz`.
-// This should hopefully be fixed with Chalk.
+// check-pass
 
 #![feature(associated_type_bounds)]
 
@@ -24,9 +23,6 @@ impl<'a, 'b> Lam<&'a &'b u8> for L2 {
 
 trait Case1 {
     type C: Clone + Iterator<Item: Send + Iterator<Item: for<'a> Lam<&'a u8, App: Debug>> + Sync>;
-    //~^ ERROR `<<Self as Case1>::C as Iterator>::Item` is not an iterator
-    //~| ERROR `<<Self as Case1>::C as Iterator>::Item` cannot be sent between threads safely
-    //~| ERROR `<<Self as Case1>::C as Iterator>::Item` cannot be shared between threads safely
 }
 
 pub struct S1;
@@ -35,33 +31,17 @@ impl Case1 for S1 {
 }
 
 fn assume_case1<T: Case1>() {
-    fn assert_a<_0, A>()
-    where
-        A: Iterator<Item = _0>,
-        _0: Debug,
-    {
-    }
-    assert_a::<_, T::A>();
-
-    fn assert_b<_0, B>()
-    where
-        B: Iterator<Item = _0>,
-        _0: 'static,
-    {
-    }
-    assert_b::<_, T::B>();
-
-    fn assert_c<_0, _1, _2, C>()
+    fn assert_c<_1, _2, C>()
     where
         C: Clone + Iterator<Item = _2>,
         _2: Send + Iterator<Item = _1>,
-        _1: for<'a> Lam<&'a u8, App = _0>,
-        _0: Debug,
+        _1: for<'a> Lam<&'a u8>,
+        for<'a> <_1 as Lam<&'a u8>>::App: Debug,
     {
     }
-    assert_c::<_, _, _, T::C>();
+    assert_c::<_, _, T::C>();
 }
 
 fn main() {
-    assume_case1(S1);
+    assume_case1::<S1>();
 }
diff --git a/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr b/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr
deleted file mode 100644
index c23e54594ee..00000000000
--- a/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr
+++ /dev/null
@@ -1,39 +0,0 @@
-error[E0277]: `<<Self as Case1>::C as Iterator>::Item` cannot be sent between threads safely
-  --> $DIR/bad-bounds-on-assoc-in-trait.rs:26:36
-   |
-LL |     type C: Clone + Iterator<Item: Send + Iterator<Item: for<'a> Lam<&'a u8, App: Debug>> + Sync>;
-   |                                    ^^^^ `<<Self as Case1>::C as Iterator>::Item` cannot be sent between threads safely
-   |
-   = help: the trait `Send` is not implemented for `<<Self as Case1>::C as Iterator>::Item`
-help: consider further restricting the associated type
-   |
-LL | trait Case1 where <<Self as Case1>::C as Iterator>::Item: Send {
-   |             ++++++++++++++++++++++++++++++++++++++++++++++++++
-
-error[E0277]: `<<Self as Case1>::C as Iterator>::Item` is not an iterator
-  --> $DIR/bad-bounds-on-assoc-in-trait.rs:26:43
-   |
-LL |     type C: Clone + Iterator<Item: Send + Iterator<Item: for<'a> Lam<&'a u8, App: Debug>> + Sync>;
-   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `<<Self as Case1>::C as Iterator>::Item` is not an iterator
-   |
-   = help: the trait `Iterator` is not implemented for `<<Self as Case1>::C as Iterator>::Item`
-help: consider further restricting the associated type
-   |
-LL | trait Case1 where <<Self as Case1>::C as Iterator>::Item: Iterator {
-   |             ++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-error[E0277]: `<<Self as Case1>::C as Iterator>::Item` cannot be shared between threads safely
-  --> $DIR/bad-bounds-on-assoc-in-trait.rs:26:93
-   |
-LL |     type C: Clone + Iterator<Item: Send + Iterator<Item: for<'a> Lam<&'a u8, App: Debug>> + Sync>;
-   |                                                                                             ^^^^ `<<Self as Case1>::C as Iterator>::Item` cannot be shared between threads safely
-   |
-   = help: the trait `Sync` is not implemented for `<<Self as Case1>::C as Iterator>::Item`
-help: consider further restricting the associated type
-   |
-LL | trait Case1 where <<Self as Case1>::C as Iterator>::Item: Sync {
-   |             ++++++++++++++++++++++++++++++++++++++++++++++++++
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs b/tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs
index 23be735010b..7bc2970ade9 100644
--- a/tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs
+++ b/tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs
@@ -1,3 +1,5 @@
+// check-pass
+
 #![feature(associated_type_bounds)]
 
 use std::fmt::Debug;
@@ -16,8 +18,6 @@ impl<'a, 'b> Lam<&'a &'b u8> for L2 { type App = u8; }
 
 trait Case1 {
     type A: Iterator<Item: Debug>;
-    //~^ ERROR `<<Self as Case1>::A as Iterator>::Item` doesn't implement `Debug`
-
     type B: Iterator<Item: 'static>;
 }
 
@@ -33,7 +33,6 @@ impl Case1 for S1 {
 // bounds of `Out`, but trait selection can't find the bound since it applies
 // to a type other than `Self::Out`.
 pub trait Foo { type Out: Baz<Assoc: Default>; }
-//~^ ERROR trait bound `<<Self as Foo>::Out as Baz>::Assoc: Default` is not satisfied
 pub trait Baz { type Assoc; }
 
 #[derive(Default)]
diff --git a/tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.stderr b/tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.stderr
deleted file mode 100644
index 4e2313bd4e4..00000000000
--- a/tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.stderr
+++ /dev/null
@@ -1,26 +0,0 @@
-error[E0277]: `<<Self as Case1>::A as Iterator>::Item` doesn't implement `Debug`
-  --> $DIR/bounds-on-assoc-in-trait.rs:18:28
-   |
-LL |     type A: Iterator<Item: Debug>;
-   |                            ^^^^^ `<<Self as Case1>::A as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug`
-   |
-   = help: the trait `Debug` is not implemented for `<<Self as Case1>::A as Iterator>::Item`
-help: consider further restricting the associated type
-   |
-LL | trait Case1 where <<Self as Case1>::A as Iterator>::Item: Debug {
-   |             +++++++++++++++++++++++++++++++++++++++++++++++++++
-
-error[E0277]: the trait bound `<<Self as Foo>::Out as Baz>::Assoc: Default` is not satisfied
-  --> $DIR/bounds-on-assoc-in-trait.rs:35:38
-   |
-LL | pub trait Foo { type Out: Baz<Assoc: Default>; }
-   |                                      ^^^^^^^ the trait `Default` is not implemented for `<<Self as Foo>::Out as Baz>::Assoc`
-   |
-help: consider further restricting the associated type
-   |
-LL | pub trait Foo where <<Self as Foo>::Out as Baz>::Assoc: Default { type Out: Baz<Assoc: Default>; }
-   |               +++++++++++++++++++++++++++++++++++++++++++++++++
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-type-bounds/duplicate.rs b/tests/ui/associated-type-bounds/duplicate.rs
index 160b524c881..036f8ede1b3 100644
--- a/tests/ui/associated-type-bounds/duplicate.rs
+++ b/tests/ui/associated-type-bounds/duplicate.rs
@@ -251,13 +251,10 @@ where
 trait TRA1 {
     type A: Iterator<Item: Copy, Item: Send>;
     //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    //~| ERROR `<<Self as TRA1>::A as Iterator>::Item` cannot be sent between threads safely
-    //~| ERROR the trait bound `<<Self as TRA1>::A as Iterator>::Item: Copy` is not satisfied
 }
 trait TRA2 {
     type A: Iterator<Item: Copy, Item: Copy>;
     //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    //~| ERROR the trait bound `<<Self as TRA2>::A as Iterator>::Item: Copy` is not satisfied
 }
 trait TRA3 {
     type A: Iterator<Item: 'static, Item: 'static>;
diff --git a/tests/ui/associated-type-bounds/duplicate.stderr b/tests/ui/associated-type-bounds/duplicate.stderr
index accb366dd15..bf6aab96dc7 100644
--- a/tests/ui/associated-type-bounds/duplicate.stderr
+++ b/tests/ui/associated-type-bounds/duplicate.stderr
@@ -7,7 +7,7 @@ LL | struct SI1<T: Iterator<Item: Copy, Item: Send>> {
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:267:40
+  --> $DIR/duplicate.rs:264:40
    |
 LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
    |                            ----------  ^^^^^^^^^^ re-bound here
@@ -15,7 +15,7 @@ LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:269:44
+  --> $DIR/duplicate.rs:266:44
    |
 LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
    |                                ----------  ^^^^^^^^^^ re-bound here
@@ -23,7 +23,7 @@ LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
    |                                `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:271:43
+  --> $DIR/duplicate.rs:268:43
    |
 LL | type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>;
    |                            -------------  ^^^^^^^^^^^^^ re-bound here
@@ -523,7 +523,7 @@ LL |     type A: Iterator<Item: Copy, Item: Send>;
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:258:34
+  --> $DIR/duplicate.rs:256:34
    |
 LL |     type A: Iterator<Item: Copy, Item: Copy>;
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -531,7 +531,7 @@ LL |     type A: Iterator<Item: Copy, Item: Copy>;
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:263:37
+  --> $DIR/duplicate.rs:260:37
    |
 LL |     type A: Iterator<Item: 'static, Item: 'static>;
    |                      -------------  ^^^^^^^^^^^^^ re-bound here
@@ -631,41 +631,7 @@ LL |     Self: Iterator<Item: 'static, Item: 'static>,
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error[E0277]: the trait bound `<<Self as TRA1>::A as Iterator>::Item: Copy` is not satisfied
-  --> $DIR/duplicate.rs:252:28
-   |
-LL |     type A: Iterator<Item: Copy, Item: Send>;
-   |                            ^^^^ the trait `Copy` is not implemented for `<<Self as TRA1>::A as Iterator>::Item`
-   |
-help: consider further restricting the associated type
-   |
-LL | trait TRA1 where <<Self as TRA1>::A as Iterator>::Item: Copy {
-   |            +++++++++++++++++++++++++++++++++++++++++++++++++
-
-error[E0277]: `<<Self as TRA1>::A as Iterator>::Item` cannot be sent between threads safely
-  --> $DIR/duplicate.rs:252:40
-   |
-LL |     type A: Iterator<Item: Copy, Item: Send>;
-   |                                        ^^^^ `<<Self as TRA1>::A as Iterator>::Item` cannot be sent between threads safely
-   |
-   = help: the trait `Send` is not implemented for `<<Self as TRA1>::A as Iterator>::Item`
-help: consider further restricting the associated type
-   |
-LL | trait TRA1 where <<Self as TRA1>::A as Iterator>::Item: Send {
-   |            +++++++++++++++++++++++++++++++++++++++++++++++++
-
-error[E0277]: the trait bound `<<Self as TRA2>::A as Iterator>::Item: Copy` is not satisfied
-  --> $DIR/duplicate.rs:258:28
-   |
-LL |     type A: Iterator<Item: Copy, Item: Copy>;
-   |                            ^^^^ the trait `Copy` is not implemented for `<<Self as TRA2>::A as Iterator>::Item`
-   |
-help: consider further restricting the associated type
-   |
-LL | trait TRA2 where <<Self as TRA2>::A as Iterator>::Item: Copy {
-   |            +++++++++++++++++++++++++++++++++++++++++++++++++
-
-error: aborting due to 78 previous errors
+error: aborting due to 75 previous errors
 
-Some errors have detailed explanations: E0277, E0282, E0719.
-For more information about an error, try `rustc --explain E0277`.
+Some errors have detailed explanations: E0282, E0719.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/tests/ui/associated-type-bounds/higher-ranked.rs b/tests/ui/associated-type-bounds/higher-ranked.rs
new file mode 100644
index 00000000000..2bd5f316811
--- /dev/null
+++ b/tests/ui/associated-type-bounds/higher-ranked.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+#![feature(associated_type_bounds)]
+
+trait A<'a> {
+    type Assoc: ?Sized;
+}
+
+impl<'a> A<'a> for () {
+    type Assoc = &'a ();
+}
+
+fn hello() -> impl for<'a> A<'a, Assoc: Sized> {
+    ()
+}
+
+fn main() {}
diff --git a/tests/ui/associated-type-bounds/nested-bounds-dont-eliminate-alias-bounds.rs b/tests/ui/associated-type-bounds/nested-bounds-dont-eliminate-alias-bounds.rs
new file mode 100644
index 00000000000..05e4e323d87
--- /dev/null
+++ b/tests/ui/associated-type-bounds/nested-bounds-dont-eliminate-alias-bounds.rs
@@ -0,0 +1,37 @@
+// check-pass
+
+#![feature(associated_type_bounds)]
+
+trait Trait1 {
+    type Assoc1: Bar;
+
+    fn assoc(self) -> Self::Assoc1;
+}
+
+impl Trait1 for () {
+    type Assoc1 = ();
+    fn assoc(self) {}
+}
+
+trait Foo {}
+impl Foo for () {}
+trait Bar {}
+impl Bar for () {}
+
+fn hello() -> impl Trait1<Assoc1: Foo> {
+    ()
+}
+
+fn world() {
+    // Tests that `Assoc1: Foo` bound in the RPIT doesn't disqualify
+    // the `Assoc1: Bar` bound in the item, as a nested RPIT desugaring
+    // would do.
+
+    fn is_foo(_: impl Foo) {}
+    is_foo(hello().assoc());
+
+    fn is_bar(_: impl Bar) {}
+    is_bar(hello().assoc());
+}
+
+fn main() {}
diff --git a/tests/ui/associated-types/hr-associated-type-bound-object.stderr b/tests/ui/associated-types/hr-associated-type-bound-object.stderr
index 8c91211b964..87a048d0a13 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-object.stderr
+++ b/tests/ui/associated-types/hr-associated-type-bound-object.stderr
@@ -12,6 +12,10 @@ LL | trait X<'a>
 LL | where
 LL |     for<'b> <Self as X<'b>>::U: Clone,
    |                                 ^^^^^ required by this bound in `X`
+help: consider further restricting the associated type
+   |
+LL | fn f<'a, T: X<'a> + ?Sized>(x: &<T as X<'a>>::U) where for<'b> <T as X<'b>>::U: Clone {
+   |                                                  ++++++++++++++++++++++++++++++++++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.current.stderr b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.current.stderr
index d2db6abe313..2e82a3fcdb4 100644
--- a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.current.stderr
+++ b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.current.stderr
@@ -1,5 +1,5 @@
 warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/normalizing-self-auto-trait-issue-109924.rs:7:12
+  --> $DIR/normalizing-self-auto-trait-issue-109924.rs:6:12
    |
 LL | #![feature(return_type_notation)]
    |            ^^^^^^^^^^^^^^^^^^^^
@@ -7,29 +7,5 @@ LL | #![feature(return_type_notation)]
    = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error[E0277]: `impl Future<Output = ()> { <_ as Foo>::bar() }` cannot be sent between threads safely
-  --> $DIR/normalizing-self-auto-trait-issue-109924.rs:22:11
-   |
-LL |     build(Bar);
-   |     ----- ^^^ `impl Future<Output = ()> { <_ as Foo>::bar() }` cannot be sent between threads safely
-   |     |
-   |     required by a bound introduced by this call
-   |
-   = help: the trait `for<'a> Send` is not implemented for `impl Future<Output = ()> { <_ as Foo>::bar() }`
-note: this is a known limitation of the trait solver that will be lifted in the future
-  --> $DIR/normalizing-self-auto-trait-issue-109924.rs:22:11
-   |
-LL |     build(Bar);
-   |     ------^^^-
-   |     |     |
-   |     |     the trait solver is unable to infer the generic types that should be inferred from this argument
-   |     add turbofish arguments to this call to specify the types manually, even if it's redundant
-note: required by a bound in `build`
-  --> $DIR/normalizing-self-auto-trait-issue-109924.rs:19:39
-   |
-LL | fn build<T>(_: T) where T: Foo<bar(): Send> {}
-   |                                       ^^^^ required by this bound in `build`
-
-error: aborting due to 1 previous error; 1 warning emitted
+warning: 1 warning emitted
 
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.next.stderr b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.next.stderr
index 4837815fad4..2e82a3fcdb4 100644
--- a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.next.stderr
+++ b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.next.stderr
@@ -1,5 +1,5 @@
 warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/normalizing-self-auto-trait-issue-109924.rs:7:12
+  --> $DIR/normalizing-self-auto-trait-issue-109924.rs:6:12
    |
 LL | #![feature(return_type_notation)]
    |            ^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs
index 6097c7f1073..5341c39a975 100644
--- a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs
+++ b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs
@@ -1,11 +1,10 @@
+// check-pass
 // revisions: current next
-//[current] known-bug: #109924
-//[next] check-pass
 //[next] compile-flags: -Znext-solver
 // edition:2021
 
 #![feature(return_type_notation)]
-//[next]~^ WARN the feature `return_type_notation` is incomplete
+//~^ WARN the feature `return_type_notation` is incomplete
 
 trait Foo {
     async fn bar(&self);
diff --git a/tests/ui/feature-gates/feature-gate-associated_type_bounds.rs b/tests/ui/feature-gates/feature-gate-associated_type_bounds.rs
index 073599edad7..f87d3aab635 100644
--- a/tests/ui/feature-gates/feature-gate-associated_type_bounds.rs
+++ b/tests/ui/feature-gates/feature-gate-associated_type_bounds.rs
@@ -11,7 +11,6 @@ impl Tr1 for S1 { type As1 = S2; }
 trait _Tr3 {
     type A: Iterator<Item: Copy>;
     //~^ ERROR associated type bounds are unstable
-    //~| ERROR the trait bound `<<Self as _Tr3>::A as Iterator>::Item: Copy` is not satisfied
 
     type B: Iterator<Item: 'static>;
     //~^ ERROR associated type bounds are unstable
diff --git a/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr b/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr
index efab91f25f0..855a29953f1 100644
--- a/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr
+++ b/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr
@@ -9,7 +9,7 @@ LL |     type A: Iterator<Item: Copy>;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:16:22
+  --> $DIR/feature-gate-associated_type_bounds.rs:15:22
    |
 LL |     type B: Iterator<Item: 'static>;
    |                      ^^^^^^^^^^^^^
@@ -19,7 +19,7 @@ LL |     type B: Iterator<Item: 'static>;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:20:20
+  --> $DIR/feature-gate-associated_type_bounds.rs:19:20
    |
 LL | struct _St1<T: Tr1<As1: Tr2>> {
    |                    ^^^^^^^^
@@ -29,7 +29,7 @@ LL | struct _St1<T: Tr1<As1: Tr2>> {
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:27:18
+  --> $DIR/feature-gate-associated_type_bounds.rs:26:18
    |
 LL | enum _En1<T: Tr1<As1: Tr2>> {
    |                  ^^^^^^^^
@@ -39,7 +39,7 @@ LL | enum _En1<T: Tr1<As1: Tr2>> {
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:34:19
+  --> $DIR/feature-gate-associated_type_bounds.rs:33:19
    |
 LL | union _Un1<T: Tr1<As1: Tr2>> {
    |                   ^^^^^^^^
@@ -49,7 +49,7 @@ LL | union _Un1<T: Tr1<As1: Tr2>> {
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:41:37
+  --> $DIR/feature-gate-associated_type_bounds.rs:40:37
    |
 LL | type _TaWhere1<T> where T: Iterator<Item: Copy> = T;
    |                                     ^^^^^^^^^^
@@ -59,7 +59,7 @@ LL | type _TaWhere1<T> where T: Iterator<Item: Copy> = T;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:44:22
+  --> $DIR/feature-gate-associated_type_bounds.rs:43:22
    |
 LL | fn _apit(_: impl Tr1<As1: Copy>) {}
    |                      ^^^^^^^^^
@@ -69,7 +69,7 @@ LL | fn _apit(_: impl Tr1<As1: Copy>) {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:46:26
+  --> $DIR/feature-gate-associated_type_bounds.rs:45:26
    |
 LL | fn _apit_dyn(_: &dyn Tr1<As1: Copy>) {}
    |                          ^^^^^^^^^
@@ -79,7 +79,7 @@ LL | fn _apit_dyn(_: &dyn Tr1<As1: Copy>) {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:49:24
+  --> $DIR/feature-gate-associated_type_bounds.rs:48:24
    |
 LL | fn _rpit() -> impl Tr1<As1: Copy> { S1 }
    |                        ^^^^^^^^^
@@ -89,7 +89,7 @@ LL | fn _rpit() -> impl Tr1<As1: Copy> { S1 }
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:52:31
+  --> $DIR/feature-gate-associated_type_bounds.rs:51:31
    |
 LL | fn _rpit_dyn() -> Box<dyn Tr1<As1: Copy>> { Box::new(S1) }
    |                               ^^^^^^^^^
@@ -99,7 +99,7 @@ LL | fn _rpit_dyn() -> Box<dyn Tr1<As1: Copy>> { Box::new(S1) }
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:55:23
+  --> $DIR/feature-gate-associated_type_bounds.rs:54:23
    |
 LL | const _cdef: impl Tr1<As1: Copy> = S1;
    |                       ^^^^^^^^^
@@ -109,7 +109,7 @@ LL | const _cdef: impl Tr1<As1: Copy> = S1;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:61:24
+  --> $DIR/feature-gate-associated_type_bounds.rs:60:24
    |
 LL | static _sdef: impl Tr1<As1: Copy> = S1;
    |                        ^^^^^^^^^
@@ -119,7 +119,7 @@ LL | static _sdef: impl Tr1<As1: Copy> = S1;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:68:21
+  --> $DIR/feature-gate-associated_type_bounds.rs:67:21
    |
 LL |     let _: impl Tr1<As1: Copy> = S1;
    |                     ^^^^^^^^^
@@ -129,7 +129,7 @@ LL |     let _: impl Tr1<As1: Copy> = S1;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0562]: `impl Trait` is not allowed in const types
-  --> $DIR/feature-gate-associated_type_bounds.rs:55:14
+  --> $DIR/feature-gate-associated_type_bounds.rs:54:14
    |
 LL | const _cdef: impl Tr1<As1: Copy> = S1;
    |              ^^^^^^^^^^^^^^^^^^^
@@ -137,7 +137,7 @@ LL | const _cdef: impl Tr1<As1: Copy> = S1;
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in static types
-  --> $DIR/feature-gate-associated_type_bounds.rs:61:15
+  --> $DIR/feature-gate-associated_type_bounds.rs:60:15
    |
 LL | static _sdef: impl Tr1<As1: Copy> = S1;
    |               ^^^^^^^^^^^^^^^^^^^
@@ -145,25 +145,14 @@ LL | static _sdef: impl Tr1<As1: Copy> = S1;
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in the type of variable bindings
-  --> $DIR/feature-gate-associated_type_bounds.rs:68:12
+  --> $DIR/feature-gate-associated_type_bounds.rs:67:12
    |
 LL |     let _: impl Tr1<As1: Copy> = S1;
    |            ^^^^^^^^^^^^^^^^^^^
    |
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
-error[E0277]: the trait bound `<<Self as _Tr3>::A as Iterator>::Item: Copy` is not satisfied
-  --> $DIR/feature-gate-associated_type_bounds.rs:12:28
-   |
-LL |     type A: Iterator<Item: Copy>;
-   |                            ^^^^ the trait `Copy` is not implemented for `<<Self as _Tr3>::A as Iterator>::Item`
-   |
-help: consider further restricting the associated type
-   |
-LL | trait _Tr3 where <<Self as _Tr3>::A as Iterator>::Item: Copy {
-   |            +++++++++++++++++++++++++++++++++++++++++++++++++
-
-error: aborting due to 17 previous errors
+error: aborting due to 16 previous errors
 
-Some errors have detailed explanations: E0277, E0562, E0658.
-For more information about an error, try `rustc --explain E0277`.
+Some errors have detailed explanations: E0562, E0658.
+For more information about an error, try `rustc --explain E0562`.
diff --git a/tests/ui/generic-associated-types/bugs/issue-88460.rs b/tests/ui/generic-associated-types/bugs/issue-88460.rs
index 224e696ad2c..3d2b225f0cd 100644
--- a/tests/ui/generic-associated-types/bugs/issue-88460.rs
+++ b/tests/ui/generic-associated-types/bugs/issue-88460.rs
@@ -1,7 +1,4 @@
-// check-fail
-// known-bug: #88460
-
-// This should pass, but has a missed normalization due to HRTB.
+// check-pass
 
 pub trait Marker {}
 
diff --git a/tests/ui/generic-associated-types/bugs/issue-88460.stderr b/tests/ui/generic-associated-types/bugs/issue-88460.stderr
deleted file mode 100644
index 74418a0c0bd..00000000000
--- a/tests/ui/generic-associated-types/bugs/issue-88460.stderr
+++ /dev/null
@@ -1,29 +0,0 @@
-error[E0277]: the trait bound `for<'a> <_ as Trait>::Assoc<'a>: Marker` is not satisfied
-  --> $DIR/issue-88460.rs:28:10
-   |
-LL |     test(Foo);
-   |     ---- ^^^ the trait `for<'a> Marker` is not implemented for `<_ as Trait>::Assoc<'a>`
-   |     |
-   |     required by a bound introduced by this call
-   |
-   = help: the trait `Marker` is implemented for `()`
-note: this is a known limitation of the trait solver that will be lifted in the future
-  --> $DIR/issue-88460.rs:28:10
-   |
-LL |     test(Foo);
-   |     -----^^^-
-   |     |    |
-   |     |    the trait solver is unable to infer the generic types that should be inferred from this argument
-   |     add turbofish arguments to this call to specify the types manually, even if it's redundant
-note: required by a bound in `test`
-  --> $DIR/issue-88460.rs:15:27
-   |
-LL | fn test<T>(value: T)
-   |    ---- required by a bound in this function
-...
-LL |     for<'a> T::Assoc<'a>: Marker,
-   |                           ^^^^^^ required by this bound in `test`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.rs
index ab9d9a7ce6f..7072f41066b 100644
--- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.rs
@@ -1,5 +1,4 @@
-// check-fail
-// known-bug: #90950
+// check-pass
 
 trait Yokeable<'a>: 'static {
     type Output: 'a;
diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.stderr
deleted file mode 100644
index 075e422e29c..00000000000
--- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.stderr
+++ /dev/null
@@ -1,29 +0,0 @@
-error[E0277]: the trait bound `for<'a> <_ as Yokeable<'a>>::Output: IsCovariant<'a>` is not satisfied
-  --> $DIR/issue-90950.rs:50:12
-   |
-LL |     upcast(y)
-   |     ------ ^ the trait `for<'a> IsCovariant<'a>` is not implemented for `<_ as Yokeable<'a>>::Output`
-   |     |
-   |     required by a bound introduced by this call
-   |
-   = help: the trait `IsCovariant<'a>` is implemented for `std::borrow::Cow<'a, T>`
-note: this is a known limitation of the trait solver that will be lifted in the future
-  --> $DIR/issue-90950.rs:50:12
-   |
-LL |     upcast(y)
-   |     -------^-
-   |     |      |
-   |     |      the trait solver is unable to infer the generic types that should be inferred from this argument
-   |     add turbofish arguments to this call to specify the types manually, even if it's redundant
-note: required by a bound in `upcast`
-  --> $DIR/issue-90950.rs:27:42
-   |
-LL | fn upcast<Y>(x: Yoke<Y>) -> Yoke<Box<dyn IsCovariant<'static> + 'static>> where
-   |    ------ required by a bound in this function
-LL |     Y: for<'a> Yokeable<'a>,
-LL |     for<'a> <Y as Yokeable<'a>>::Output: IsCovariant<'a>
-   |                                          ^^^^^^^^^^^^^^^ required by this bound in `upcast`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.rs
index 7693b118247..58ca5b0c187 100644
--- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.rs
@@ -1,5 +1,4 @@
-// check-fail
-// known-bug: #89196
+// check-pass
 
 // Should pass, but we normalize and check bounds before we resolve the generics
 // of the function (which we know because of the return type).
diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr
deleted file mode 100644
index f42fc59536c..00000000000
--- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-error[E0277]: the trait bound `for<'a> <_ as Trait<'a>>::Out: Copy` is not satisfied
-  --> $DIR/norm-before-method-resolution.rs:22:17
-   |
-LL |     let _: () = weird_bound();
-   |                 ^^^^^^^^^^^^^ the trait `for<'a> Copy` is not implemented for `<_ as Trait<'a>>::Out`
-   |
-note: this is a known limitation of the trait solver that will be lifted in the future
-  --> $DIR/norm-before-method-resolution.rs:22:17
-   |
-LL |     let _: () = weird_bound();
-   |                 ^^^^^^^^^^^^^ try adding turbofish arguments to this expression to specify the types manually, even if it's redundant
-note: required by a bound in `weird_bound`
-  --> $DIR/norm-before-method-resolution.rs:18:40
-   |
-LL | fn weird_bound<X>() -> X
-   |    ----------- required by a bound in this function
-...
-LL |         for<'a> <X as Trait<'a>>::Out: Copy
-   |                                        ^^^^ required by this bound in `weird_bound`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0277`.