diff --git a/Cargo.lock b/Cargo.lock
index 4daf6f42b78e8..fff30b0f27bcb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2090,9 +2090,9 @@ dependencies = [
 
 [[package]]
 name = "jobserver"
-version = "0.1.27"
+version = "0.1.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d"
+checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6"
 dependencies = [
  "libc",
 ]
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 75410323f97df..fb52f9cf58f26 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -569,7 +569,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     });
                 }
 
-                let path = if trees.is_empty() && !prefix.segments.is_empty() {
+                // Condition should match `build_reduced_graph_for_use_tree`.
+                let path = if trees.is_empty()
+                    && !(prefix.segments.is_empty()
+                        || prefix.segments.len() == 1
+                            && prefix.segments[0].ident.name == kw::PathRoot)
+                {
                     // For empty lists we need to lower the prefix so it is checked for things
                     // like stability later.
                     let res = self.lower_import_res(id, span);
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index dc427f607f5d2..4ef9c7607be5e 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_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml
index 7d2f5bb193a39..c4aaf421444ec 100644
--- a/compiler/rustc_codegen_ssa/Cargo.toml
+++ b/compiler/rustc_codegen_ssa/Cargo.toml
@@ -9,7 +9,7 @@ ar_archive_writer = "0.1.5"
 bitflags = "2.4.1"
 cc = "1.0.69"
 itertools = "0.11"
-jobserver = "0.1.27"
+jobserver = "0.1.28"
 pathdiff = "0.2.0"
 regex = "1.4"
 rustc_arena = { path = "../rustc_arena" }
diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml
index 08aa68ca54a7a..0635d8552ae55 100644
--- a/compiler/rustc_data_structures/Cargo.toml
+++ b/compiler/rustc_data_structures/Cargo.toml
@@ -11,7 +11,7 @@ either = "1.0"
 elsa = "=1.7.1"
 ena = "0.14.2"
 indexmap = { version = "2.0.0" }
-jobserver_crate = { version = "0.1.27", package = "jobserver" }
+jobserver_crate = { version = "0.1.28", package = "jobserver" }
 libc = "0.2"
 measureme = "11"
 rustc-hash = "1.1.0"
diff --git a/compiler/rustc_data_structures/src/jobserver.rs b/compiler/rustc_data_structures/src/jobserver.rs
index 412e33aaa6551..89088bc5c1b87 100644
--- a/compiler/rustc_data_structures/src/jobserver.rs
+++ b/compiler/rustc_data_structures/src/jobserver.rs
@@ -23,7 +23,10 @@ static GLOBAL_CLIENT: LazyLock<Result<Client, String>> = LazyLock::new(|| {
 
     if matches!(
         error.kind(),
-        FromEnvErrorKind::NoEnvVar | FromEnvErrorKind::NoJobserver | FromEnvErrorKind::Unsupported
+        FromEnvErrorKind::NoEnvVar
+            | FromEnvErrorKind::NoJobserver
+            | FromEnvErrorKind::NegativeFd
+            | FromEnvErrorKind::Unsupported
     ) {
         return Ok(default_client());
     }
diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs
index caa015565914d..d3d7698e7f927 100644
--- a/compiler/rustc_lint/src/late.rs
+++ b/compiler/rustc_lint/src/late.rs
@@ -364,14 +364,11 @@ pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx> + 'tcx>(
     // Note: `passes` is often empty. In that case, it's faster to run
     // `builtin_lints` directly rather than bundling it up into the
     // `RuntimeCombinedLateLintPass`.
-    let mut passes: Vec<_> = unerased_lint_store(tcx.sess)
-        .late_module_passes
-        .iter()
-        .map(|mk_pass| (mk_pass)(tcx))
-        .collect();
-    if passes.is_empty() {
+    let late_module_passes = &unerased_lint_store(tcx.sess).late_module_passes;
+    if late_module_passes.is_empty() {
         late_lint_mod_inner(tcx, module_def_id, context, builtin_lints);
     } else {
+        let mut passes: Vec<_> = late_module_passes.iter().map(|mk_pass| (mk_pass)(tcx)).collect();
         passes.push(Box::new(builtin_lints));
         let pass = RuntimeCombinedLateLintPass { passes: &mut passes[..] };
         late_lint_mod_inner(tcx, module_def_id, context, pass);
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
index 3b9515e16701a..81c0cfea85a77 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 d271a0ea33be8..95f833372fb77 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 d056dd51f507e..27dbe0351da12 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 f0c49253dbd7a..42074f4a079e2 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 5befff5372aa4..ac6cfcdeb5950 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/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index 7e4a01a5ecd33..84297316a421d 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/pal/unix/thread.rs
@@ -320,6 +320,7 @@ pub fn available_parallelism() -> io::Result<NonZeroUsize> {
             target_os = "solaris",
             target_os = "illumos",
             target_os = "aix",
+            target_os = "freebsd",
         ))] {
             #[allow(unused_assignments)]
             #[allow(unused_mut)]
@@ -328,9 +329,17 @@ pub fn available_parallelism() -> io::Result<NonZeroUsize> {
             #[cfg(any(target_os = "android", target_os = "linux"))]
             {
                 quota = cgroups::quota().max(1);
-                let mut set: libc::cpu_set_t = unsafe { mem::zeroed() };
+            }
+
+            #[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
+            {
+                #[cfg(not(target_os = "freebsd"))]
+                type cpuset = libc::cpu_set_t;
+                #[cfg(target_os = "freebsd")]
+                type cpuset = libc::cpuset_t;
+                let mut set: cpuset = unsafe { mem::zeroed() };
                 unsafe {
-                    if libc::sched_getaffinity(0, mem::size_of::<libc::cpu_set_t>(), &mut set) == 0 {
+                    if libc::sched_getaffinity(0, mem::size_of::<cpuset>(), &mut set) == 0 {
                         let count = libc::CPU_COUNT(&set) as usize;
                         let count = count.min(quota);
 
@@ -355,32 +364,12 @@ pub fn available_parallelism() -> io::Result<NonZeroUsize> {
                 }
             }
         } else if #[cfg(any(
-                   target_os = "freebsd",
                    target_os = "dragonfly",
                    target_os = "openbsd",
                    target_os = "netbsd",
                ))] {
             use crate::ptr;
 
-            #[cfg(target_os = "freebsd")]
-            {
-                let mut set: libc::cpuset_t = unsafe { mem::zeroed() };
-                unsafe {
-                    if libc::cpuset_getaffinity(
-                        libc::CPU_LEVEL_WHICH,
-                        libc::CPU_WHICH_PID,
-                        -1,
-                        mem::size_of::<libc::cpuset_t>(),
-                        &mut set,
-                    ) == 0 {
-                        let count = libc::CPU_COUNT(&set) as usize;
-                        if count > 0 {
-                            return Ok(NonZeroUsize::new_unchecked(count));
-                        }
-                    }
-                }
-            }
-
             #[cfg(target_os = "netbsd")]
             {
                 unsafe {
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index f65c09bf0e810..7ca4392233ed4 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -191,6 +191,20 @@ pub(crate) fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> &'hir [ast:
     cx.tcx.get_attrs_unchecked(did)
 }
 
+pub(crate) fn item_relative_path(tcx: TyCtxt<'_>, def_id: DefId) -> Vec<Symbol> {
+    tcx.def_path(def_id)
+        .data
+        .into_iter()
+        .filter_map(|elem| {
+            // extern blocks (and a few others things) have an empty name.
+            match elem.data.get_opt_name() {
+                Some(s) if !s.is_empty() => Some(s),
+                _ => None,
+            }
+        })
+        .collect()
+}
+
 /// Record an external fully qualified name in the external_paths cache.
 ///
 /// These names are used later on by HTML rendering to generate things like
@@ -206,8 +220,7 @@ pub(crate) fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: ItemT
 
     let crate_name = cx.tcx.crate_name(did.krate);
 
-    let relative =
-        cx.tcx.def_path(did).data.into_iter().filter_map(|elem| elem.data.get_opt_name());
+    let relative = item_relative_path(cx.tcx, did);
     let fqn = if let ItemType::Macro = kind {
         // Check to see if it is a macro 2.0 or built-in macro
         if matches!(
@@ -218,7 +231,7 @@ pub(crate) fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: ItemT
         ) {
             once(crate_name).chain(relative).collect()
         } else {
-            vec![crate_name, relative.last().expect("relative was empty")]
+            vec![crate_name, *relative.last().expect("relative was empty")]
         }
     } else {
         once(crate_name).chain(relative).collect()
diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs
index e80da46adb4ca..f10c829bf4eed 100644
--- a/src/librustdoc/formats/item_type.rs
+++ b/src/librustdoc/formats/item_type.rs
@@ -4,7 +4,7 @@ use std::fmt;
 
 use serde::{Serialize, Serializer};
 
-use rustc_hir::def::DefKind;
+use rustc_hir::def::{CtorOf, DefKind};
 use rustc_span::hygiene::MacroKind;
 
 use crate::clean;
@@ -115,7 +115,15 @@ impl<'a> From<&'a clean::Item> for ItemType {
 
 impl From<DefKind> for ItemType {
     fn from(other: DefKind) -> Self {
-        match other {
+        Self::from_def_kind(other, None)
+    }
+}
+
+impl ItemType {
+    /// Depending on the parent kind, some variants have a different translation (like a `Method`
+    /// becoming a `TyMethod`).
+    pub(crate) fn from_def_kind(kind: DefKind, parent_kind: Option<DefKind>) -> Self {
+        match kind {
             DefKind::Enum => Self::Enum,
             DefKind::Fn => Self::Function,
             DefKind::Mod => Self::Module,
@@ -131,30 +139,35 @@ impl From<DefKind> for ItemType {
                 MacroKind::Attr => ItemType::ProcAttribute,
                 MacroKind::Derive => ItemType::ProcDerive,
             },
-            DefKind::ForeignTy
-            | DefKind::Variant
-            | DefKind::AssocTy
-            | DefKind::TyParam
+            DefKind::ForeignTy => Self::ForeignType,
+            DefKind::Variant => Self::Variant,
+            DefKind::Field => Self::StructField,
+            DefKind::AssocTy => Self::AssocType,
+            DefKind::AssocFn => {
+                if let Some(DefKind::Trait) = parent_kind {
+                    Self::TyMethod
+                } else {
+                    Self::Method
+                }
+            }
+            DefKind::Ctor(CtorOf::Struct, _) => Self::Struct,
+            DefKind::Ctor(CtorOf::Variant, _) => Self::Variant,
+            DefKind::AssocConst => Self::AssocConst,
+            DefKind::TyParam
             | DefKind::ConstParam
-            | DefKind::Ctor(..)
-            | DefKind::AssocFn
-            | DefKind::AssocConst
             | DefKind::ExternCrate
             | DefKind::Use
             | DefKind::ForeignMod
             | DefKind::AnonConst
             | DefKind::InlineConst
             | DefKind::OpaqueTy
-            | DefKind::Field
             | DefKind::LifetimeParam
             | DefKind::GlobalAsm
             | DefKind::Impl { .. }
             | DefKind::Closure => Self::ForeignType,
         }
     }
-}
 
-impl ItemType {
     pub(crate) fn as_str(&self) -> &'static str {
         match *self {
             ItemType::Module => "mod",
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 1923fc1511970..4ba1665bdc9f1 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -32,6 +32,7 @@ use crate::clean::{
     self, types::ExternalLocation, utils::find_nearest_parent_module, ExternalCrate, ItemId,
     PrimitiveType,
 };
+use crate::formats::cache::Cache;
 use crate::formats::item_type::ItemType;
 use crate::html::escape::Escape;
 use crate::html::render::Context;
@@ -581,22 +582,11 @@ fn generate_macro_def_id_path(
     cx: &Context<'_>,
     root_path: Option<&str>,
 ) -> Result<(String, ItemType, Vec<Symbol>), HrefError> {
-    let tcx = cx.shared.tcx;
+    let tcx = cx.tcx();
     let crate_name = tcx.crate_name(def_id.krate);
     let cache = cx.cache();
 
-    let fqp: Vec<Symbol> = tcx
-        .def_path(def_id)
-        .data
-        .into_iter()
-        .filter_map(|elem| {
-            // extern blocks (and a few others things) have an empty name.
-            match elem.data.get_opt_name() {
-                Some(s) if !s.is_empty() => Some(s),
-                _ => None,
-            }
-        })
-        .collect();
+    let fqp = clean::inline::item_relative_path(tcx, def_id);
     let mut relative = fqp.iter().copied();
     let cstore = CStore::from_tcx(tcx);
     // We need this to prevent a `panic` when this function is used from intra doc links...
@@ -651,92 +641,168 @@ fn generate_macro_def_id_path(
     Ok((url, ItemType::Macro, fqp))
 }
 
+fn generate_item_def_id_path(
+    mut def_id: DefId,
+    original_def_id: DefId,
+    cx: &Context<'_>,
+    root_path: Option<&str>,
+    original_def_kind: DefKind,
+) -> Result<(String, ItemType, Vec<Symbol>), HrefError> {
+    use crate::rustc_trait_selection::infer::TyCtxtInferExt;
+    use crate::rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;
+    use rustc_middle::traits::ObligationCause;
+
+    let tcx = cx.tcx();
+    let crate_name = tcx.crate_name(def_id.krate);
+
+    // No need to try to infer the actual parent item if it's not an associated item from the `impl`
+    // block.
+    if def_id != original_def_id && matches!(tcx.def_kind(def_id), DefKind::Impl { .. }) {
+        let infcx = tcx.infer_ctxt().build();
+        def_id = infcx
+            .at(&ObligationCause::dummy(), tcx.param_env(def_id))
+            .query_normalize(ty::Binder::dummy(tcx.type_of(def_id).instantiate_identity()))
+            .map(|resolved| infcx.resolve_vars_if_possible(resolved.value))
+            .ok()
+            .and_then(|normalized| normalized.skip_binder().ty_adt_def())
+            .map(|adt| adt.did())
+            .unwrap_or(def_id);
+    }
+
+    let relative = clean::inline::item_relative_path(tcx, def_id);
+    let fqp: Vec<Symbol> = once(crate_name).chain(relative).collect();
+
+    let def_kind = tcx.def_kind(def_id);
+    let shortty = def_kind.into();
+    let module_fqp = to_module_fqp(shortty, &fqp);
+    let mut is_remote = false;
+
+    let url_parts = url_parts(cx.cache(), def_id, &module_fqp, &cx.current, &mut is_remote)?;
+    let (url_parts, shortty, fqp) = make_href(root_path, shortty, url_parts, &fqp, is_remote)?;
+    if def_id == original_def_id {
+        return Ok((url_parts, shortty, fqp));
+    }
+    let kind = ItemType::from_def_kind(original_def_kind, Some(def_kind));
+    Ok((format!("{url_parts}#{kind}.{}", tcx.item_name(original_def_id)), shortty, fqp))
+}
+
+fn to_module_fqp(shortty: ItemType, fqp: &[Symbol]) -> &[Symbol] {
+    if shortty == ItemType::Module { fqp } else { &fqp[..fqp.len() - 1] }
+}
+
+fn url_parts(
+    cache: &Cache,
+    def_id: DefId,
+    module_fqp: &[Symbol],
+    relative_to: &[Symbol],
+    is_remote: &mut bool,
+) -> Result<UrlPartsBuilder, HrefError> {
+    match cache.extern_locations[&def_id.krate] {
+        ExternalLocation::Remote(ref s) => {
+            *is_remote = true;
+            let s = s.trim_end_matches('/');
+            let mut builder = UrlPartsBuilder::singleton(s);
+            builder.extend(module_fqp.iter().copied());
+            Ok(builder)
+        }
+        ExternalLocation::Local => Ok(href_relative_parts(module_fqp, relative_to).collect()),
+        ExternalLocation::Unknown => Err(HrefError::DocumentationNotBuilt),
+    }
+}
+
+fn make_href(
+    root_path: Option<&str>,
+    shortty: ItemType,
+    mut url_parts: UrlPartsBuilder,
+    fqp: &[Symbol],
+    is_remote: bool,
+) -> Result<(String, ItemType, Vec<Symbol>), HrefError> {
+    if !is_remote && let Some(root_path) = root_path {
+        let root = root_path.trim_end_matches('/');
+        url_parts.push_front(root);
+    }
+    debug!(?url_parts);
+    match shortty {
+        ItemType::Module => {
+            url_parts.push("index.html");
+        }
+        _ => {
+            let prefix = shortty.as_str();
+            let last = fqp.last().unwrap();
+            url_parts.push_fmt(format_args!("{prefix}.{last}.html"));
+        }
+    }
+    Ok((url_parts.finish(), shortty, fqp.to_vec()))
+}
+
 pub(crate) fn href_with_root_path(
-    did: DefId,
+    original_did: DefId,
     cx: &Context<'_>,
     root_path: Option<&str>,
 ) -> Result<(String, ItemType, Vec<Symbol>), HrefError> {
     let tcx = cx.tcx();
-    let def_kind = tcx.def_kind(did);
+    let def_kind = tcx.def_kind(original_did);
     let did = match def_kind {
         DefKind::AssocTy | DefKind::AssocFn | DefKind::AssocConst | DefKind::Variant => {
             // documented on their parent's page
-            tcx.parent(did)
+            tcx.parent(original_did)
         }
+        // If this a constructor, we get the parent (either a struct or a variant) and then
+        // generate the link for this item.
+        DefKind::Ctor(..) => return href_with_root_path(tcx.parent(original_did), cx, root_path),
         DefKind::ExternCrate => {
             // Link to the crate itself, not the `extern crate` item.
-            if let Some(local_did) = did.as_local() {
+            if let Some(local_did) = original_did.as_local() {
                 tcx.extern_mod_stmt_cnum(local_did).unwrap_or(LOCAL_CRATE).as_def_id()
             } else {
-                did
+                original_did
             }
         }
-        _ => did,
+        _ => original_did,
     };
     let cache = cx.cache();
     let relative_to = &cx.current;
-    fn to_module_fqp(shortty: ItemType, fqp: &[Symbol]) -> &[Symbol] {
-        if shortty == ItemType::Module { fqp } else { &fqp[..fqp.len() - 1] }
-    }
 
-    if !did.is_local()
-        && !cache.effective_visibilities.is_directly_public(tcx, did)
-        && !cache.document_private
-        && !cache.primitive_locations.values().any(|&id| id == did)
-    {
-        return Err(HrefError::Private);
+    if !original_did.is_local() {
+        // If we are generating an href for the "jump to def" feature, then the only case we want
+        // to ignore is if the item is `doc(hidden)` because we can't link to it.
+        if root_path.is_some() {
+            if tcx.is_doc_hidden(original_did) {
+                return Err(HrefError::Private);
+            }
+        } else if !cache.effective_visibilities.is_directly_public(tcx, did)
+            && !cache.document_private
+            && !cache.primitive_locations.values().any(|&id| id == did)
+        {
+            return Err(HrefError::Private);
+        }
     }
 
     let mut is_remote = false;
-    let (fqp, shortty, mut url_parts) = match cache.paths.get(&did) {
+    let (fqp, shortty, url_parts) = match cache.paths.get(&did) {
         Some(&(ref fqp, shortty)) => (fqp, shortty, {
             let module_fqp = to_module_fqp(shortty, fqp.as_slice());
             debug!(?fqp, ?shortty, ?module_fqp);
             href_relative_parts(module_fqp, relative_to).collect()
         }),
         None => {
-            if let Some(&(ref fqp, shortty)) = cache.external_paths.get(&did) {
+            // Associated items are handled differently with "jump to def". The anchor is generated
+            // directly here whereas for intra-doc links, we have some extra computation being
+            // performed there.
+            let def_id_to_get = if root_path.is_some() { original_did } else { did };
+            if let Some(&(ref fqp, shortty)) = cache.external_paths.get(&def_id_to_get) {
                 let module_fqp = to_module_fqp(shortty, fqp);
-                (
-                    fqp,
-                    shortty,
-                    match cache.extern_locations[&did.krate] {
-                        ExternalLocation::Remote(ref s) => {
-                            is_remote = true;
-                            let s = s.trim_end_matches('/');
-                            let mut builder = UrlPartsBuilder::singleton(s);
-                            builder.extend(module_fqp.iter().copied());
-                            builder
-                        }
-                        ExternalLocation::Local => {
-                            href_relative_parts(module_fqp, relative_to).collect()
-                        }
-                        ExternalLocation::Unknown => return Err(HrefError::DocumentationNotBuilt),
-                    },
-                )
+                (fqp, shortty, url_parts(cache, did, module_fqp, relative_to, &mut is_remote)?)
             } else if matches!(def_kind, DefKind::Macro(_)) {
                 return generate_macro_def_id_path(did, cx, root_path);
+            } else if did.is_local() {
+                return Err(HrefError::Private);
             } else {
-                return Err(HrefError::NotInExternalCache);
+                return generate_item_def_id_path(did, original_did, cx, root_path, def_kind);
             }
         }
     };
-    if !is_remote && let Some(root_path) = root_path {
-        let root = root_path.trim_end_matches('/');
-        url_parts.push_front(root);
-    }
-    debug!(?url_parts);
-    match shortty {
-        ItemType::Module => {
-            url_parts.push("index.html");
-        }
-        _ => {
-            let prefix = shortty.as_str();
-            let last = fqp.last().unwrap();
-            url_parts.push_fmt(format_args!("{prefix}.{last}.html"));
-        }
-    }
-    Ok((url_parts.finish(), shortty, fqp.to_vec()))
+    make_href(root_path, shortty, url_parts, fqp, is_remote)
 }
 
 pub(crate) fn href(
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index d5df05bacd93f..03f8a701627d3 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -14,8 +14,8 @@ use std::path::{Path, PathBuf};
 // #73494.
 const ENTRY_LIMIT: usize = 900;
 // FIXME: The following limits should be reduced eventually.
-const ISSUES_ENTRY_LIMIT: usize = 1819;
-const ROOT_ENTRY_LIMIT: usize = 872;
+const ISSUES_ENTRY_LIMIT: usize = 1794;
+const ROOT_ENTRY_LIMIT: usize = 870;
 
 const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
     "rs",     // test source files
diff --git a/tests/rustdoc/jump-to-non-local-method.rs b/tests/rustdoc/jump-to-non-local-method.rs
new file mode 100644
index 0000000000000..7767b92fbe557
--- /dev/null
+++ b/tests/rustdoc/jump-to-non-local-method.rs
@@ -0,0 +1,48 @@
+// compile-flags: -Zunstable-options --generate-link-to-definition
+
+#![crate_name = "foo"]
+
+// @has 'src/foo/jump-to-non-local-method.rs.html'
+
+// @has - '//a[@href="{{channel}}/core/sync/atomic/struct.AtomicIsize.html"]' 'std::sync::atomic::AtomicIsize'
+use std::sync::atomic::AtomicIsize;
+// @has - '//a[@href="{{channel}}/std/io/trait.Read.html"]' 'std::io::Read'
+use std::io::Read;
+// @has - '//a[@href="{{channel}}/std/io/index.html"]' 'std::io'
+use std::io;
+// @has - '//a[@href="{{channel}}/std/process/fn.exit.html"]' 'std::process::exit'
+use std::process::exit;
+use std::cmp::Ordering;
+use std::marker::PhantomData;
+
+pub fn bar2<T: Read>(readable: T) {
+    // @has - '//a[@href="{{channel}}/std/io/trait.Read.html#tymethod.read"]' 'read'
+    let _ = readable.read(&mut []);
+}
+
+pub fn bar() {
+    // @has - '//a[@href="{{channel}}/core/sync/atomic/struct.AtomicIsize.html#method.new"]' 'AtomicIsize::new'
+    let _ = AtomicIsize::new(0);
+    // @has - '//a[@href="#48"]' 'local_private'
+    local_private();
+}
+
+pub fn extern_call() {
+    // @has - '//a[@href="{{channel}}/std/process/fn.exit.html"]' 'exit'
+    exit(0);
+}
+
+pub fn macro_call() -> Result<(), ()> {
+    // @has - '//a[@href="{{channel}}/core/macro.try.html"]' 'try!'
+    try!(Err(()));
+    Ok(())
+}
+
+pub fn variant() {
+    // @has - '//a[@href="{{channel}}/core/cmp/enum.Ordering.html#variant.Less"]' 'Ordering::Less'
+    let _ = Ordering::Less;
+    // @has - '//a[@href="{{channel}}/core/marker/struct.PhantomData.html"]' 'PhantomData'
+    let _: PhantomData::<usize> = PhantomData;
+}
+
+fn local_private() {}
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 d180de9be3bf3..1c48aadecceb9 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 c23e54594ee30..0000000000000
--- 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 23be735010bf3..7bc2970ade9a2 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 4e2313bd4e4a9..0000000000000
--- 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 160b524c881c9..036f8ede1b3b7 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 accb366dd1552..bf6aab96dc726 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 0000000000000..2bd5f316811d9
--- /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 0000000000000..05e4e323d879d
--- /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 8c91211b964b4..87a048d0a134c 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/issues/issue-65634-raw-ident-suggestion.edition2015.stderr b/tests/ui/async-await/issue-65634-raw-ident-suggestion.edition2015.stderr
similarity index 100%
rename from tests/ui/issues/issue-65634-raw-ident-suggestion.edition2015.stderr
rename to tests/ui/async-await/issue-65634-raw-ident-suggestion.edition2015.stderr
diff --git a/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2018.stderr b/tests/ui/async-await/issue-65634-raw-ident-suggestion.edition2018.stderr
similarity index 100%
rename from tests/ui/issues/issue-65634-raw-ident-suggestion.edition2018.stderr
rename to tests/ui/async-await/issue-65634-raw-ident-suggestion.edition2018.stderr
diff --git a/tests/ui/issues/issue-65634-raw-ident-suggestion.rs b/tests/ui/async-await/issue-65634-raw-ident-suggestion.rs
similarity index 100%
rename from tests/ui/issues/issue-65634-raw-ident-suggestion.rs
rename to tests/ui/async-await/issue-65634-raw-ident-suggestion.rs
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 d2db6abe3132c..2e82a3fcdb4c3 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 4837815fad4ad..2e82a3fcdb4c3 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 6097c7f1073ed..5341c39a975aa 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/issues/issue-62375.rs b/tests/ui/binop/issue-62375.rs
similarity index 100%
rename from tests/ui/issues/issue-62375.rs
rename to tests/ui/binop/issue-62375.rs
diff --git a/tests/ui/issues/issue-62375.stderr b/tests/ui/binop/issue-62375.stderr
similarity index 100%
rename from tests/ui/issues/issue-62375.stderr
rename to tests/ui/binop/issue-62375.stderr
diff --git a/tests/ui/issues/issue-82833-slice-miscompile.rs b/tests/ui/codegen/issue-82833-slice-miscompile.rs
similarity index 100%
rename from tests/ui/issues/issue-82833-slice-miscompile.rs
rename to tests/ui/codegen/issue-82833-slice-miscompile.rs
diff --git a/tests/ui/issues/issue-26905-rpass.rs b/tests/ui/coercion/issue-26905-rpass.rs
similarity index 100%
rename from tests/ui/issues/issue-26905-rpass.rs
rename to tests/ui/coercion/issue-26905-rpass.rs
diff --git a/tests/ui/issues/issue-26905.rs b/tests/ui/coercion/issue-26905.rs
similarity index 100%
rename from tests/ui/issues/issue-26905.rs
rename to tests/ui/coercion/issue-26905.rs
diff --git a/tests/ui/issues/issue-26905.stderr b/tests/ui/coercion/issue-26905.stderr
similarity index 100%
rename from tests/ui/issues/issue-26905.stderr
rename to tests/ui/coercion/issue-26905.stderr
diff --git a/tests/ui/extern-mod-syntax.rs b/tests/ui/extern-mod-syntax.rs
deleted file mode 100644
index 65dfa6a0f5790..0000000000000
--- a/tests/ui/extern-mod-syntax.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-// run-pass
-
-#![allow(unused_imports)]
-#![no_std]
-
-extern crate std;
-use std::ffi::c_void;
-
-pub fn main() {
-    std::println!("Hello world!");
-}
diff --git a/tests/ui/issues/issue-16250.rs b/tests/ui/extern/issue-16250.rs
similarity index 100%
rename from tests/ui/issues/issue-16250.rs
rename to tests/ui/extern/issue-16250.rs
diff --git a/tests/ui/issues/issue-16250.stderr b/tests/ui/extern/issue-16250.stderr
similarity index 100%
rename from tests/ui/issues/issue-16250.stderr
rename to tests/ui/extern/issue-16250.stderr
diff --git a/tests/ui/issues/issue-47725.rs b/tests/ui/extern/issue-47725.rs
similarity index 100%
rename from tests/ui/issues/issue-47725.rs
rename to tests/ui/extern/issue-47725.rs
diff --git a/tests/ui/issues/issue-47725.stderr b/tests/ui/extern/issue-47725.stderr
similarity index 100%
rename from tests/ui/issues/issue-47725.stderr
rename to tests/ui/extern/issue-47725.stderr
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 073599edad7b9..f87d3aab635c0 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 efab91f25f0d2..855a29953f1b0 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 224e696ad2c9c..3d2b225f0cd01 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 74418a0c0bd52..0000000000000
--- 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 ab9d9a7ce6f08..7072f41066b3a 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 075e422e29c0b..0000000000000
--- 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 7693b11824762..58ca5b0c1874a 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 f42fc59536c43..0000000000000
--- 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`.
diff --git a/tests/ui/imports/empty-import-prefix-pass-2015.rs b/tests/ui/imports/empty-import-prefix-pass-2015.rs
new file mode 100644
index 0000000000000..a3278007c119a
--- /dev/null
+++ b/tests/ui/imports/empty-import-prefix-pass-2015.rs
@@ -0,0 +1,10 @@
+// check-pass
+// edition:2015
+
+use {};
+use {{}};
+
+use ::{};
+use {::{}};
+
+fn main() {}
diff --git a/tests/ui/imports/empty-import-prefix-pass.rs b/tests/ui/imports/empty-import-prefix-pass.rs
new file mode 100644
index 0000000000000..d76c0da4bd8eb
--- /dev/null
+++ b/tests/ui/imports/empty-import-prefix-pass.rs
@@ -0,0 +1,10 @@
+// check-pass
+// edition:2018
+
+use {};
+use {{}};
+
+use ::{};
+use {::{}};
+
+fn main() {}
diff --git a/tests/ui/issues/issue-3878.rs b/tests/ui/issues/issue-3878.rs
deleted file mode 100644
index 6de3405af0d95..0000000000000
--- a/tests/ui/issues/issue-3878.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-// run-pass
-// pretty-expanded FIXME #23616
-
-#![allow(path_statements)]
-
-pub fn main() {
-    let y: Box<_> = Box::new(1);
-    y;
-}
diff --git a/tests/ui/auxiliary/hello_macro.rs b/tests/ui/macros/auxiliary/hello_macro.rs
similarity index 100%
rename from tests/ui/auxiliary/hello_macro.rs
rename to tests/ui/macros/auxiliary/hello_macro.rs
diff --git a/tests/ui/issues/issue-46438.rs b/tests/ui/macros/issue-46438.rs
similarity index 100%
rename from tests/ui/issues/issue-46438.rs
rename to tests/ui/macros/issue-46438.rs
diff --git a/tests/ui/issues/issue-46438.stderr b/tests/ui/macros/issue-46438.stderr
similarity index 100%
rename from tests/ui/issues/issue-46438.stderr
rename to tests/ui/macros/issue-46438.stderr
diff --git a/tests/ui/macro-quote-test.rs b/tests/ui/macros/macro-quote-test.rs
similarity index 100%
rename from tests/ui/macro-quote-test.rs
rename to tests/ui/macros/macro-quote-test.rs
diff --git a/tests/ui/issues/issue-28992-empty.rs b/tests/ui/pattern/issue-28992-empty.rs
similarity index 100%
rename from tests/ui/issues/issue-28992-empty.rs
rename to tests/ui/pattern/issue-28992-empty.rs
diff --git a/tests/ui/issues/issue-28992-empty.stderr b/tests/ui/pattern/issue-28992-empty.stderr
similarity index 100%
rename from tests/ui/issues/issue-28992-empty.stderr
rename to tests/ui/pattern/issue-28992-empty.stderr
diff --git a/tests/ui/issues/auxiliary/private-trait-xc.rs b/tests/ui/privacy/auxiliary/private-trait-xc.rs
similarity index 100%
rename from tests/ui/issues/auxiliary/private-trait-xc.rs
rename to tests/ui/privacy/auxiliary/private-trait-xc.rs
diff --git a/tests/ui/issues/issue-11593.rs b/tests/ui/privacy/issue-11593.rs
similarity index 100%
rename from tests/ui/issues/issue-11593.rs
rename to tests/ui/privacy/issue-11593.rs
diff --git a/tests/ui/issues/issue-11593.stderr b/tests/ui/privacy/issue-11593.stderr
similarity index 100%
rename from tests/ui/issues/issue-11593.stderr
rename to tests/ui/privacy/issue-11593.stderr
diff --git a/tests/ui/issues/issue-33096.rs b/tests/ui/traits/issue-33096.rs
similarity index 100%
rename from tests/ui/issues/issue-33096.rs
rename to tests/ui/traits/issue-33096.rs
diff --git a/tests/ui/issues/issue-40085.rs b/tests/ui/traits/issue-40085.rs
similarity index 100%
rename from tests/ui/issues/issue-40085.rs
rename to tests/ui/traits/issue-40085.rs
diff --git a/tests/ui/issues/issue-58344.rs b/tests/ui/traits/issue-58344.rs
similarity index 100%
rename from tests/ui/issues/issue-58344.rs
rename to tests/ui/traits/issue-58344.rs
diff --git a/tests/ui/issues/issue-16338.rs b/tests/ui/typeck/issue-16338.rs
similarity index 100%
rename from tests/ui/issues/issue-16338.rs
rename to tests/ui/typeck/issue-16338.rs
diff --git a/tests/ui/issues/issue-16338.stderr b/tests/ui/typeck/issue-16338.stderr
similarity index 100%
rename from tests/ui/issues/issue-16338.stderr
rename to tests/ui/typeck/issue-16338.stderr