about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-10-05 06:19:35 +0000
committerbors <bors@rust-lang.org>2024-10-05 06:19:35 +0000
commit5a4ee43c387110736440cecc375cb5aedc441dbc (patch)
tree71f8bfc5b77e7d01efafb70c7d6e298d6c42b9f4
parentd30c3924a4ef6ab4f331134562c145d5cec0179a (diff)
parentef17eb79bbc5c7f5b303e203c1095e2eb216f84b (diff)
downloadrust-5a4ee43c387110736440cecc375cb5aedc441dbc.tar.gz
rust-5a4ee43c387110736440cecc375cb5aedc441dbc.zip
Auto merge of #129244 - cjgillot:opaque-hir, r=compiler-errors
Make opaque types regular HIR nodes

Having opaque types as HIR owner introduces all sorts of complications. This PR proposes to make them regular HIR nodes instead.

I haven't gone through all the test changes yet, so there may be a few surprises.

Many thanks to `@camelid` for the first draft.
Fixes https://github.com/rust-lang/rust/issues/129023

Fixes #129099
Fixes #125843
Fixes #119716
Fixes #121422
-rw-r--r--compiler/rustc_ast_lowering/src/index.rs8
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs27
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_name.rs10
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs4
-rw-r--r--compiler/rustc_hir/src/hir.rs15
-rw-r--r--compiler/rustc_hir/src/intravisit.rs25
-rw-r--r--compiler/rustc_hir/src/target.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs30
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs50
-rw-r--r--compiler/rustc_hir_analysis/src/collect/dump.rs11
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs57
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs13
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs129
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs62
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs67
-rw-r--r--compiler/rustc_hir_analysis/src/variance/dump.rs13
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs15
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs5
-rw-r--r--compiler/rustc_lint/src/async_fn_in_trait.rs7
-rw-r--r--compiler/rustc_lint/src/impl_trait_overcaptures.rs2
-rw-r--r--compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs6
-rw-r--r--compiler/rustc_lint/src/types.rs1
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs31
-rw-r--r--compiler/rustc_middle/src/hir/mod.rs12
-rw-r--r--compiler/rustc_middle/src/middle/resolve_bound_vars.rs10
-rw-r--r--compiler/rustc_middle/src/query/mod.rs26
-rw-r--r--compiler/rustc_middle/src/ty/context.rs22
-rw-r--r--compiler/rustc_middle/src/ty/diagnostics.rs10
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs2
-rw-r--r--compiler/rustc_passes/src/check_attr.rs2
-rw-r--r--compiler/rustc_passes/src/dead.rs10
-rw-r--r--compiler/rustc_passes/src/hir_stats.rs1
-rw-r--r--compiler/rustc_passes/src/reachable.rs4
-rw-r--r--compiler/rustc_privacy/src/lib.rs100
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs9
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/region.rs11
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs8
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs18
-rw-r--r--compiler/rustc_ty_utils/src/assoc.rs15
-rw-r--r--compiler/rustc_ty_utils/src/opaque_types.rs1
-rw-r--r--src/librustdoc/clean/mod.rs12
-rw-r--r--src/librustdoc/html/render/span_map.rs1
-rw-r--r--src/librustdoc/visit_ast.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/len_zero.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/lifetimes.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_async_fn.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_doc.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_inline.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/use_self.rs10
-rw-r--r--src/tools/clippy/clippy_utils/src/check_proc_macro.rs2
-rw-r--r--tests/crashes/119716-2.rs4
-rw-r--r--tests/crashes/119716.rs4
-rw-r--r--tests/crashes/121422.rs8
-rw-r--r--tests/crashes/125843.rs4
-rw-r--r--tests/crashes/129099.rs15
-rw-r--r--tests/incremental/hashes/function_interfaces.rs4
-rw-r--r--tests/ui/associated-type-bounds/duplicate.stderr66
-rw-r--r--tests/ui/async-await/async-fn/edition-2015.stderr8
-rw-r--r--tests/ui/async-await/inference_var_self_argument.stderr18
-rw-r--r--tests/ui/async-await/issue-66312.stderr12
-rw-r--r--tests/ui/const-generics/opaque_types.stderr16
-rw-r--r--tests/ui/delegation/unsupported.stderr32
-rw-r--r--tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr16
-rw-r--r--tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr5
-rw-r--r--tests/ui/impl-trait/issues/issue-78722-2.stderr12
-rw-r--r--tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr44
-rw-r--r--tests/ui/impl-trait/where-allowed.stderr94
-rw-r--r--tests/ui/privacy/private-type-in-interface.rs2
-rw-r--r--tests/ui/privacy/private-type-in-interface.stderr16
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr56
-rw-r--r--tests/ui/self/arbitrary-self-opaque.stderr18
-rw-r--r--tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr12
-rw-r--r--tests/ui/self/elision/lt-ref-self-async.fixed12
-rw-r--r--tests/ui/self/elision/lt-ref-self-async.stderr24
-rw-r--r--tests/ui/self/elision/ref-assoc-async.stderr20
-rw-r--r--tests/ui/self/elision/ref-mut-self-async.stderr24
-rw-r--r--tests/ui/self/elision/ref-mut-struct-async.stderr20
-rw-r--r--tests/ui/self/elision/ref-self-async.stderr28
-rw-r--r--tests/ui/self/elision/ref-struct-async.stderr20
-rw-r--r--tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.rs18
-rw-r--r--tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.stderr28
-rw-r--r--tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr16
-rw-r--r--tests/ui/type-alias-impl-trait/constrain_inputs.stderr26
-rw-r--r--tests/ui/type-alias-impl-trait/generic_underconstrained.stderr22
-rw-r--r--tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr44
-rw-r--r--tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/in-where-clause.stderr42
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53092-2.rs9
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53092-2.stderr66
-rw-r--r--tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr18
-rw-r--r--tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr18
-rw-r--r--tests/ui/type-alias-impl-trait/nested-in-anon-const.stderr16
-rw-r--r--tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs13
-rw-r--r--tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr30
-rw-r--r--tests/ui/type-alias-impl-trait/non-lifetime-binder.rs10
-rw-r--r--tests/ui/type-alias-impl-trait/non-lifetime-binder.stderr25
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-4.stderr14
-rw-r--r--tests/ui/typeck/typeck_type_placeholder_item.rs4
-rw-r--r--tests/ui/typeck/typeck_type_placeholder_item.stderr91
105 files changed, 1016 insertions, 1072 deletions
diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs
index e77c0fb3a3e..6289966561f 100644
--- a/compiler/rustc_ast_lowering/src/index.rs
+++ b/compiler/rustc_ast_lowering/src/index.rs
@@ -226,6 +226,14 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
         });
     }
 
+    fn visit_opaque_ty(&mut self, opaq: &'hir OpaqueTy<'hir>) {
+        self.insert(opaq.span, opaq.hir_id, Node::OpaqueTy(opaq));
+
+        self.with_parent(opaq.hir_id, |this| {
+            intravisit::walk_opaque_ty(this, opaq);
+        });
+    }
+
     fn visit_anon_const(&mut self, constant: &'hir AnonConst) {
         // FIXME: use real span?
         self.insert(DUMMY_SP, constant.hir_id, Node::AnonConst(constant));
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 9275308cccb..b26797f4203 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1603,7 +1603,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>],
     ) -> hir::TyKind<'hir> {
         let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
-        debug!(?opaque_ty_def_id);
+        let opaque_ty_hir_id = self.lower_node_id(opaque_ty_node_id);
+        debug!(?opaque_ty_def_id, ?opaque_ty_hir_id);
 
         // Map from captured (old) lifetime to synthetic (new) lifetime.
         // Used to resolve lifetimes in the bounds of the opaque.
@@ -1676,7 +1677,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             }
         }
 
-        self.with_hir_id_owner(opaque_ty_node_id, |this| {
+        let opaque_ty_def = self.with_def_id_parent(opaque_ty_def_id, |this| {
             // Install the remapping from old to new (if any). This makes sure that
             // any lifetimes that would have resolved to the def-id of captured
             // lifetimes are remapped to the new *synthetic* lifetimes of the opaque.
@@ -1714,7 +1715,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
             let lifetime_mapping = self.arena.alloc_slice(&synthesized_lifetime_args);
 
-            let opaque_ty_item = hir::OpaqueTy {
+            trace!("registering opaque type with id {:#?}", opaque_ty_def_id);
+            let opaque_ty_def = hir::OpaqueTy {
+                hir_id: opaque_ty_hir_id,
+                def_id: opaque_ty_def_id,
                 generics: this.arena.alloc(hir::Generics {
                     params: generic_params,
                     predicates: &[],
@@ -1725,19 +1729,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 bounds,
                 origin,
                 lifetime_mapping,
-            };
-
-            // Generate an `type Foo = impl Trait;` declaration.
-            trace!("registering opaque type with id {:#?}", opaque_ty_def_id);
-            let opaque_ty_item = hir::Item {
-                owner_id: hir::OwnerId { def_id: opaque_ty_def_id },
-                ident: Ident::empty(),
-                kind: hir::ItemKind::OpaqueTy(this.arena.alloc(opaque_ty_item)),
-                vis_span: this.lower_span(span.shrink_to_lo()),
                 span: this.lower_span(opaque_ty_span),
             };
-
-            hir::OwnerNode::Item(this.arena.alloc(opaque_ty_item))
+            this.arena.alloc(opaque_ty_def)
         });
 
         let generic_args = self.arena.alloc_from_iter(
@@ -1750,10 +1744,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         // Foo = impl Trait` is, internally, created as a child of the
         // async fn, so the *type parameters* are inherited. It's
         // only the lifetime parameters that we must supply.
-        hir::TyKind::OpaqueDef(
-            hir::ItemId { owner_id: hir::OwnerId { def_id: opaque_ty_def_id } },
-            generic_args,
-        )
+        hir::TyKind::OpaqueDef(opaque_ty_def, generic_args)
     }
 
     fn lower_precise_capturing_args(
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index d4598a1f582..1a5f9bdb154 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -830,20 +830,14 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
     ///
     /// [`OpaqueDef`]: hir::TyKind::OpaqueDef
     fn get_future_inner_return_ty(&self, hir_ty: &'tcx hir::Ty<'tcx>) -> &'tcx hir::Ty<'tcx> {
-        let hir = self.infcx.tcx.hir();
-
-        let hir::TyKind::OpaqueDef(id, _) = hir_ty.kind else {
+        let hir::TyKind::OpaqueDef(opaque_ty, _) = hir_ty.kind else {
             span_bug!(
                 hir_ty.span,
                 "lowered return type of async fn is not OpaqueDef: {:?}",
                 hir_ty
             );
         };
-        let opaque_ty = hir.item(id);
-        if let hir::ItemKind::OpaqueTy(hir::OpaqueTy {
-            bounds: [hir::GenericBound::Trait(trait_ref, _)],
-            ..
-        }) = opaque_ty.kind
+        if let hir::OpaqueTy { bounds: [hir::GenericBound::Trait(trait_ref, _)], .. } = opaque_ty
             && let Some(segment) = trait_ref.trait_ref.path.segments.last()
             && let Some(args) = segment.args
             && let [constraint] = args.constraints
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index 2f90e916281..a16c1931a55 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -329,8 +329,8 @@ fn check_opaque_type_well_formed<'tcx>(
 ) -> Result<Ty<'tcx>, ErrorGuaranteed> {
     // Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs`
     // on stable and we'd break that.
-    let opaque_ty_hir = tcx.hir().expect_item(def_id);
-    let OpaqueTyOrigin::TyAlias { .. } = opaque_ty_hir.expect_opaque_ty().origin else {
+    let opaque_ty_hir = tcx.hir().expect_opaque_ty(def_id);
+    let OpaqueTyOrigin::TyAlias { .. } = opaque_ty_hir.origin else {
         return Ok(definition_ty);
     };
     let param_env = tcx.param_env(def_id);
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index f58ec22aea9..2ef6fa53f4e 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -2749,6 +2749,8 @@ pub struct BareFnTy<'hir> {
 
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub struct OpaqueTy<'hir> {
+    pub hir_id: HirId,
+    pub def_id: LocalDefId,
     pub generics: &'hir Generics<'hir>,
     pub bounds: GenericBounds<'hir>,
     pub origin: OpaqueTyOrigin,
@@ -2762,6 +2764,7 @@ pub struct OpaqueTy<'hir> {
     /// This mapping associated a captured lifetime (first parameter) with the new
     /// early-bound lifetime that was generated for the opaque.
     pub lifetime_mapping: &'hir [(&'hir Lifetime, LocalDefId)],
+    pub span: Span,
 }
 
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
@@ -2868,7 +2871,7 @@ pub enum TyKind<'hir> {
     /// possibly parameters) that are actually bound on the `impl Trait`.
     ///
     /// The last parameter specifies whether this opaque appears in a trait definition.
-    OpaqueDef(ItemId, &'hir [GenericArg<'hir>]),
+    OpaqueDef(&'hir OpaqueTy<'hir>, &'hir [GenericArg<'hir>]),
     /// A trait object type `Bound1 + Bound2 + Bound3`
     /// where `Bound` is a trait or a lifetime.
     TraitObject(
@@ -3337,8 +3340,6 @@ impl<'hir> Item<'hir> {
         expect_ty_alias, (&'hir Ty<'hir>, &'hir Generics<'hir>),
             ItemKind::TyAlias(ty, generics), (ty, generics);
 
-        expect_opaque_ty, &OpaqueTy<'hir>, ItemKind::OpaqueTy(ty), ty;
-
         expect_enum, (&EnumDef<'hir>, &'hir Generics<'hir>), ItemKind::Enum(def, generics), (def, generics);
 
         expect_struct, (&VariantData<'hir>, &'hir Generics<'hir>),
@@ -3451,8 +3452,6 @@ pub enum ItemKind<'hir> {
     GlobalAsm(&'hir InlineAsm<'hir>),
     /// A type alias, e.g., `type Foo = Bar<u8>`.
     TyAlias(&'hir Ty<'hir>, &'hir Generics<'hir>),
-    /// An opaque `impl Trait` type alias, e.g., `type Foo = impl Bar;`.
-    OpaqueTy(&'hir OpaqueTy<'hir>),
     /// An enum definition, e.g., `enum Foo<A, B> {C<A>, D<B>}`.
     Enum(EnumDef<'hir>, &'hir Generics<'hir>),
     /// A struct definition, e.g., `struct Foo<A> {x: A}`.
@@ -3496,7 +3495,6 @@ impl ItemKind<'_> {
             ItemKind::Fn(_, ref generics, _)
             | ItemKind::TyAlias(_, ref generics)
             | ItemKind::Const(_, ref generics, _)
-            | ItemKind::OpaqueTy(OpaqueTy { ref generics, .. })
             | ItemKind::Enum(_, ref generics)
             | ItemKind::Struct(_, ref generics)
             | ItemKind::Union(_, ref generics)
@@ -3519,7 +3517,6 @@ impl ItemKind<'_> {
             ItemKind::ForeignMod { .. } => "extern block",
             ItemKind::GlobalAsm(..) => "global asm item",
             ItemKind::TyAlias(..) => "type alias",
-            ItemKind::OpaqueTy(..) => "opaque type",
             ItemKind::Enum(..) => "enum",
             ItemKind::Struct(..) => "struct",
             ItemKind::Union(..) => "union",
@@ -3806,6 +3803,7 @@ pub enum Node<'hir> {
     Ty(&'hir Ty<'hir>),
     AssocItemConstraint(&'hir AssocItemConstraint<'hir>),
     TraitRef(&'hir TraitRef<'hir>),
+    OpaqueTy(&'hir OpaqueTy<'hir>),
     Pat(&'hir Pat<'hir>),
     PatField(&'hir PatField<'hir>),
     Arm(&'hir Arm<'hir>),
@@ -3871,6 +3869,7 @@ impl<'hir> Node<'hir> {
             | Node::Crate(..)
             | Node::Ty(..)
             | Node::TraitRef(..)
+            | Node::OpaqueTy(..)
             | Node::Infer(..)
             | Node::WhereBoundPredicate(..)
             | Node::ArrayLenInfer(..)
@@ -3996,6 +3995,7 @@ impl<'hir> Node<'hir> {
             | Node::TraitItem(TraitItem { generics, .. })
             | Node::ImplItem(ImplItem { generics, .. }) => Some(generics),
             Node::Item(item) => item.kind.generics(),
+            Node::OpaqueTy(opaque) => Some(opaque.generics),
             _ => None,
         }
     }
@@ -4055,6 +4055,7 @@ impl<'hir> Node<'hir> {
         expect_ty,            &'hir Ty<'hir>,           Node::Ty(n),           n;
         expect_assoc_item_constraint,  &'hir AssocItemConstraint<'hir>,  Node::AssocItemConstraint(n),  n;
         expect_trait_ref,     &'hir TraitRef<'hir>,     Node::TraitRef(n),     n;
+        expect_opaque_ty,     &'hir OpaqueTy<'hir>,     Node::OpaqueTy(n),     n;
         expect_pat,           &'hir Pat<'hir>,          Node::Pat(n),          n;
         expect_pat_field,     &'hir PatField<'hir>,     Node::PatField(n),     n;
         expect_arm,           &'hir Arm<'hir>,          Node::Arm(n),          n;
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index d0a8aaa85bb..58916d05865 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -111,6 +111,7 @@ impl<'a> FnKind<'a> {
 pub trait Map<'hir> {
     /// Retrieves the `Node` corresponding to `id`.
     fn hir_node(&self, hir_id: HirId) -> Node<'hir>;
+    fn hir_node_by_def_id(&self, def_id: LocalDefId) -> Node<'hir>;
     fn body(&self, id: BodyId) -> &'hir Body<'hir>;
     fn item(&self, id: ItemId) -> &'hir Item<'hir>;
     fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir>;
@@ -123,6 +124,9 @@ impl<'hir> Map<'hir> for ! {
     fn hir_node(&self, _: HirId) -> Node<'hir> {
         *self;
     }
+    fn hir_node_by_def_id(&self, _: LocalDefId) -> Node<'hir> {
+        *self;
+    }
     fn body(&self, _: BodyId) -> &'hir Body<'hir> {
         *self;
     }
@@ -423,6 +427,9 @@ pub trait Visitor<'v>: Sized {
     fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef<'v>) -> Self::Result {
         walk_poly_trait_ref(self, t)
     }
+    fn visit_opaque_ty(&mut self, opaque: &'v OpaqueTy<'v>) -> Self::Result {
+        walk_opaque_ty(self, opaque)
+    }
     fn visit_variant_data(&mut self, s: &'v VariantData<'v>) -> Self::Result {
         walk_struct_def(self, s)
     }
@@ -536,11 +543,6 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::
             try_visit!(visitor.visit_ty(ty));
             try_visit!(visitor.visit_generics(generics));
         }
-        ItemKind::OpaqueTy(&OpaqueTy { generics, bounds, .. }) => {
-            try_visit!(visitor.visit_id(item.hir_id()));
-            try_visit!(walk_generics(visitor, generics));
-            walk_list!(visitor, visit_param_bound, bounds);
-        }
         ItemKind::Enum(ref enum_definition, ref generics) => {
             try_visit!(visitor.visit_generics(generics));
             // `visit_enum_def()` takes care of visiting the `Item`'s `HirId`.
@@ -894,8 +896,8 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Resul
         TyKind::Path(ref qpath) => {
             try_visit!(visitor.visit_qpath(qpath, typ.hir_id, typ.span));
         }
-        TyKind::OpaqueDef(item_id, lifetimes) => {
-            try_visit!(visitor.visit_nested_item(item_id));
+        TyKind::OpaqueDef(opaque, lifetimes) => {
+            try_visit!(visitor.visit_opaque_ty(opaque));
             walk_list!(visitor, visit_generic_arg, lifetimes);
         }
         TyKind::Array(ref ty, ref length) => {
@@ -1185,6 +1187,15 @@ pub fn walk_poly_trait_ref<'v, V: Visitor<'v>>(
     visitor.visit_trait_ref(&trait_ref.trait_ref)
 }
 
+pub fn walk_opaque_ty<'v, V: Visitor<'v>>(visitor: &mut V, opaque: &'v OpaqueTy<'v>) -> V::Result {
+    let &OpaqueTy { hir_id, def_id: _, generics, bounds, origin: _, lifetime_mapping: _, span: _ } =
+        opaque;
+    try_visit!(visitor.visit_id(hir_id));
+    try_visit!(walk_generics(visitor, generics));
+    walk_list!(visitor, visit_param_bound, bounds);
+    V::Result::output()
+}
+
 pub fn walk_struct_def<'v, V: Visitor<'v>>(
     visitor: &mut V,
     struct_definition: &'v VariantData<'v>,
diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs
index 155270ca6a7..6ff57396b4a 100644
--- a/compiler/rustc_hir/src/target.rs
+++ b/compiler/rustc_hir/src/target.rs
@@ -34,7 +34,6 @@ pub enum Target {
     ForeignMod,
     GlobalAsm,
     TyAlias,
-    OpaqueTy,
     Enum,
     Variant,
     Struct,
@@ -79,7 +78,6 @@ impl Target {
             | Target::ForeignMod
             | Target::GlobalAsm
             | Target::TyAlias
-            | Target::OpaqueTy
             | Target::Enum
             | Target::Variant
             | Target::Struct
@@ -114,7 +112,6 @@ impl Target {
             ItemKind::ForeignMod { .. } => Target::ForeignMod,
             ItemKind::GlobalAsm(..) => Target::GlobalAsm,
             ItemKind::TyAlias(..) => Target::TyAlias,
-            ItemKind::OpaqueTy(..) => Target::OpaqueTy,
             ItemKind::Enum(..) => Target::Enum,
             ItemKind::Struct(..) => Target::Struct,
             ItemKind::Union(..) => Target::Union,
@@ -137,7 +134,6 @@ impl Target {
             DefKind::ForeignMod => Target::ForeignMod,
             DefKind::GlobalAsm => Target::GlobalAsm,
             DefKind::TyAlias => Target::TyAlias,
-            DefKind::OpaqueTy => Target::OpaqueTy,
             DefKind::Enum => Target::Enum,
             DefKind::Struct => Target::Struct,
             DefKind::Union => Target::Union,
@@ -191,7 +187,6 @@ impl Target {
             Target::ForeignMod => "foreign module",
             Target::GlobalAsm => "global asm",
             Target::TyAlias => "type alias",
-            Target::OpaqueTy => "opaque type",
             Target::Enum => "enum",
             Target::Variant => "enum variant",
             Target::Struct => "struct",
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 785258d011c..eb62ff86c71 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -252,10 +252,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
 /// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
 /// projections that would result in "inheriting lifetimes".
 fn check_opaque(tcx: TyCtxt<'_>, def_id: LocalDefId) {
-    let item = tcx.hir().expect_item(def_id);
-    let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item.kind else {
-        tcx.dcx().span_bug(item.span, "expected opaque item");
-    };
+    let hir::OpaqueTy { origin, .. } = tcx.hir().expect_opaque_ty(def_id);
 
     // HACK(jynelson): trying to infer the type of `impl trait` breaks documenting
     // `async-std` (and `pub async fn` in general).
@@ -265,16 +262,16 @@ fn check_opaque(tcx: TyCtxt<'_>, def_id: LocalDefId) {
         return;
     }
 
-    let span = tcx.def_span(item.owner_id.def_id);
+    let span = tcx.def_span(def_id);
 
-    if tcx.type_of(item.owner_id.def_id).instantiate_identity().references_error() {
+    if tcx.type_of(def_id).instantiate_identity().references_error() {
         return;
     }
-    if check_opaque_for_cycles(tcx, item.owner_id.def_id, span).is_err() {
+    if check_opaque_for_cycles(tcx, def_id, span).is_err() {
         return;
     }
 
-    let _ = check_opaque_meets_bounds(tcx, item.owner_id.def_id, span, origin);
+    let _ = check_opaque_meets_bounds(tcx, def_id, span, origin);
 }
 
 /// Checks that an opaque type does not contain cycles.
@@ -481,8 +478,7 @@ fn sanity_check_found_hidden_type<'tcx>(
 /// 2. Checking that all lifetimes that are implicitly captured are mentioned.
 /// 3. Asserting that all parameters mentioned in the captures list are invariant.
 fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDefId) {
-    let hir::OpaqueTy { bounds, .. } =
-        *tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty();
+    let hir::OpaqueTy { bounds, .. } = *tcx.hir_node_by_def_id(opaque_def_id).expect_opaque_ty();
     let Some(precise_capturing_args) = bounds.iter().find_map(|bound| match *bound {
         hir::GenericBound::Use(bounds, ..) => Some(bounds),
         _ => None,
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
index 35c2b7e7ce2..80334c6efe7 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
@@ -93,7 +93,7 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
         // it's a refinement to a TAIT.
         if !tcx.hir().get_if_local(impl_opaque.def_id).is_some_and(|node| {
             matches!(
-                node.expect_item().expect_opaque_ty().origin,
+                node.expect_opaque_ty().origin,
                 hir::OpaqueTyOrigin::AsyncFn { parent, .. }  | hir::OpaqueTyOrigin::FnReturn { parent, .. }
                     if parent == impl_m.def_id.expect_local()
             )
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 02d23b95d46..3a9d2640eee 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -185,15 +185,16 @@ where
     }
 }
 
-fn check_well_formed(tcx: TyCtxt<'_>, def_id: hir::OwnerId) -> Result<(), ErrorGuaranteed> {
-    let node = tcx.hir_owner_node(def_id);
+fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
+    let node = tcx.hir_node_by_def_id(def_id);
     let mut res = match node {
-        hir::OwnerNode::Crate(_) => bug!("check_well_formed cannot be applied to the crate root"),
-        hir::OwnerNode::Item(item) => check_item(tcx, item),
-        hir::OwnerNode::TraitItem(item) => check_trait_item(tcx, item),
-        hir::OwnerNode::ImplItem(item) => check_impl_item(tcx, item),
-        hir::OwnerNode::ForeignItem(item) => check_foreign_item(tcx, item),
-        hir::OwnerNode::Synthetic => unreachable!(),
+        hir::Node::Crate(_) => bug!("check_well_formed cannot be applied to the crate root"),
+        hir::Node::Item(item) => check_item(tcx, item),
+        hir::Node::TraitItem(item) => check_trait_item(tcx, item),
+        hir::Node::ImplItem(item) => check_impl_item(tcx, item),
+        hir::Node::ForeignItem(item) => check_foreign_item(tcx, item),
+        hir::Node::OpaqueTy(_) => Ok(crate::check::check::check_item_type(tcx, def_id)),
+        _ => unreachable!(),
     };
 
     if let Some(generics) = node.generics() {
@@ -201,6 +202,7 @@ fn check_well_formed(tcx: TyCtxt<'_>, def_id: hir::OwnerId) -> Result<(), ErrorG
             res = res.and(check_param_wf(tcx, param));
         }
     }
+
     res
 }
 
@@ -2172,10 +2174,14 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
 
 fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), ErrorGuaranteed> {
     let items = tcx.hir_module_items(module);
-    let mut res = items.par_items(|item| tcx.ensure().check_well_formed(item.owner_id));
-    res = res.and(items.par_impl_items(|item| tcx.ensure().check_well_formed(item.owner_id)));
-    res = res.and(items.par_trait_items(|item| tcx.ensure().check_well_formed(item.owner_id)));
-    res = res.and(items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id)));
+    let mut res = items.par_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id));
+    res =
+        res.and(items.par_impl_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)));
+    res =
+        res.and(items.par_trait_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)));
+    res = res
+        .and(items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)));
+    res = res.and(items.par_opaques(|item| tcx.ensure().check_well_formed(item)));
     if module == LocalModDefId::CRATE_DEF_ID {
         super::entry::check_for_entry_fn(tcx);
     }
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 93b021be245..640907c3e4a 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -260,8 +260,7 @@ fn reject_placeholder_type_signatures_in_item<'tcx>(
         | hir::ItemKind::Trait(_, _, generics, ..)
         | hir::ItemKind::Impl(hir::Impl { generics, .. })
         | hir::ItemKind::Struct(_, generics) => (generics, true),
-        hir::ItemKind::OpaqueTy(hir::OpaqueTy { generics, .. })
-        | hir::ItemKind::TyAlias(_, generics) => (generics, false),
+        hir::ItemKind::TyAlias(_, generics) => (generics, false),
         // `static`, `fn` and `const` are handled elsewhere to suggest appropriate type.
         _ => return,
     };
@@ -328,6 +327,19 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
         intravisit::walk_expr(self, expr);
     }
 
+    /// Don't call `type_of` on opaque types, since that depends on type checking function bodies.
+    /// `check_item_type` ensures that it's called instead.
+    fn visit_opaque_ty(&mut self, opaque: &'tcx hir::OpaqueTy<'tcx>) {
+        let def_id = opaque.def_id;
+        self.tcx.ensure().generics_of(def_id);
+        self.tcx.ensure().predicates_of(def_id);
+        self.tcx.ensure().explicit_item_bounds(def_id);
+        self.tcx.ensure().explicit_item_super_predicates(def_id);
+        self.tcx.ensure().item_bounds(def_id);
+        self.tcx.ensure().item_super_predicates(def_id);
+        intravisit::walk_opaque_ty(self, opaque);
+    }
+
     fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
         lower_trait_item(self.tcx, trait_item.trait_item_id());
         intravisit::walk_trait_item(self, trait_item);
@@ -731,18 +743,6 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
             }
         }
 
-        // Don't call `type_of` on opaque types, since that depends on type
-        // checking function bodies. `check_item_type` ensures that it's called
-        // instead.
-        hir::ItemKind::OpaqueTy(..) => {
-            tcx.ensure().generics_of(def_id);
-            tcx.ensure().predicates_of(def_id);
-            tcx.ensure().explicit_item_bounds(def_id);
-            tcx.ensure().explicit_item_super_predicates(def_id);
-            tcx.ensure().item_bounds(def_id);
-            tcx.ensure().item_super_predicates(def_id);
-        }
-
         hir::ItemKind::TyAlias(..) => {
             tcx.ensure().generics_of(def_id);
             tcx.ensure().type_of(def_id);
@@ -1852,12 +1852,8 @@ fn coroutine_for_closure(tcx: TyCtxt<'_>, def_id: LocalDefId) -> DefId {
 }
 
 fn is_type_alias_impl_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool {
-    match tcx.hir_node_by_def_id(def_id) {
-        Node::Item(hir::Item { kind: hir::ItemKind::OpaqueTy(opaque), .. }) => {
-            matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias { .. })
-        }
-        _ => bug!("tried getting opaque_ty_origin for non-opaque: {:?}", def_id),
-    }
+    let opaque = tcx.hir().expect_opaque_ty(def_id);
+    matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias { .. })
 }
 
 fn rendered_precise_capturing_args<'tcx>(
@@ -1870,12 +1866,10 @@ fn rendered_precise_capturing_args<'tcx>(
         return tcx.rendered_precise_capturing_args(opaque_def_id);
     }
 
-    tcx.hir_node_by_def_id(def_id).expect_item().expect_opaque_ty().bounds.iter().find_map(
-        |bound| match bound {
-            hir::GenericBound::Use(args, ..) => {
-                Some(&*tcx.arena.alloc_from_iter(args.iter().map(|arg| arg.name())))
-            }
-            _ => None,
-        },
-    )
+    tcx.hir_node_by_def_id(def_id).expect_opaque_ty().bounds.iter().find_map(|bound| match bound {
+        hir::GenericBound::Use(args, ..) => {
+            Some(&*tcx.arena.alloc_from_iter(args.iter().map(|arg| arg.name())))
+        }
+        _ => None,
+    })
 }
diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs
index d76d9213129..8648a7d1e32 100644
--- a/compiler/rustc_hir_analysis/src/collect/dump.rs
+++ b/compiler/rustc_hir_analysis/src/collect/dump.rs
@@ -1,4 +1,3 @@
-use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
 use rustc_hir::intravisit;
 use rustc_middle::hir::nested_filter::OnlyBodies;
@@ -10,12 +9,10 @@ pub(crate) fn opaque_hidden_types(tcx: TyCtxt<'_>) {
         return;
     }
 
-    for id in tcx.hir().items() {
-        let DefKind::OpaqueTy = tcx.def_kind(id.owner_id) else { continue };
-
-        let ty = tcx.type_of(id.owner_id).instantiate_identity();
-
-        tcx.dcx().emit_err(crate::errors::TypeOf { span: tcx.def_span(id.owner_id), ty });
+    for id in tcx.hir_crate_items(()).opaques() {
+        let ty = tcx.type_of(id).instantiate_identity();
+        let span = tcx.def_span(id);
+        tcx.dcx().emit_err(crate::errors::TypeOf { span, ty });
     }
 }
 
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 8ff9640a874..14b6b17ed18 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -24,6 +24,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
     if let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, opaque_def_id }) =
         tcx.opt_rpitit_info(def_id.to_def_id())
     {
+        debug!("RPITIT fn_def_id={fn_def_id:?} opaque_def_id={opaque_def_id:?}");
         let trait_def_id = tcx.parent(fn_def_id);
         let opaque_ty_generics = tcx.generics_of(opaque_def_id);
         let opaque_ty_parent_count = opaque_ty_generics.parent_count;
@@ -207,36 +208,33 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
         | Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {
             Some(tcx.typeck_root_def_id(def_id.to_def_id()))
         }
-        Node::Item(item) => match item.kind {
-            ItemKind::OpaqueTy(&hir::OpaqueTy {
-                origin:
-                    hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, in_trait_or_impl }
-                    | hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl },
-                ..
-            }) => {
-                if in_trait_or_impl.is_some() {
-                    assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn);
-                } else {
-                    assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn);
-                }
-                Some(fn_def_id.to_def_id())
+        Node::OpaqueTy(&hir::OpaqueTy {
+            origin:
+                hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, in_trait_or_impl }
+                | hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl },
+            ..
+        }) => {
+            if in_trait_or_impl.is_some() {
+                assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn);
+            } else {
+                assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn);
             }
-            ItemKind::OpaqueTy(&hir::OpaqueTy {
-                origin: hir::OpaqueTyOrigin::TyAlias { parent, in_assoc_ty },
-                ..
-            }) => {
-                if in_assoc_ty {
-                    assert_matches!(tcx.def_kind(parent), DefKind::AssocTy);
-                } else {
-                    assert_matches!(tcx.def_kind(parent), DefKind::TyAlias);
-                }
-                debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent);
-                // Opaque types are always nested within another item, and
-                // inherit the generics of the item.
-                Some(parent.to_def_id())
+            Some(fn_def_id.to_def_id())
+        }
+        Node::OpaqueTy(&hir::OpaqueTy {
+            origin: hir::OpaqueTyOrigin::TyAlias { parent, in_assoc_ty },
+            ..
+        }) => {
+            if in_assoc_ty {
+                assert_matches!(tcx.def_kind(parent), DefKind::AssocTy);
+            } else {
+                assert_matches!(tcx.def_kind(parent), DefKind::TyAlias);
             }
-            _ => None,
-        },
+            debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent);
+            // Opaque types are always nested within another item, and
+            // inherit the generics of the item.
+            Some(parent.to_def_id())
+        }
         _ => None,
     };
 
@@ -272,13 +270,14 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
                 ItemKind::TyAlias(..)
                 | ItemKind::Enum(..)
                 | ItemKind::Struct(..)
-                | ItemKind::OpaqueTy(..)
                 | ItemKind::Union(..) => (None, Defaults::Allowed),
                 ItemKind::Const(..) => (None, Defaults::Deny),
                 _ => (None, Defaults::FutureCompatDisallowed),
             }
         }
 
+        Node::OpaqueTy(..) => (None, Defaults::Allowed),
+
         // GATs
         Node::TraitItem(item) if matches!(item.kind, TraitItemKind::Type(..)) => {
             (None, Defaults::Deny)
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index 2418037ae96..4346504450d 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -335,8 +335,7 @@ pub(super) fn explicit_item_bounds_with_filter(
         // RPITIT's bounds are the same as opaque type bounds, but with
         // a projection self type.
         Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
-            let item = tcx.hir_node_by_def_id(opaque_def_id.expect_local()).expect_item();
-            let opaque_ty = item.expect_opaque_ty();
+            let opaque_ty = tcx.hir_node_by_def_id(opaque_def_id.expect_local()).expect_opaque_ty();
             let item_ty = Ty::new_projection_from_args(
                 tcx,
                 def_id.to_def_id(),
@@ -347,7 +346,7 @@ pub(super) fn explicit_item_bounds_with_filter(
                 opaque_def_id.expect_local(),
                 opaque_ty.bounds,
                 item_ty,
-                item.span,
+                opaque_ty.span,
                 filter,
             );
             assert_only_contains_predicates_from(filter, bounds, item_ty);
@@ -369,11 +368,7 @@ pub(super) fn explicit_item_bounds_with_filter(
             span,
             ..
         }) => associated_type_bounds(tcx, def_id, bounds, *span, filter),
-        hir::Node::Item(hir::Item {
-            kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, origin, .. }),
-            span,
-            ..
-        }) => match origin {
+        hir::Node::OpaqueTy(hir::OpaqueTy { bounds, origin, span, .. }) => match origin {
             // Since RPITITs are lowered as projections in `<dyn HirTyLowerer>::lower_ty`,
             // when we're asking for the item bounds of the *opaques* in a trait's default
             // method signature, we need to map these projections back to opaques.
@@ -412,7 +407,7 @@ pub(super) fn explicit_item_bounds_with_filter(
             }
         },
         hir::Node::Item(hir::Item { kind: hir::ItemKind::TyAlias(..), .. }) => &[],
-        _ => bug!("item_bounds called on {:?}", def_id),
+        node => bug!("item_bounds called on {def_id:?} => {node:?}"),
     };
 
     ty::EarlyBinder::bind(bounds)
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 33f6623edfd..6d30f7c7b9d 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -330,7 +330,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
     // Opaque types duplicate some of their generic parameters.
     // We create bi-directional Outlives predicates between the original
     // and the duplicated parameter, to ensure that they do not get out of sync.
-    if let Node::Item(&Item { kind: ItemKind::OpaqueTy(..), .. }) = node {
+    if let Node::OpaqueTy(..) = node {
         let opaque_ty_node = tcx.parent_hir_node(hir_id);
         let Node::Ty(&hir::Ty { kind: TyKind::OpaqueDef(_, lifetimes), .. }) = opaque_ty_node
         else {
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index a15621bf28b..c8852a3a369 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -11,10 +11,13 @@ use std::fmt;
 
 use rustc_ast::visit::walk_list;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
+use rustc_data_structures::sorted_map::SortedMap;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit::{self, Visitor};
-use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirId, HirIdMap, LifetimeName, Node};
+use rustc_hir::{
+    GenericArg, GenericParam, GenericParamKind, HirId, ItemLocalMap, LifetimeName, Node,
+};
 use rustc_macros::extension;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::middle::resolve_bound_vars::*;
@@ -74,7 +77,7 @@ impl ResolvedArg {
 struct NamedVarMap {
     // maps from every use of a named (not anonymous) bound var to a
     // `ResolvedArg` describing how that variable is bound
-    defs: HirIdMap<ResolvedArg>,
+    defs: ItemLocalMap<ResolvedArg>,
 
     // Maps relevant hir items to the bound vars on them. These include:
     // - function defs
@@ -82,7 +85,7 @@ struct NamedVarMap {
     // - closures
     // - trait refs
     // - bound types (like `T` in `for<'a> T<'a>: Foo`)
-    late_bound_vars: HirIdMap<Vec<ty::BoundVariableKind>>,
+    late_bound_vars: ItemLocalMap<Vec<ty::BoundVariableKind>>,
 }
 
 struct BoundVarContext<'a, 'tcx> {
@@ -225,10 +228,10 @@ pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers {
         resolve_bound_vars,
 
-        named_variable_map: |tcx, id| tcx.resolve_bound_vars(id).defs.get(&id),
+        named_variable_map: |tcx, id| &tcx.resolve_bound_vars(id).defs,
         is_late_bound_map,
         object_lifetime_default,
-        late_bound_vars_map: |tcx, id| tcx.resolve_bound_vars(id).late_bound_vars.get(&id),
+        late_bound_vars_map: |tcx, id| &tcx.resolve_bound_vars(id).late_bound_vars,
 
         ..*providers
     };
@@ -265,16 +268,12 @@ fn resolve_bound_vars(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveBou
         hir::OwnerNode::Synthetic => unreachable!(),
     }
 
-    let mut rl = ResolveBoundVars::default();
-
-    for (hir_id, v) in named_variable_map.defs {
-        let map = rl.defs.entry(hir_id.owner).or_default();
-        map.insert(hir_id.local_id, v);
-    }
-    for (hir_id, v) in named_variable_map.late_bound_vars {
-        let map = rl.late_bound_vars.entry(hir_id.owner).or_default();
-        map.insert(hir_id.local_id, v);
-    }
+    let defs = named_variable_map.defs.into_sorted_stable_ord();
+    let late_bound_vars = named_variable_map.late_bound_vars.into_sorted_stable_ord();
+    let rl = ResolveBoundVars {
+        defs: SortedMap::from_presorted_elements(defs),
+        late_bound_vars: SortedMap::from_presorted_elements(late_bound_vars),
+    };
 
     debug!(?rl.defs);
     debug!(?rl.late_bound_vars);
@@ -340,7 +339,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                 Scope::Binder { hir_id, .. } => {
                     // Nested poly trait refs have the binders concatenated
                     let mut full_binders =
-                        self.map.late_bound_vars.entry(*hir_id).or_default().clone();
+                        self.map.late_bound_vars.entry(hir_id.local_id).or_default().clone();
                     full_binders.extend(supertrait_bound_vars);
                     break (full_binders, BinderScopeType::Concatenating);
                 }
@@ -487,6 +486,31 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
     }
 
     #[instrument(level = "debug", skip(self))]
+    fn visit_opaque_ty(&mut self, opaque: &'tcx rustc_hir::OpaqueTy<'tcx>) {
+        // We want to start our early-bound indices at the end of the parent scope,
+        // not including any parent `impl Trait`s.
+        let mut bound_vars = FxIndexMap::default();
+        debug!(?opaque.generics.params);
+        for param in opaque.generics.params {
+            let (def_id, reg) = ResolvedArg::early(param);
+            bound_vars.insert(def_id, reg);
+        }
+
+        let hir_id = self.tcx.local_def_id_to_hir_id(opaque.def_id);
+        let scope = Scope::Binder {
+            hir_id,
+            bound_vars,
+            s: self.scope,
+            scope_type: BinderScopeType::Normal,
+            where_bound_origin: None,
+        };
+        self.with(scope, |this| {
+            let scope = Scope::TraitRefBoundary { s: this.scope };
+            this.with(scope, |this| intravisit::walk_opaque_ty(this, opaque))
+        })
+    }
+
+    #[instrument(level = "debug", skip(self))]
     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
         match &item.kind {
             hir::ItemKind::Impl(hir::Impl { of_trait, .. }) => {
@@ -513,38 +537,6 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                 // These sorts of items have no lifetime parameters at all.
                 intravisit::walk_item(self, item);
             }
-            hir::ItemKind::OpaqueTy(&hir::OpaqueTy {
-                origin:
-                    hir::OpaqueTyOrigin::FnReturn { parent, .. }
-                    | hir::OpaqueTyOrigin::AsyncFn { parent, .. }
-                    | hir::OpaqueTyOrigin::TyAlias { parent, .. },
-                generics,
-                ..
-            }) => {
-                // We want to start our early-bound indices at the end of the parent scope,
-                // not including any parent `impl Trait`s.
-                let mut bound_vars = FxIndexMap::default();
-                debug!(?generics.params);
-                for param in generics.params {
-                    let (def_id, reg) = ResolvedArg::early(param);
-                    bound_vars.insert(def_id, reg);
-                }
-
-                let scope = Scope::Root { opt_parent_item: Some(parent) };
-                self.with(scope, |this| {
-                    let scope = Scope::Binder {
-                        hir_id: item.hir_id(),
-                        bound_vars,
-                        s: this.scope,
-                        scope_type: BinderScopeType::Normal,
-                        where_bound_origin: None,
-                    };
-                    this.with(scope, |this| {
-                        let scope = Scope::TraitRefBoundary { s: this.scope };
-                        this.with(scope, |this| intravisit::walk_item(this, item))
-                    });
-                })
-            }
             hir::ItemKind::TyAlias(_, generics)
             | hir::ItemKind::Const(_, generics, _)
             | hir::ItemKind::Enum(_, generics)
@@ -684,22 +676,19 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
             hir::TyKind::Ref(lifetime_ref, ref mt) => {
                 self.visit_lifetime(lifetime_ref);
                 let scope = Scope::ObjectLifetimeDefault {
-                    lifetime: self.map.defs.get(&lifetime_ref.hir_id).cloned(),
+                    lifetime: self.map.defs.get(&lifetime_ref.hir_id.local_id).cloned(),
                     s: self.scope,
                 };
                 self.with(scope, |this| this.visit_ty(mt.ty));
             }
-            hir::TyKind::OpaqueDef(item_id, lifetimes) => {
+            hir::TyKind::OpaqueDef(opaque_ty, lifetimes) => {
+                self.visit_opaque_ty(opaque_ty);
+
                 // Resolve the lifetimes in the bounds to the lifetime defs in the generics.
                 // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
                 // `type MyAnonTy<'b> = impl MyTrait<'b>;`
                 //                 ^                  ^ this gets resolved in the scope of
                 //                                      the opaque_ty generics
-                let opaque_ty = self.tcx.hir().item(item_id);
-                match &opaque_ty.kind {
-                    hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin: _, .. }) => {}
-                    i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
-                };
 
                 // Resolve the lifetimes that are applied to the opaque type.
                 // These are resolved in the current scope.
@@ -714,7 +703,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                     // and ban them. Type variables instantiated inside binders aren't
                     // well-supported at the moment, so this doesn't work.
                     // In the future, this should be fixed and this error should be removed.
-                    let def = self.map.defs.get(&lifetime.hir_id).copied();
+                    let def = self.map.defs.get(&lifetime.hir_id.local_id).copied();
                     let Some(ResolvedArg::LateBound(_, _, lifetime_def_id)) = def else { continue };
                     let lifetime_hir_id = self.tcx.local_def_id_to_hir_id(lifetime_def_id);
 
@@ -722,9 +711,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                     {
                         // Opaques do not declare their own lifetimes, so if a lifetime comes from an opaque
                         // it must be a reified late-bound lifetime from a trait goal.
-                        hir::Node::Item(hir::Item {
-                            kind: hir::ItemKind::OpaqueTy { .. }, ..
-                        }) => "higher-ranked lifetime from outer `impl Trait`",
+                        hir::Node::OpaqueTy(_) => "higher-ranked lifetime from outer `impl Trait`",
                         // Other items are fine.
                         hir::Node::Item(_) | hir::Node::TraitItem(_) | hir::Node::ImplItem(_) => {
                             continue;
@@ -740,8 +727,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
 
                     let (span, label) = if lifetime.ident.span == self.tcx.def_span(lifetime_def_id)
                     {
-                        let opaque_span = self.tcx.def_span(item_id.owner_id);
-                        (opaque_span, Some(opaque_span))
+                        (opaque_ty.span, Some(opaque_ty.span))
                     } else {
                         (lifetime.ident.span, None)
                     };
@@ -854,7 +840,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
             let bound_vars: Vec<_> =
                 self.tcx.fn_sig(sig_id).skip_binder().bound_vars().iter().collect();
             let hir_id = self.tcx.local_def_id_to_hir_id(def_id);
-            self.map.late_bound_vars.insert(hir_id, bound_vars);
+            self.map.late_bound_vars.insert(hir_id.local_id, bound_vars);
         }
         self.visit_fn_like_elision(fd.inputs, output, matches!(fk, intravisit::FnKind::Closure));
         intravisit::walk_fn_kind(self, fk);
@@ -1032,10 +1018,10 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
     }
 
     fn record_late_bound_vars(&mut self, hir_id: HirId, binder: Vec<ty::BoundVariableKind>) {
-        if let Some(old) = self.map.late_bound_vars.insert(hir_id, binder) {
+        if let Some(old) = self.map.late_bound_vars.insert(hir_id.local_id, binder) {
             bug!(
                 "overwrote bound vars for {hir_id:?}:\nold={old:?}\nnew={:?}",
-                self.map.late_bound_vars[&hir_id]
+                self.map.late_bound_vars[&hir_id.local_id]
             )
         }
     }
@@ -1394,9 +1380,9 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                         kind.descr(param_def_id.to_def_id())
                     ),
                 };
-                self.map.defs.insert(hir_id, ResolvedArg::Error(guar));
+                self.map.defs.insert(hir_id.local_id, ResolvedArg::Error(guar));
             } else {
-                self.map.defs.insert(hir_id, def);
+                self.map.defs.insert(hir_id.local_id, def);
             }
             return;
         }
@@ -1429,7 +1415,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                             bug!("unexpected def-kind: {}", kind.descr(param_def_id.to_def_id()))
                         }
                     });
-                    self.map.defs.insert(hir_id, ResolvedArg::Error(guar));
+                    self.map.defs.insert(hir_id.local_id, ResolvedArg::Error(guar));
                     return;
                 }
                 Scope::Root { .. } => break,
@@ -1539,7 +1525,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                     // This index can be used with `generic_args` since `parent_count == 0`.
                     let index = generics.param_def_id_to_index[&param_def_id] as usize;
                     generic_args.args.get(index).and_then(|arg| match arg {
-                        GenericArg::Lifetime(lt) => map.defs.get(&lt.hir_id).copied(),
+                        GenericArg::Lifetime(lt) => map.defs.get(&lt.hir_id.local_id).copied(),
                         _ => None,
                     })
                 }
@@ -1829,7 +1815,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
     #[instrument(level = "debug", skip(self))]
     fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: ResolvedArg) {
         debug!(span = ?lifetime_ref.ident.span);
-        self.map.defs.insert(lifetime_ref.hir_id, def);
+        self.map.defs.insert(lifetime_ref.hir_id.local_id, def);
     }
 
     /// Sometimes we resolve a lifetime, but later find that it is an
@@ -1840,8 +1826,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
         lifetime_ref: &'tcx hir::Lifetime,
         bad_def: ResolvedArg,
     ) {
-        // FIXME(#120456) - is `swap_remove` correct?
-        let old_value = self.map.defs.swap_remove(&lifetime_ref.hir_id);
+        let old_value = self.map.defs.remove(&lifetime_ref.hir_id.local_id);
         assert_eq!(old_value, Some(bad_def));
     }
 
@@ -2011,7 +1996,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
         // See where these vars are used in `HirTyLowerer::lower_ty_maybe_return_type_notation`.
         // And this is exercised in:
         // `tests/ui/associated-type-bounds/return-type-notation/higher-ranked-bound-works.rs`.
-        let existing_bound_vars = self.map.late_bound_vars.get_mut(&hir_id).unwrap();
+        let existing_bound_vars = self.map.late_bound_vars.get_mut(&hir_id.local_id).unwrap();
         let existing_bound_vars_saved = existing_bound_vars.clone();
         existing_bound_vars.extend(bound_vars);
         self.record_late_bound_vars(item_segment.hir_id, existing_bound_vars_saved);
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 3af4d1f5eda..470bcaeded1 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -529,10 +529,6 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
                 let args = ty::GenericArgs::identity_for_item(tcx, def_id);
                 Ty::new_adt(tcx, def, args)
             }
-            ItemKind::OpaqueTy(..) => tcx.type_of_opaque(def_id).map_or_else(
-                |CyclePlaceholder(guar)| Ty::new_error(tcx, guar),
-                |ty| ty.instantiate_identity(),
-            ),
             ItemKind::Trait(..)
             | ItemKind::TraitAlias(..)
             | ItemKind::Macro(..)
@@ -545,6 +541,11 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
             }
         },
 
+        Node::OpaqueTy(..) => tcx.type_of_opaque(def_id).map_or_else(
+            |CyclePlaceholder(guar)| Ty::new_error(tcx, guar),
+            |ty| ty.instantiate_identity(),
+        ),
+
         Node::ForeignItem(foreign_item) => match foreign_item.kind {
             ForeignItemKind::Fn(..) => {
                 let args = ty::GenericArgs::identity_for_item(tcx, def_id);
@@ -603,42 +604,25 @@ pub(super) fn type_of_opaque(
     def_id: DefId,
 ) -> Result<ty::EarlyBinder<'_, Ty<'_>>, CyclePlaceholder> {
     if let Some(def_id) = def_id.as_local() {
-        use rustc_hir::*;
-
-        Ok(ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id) {
-            Node::Item(item) => match item.kind {
-                ItemKind::OpaqueTy(OpaqueTy {
-                    origin: hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. },
-                    ..
-                }) => opaque::find_opaque_ty_constraints_for_tait(tcx, def_id),
-                ItemKind::OpaqueTy(OpaqueTy {
-                    origin: hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: true, .. },
-                    ..
-                }) => opaque::find_opaque_ty_constraints_for_impl_trait_in_assoc_type(tcx, def_id),
-                // Opaque types desugared from `impl Trait`.
-                ItemKind::OpaqueTy(&OpaqueTy {
-                    origin:
-                        hir::OpaqueTyOrigin::FnReturn { parent: owner, in_trait_or_impl }
-                        | hir::OpaqueTyOrigin::AsyncFn { parent: owner, in_trait_or_impl },
-                    ..
-                }) => {
-                    if in_trait_or_impl == Some(hir::RpitContext::Trait)
-                        && !tcx.defaultness(owner).has_value()
-                    {
-                        span_bug!(
-                            tcx.def_span(def_id),
-                            "tried to get type of this RPITIT with no definition"
-                        );
-                    }
-                    opaque::find_opaque_ty_constraints_for_rpit(tcx, def_id, owner)
-                }
-                _ => {
-                    span_bug!(item.span, "type_of_opaque: unexpected item type: {:?}", item.kind);
+        Ok(ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin {
+            hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. } => {
+                opaque::find_opaque_ty_constraints_for_tait(tcx, def_id)
+            }
+            hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: true, .. } => {
+                opaque::find_opaque_ty_constraints_for_impl_trait_in_assoc_type(tcx, def_id)
+            }
+            // Opaque types desugared from `impl Trait`.
+            hir::OpaqueTyOrigin::FnReturn { parent: owner, in_trait_or_impl }
+            | hir::OpaqueTyOrigin::AsyncFn { parent: owner, in_trait_or_impl } => {
+                if in_trait_or_impl == Some(hir::RpitContext::Trait)
+                    && !tcx.defaultness(owner).has_value()
+                {
+                    span_bug!(
+                        tcx.def_span(def_id),
+                        "tried to get type of this RPITIT with no definition"
+                    );
                 }
-            },
-
-            x => {
-                bug!("unexpected sort of node in type_of_opaque(): {:?}", x);
+                opaque::find_opaque_ty_constraints_for_rpit(tcx, def_id, owner)
             }
         }))
     } else {
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index 95f83836d75..28a1fc88741 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -2087,43 +2087,36 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
                 self.lower_path(opt_self_ty, path, hir_ty.hir_id, false)
             }
-            &hir::TyKind::OpaqueDef(item_id, lifetimes) => {
-                let opaque_ty = tcx.hir().item(item_id);
-
-                match opaque_ty.kind {
-                    hir::ItemKind::OpaqueTy(&hir::OpaqueTy { origin, .. }) => {
-                        let local_def_id = item_id.owner_id.def_id;
-                        // If this is an RPITIT and we are using the new RPITIT lowering scheme, we
-                        // generate the def_id of an associated type for the trait and return as
-                        // type a projection.
-                        match origin {
-                            hir::OpaqueTyOrigin::FnReturn {
-                                in_trait_or_impl: Some(hir::RpitContext::Trait),
-                                ..
-                            }
-                            | hir::OpaqueTyOrigin::AsyncFn {
-                                in_trait_or_impl: Some(hir::RpitContext::Trait),
-                                ..
-                            } => self.lower_opaque_ty(
-                                tcx.associated_type_for_impl_trait_in_trait(local_def_id)
-                                    .to_def_id(),
-                                lifetimes,
-                                true,
-                            ),
-                            hir::OpaqueTyOrigin::FnReturn {
-                                in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
-                                ..
-                            }
-                            | hir::OpaqueTyOrigin::AsyncFn {
-                                in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
-                                ..
-                            }
-                            | hir::OpaqueTyOrigin::TyAlias { .. } => {
-                                self.lower_opaque_ty(local_def_id.to_def_id(), lifetimes, false)
-                            }
-                        }
+            &hir::TyKind::OpaqueDef(opaque_ty, lifetimes) => {
+                let local_def_id = opaque_ty.def_id;
+
+                // If this is an RPITIT and we are using the new RPITIT lowering scheme, we
+                // generate the def_id of an associated type for the trait and return as
+                // type a projection.
+                match opaque_ty.origin {
+                    hir::OpaqueTyOrigin::FnReturn {
+                        in_trait_or_impl: Some(hir::RpitContext::Trait),
+                        ..
+                    }
+                    | hir::OpaqueTyOrigin::AsyncFn {
+                        in_trait_or_impl: Some(hir::RpitContext::Trait),
+                        ..
+                    } => self.lower_opaque_ty(
+                        tcx.associated_type_for_impl_trait_in_trait(local_def_id).to_def_id(),
+                        lifetimes,
+                        true,
+                    ),
+                    hir::OpaqueTyOrigin::FnReturn {
+                        in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
+                        ..
+                    }
+                    | hir::OpaqueTyOrigin::AsyncFn {
+                        in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
+                        ..
+                    }
+                    | hir::OpaqueTyOrigin::TyAlias { .. } => {
+                        self.lower_opaque_ty(local_def_id.to_def_id(), lifetimes, false)
                     }
-                    ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
                 }
             }
             // If we encounter a type relative path with RTN generics, then it must have
@@ -2289,7 +2282,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     span_bug!(
                         tcx.def_span(param.def_id),
                         "only expected lifetime for opaque's own generics, got {:?}",
-                        param.kind
+                        param
                     );
                 };
                 let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] else {
diff --git a/compiler/rustc_hir_analysis/src/variance/dump.rs b/compiler/rustc_hir_analysis/src/variance/dump.rs
index dbaf9c2c6f0..a0fdf95a831 100644
--- a/compiler/rustc_hir_analysis/src/variance/dump.rs
+++ b/compiler/rustc_hir_analysis/src/variance/dump.rs
@@ -1,6 +1,5 @@
 use std::fmt::Write;
 
-use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
 use rustc_middle::ty::{GenericArgs, TyCtxt};
 use rustc_span::symbol::sym;
@@ -24,18 +23,18 @@ fn format_variances(tcx: TyCtxt<'_>, def_id: LocalDefId) -> String {
 }
 
 pub(crate) fn variances(tcx: TyCtxt<'_>) {
-    if tcx.has_attr(CRATE_DEF_ID, sym::rustc_variance_of_opaques) {
-        for id in tcx.hir().items() {
-            let DefKind::OpaqueTy = tcx.def_kind(id.owner_id) else { continue };
+    let crate_items = tcx.hir_crate_items(());
 
+    if tcx.has_attr(CRATE_DEF_ID, sym::rustc_variance_of_opaques) {
+        for id in crate_items.opaques() {
             tcx.dcx().emit_err(crate::errors::VariancesOf {
-                span: tcx.def_span(id.owner_id),
-                variances: format_variances(tcx, id.owner_id.def_id),
+                span: tcx.def_span(id),
+                variances: format_variances(tcx, id),
             });
         }
     }
 
-    for id in tcx.hir().items() {
+    for id in crate_items.free_items() {
         if !tcx.has_attr(id.owner_id, sym::rustc_variance) {
             continue;
         }
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 1c52283d537..9fe6a8ee342 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -96,6 +96,7 @@ impl<'a> State<'a> {
             Node::Ty(a) => self.print_type(a),
             Node::AssocItemConstraint(a) => self.print_assoc_item_constraint(a),
             Node::TraitRef(a) => self.print_trait_ref(a),
+            Node::OpaqueTy(o) => self.print_opaque_ty(o),
             Node::Pat(a) => self.print_pat(a),
             Node::PatField(a) => self.print_patfield(a),
             Node::Arm(a) => self.print_arm(a),
@@ -568,11 +569,6 @@ impl<'a> State<'a> {
                     state.print_type(ty);
                 });
             }
-            hir::ItemKind::OpaqueTy(opaque_ty) => {
-                self.print_item_type(item, opaque_ty.generics, |state| {
-                    state.print_bounds("= impl", opaque_ty.bounds)
-                });
-            }
             hir::ItemKind::Enum(ref enum_definition, params) => {
                 self.print_enum_def(enum_definition, params, item.ident.name, item.span);
             }
@@ -665,6 +661,15 @@ impl<'a> State<'a> {
         self.print_path(t.path, false);
     }
 
+    fn print_opaque_ty(&mut self, o: &hir::OpaqueTy<'_>) {
+        self.head("opaque");
+        self.print_generic_params(o.generics.params);
+        self.print_where_clause(o.generics);
+        self.word("{");
+        self.print_bounds("impl", o.bounds);
+        self.word("}");
+    }
+
     fn print_formal_generic_params(&mut self, generic_params: &[hir::GenericParam<'_>]) {
         if !generic_params.is_empty() {
             self.word("for");
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index d0e91ec07f6..435b7d0f39a 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -847,11 +847,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 return true;
             }
             hir::FnRetTy::Return(hir_ty) => {
-                if let hir::TyKind::OpaqueDef(item_id, ..) = hir_ty.kind
+                if let hir::TyKind::OpaqueDef(op_ty, ..) = hir_ty.kind
                     // FIXME: account for RPITIT.
-                    && let hir::Node::Item(hir::Item {
-                        kind: hir::ItemKind::OpaqueTy(op_ty), ..
-                    }) = self.tcx.hir_node(item_id.hir_id())
                     && let [hir::GenericBound::Trait(trait_ref, _)] = op_ty.bounds
                     && let Some(hir::PathSegment { args: Some(generic_args), .. }) =
                         trait_ref.trait_ref.path.segments.last()
diff --git a/compiler/rustc_lint/src/async_fn_in_trait.rs b/compiler/rustc_lint/src/async_fn_in_trait.rs
index d9040207300..63a8a949e96 100644
--- a/compiler/rustc_lint/src/async_fn_in_trait.rs
+++ b/compiler/rustc_lint/src/async_fn_in_trait.rs
@@ -104,8 +104,9 @@ impl<'tcx> LateLintPass<'tcx> for AsyncFnInTrait {
                 return;
             }
 
-            let hir::FnRetTy::Return(hir::Ty { kind: hir::TyKind::OpaqueDef(def, ..), .. }) =
-                sig.decl.output
+            let hir::FnRetTy::Return(hir::Ty {
+                kind: hir::TyKind::OpaqueDef(opaq_def, ..), ..
+            }) = sig.decl.output
             else {
                 // This should never happen, but let's not ICE.
                 return;
@@ -114,7 +115,7 @@ impl<'tcx> LateLintPass<'tcx> for AsyncFnInTrait {
                 cx.tcx,
                 sig,
                 body,
-                def.owner_id.def_id,
+                opaq_def.def_id,
                 " + Send",
             );
             cx.tcx.emit_node_span_lint(
diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs
index 5aeaad42069..d029ad93407 100644
--- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs
+++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs
@@ -258,7 +258,7 @@ where
             && self.seen.insert(opaque_def_id)
             // If it's owned by this function
             && let opaque =
-                self.tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty()
+                self.tcx.hir_node_by_def_id(opaque_def_id).expect_opaque_ty()
             && let hir::OpaqueTyOrigin::FnReturn { parent, .. } = opaque.origin
             && parent == self.parent_def_id
         {
diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
index 342ebfa0b06..ffbcf7f808e 100644
--- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
+++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
@@ -68,8 +68,8 @@ declare_lint! {
 declare_lint_pass!(OpaqueHiddenInferredBound => [OPAQUE_HIDDEN_INFERRED_BOUND]);
 
 impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
-    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
-        let hir::ItemKind::OpaqueTy(opaque) = &item.kind else {
+    fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx hir::Ty<'tcx>) {
+        let hir::TyKind::OpaqueDef(opaque, _) = &ty.kind else {
             return;
         };
 
@@ -84,7 +84,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
             return;
         }
 
-        let def_id = item.owner_id.def_id.to_def_id();
+        let def_id = opaque.def_id.to_def_id();
         let infcx = &cx.tcx.infer_ctxt().build();
         // For every projection predicate in the opaque type's explicit bounds,
         // check that the type that we're assigning actually satisfies the bounds
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 75611d71025..db4413149a4 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -1419,7 +1419,6 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDefinitions {
             hir::ItemKind::Impl(..)
             | hir::ItemKind::TraitAlias(..)
             | hir::ItemKind::Trait(..)
-            | hir::ItemKind::OpaqueTy(..)
             | hir::ItemKind::GlobalAsm(..)
             | hir::ItemKind::ForeignMod { .. }
             | hir::ItemKind::Mod(..)
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 72e6c96e6f6..8fd5ff1f369 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -732,6 +732,19 @@ impl<'hir> Map<'hir> {
         }
     }
 
+    #[track_caller]
+    pub fn expect_opaque_ty(self, id: LocalDefId) -> &'hir OpaqueTy<'hir> {
+        match self.tcx.hir_node_by_def_id(id) {
+            Node::OpaqueTy(opaq) => opaq,
+            _ => {
+                bug!(
+                    "expected opaque type definition, found {}",
+                    self.node_to_string(self.tcx.local_def_id_to_hir_id(id))
+                )
+            }
+        }
+    }
+
     pub fn expect_expr(self, id: HirId) -> &'hir Expr<'hir> {
         match self.tcx.hir_node(id) {
             Node::Expr(expr) => expr,
@@ -923,6 +936,7 @@ impl<'hir> Map<'hir> {
             Node::Ty(ty) => ty.span,
             Node::AssocItemConstraint(constraint) => constraint.span,
             Node::TraitRef(tr) => tr.path.span,
+            Node::OpaqueTy(op) => op.span,
             Node::Pat(pat) => pat.span,
             Node::PatField(field) => field.span,
             Node::Arm(arm) => arm.span,
@@ -1006,6 +1020,10 @@ impl<'hir> intravisit::Map<'hir> for Map<'hir> {
         self.tcx.hir_node(hir_id)
     }
 
+    fn hir_node_by_def_id(&self, def_id: LocalDefId) -> Node<'hir> {
+        self.tcx.hir_node_by_def_id(def_id)
+    }
+
     fn body(&self, id: BodyId) -> &'hir Body<'hir> {
         (*self).body(id)
     }
@@ -1139,7 +1157,6 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
                 ItemKind::ForeignMod { .. } => "foreign mod",
                 ItemKind::GlobalAsm(..) => "global asm",
                 ItemKind::TyAlias(..) => "ty",
-                ItemKind::OpaqueTy(..) => "opaque type",
                 ItemKind::Enum(..) => "enum",
                 ItemKind::Struct(..) => "struct",
                 ItemKind::Union(..) => "union",
@@ -1191,6 +1208,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
         Node::Ty(_) => node_str("type"),
         Node::AssocItemConstraint(_) => node_str("assoc item constraint"),
         Node::TraitRef(_) => node_str("trait ref"),
+        Node::OpaqueTy(_) => node_str("opaque type"),
         Node::Pat(_) => node_str("pat"),
         Node::PatField(_) => node_str("pattern field"),
         Node::Param(_) => node_str("param"),
@@ -1228,6 +1246,7 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> Mod
         impl_items,
         foreign_items,
         body_owners,
+        opaques,
         ..
     } = collector;
     ModuleItems {
@@ -1237,6 +1256,7 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> Mod
         impl_items: impl_items.into_boxed_slice(),
         foreign_items: foreign_items.into_boxed_slice(),
         body_owners: body_owners.into_boxed_slice(),
+        opaques: opaques.into_boxed_slice(),
     }
 }
 
@@ -1256,6 +1276,7 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
         impl_items,
         foreign_items,
         body_owners,
+        opaques,
         ..
     } = collector;
 
@@ -1266,6 +1287,7 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
         impl_items: impl_items.into_boxed_slice(),
         foreign_items: foreign_items.into_boxed_slice(),
         body_owners: body_owners.into_boxed_slice(),
+        opaques: opaques.into_boxed_slice(),
     }
 }
 
@@ -1280,6 +1302,7 @@ struct ItemCollector<'tcx> {
     impl_items: Vec<ImplItemId>,
     foreign_items: Vec<ForeignItemId>,
     body_owners: Vec<LocalDefId>,
+    opaques: Vec<LocalDefId>,
 }
 
 impl<'tcx> ItemCollector<'tcx> {
@@ -1293,6 +1316,7 @@ impl<'tcx> ItemCollector<'tcx> {
             impl_items: Vec::default(),
             foreign_items: Vec::default(),
             body_owners: Vec::default(),
+            opaques: Vec::default(),
         }
     }
 }
@@ -1338,6 +1362,11 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
         intravisit::walk_inline_const(self, c)
     }
 
+    fn visit_opaque_ty(&mut self, o: &'hir OpaqueTy<'hir>) {
+        self.opaques.push(o.def_id);
+        intravisit::walk_opaque_ty(self, o)
+    }
+
     fn visit_expr(&mut self, ex: &'hir Expr<'hir>) {
         if let ExprKind::Closure(closure) = ex.kind {
             self.body_owners.push(closure.def_id);
diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs
index 7a07ef80ded..ad0d70152e1 100644
--- a/compiler/rustc_middle/src/hir/mod.rs
+++ b/compiler/rustc_middle/src/hir/mod.rs
@@ -28,6 +28,7 @@ pub struct ModuleItems {
     trait_items: Box<[TraitItemId]>,
     impl_items: Box<[ImplItemId]>,
     foreign_items: Box<[ForeignItemId]>,
+    opaques: Box<[LocalDefId]>,
     body_owners: Box<[LocalDefId]>,
 }
 
@@ -65,6 +66,10 @@ impl ModuleItems {
             .chain(self.foreign_items.iter().map(|id| id.owner_id))
     }
 
+    pub fn opaques(&self) -> impl Iterator<Item = LocalDefId> + '_ {
+        self.opaques.iter().copied()
+    }
+
     pub fn definitions(&self) -> impl Iterator<Item = LocalDefId> + '_ {
         self.owners().map(|id| id.def_id)
     }
@@ -96,6 +101,13 @@ impl ModuleItems {
     ) -> Result<(), ErrorGuaranteed> {
         try_par_for_each_in(&self.foreign_items[..], |&id| f(id))
     }
+
+    pub fn par_opaques(
+        &self,
+        f: impl Fn(LocalDefId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
+    ) -> Result<(), ErrorGuaranteed> {
+        try_par_for_each_in(&self.opaques[..], |&id| f(id))
+    }
 }
 
 impl<'tcx> TyCtxt<'tcx> {
diff --git a/compiler/rustc_middle/src/middle/resolve_bound_vars.rs b/compiler/rustc_middle/src/middle/resolve_bound_vars.rs
index 32e2f3b4b16..13e35cd0909 100644
--- a/compiler/rustc_middle/src/middle/resolve_bound_vars.rs
+++ b/compiler/rustc_middle/src/middle/resolve_bound_vars.rs
@@ -1,9 +1,9 @@
 //! Name resolution for lifetimes and late-bound type and const variables: type declarations.
 
-use rustc_data_structures::fx::FxIndexMap;
+use rustc_data_structures::sorted_map::SortedMap;
 use rustc_errors::ErrorGuaranteed;
+use rustc_hir::ItemLocalId;
 use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_hir::{ItemLocalId, OwnerId};
 use rustc_macros::{Decodable, Encodable, HashStable, TyDecodable, TyEncodable};
 
 use crate::ty;
@@ -47,11 +47,11 @@ pub enum ObjectLifetimeDefault {
 
 /// Maps the id of each lifetime reference to the lifetime decl
 /// that it corresponds to.
-#[derive(Default, HashStable, Debug)]
+#[derive(HashStable, Debug)]
 pub struct ResolveBoundVars {
     /// Maps from every use of a named (not anonymous) lifetime to a
     /// `Region` describing how that region is bound
-    pub defs: FxIndexMap<OwnerId, FxIndexMap<ItemLocalId, ResolvedArg>>,
+    pub defs: SortedMap<ItemLocalId, ResolvedArg>,
 
-    pub late_bound_vars: FxIndexMap<OwnerId, FxIndexMap<ItemLocalId, Vec<ty::BoundVariableKind>>>,
+    pub late_bound_vars: SortedMap<ItemLocalId, Vec<ty::BoundVariableKind>>,
 }
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 989fbd711c3..f0be70e00df 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -16,6 +16,7 @@ use rustc_ast::expand::StrippedCfgItem;
 use rustc_ast::expand::allocator::AllocatorKind;
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
+use rustc_data_structures::sorted_map::SortedMap;
 use rustc_data_structures::steal::Steal;
 use rustc_data_structures::svh::Svh;
 use rustc_data_structures::sync::Lrc;
@@ -1552,7 +1553,7 @@ rustc_queries! {
         feedable
     }
 
-    query check_well_formed(key: hir::OwnerId) -> Result<(), ErrorGuaranteed> {
+    query check_well_formed(key: LocalDefId) -> Result<(), ErrorGuaranteed> {
         desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key) }
         ensure_forwards_result_if_red
     }
@@ -1738,29 +1739,28 @@ rustc_queries! {
     /// Does lifetime resolution on items. Importantly, we can't resolve
     /// lifetimes directly on things like trait methods, because of trait params.
     /// See `rustc_resolve::late::lifetimes` for details.
-    query resolve_bound_vars(_: hir::OwnerId) -> &'tcx ResolveBoundVars {
+    query resolve_bound_vars(owner_id: hir::OwnerId) -> &'tcx ResolveBoundVars {
         arena_cache
-        desc { "resolving lifetimes" }
+        desc { |tcx| "resolving lifetimes for `{}`", tcx.def_path_str(owner_id) }
     }
-    query named_variable_map(_: hir::OwnerId) ->
-        Option<&'tcx FxIndexMap<ItemLocalId, ResolvedArg>> {
-        desc { "looking up a named region" }
+    query named_variable_map(owner_id: hir::OwnerId) -> &'tcx SortedMap<ItemLocalId, ResolvedArg> {
+        desc { |tcx| "looking up a named region inside `{}`", tcx.def_path_str(owner_id) }
     }
-    query is_late_bound_map(_: hir::OwnerId) -> Option<&'tcx FxIndexSet<ItemLocalId>> {
-        desc { "testing if a region is late bound" }
+    query is_late_bound_map(owner_id: hir::OwnerId) -> Option<&'tcx FxIndexSet<ItemLocalId>> {
+        desc { |tcx| "testing if a region is late bound inside `{}`", tcx.def_path_str(owner_id) }
     }
     /// For a given item's generic parameter, gets the default lifetimes to be used
     /// for each parameter if a trait object were to be passed for that parameter.
     /// For example, for `T` in `struct Foo<'a, T>`, this would be `'static`.
     /// For `T` in `struct Foo<'a, T: 'a>`, this would instead be `'a`.
     /// This query will panic if passed something that is not a type parameter.
-    query object_lifetime_default(key: DefId) -> ObjectLifetimeDefault {
-        desc { "looking up lifetime defaults for generic parameter `{}`", tcx.def_path_str(key) }
+    query object_lifetime_default(def_id: DefId) -> ObjectLifetimeDefault {
+        desc { "looking up lifetime defaults for generic parameter `{}`", tcx.def_path_str(def_id) }
         separate_provide_extern
     }
-    query late_bound_vars_map(_: hir::OwnerId)
-        -> Option<&'tcx FxIndexMap<ItemLocalId, Vec<ty::BoundVariableKind>>> {
-        desc { "looking up late bound vars" }
+    query late_bound_vars_map(owner_id: hir::OwnerId)
+        -> &'tcx SortedMap<ItemLocalId, Vec<ty::BoundVariableKind>> {
+        desc { |tcx| "looking up late bound vars inside `{}`", tcx.def_path_str(owner_id) }
     }
 
     /// Computes the visibility of the provided `def_id`.
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 2ffb273cb6f..27c1b88f93f 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -56,7 +56,7 @@ use rustc_type_ir::lang_items::TraitSolverLangItem;
 pub use rustc_type_ir::lift::Lift;
 use rustc_type_ir::solve::SolverMode;
 use rustc_type_ir::{CollectAndApply, Interner, TypeFlags, WithCachedTypeInfo, search_graph};
-use tracing::{debug, instrument};
+use tracing::{debug, trace};
 
 use crate::arena::Arena;
 use crate::dep_graph::{DepGraph, DepKindStruct};
@@ -2073,9 +2073,11 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     /// Returns the origin of the opaque type `def_id`.
-    #[instrument(skip(self), level = "trace", ret)]
+    #[track_caller]
     pub fn opaque_type_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin {
-        self.hir().expect_item(def_id).expect_opaque_ty().origin
+        let origin = self.hir().expect_opaque_ty(def_id).origin;
+        trace!("opaque_type_origin({def_id:?}) => {origin:?}");
+        origin
     }
 }
 
@@ -2994,7 +2996,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
     pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
         debug!(?id, "named_region");
-        self.named_variable_map(id.owner).and_then(|map| map.get(&id.local_id).cloned())
+        self.named_variable_map(id.owner).get(&id.local_id).cloned()
     }
 
     pub fn is_late_bound(self, id: HirId) -> bool {
@@ -3003,12 +3005,9 @@ impl<'tcx> TyCtxt<'tcx> {
 
     pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
         self.mk_bound_variable_kinds(
-            &self
-                .late_bound_vars_map(id.owner)
-                .and_then(|map| map.get(&id.local_id).cloned())
-                .unwrap_or_else(|| {
-                    bug!("No bound vars found for {}", self.hir().node_to_string(id))
-                }),
+            &self.late_bound_vars_map(id.owner).get(&id.local_id).cloned().unwrap_or_else(|| {
+                bug!("No bound vars found for {}", self.hir().node_to_string(id))
+            }),
         )
     }
 
@@ -3031,8 +3030,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
         loop {
             let parent = self.local_parent(opaque_lifetime_param_def_id);
-            let hir::OpaqueTy { lifetime_mapping, .. } =
-                self.hir_node_by_def_id(parent).expect_item().expect_opaque_ty();
+            let hir::OpaqueTy { lifetime_mapping, .. } = self.hir().expect_opaque_ty(parent);
 
             let Some((lifetime, _)) = lifetime_mapping
                 .iter()
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index d98e18c1b0c..751f0c71eb4 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -507,14 +507,8 @@ impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> {
                     ..
                 },
                 _,
-            ) => {
-                self.0.push(ty);
-            }
-            hir::TyKind::OpaqueDef(item_id, _) => {
-                self.0.push(ty);
-                let item = self.1.item(item_id);
-                hir::intravisit::walk_item(self, item);
-            }
+            )
+            | hir::TyKind::OpaqueDef(..) => self.0.push(ty),
             _ => {}
         }
         hir::intravisit::walk_ty(self, ty);
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 31d591a9695..3f00458d195 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -21,6 +21,7 @@ use rustc_target::spec::abi;
 use rustc_type_ir::TyKind::*;
 use rustc_type_ir::visit::TypeVisitableExt;
 use rustc_type_ir::{self as ir, BoundVar, CollectAndApply, DynKind};
+use tracing::instrument;
 use ty::util::{AsyncDropGlueMorphology, IntTypeExt};
 
 use super::GenericParamDefKind;
@@ -500,6 +501,7 @@ impl<'tcx> Ty<'tcx> {
     }
 
     #[inline]
+    #[instrument(level = "debug", skip(tcx))]
     pub fn new_opaque(tcx: TyCtxt<'tcx>, def_id: DefId, args: GenericArgsRef<'tcx>) -> Ty<'tcx> {
         Ty::new_alias(tcx, ty::Opaque, AliasTy::new_from_args(tcx, def_id, args))
     }
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index a24259a1e35..b3334bb70aa 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -814,7 +814,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             | Target::Mod
             | Target::GlobalAsm
             | Target::TyAlias
-            | Target::OpaqueTy
             | Target::Enum
             | Target::Variant
             | Target::Struct
@@ -1328,7 +1327,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         ) {
             let article = match target {
                 Target::ExternCrate
-                | Target::OpaqueTy
                 | Target::Enum
                 | Target::Impl
                 | Target::Expression
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index 100f3e80603..af17fbf7e4d 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -41,6 +41,7 @@ fn should_explore(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
             | Node::TraitItem(..)
             | Node::Variant(..)
             | Node::AnonConst(..)
+            | Node::OpaqueTy(..)
     )
 }
 
@@ -494,6 +495,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
             Node::ForeignItem(foreign_item) => {
                 intravisit::walk_foreign_item(self, foreign_item);
             }
+            Node::OpaqueTy(opaq) => intravisit::walk_opaque_ty(self, opaq),
             _ => {}
         }
         self.repr_has_repr_simd = had_repr_simd;
@@ -655,14 +657,6 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
         intravisit::walk_path(self, path);
     }
 
-    fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
-        if let TyKind::OpaqueDef(item_id, _) = ty.kind {
-            let item = self.tcx.hir().item(item_id);
-            intravisit::walk_item(self, item);
-        }
-        intravisit::walk_ty(self, ty);
-    }
-
     fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) {
         // When inline const blocks are used in pattern position, paths
         // referenced by it should be considered as used.
diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs
index 903fb114744..8ad14b6eb74 100644
--- a/compiler/rustc_passes/src/hir_stats.rs
+++ b/compiler/rustc_passes/src/hir_stats.rs
@@ -230,7 +230,6 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
             ForeignMod,
             GlobalAsm,
             TyAlias,
-            OpaqueTy,
             Enum,
             Struct,
             Union,
diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs
index 925ee262022..056318fbcb7 100644
--- a/compiler/rustc_passes/src/reachable.rs
+++ b/compiler/rustc_passes/src/reachable.rs
@@ -236,7 +236,6 @@ impl<'tcx> ReachableContext<'tcx> {
                     // worklist, as determined by the privacy pass
                     hir::ItemKind::ExternCrate(_)
                     | hir::ItemKind::Use(..)
-                    | hir::ItemKind::OpaqueTy(..)
                     | hir::ItemKind::TyAlias(..)
                     | hir::ItemKind::Macro(..)
                     | hir::ItemKind::Mod(..)
@@ -287,7 +286,8 @@ impl<'tcx> ReachableContext<'tcx> {
             | Node::Field(_)
             | Node::Ty(_)
             | Node::Crate(_)
-            | Node::Synthetic => {}
+            | Node::Synthetic
+            | Node::OpaqueTy(..) => {}
             _ => {
                 bug!(
                     "found unexpected node kind in worklist: {} ({:?})",
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index d00e7eff752..f67c4cb922c 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -402,8 +402,6 @@ struct EmbargoVisitor<'tcx> {
     ///     n::p::f()
     /// }
     macro_reachable: FxHashSet<(LocalModDefId, LocalModDefId)>,
-    /// Preliminary pass for marking all underlying types of `impl Trait`s as reachable.
-    impl_trait_pass: bool,
     /// Has something changed in the level map?
     changed: bool,
 }
@@ -635,48 +633,6 @@ impl<'tcx> EmbargoVisitor<'tcx> {
 
 impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
-        if self.impl_trait_pass
-            && let hir::ItemKind::OpaqueTy(opaque) = item.kind
-        {
-            let should_visit = match opaque.origin {
-                hir::OpaqueTyOrigin::FnReturn {
-                    parent,
-                    in_trait_or_impl: Some(hir::RpitContext::Trait),
-                }
-                | hir::OpaqueTyOrigin::AsyncFn {
-                    parent,
-                    in_trait_or_impl: Some(hir::RpitContext::Trait),
-                } => match self.tcx.hir_node_by_def_id(parent).expect_trait_item().expect_fn().1 {
-                    hir::TraitFn::Required(_) => false,
-                    hir::TraitFn::Provided(..) => true,
-                },
-
-                // Always visit RPITs in functions that have definitions,
-                // and all TAITs.
-                hir::OpaqueTyOrigin::FnReturn {
-                    in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
-                    ..
-                }
-                | hir::OpaqueTyOrigin::AsyncFn {
-                    in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
-                    ..
-                }
-                | hir::OpaqueTyOrigin::TyAlias { .. } => true,
-            };
-
-            if should_visit {
-                // FIXME: This is some serious pessimization intended to workaround deficiencies
-                // in the reachability pass (`middle/reachable.rs`). Types are marked as link-time
-                // reachable if they are returned via `impl Trait`, even from private functions.
-                let pub_ev = EffectiveVisibility::from_vis(ty::Visibility::Public);
-                self.reach_through_impl_trait(item.owner_id.def_id, pub_ev)
-                    .generics()
-                    .predicates()
-                    .ty();
-                return;
-            }
-        }
-
         // Update levels of nested things and mark all items
         // in interfaces of reachable items as reachable.
         let item_ev = self.get(item.owner_id.def_id);
@@ -686,7 +642,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
             | hir::ItemKind::ExternCrate(..)
             | hir::ItemKind::GlobalAsm(..) => {}
             // The interface is empty, and all nested items are processed by `visit_item`.
-            hir::ItemKind::Mod(..) | hir::ItemKind::OpaqueTy(..) => {}
+            hir::ItemKind::Mod(..) => {}
             hir::ItemKind::Macro(macro_def, _) => {
                 if let Some(item_ev) = item_ev {
                     self.update_reachability_from_macro(item.owner_id.def_id, macro_def, item_ev);
@@ -1752,19 +1708,59 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities {
         tcx,
         effective_visibilities: tcx.resolutions(()).effective_visibilities.clone(),
         macro_reachable: Default::default(),
-        // HACK(jynelson): trying to infer the type of `impl Trait` breaks `async-std` (and
-        // `pub async fn` in general). Since rustdoc never needs to do codegen and doesn't
-        // care about link-time reachability, keep them unreachable (issue #75100).
-        impl_trait_pass: !tcx.sess.opts.actually_rustdoc,
         changed: false,
     };
 
     visitor.effective_visibilities.check_invariants(tcx);
-    if visitor.impl_trait_pass {
+
+    // HACK(jynelson): trying to infer the type of `impl Trait` breaks `async-std` (and
+    // `pub async fn` in general). Since rustdoc never needs to do codegen and doesn't
+    // care about link-time reachability, keep them unreachable (issue #75100).
+    let impl_trait_pass = !tcx.sess.opts.actually_rustdoc;
+    if impl_trait_pass {
         // Underlying types of `impl Trait`s are marked as reachable unconditionally,
         // so this pass doesn't need to be a part of the fixed point iteration below.
-        tcx.hir().visit_all_item_likes_in_crate(&mut visitor);
-        visitor.impl_trait_pass = false;
+        let krate = tcx.hir_crate_items(());
+        for id in krate.opaques() {
+            let opaque = tcx.hir_node_by_def_id(id).expect_opaque_ty();
+            let should_visit = match opaque.origin {
+                hir::OpaqueTyOrigin::FnReturn {
+                    parent,
+                    in_trait_or_impl: Some(hir::RpitContext::Trait),
+                }
+                | hir::OpaqueTyOrigin::AsyncFn {
+                    parent,
+                    in_trait_or_impl: Some(hir::RpitContext::Trait),
+                } => match tcx.hir_node_by_def_id(parent).expect_trait_item().expect_fn().1 {
+                    hir::TraitFn::Required(_) => false,
+                    hir::TraitFn::Provided(..) => true,
+                },
+
+                // Always visit RPITs in functions that have definitions,
+                // and all TAITs.
+                hir::OpaqueTyOrigin::FnReturn {
+                    in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
+                    ..
+                }
+                | hir::OpaqueTyOrigin::AsyncFn {
+                    in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
+                    ..
+                }
+                | hir::OpaqueTyOrigin::TyAlias { .. } => true,
+            };
+            if should_visit {
+                // FIXME: This is some serious pessimization intended to workaround deficiencies
+                // in the reachability pass (`middle/reachable.rs`). Types are marked as link-time
+                // reachable if they are returned via `impl Trait`, even from private functions.
+                let pub_ev = EffectiveVisibility::from_vis(ty::Visibility::Public);
+                visitor
+                    .reach_through_impl_trait(opaque.def_id, pub_ev)
+                    .generics()
+                    .predicates()
+                    .ty();
+            }
+        }
+
         visitor.changed = false;
     }
 
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs
index 31256bca55e..a6ecd1cc987 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs
@@ -284,14 +284,9 @@ pub fn suggest_new_region_bound(
         }
         match fn_return.kind {
             // FIXME(precise_captures): Suggest adding to `use<...>` list instead.
-            TyKind::OpaqueDef(item_id, _) => {
-                let item = tcx.hir().item(item_id);
-                let ItemKind::OpaqueTy(opaque) = &item.kind else {
-                    return;
-                };
-
+            TyKind::OpaqueDef(opaque, _) => {
                 // Get the identity type for this RPIT
-                let did = item_id.owner_id.to_def_id();
+                let did = opaque.def_id.to_def_id();
                 let ty = Ty::new_opaque(tcx, did, ty::GenericArgs::identity_for_item(tcx, did));
 
                 if let Some(span) = opaque.bounds.iter().find_map(|arg| match arg {
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
index 7802d5bf7a6..cf0ab630f2e 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
@@ -720,7 +720,7 @@ fn foo(&self) -> Self::T { String::new() }
         if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *proj_ty.self_ty().kind() {
             let opaque_local_def_id = def_id.as_local();
             let opaque_hir_ty = if let Some(opaque_local_def_id) = opaque_local_def_id {
-                tcx.hir().expect_item(opaque_local_def_id).expect_opaque_ty()
+                tcx.hir().expect_opaque_ty(opaque_local_def_id)
             } else {
                 return false;
             };
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
index a2d717817db..94610a9e0e6 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
@@ -842,14 +842,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         lifetime: Region<'tcx>,
         add_lt_suggs: &mut Vec<(Span, String)>,
     ) -> String {
-        struct LifetimeReplaceVisitor<'a, 'tcx> {
-            tcx: TyCtxt<'tcx>,
+        struct LifetimeReplaceVisitor<'a> {
             needle: hir::LifetimeName,
             new_lt: &'a str,
             add_lt_suggs: &'a mut Vec<(Span, String)>,
         }
 
-        impl<'hir, 'tcx> hir::intravisit::Visitor<'hir> for LifetimeReplaceVisitor<'_, 'tcx> {
+        impl<'hir> hir::intravisit::Visitor<'hir> for LifetimeReplaceVisitor<'_> {
             fn visit_lifetime(&mut self, lt: &'hir hir::Lifetime) {
                 if lt.res == self.needle {
                     self.add_lt_suggs.push(lt.suggestion(self.new_lt));
@@ -857,10 +856,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             }
 
             fn visit_ty(&mut self, ty: &'hir hir::Ty<'hir>) {
-                let hir::TyKind::OpaqueDef(item_id, _) = ty.kind else {
+                let hir::TyKind::OpaqueDef(opaque_ty, _) = ty.kind else {
                     return hir::intravisit::walk_ty(self, ty);
                 };
-                let opaque_ty = self.tcx.hir().item(item_id).expect_opaque_ty();
                 if let Some(&(_, b)) =
                     opaque_ty.lifetime_mapping.iter().find(|&(a, _)| a.res == self.needle)
                 {
@@ -905,7 +903,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         };
 
         let mut visitor = LifetimeReplaceVisitor {
-            tcx: self.tcx,
             needle: hir::LifetimeName::Param(lifetime_def_id),
             add_lt_suggs,
             new_lt: &new_lt,
@@ -1269,7 +1266,7 @@ fn suggest_precise_capturing<'tcx>(
     diag: &mut Diag<'_>,
 ) {
     let hir::OpaqueTy { bounds, origin, .. } =
-        tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty();
+        tcx.hir_node_by_def_id(opaque_def_id).expect_opaque_ty();
 
     let hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. } = *origin else {
         return;
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs
index 6c3f3afce11..709b6eb18e3 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs
@@ -731,12 +731,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 let exp_local_id = exp_def_id.as_local()?;
 
                 match (
-                    &self.tcx.hir().expect_item(last_local_id).kind,
-                    &self.tcx.hir().expect_item(exp_local_id).kind,
+                    &self.tcx.hir().expect_opaque_ty(last_local_id),
+                    &self.tcx.hir().expect_opaque_ty(exp_local_id),
                 ) {
                     (
-                        hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: last_bounds, .. }),
-                        hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: exp_bounds, .. }),
+                        hir::OpaqueTy { bounds: last_bounds, .. },
+                        hir::OpaqueTy { bounds: exp_bounds, .. },
                     ) if std::iter::zip(*last_bounds, *exp_bounds).all(|(left, right)| match (
                         left, right,
                     ) {
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index 6df7fac949c..87834c329e1 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -355,12 +355,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         | hir::ItemKind::Fn(_, generics, _)
                         | hir::ItemKind::TyAlias(_, generics)
                         | hir::ItemKind::Const(_, generics, _)
-                        | hir::ItemKind::TraitAlias(generics, _)
-                        | hir::ItemKind::OpaqueTy(hir::OpaqueTy { generics, .. }),
+                        | hir::ItemKind::TraitAlias(generics, _),
                     ..
                 })
                 | hir::Node::TraitItem(hir::TraitItem { generics, .. })
                 | hir::Node::ImplItem(hir::ImplItem { generics, .. })
+                | hir::Node::OpaqueTy(hir::OpaqueTy { generics, .. })
                     if param_ty =>
                 {
                     // We skip the 0'th arg (self) because we do not want
@@ -421,10 +421,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         | hir::ItemKind::Fn(_, generics, _)
                         | hir::ItemKind::TyAlias(_, generics)
                         | hir::ItemKind::Const(_, generics, _)
-                        | hir::ItemKind::TraitAlias(generics, _)
-                        | hir::ItemKind::OpaqueTy(hir::OpaqueTy { generics, .. }),
+                        | hir::ItemKind::TraitAlias(generics, _),
                     ..
-                }) if !param_ty => {
+                })
+                | hir::Node::OpaqueTy(hir::OpaqueTy { generics, .. })
+                    if !param_ty =>
+                {
                     // Missing generic type parameter bound.
                     if suggest_arbitrary_trait_bound(
                         self.tcx,
@@ -4542,7 +4544,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
         // ... whose signature is `async` (i.e. this is an AFIT)
         let (sig, body) = item.expect_fn();
-        let hir::FnRetTy::Return(hir::Ty { kind: hir::TyKind::OpaqueDef(def, ..), .. }) =
+        let hir::FnRetTy::Return(hir::Ty { kind: hir::TyKind::OpaqueDef(opaq_def, ..), .. }) =
             sig.decl.output
         else {
             // This should never happen, but let's not ICE.
@@ -4551,7 +4553,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
         // Check that this is *not* a nested `impl Future` RPIT in an async fn
         // (i.e. `async fn foo() -> impl Future`)
-        if def.owner_id.to_def_id() != opaque_def_id {
+        if opaq_def.def_id.to_def_id() != opaque_def_id {
             return;
         }
 
@@ -5159,7 +5161,7 @@ pub fn suggest_desugaring_async_fn_to_impl_future_in_trait<'tcx>(
     };
     let async_span = tcx.sess.source_map().span_extend_while_whitespace(async_span);
 
-    let future = tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty();
+    let future = tcx.hir_node_by_def_id(opaque_def_id).expect_opaque_ty();
     let [hir::GenericBound::Trait(trait_ref, _)] = future.bounds else {
         // `async fn` should always lower to a single bound... but don't ICE.
         return None;
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs
index e41f2c8ce48..a057caa9329 100644
--- a/compiler/rustc_ty_utils/src/assoc.rs
+++ b/compiler/rustc_ty_utils/src/assoc.rs
@@ -316,19 +316,16 @@ fn associated_types_for_impl_traits_in_associated_fn(
 
     match tcx.def_kind(parent_def_id) {
         DefKind::Trait => {
-            struct RPITVisitor<'tcx> {
+            struct RPITVisitor {
                 rpits: FxIndexSet<LocalDefId>,
-                tcx: TyCtxt<'tcx>,
             }
 
-            impl<'tcx> Visitor<'tcx> for RPITVisitor<'tcx> {
+            impl<'tcx> Visitor<'tcx> for RPITVisitor {
                 fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
-                    if let hir::TyKind::OpaqueDef(item_id, _) = ty.kind
-                        && self.rpits.insert(item_id.owner_id.def_id)
+                    if let hir::TyKind::OpaqueDef(opaq, _) = ty.kind
+                        && self.rpits.insert(opaq.def_id)
                     {
-                        let opaque_item =
-                            self.tcx.hir().expect_item(item_id.owner_id.def_id).expect_opaque_ty();
-                        for bound in opaque_item.bounds {
+                        for bound in opaq.bounds {
                             intravisit::walk_param_bound(self, bound);
                         }
                     }
@@ -336,7 +333,7 @@ fn associated_types_for_impl_traits_in_associated_fn(
                 }
             }
 
-            let mut visitor = RPITVisitor { tcx, rpits: FxIndexSet::default() };
+            let mut visitor = RPITVisitor { rpits: FxIndexSet::default() };
 
             if let Some(output) = tcx.hir().get_fn_output(fn_def_id) {
                 visitor.visit_fn_ret_ty(output);
diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs
index 7c4b4887b2d..5e2232ff47d 100644
--- a/compiler/rustc_ty_utils/src/opaque_types.rs
+++ b/compiler/rustc_ty_utils/src/opaque_types.rs
@@ -132,6 +132,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
         TaitInBodyFinder { collector: self }.visit_expr(body);
     }
 
+    #[instrument(level = "debug", skip(self))]
     fn visit_opaque_ty(&mut self, alias_ty: ty::AliasTy<'tcx>) {
         if !self.seen.insert(alias_ty.def_id.expect_local()) {
             return;
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index b79458eaa78..fa73733360c 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1828,13 +1828,8 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
             Array(Box::new(clean_ty(ty, cx)), length.into())
         }
         TyKind::Tup(tys) => Tuple(tys.iter().map(|ty| clean_ty(ty, cx)).collect()),
-        TyKind::OpaqueDef(item_id, _) => {
-            let item = cx.tcx.hir().item(item_id);
-            if let hir::ItemKind::OpaqueTy(ty) = item.kind {
-                ImplTrait(ty.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect())
-            } else {
-                unreachable!()
-            }
+        TyKind::OpaqueDef(ty, _) => {
+            ImplTrait(ty.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect())
         }
         TyKind::Path(_) => clean_qpath(ty, cx),
         TyKind::TraitObject(bounds, lifetime, _) => {
@@ -2736,9 +2731,6 @@ fn clean_maybe_renamed_item<'tcx>(
                 type_: clean_ty(ty, cx),
                 kind: ConstantKind::Local { body: body_id, def_id },
             })),
-            // clean_ty changes types which reference an OpaqueTy item to instead be
-            // an ImplTrait, so it's ok to return nothing here.
-            ItemKind::OpaqueTy(_) => return vec![],
             ItemKind::TyAlias(hir_ty, generics) => {
                 *cx.current_type_aliases.entry(def_id).or_insert(0) += 1;
                 let rustdoc_ty = clean_ty(hir_ty, cx);
diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs
index 2143f1ff236..7e1ea5cde83 100644
--- a/src/librustdoc/html/render/span_map.rs
+++ b/src/librustdoc/html/render/span_map.rs
@@ -243,7 +243,6 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
             | ItemKind::ExternCrate(_)
             | ItemKind::ForeignMod { .. }
             | ItemKind::GlobalAsm(_)
-            | ItemKind::OpaqueTy(_)
             // We already have "visit_mod" above so no need to check it here.
             | ItemKind::Mod(_) => {}
         }
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 6defe91d383..f789aca7378 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -505,21 +505,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             | hir::ItemKind::Struct(..)
             | hir::ItemKind::Union(..)
             | hir::ItemKind::TyAlias(..)
-            | hir::ItemKind::OpaqueTy(hir::OpaqueTy {
-                origin: hir::OpaqueTyOrigin::TyAlias { .. },
-                ..
-            })
             | hir::ItemKind::Static(..)
             | hir::ItemKind::Trait(..)
             | hir::ItemKind::TraitAlias(..) => {
                 self.add_to_current_mod(item, renamed, import_id);
             }
-            hir::ItemKind::OpaqueTy(hir::OpaqueTy {
-                origin: hir::OpaqueTyOrigin::AsyncFn { .. } | hir::OpaqueTyOrigin::FnReturn { .. },
-                ..
-            }) => {
-                // return-position impl traits are never nameable, and should never be documented.
-            }
             hir::ItemKind::Const(..) => {
                 // Underscore constants do not correspond to a nameable item and
                 // so are never useful in documentation.
diff --git a/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs b/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs
index 796af851bac..6ad879b9fe7 100644
--- a/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs
+++ b/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs
@@ -6,7 +6,7 @@ use rustc_errors::Applicability;
 use rustc_hir::intravisit::{Visitor, walk_impl_item, walk_item, walk_param_bound, walk_ty};
 use rustc_hir::{
     BodyId, ExprKind, GenericBound, GenericParam, GenericParamKind, Generics, ImplItem, ImplItemKind, Item, ItemKind,
-    PredicateOrigin, Ty, TyKind, WherePredicate,
+    PredicateOrigin, Ty, WherePredicate,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::hir::nested_filter;
@@ -199,12 +199,6 @@ impl<'tcx> Visitor<'tcx> for TypeWalker<'_, 'tcx> {
     fn visit_ty(&mut self, t: &'tcx Ty<'tcx>) {
         if let Some((def_id, _)) = t.peel_refs().as_generic_param() {
             self.ty_params.remove(&def_id);
-        } else if let TyKind::OpaqueDef(id, _) = t.kind {
-            // Explicitly walk OpaqueDef. Normally `walk_ty` would do the job, but it calls
-            // `visit_nested_item`, which checks that `Self::NestedFilter::INTER` is set. We're
-            // using `OnlyBodies`, so the check ends up failing and the type isn't fully walked.
-            let item = self.nested_visit_map().item(id);
-            walk_item(self, item);
         } else {
             walk_ty(self, t);
         }
diff --git a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
index 6794c6cabfe..5f349d78053 100644
--- a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
@@ -3,7 +3,7 @@ use clippy_utils::source::snippet;
 use rustc_errors::{Applicability, SuggestionStyle};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{
-    AssocItemConstraint, GenericArg, GenericBound, GenericBounds, ItemKind, PredicateOrigin, TraitBoundModifier,
+    AssocItemConstraint, GenericArg, GenericBound, GenericBounds, PredicateOrigin, TraitBoundModifier,
     TyKind, WherePredicate,
 };
 use rustc_hir_analysis::lower_ty;
@@ -342,11 +342,8 @@ impl<'tcx> LateLintPass<'tcx> for ImpliedBoundsInImpls {
         }
     }
 
-    fn check_ty(&mut self, cx: &LateContext<'_>, ty: &rustc_hir::Ty<'_>) {
-        if let TyKind::OpaqueDef(item_id, ..) = ty.kind
-            && let item = cx.tcx.hir().item(item_id)
-            && let ItemKind::OpaqueTy(opaque_ty) = item.kind
-        {
+    fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &rustc_hir::Ty<'tcx>) {
+        if let TyKind::OpaqueDef(opaque_ty, ..) = ty.kind {
             check(cx, opaque_ty.bounds);
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index 45346cd18a6..311bbce14bd 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -308,11 +308,7 @@ enum LenOutput {
 
 fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&'tcx PathSegment<'tcx>> {
     if let ty::Alias(_, alias_ty) = ty.kind()
-        && let Some(Node::Item(item)) = cx.tcx.hir().get_if_local(alias_ty.def_id)
-        && let Item {
-            kind: ItemKind::OpaqueTy(opaque),
-            ..
-        } = item
+        && let Some(Node::OpaqueTy(opaque)) = cx.tcx.hir().get_if_local(alias_ty.def_id)
         && let OpaqueTyOrigin::AsyncFn { .. } = opaque.origin
         && let [GenericBound::Trait(trait_ref, _)] = &opaque.bounds
         && let Some(segment) = trait_ref.trait_ref.path.segments.last()
diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs
index 5c37e735445..7c3ef98fd74 100644
--- a/src/tools/clippy/clippy_lints/src/lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs
@@ -6,7 +6,7 @@ use rustc_errors::Applicability;
 use rustc_hir::FnRetTy::Return;
 use rustc_hir::intravisit::nested_filter::{self as hir_nested_filter, NestedFilter};
 use rustc_hir::intravisit::{
-    Visitor, walk_fn_decl, walk_generic_args, walk_generics, walk_impl_item_ref, walk_item, walk_param_bound,
+    Visitor, walk_fn_decl, walk_generic_args, walk_generics, walk_impl_item_ref, walk_param_bound,
     walk_poly_trait_ref, walk_trait_ref, walk_ty, walk_where_predicate,
 };
 use rustc_hir::{
@@ -420,11 +420,9 @@ impl<'tcx> Visitor<'tcx> for RefVisitor<'_, 'tcx> {
 
     fn visit_ty(&mut self, ty: &'tcx Ty<'_>) {
         match ty.kind {
-            TyKind::OpaqueDef(item, bounds) => {
-                let map = self.cx.tcx.hir();
-                let item = map.item(item);
+            TyKind::OpaqueDef(opaque, bounds) => {
                 let len = self.lts.len();
-                walk_item(self, item);
+                self.visit_opaque_ty(opaque);
                 self.lts.truncate(len);
                 self.lts.extend(bounds.iter().filter_map(|bound| match bound {
                     GenericArg::Lifetime(&l) => Some(l),
diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
index 7097c85156c..81115cffdca 100644
--- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
@@ -4,7 +4,7 @@ use rustc_errors::Applicability;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{
     Block, Body, Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, FnDecl,
-    FnRetTy, GenericArg, GenericBound, ImplItem, Item, ItemKind, LifetimeName, Node, TraitRef, Ty, TyKind,
+    FnRetTy, GenericArg, GenericBound, ImplItem, Item, LifetimeName, Node, TraitRef, Ty, TyKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
@@ -105,9 +105,7 @@ fn future_trait_ref<'tcx>(
     cx: &LateContext<'tcx>,
     ty: &'tcx Ty<'tcx>,
 ) -> Option<(&'tcx TraitRef<'tcx>, Vec<LifetimeName>)> {
-    if let TyKind::OpaqueDef(item_id, bounds) = ty.kind
-        && let item = cx.tcx.hir().item(item_id)
-        && let ItemKind::OpaqueTy(opaque) = &item.kind
+    if let TyKind::OpaqueDef(opaque, bounds) = ty.kind
         && let Some(trait_ref) = opaque.bounds.iter().find_map(|bound| {
             if let GenericBound::Trait(poly, _) = bound {
                 Some(&poly.trait_ref)
diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs
index 64fc1a8a1a5..007bcebdff6 100644
--- a/src/tools/clippy/clippy_lints/src/missing_doc.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs
@@ -193,8 +193,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
             | hir::ItemKind::Trait(..)
             | hir::ItemKind::TraitAlias(..)
             | hir::ItemKind::TyAlias(..)
-            | hir::ItemKind::Union(..)
-            | hir::ItemKind::OpaqueTy(..) => {},
+            | hir::ItemKind::Union(..) => {}
             hir::ItemKind::ExternCrate(..)
             | hir::ItemKind::ForeignMod { .. }
             | hir::ItemKind::GlobalAsm(..)
diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs
index d342be4545c..f95a0f63fab 100644
--- a/src/tools/clippy/clippy_lints/src/missing_inline.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs
@@ -130,7 +130,6 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
             | hir::ItemKind::GlobalAsm(..)
             | hir::ItemKind::TyAlias(..)
             | hir::ItemKind::Union(..)
-            | hir::ItemKind::OpaqueTy(..)
             | hir::ItemKind::ExternCrate(..)
             | hir::ItemKind::ForeignMod { .. }
             | hir::ItemKind::Impl { .. }
diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs
index 08449de79b3..f5cf4a586fd 100644
--- a/src/tools/clippy/clippy_lints/src/use_self.rs
+++ b/src/tools/clippy/clippy_lints/src/use_self.rs
@@ -85,10 +85,6 @@ const SEGMENTS_MSG: &str = "segments should be composed of at least 1 element";
 
 impl<'tcx> LateLintPass<'tcx> for UseSelf {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &Item<'tcx>) {
-        if matches!(item.kind, ItemKind::OpaqueTy(_)) {
-            // skip over `ItemKind::OpaqueTy` in order to lint `foo() -> impl <..>`
-            return;
-        }
         // We push the self types of `impl`s on a stack here. Only the top type on the stack is
         // relevant for linting, since this is the self type of the `impl` we're currently in. To
         // avoid linting on nested items, we push `StackItem::NoCheck` on the stack to signal, that
@@ -130,10 +126,8 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
         self.stack.push(stack_item);
     }
 
-    fn check_item_post(&mut self, _: &LateContext<'_>, item: &Item<'_>) {
-        if !matches!(item.kind, ItemKind::OpaqueTy(_)) {
-            self.stack.pop();
-        }
+    fn check_item_post(&mut self, _: &LateContext<'_>, _: &Item<'_>) {
+        self.stack.pop();
     }
 
     fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) {
diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
index 9143d292f67..b18997e6ee4 100644
--- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
+++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
@@ -220,7 +220,7 @@ fn item_search_pat(item: &Item<'_>) -> (Pat, Pat) {
         ItemKind::Const(..) => (Pat::Str("const"), Pat::Str(";")),
         ItemKind::Fn(sig, ..) => (fn_header_search_pat(sig.header), Pat::Str("")),
         ItemKind::ForeignMod { .. } => (Pat::Str("extern"), Pat::Str("}")),
-        ItemKind::TyAlias(..) | ItemKind::OpaqueTy(_) => (Pat::Str("type"), Pat::Str(";")),
+        ItemKind::TyAlias(..) => (Pat::Str("type"), Pat::Str(";")),
         ItemKind::Enum(..) => (Pat::Str("enum"), Pat::Str("}")),
         ItemKind::Struct(VariantData::Struct { .. }, _) => (Pat::Str("struct"), Pat::Str("}")),
         ItemKind::Struct(..) => (Pat::Str("struct"), Pat::Str(";")),
diff --git a/tests/crashes/119716-2.rs b/tests/crashes/119716-2.rs
deleted file mode 100644
index 47bffb5c1de..00000000000
--- a/tests/crashes/119716-2.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-//@ known-bug: #119716
-#![feature(non_lifetime_binders)]
-trait Trait<T> {}
-fn f() -> impl for<T> Trait<impl Trait<T>> {}
diff --git a/tests/crashes/119716.rs b/tests/crashes/119716.rs
deleted file mode 100644
index d7cba0f51c4..00000000000
--- a/tests/crashes/119716.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-//@ known-bug: #119716
-#![feature(non_lifetime_binders)]
-trait v0<v1> {}
-fn kind  :(v3main impl for<v4> v0<'_, v2 = impl v0<v4> + '_>) {}
diff --git a/tests/crashes/121422.rs b/tests/crashes/121422.rs
deleted file mode 100644
index 5d7ef6e8ce9..00000000000
--- a/tests/crashes/121422.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-//@ known-bug: #121422
-#![feature(non_lifetime_binders)]
-
-trait Trait<T: ?Sized> {}
-
-fn produce() -> impl for<T> Trait<(), Assoc = impl Trait<T>> {
-    16
-}
diff --git a/tests/crashes/125843.rs b/tests/crashes/125843.rs
deleted file mode 100644
index 8b9a3913c7e..00000000000
--- a/tests/crashes/125843.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-//@ known-bug: rust-lang/rust#125843
-#![feature(non_lifetime_binders)]
-trait v0<> {}
-fn kind  :(v3main impl for<v4> v0<'_, v2 = impl v0<v4> + '_>) {}
diff --git a/tests/crashes/129099.rs b/tests/crashes/129099.rs
deleted file mode 100644
index 9aaab756b5b..00000000000
--- a/tests/crashes/129099.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-//@ known-bug: rust-lang/rust#129099
-
-#![feature(type_alias_impl_trait)]
-
-fn dyn_hoops<T: Sized>() -> dyn for<'a> Iterator<Item = impl Captures<'a>> {
-    loop {}
-}
-
-pub fn main() {
-    type Opaque = impl Sized;
-    fn define() -> Opaque {
-        let x: Opaque = dyn_hoops::<()>(0);
-        x
-    }
-}
diff --git a/tests/incremental/hashes/function_interfaces.rs b/tests/incremental/hashes/function_interfaces.rs
index ab4d578458d..016a1813bab 100644
--- a/tests/incremental/hashes/function_interfaces.rs
+++ b/tests/incremental/hashes/function_interfaces.rs
@@ -318,9 +318,9 @@ pub fn change_return_impl_trait() -> impl Clone {
 }
 
 #[cfg(not(any(cfail1,cfail4)))]
-#[rustc_clean(cfg = "cfail2")]
+#[rustc_clean(cfg = "cfail2", except = "opt_hir_owner_nodes")]
 #[rustc_clean(cfg = "cfail3")]
-#[rustc_clean(cfg = "cfail5", except = "typeck")]
+#[rustc_clean(cfg = "cfail5", except = "opt_hir_owner_nodes, typeck")]
 #[rustc_clean(cfg = "cfail6")]
 pub fn change_return_impl_trait() -> impl  Copy {
     0u32
diff --git a/tests/ui/associated-type-bounds/duplicate.stderr b/tests/ui/associated-type-bounds/duplicate.stderr
index cf4809991c3..0dabcbdce1b 100644
--- a/tests/ui/associated-type-bounds/duplicate.stderr
+++ b/tests/ui/associated-type-bounds/duplicate.stderr
@@ -208,17 +208,6 @@ LL | fn FRPIT1() -> impl Iterator<Item: Copy, Item: Send> {
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error[E0282]: type annotations needed
-  --> $DIR/duplicate.rs:136:5
-   |
-LL |     iter::empty()
-   |     ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
-   |
-help: consider specifying the generic argument
-   |
-LL |     iter::empty::<T>()
-   |                +++++
-
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
   --> $DIR/duplicate.rs:139:42
    |
@@ -237,17 +226,6 @@ LL | fn FRPIT2() -> impl Iterator<Item: Copy, Item: Copy> {
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error[E0282]: type annotations needed
-  --> $DIR/duplicate.rs:142:5
-   |
-LL |     iter::empty()
-   |     ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
-   |
-help: consider specifying the generic argument
-   |
-LL |     iter::empty::<T>()
-   |                +++++
-
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
   --> $DIR/duplicate.rs:145:45
    |
@@ -266,17 +244,6 @@ LL | fn FRPIT3() -> impl Iterator<Item: 'static, Item: 'static> {
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error[E0282]: type annotations needed
-  --> $DIR/duplicate.rs:148:5
-   |
-LL |     iter::empty()
-   |     ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
-   |
-help: consider specifying the generic argument
-   |
-LL |     iter::empty::<T>()
-   |                +++++
-
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
   --> $DIR/duplicate.rs:151:40
    |
@@ -697,6 +664,39 @@ LL |     type A: Iterator<Item: 'static, Item: 'static>;
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
+error[E0282]: type annotations needed
+  --> $DIR/duplicate.rs:136:5
+   |
+LL |     iter::empty()
+   |     ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
+   |
+help: consider specifying the generic argument
+   |
+LL |     iter::empty::<T>()
+   |                +++++
+
+error[E0282]: type annotations needed
+  --> $DIR/duplicate.rs:142:5
+   |
+LL |     iter::empty()
+   |     ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
+   |
+help: consider specifying the generic argument
+   |
+LL |     iter::empty::<T>()
+   |                +++++
+
+error[E0282]: type annotations needed
+  --> $DIR/duplicate.rs:148:5
+   |
+LL |     iter::empty()
+   |     ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
+   |
+help: consider specifying the generic argument
+   |
+LL |     iter::empty::<T>()
+   |                +++++
+
 error: aborting due to 81 previous errors
 
 Some errors have detailed explanations: E0282, E0719.
diff --git a/tests/ui/async-await/async-fn/edition-2015.stderr b/tests/ui/async-await/async-fn/edition-2015.stderr
index 23ffee0d0a6..358bb3e112e 100644
--- a/tests/ui/async-await/async-fn/edition-2015.stderr
+++ b/tests/ui/async-await/async-fn/edition-2015.stderr
@@ -39,20 +39,20 @@ LL | fn foo(x: impl async Fn()) -> impl async Fn() { x }
    = help: to use an async block, remove the `||`: `async {`
 
 error[E0658]: use of unstable library feature 'async_closure'
-  --> $DIR/edition-2015.rs:1:22
+  --> $DIR/edition-2015.rs:1:42
    |
 LL | fn foo(x: impl async Fn()) -> impl async Fn() { x }
-   |                      ^^^^
+   |                                          ^^^^
    |
    = note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
    = help: add `#![feature(async_closure)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: use of unstable library feature 'async_closure'
-  --> $DIR/edition-2015.rs:1:42
+  --> $DIR/edition-2015.rs:1:22
    |
 LL | fn foo(x: impl async Fn()) -> impl async Fn() { x }
-   |                                          ^^^^
+   |                      ^^^^
    |
    = note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
    = help: add `#![feature(async_closure)]` to the crate attributes to enable
diff --git a/tests/ui/async-await/inference_var_self_argument.stderr b/tests/ui/async-await/inference_var_self_argument.stderr
index 7bfa9be66dd..7b7b3dbc757 100644
--- a/tests/ui/async-await/inference_var_self_argument.stderr
+++ b/tests/ui/async-await/inference_var_self_argument.stderr
@@ -1,3 +1,12 @@
+error[E0307]: invalid `self` parameter type: `&dyn Foo`
+  --> $DIR/inference_var_self_argument.rs:5:24
+   |
+LL |     async fn foo(self: &dyn Foo) {
+   |                        ^^^^^^^^
+   |
+   = note: type of `self` must be `Self` or a type that dereferences to it
+   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
 error[E0038]: the trait `Foo` cannot be made into an object
   --> $DIR/inference_var_self_argument.rs:5:5
    |
@@ -13,15 +22,6 @@ LL |     async fn foo(self: &dyn Foo) {
    |              ^^^ ...because method `foo` is `async`
    = help: consider moving `foo` to another trait
 
-error[E0307]: invalid `self` parameter type: `&dyn Foo`
-  --> $DIR/inference_var_self_argument.rs:5:24
-   |
-LL |     async fn foo(self: &dyn Foo) {
-   |                        ^^^^^^^^
-   |
-   = note: type of `self` must be `Self` or a type that dereferences to it
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
-
 error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0038, E0307.
diff --git a/tests/ui/async-await/issue-66312.stderr b/tests/ui/async-await/issue-66312.stderr
index 702e0b375e5..c95ae1147df 100644
--- a/tests/ui/async-await/issue-66312.stderr
+++ b/tests/ui/async-await/issue-66312.stderr
@@ -1,9 +1,3 @@
-error[E0308]: mismatched types
-  --> $DIR/issue-66312.rs:9:8
-   |
-LL |     if x.is_some() {
-   |        ^^^^^^^^^^^ expected `bool`, found `()`
-
 error[E0307]: invalid `self` parameter type: `T`
   --> $DIR/issue-66312.rs:4:22
    |
@@ -13,6 +7,12 @@ LL |     fn is_some(self: T);
    = note: type of `self` must be `Self` or a type that dereferences to it
    = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
 
+error[E0308]: mismatched types
+  --> $DIR/issue-66312.rs:9:8
+   |
+LL |     if x.is_some() {
+   |        ^^^^^^^^^^^ expected `bool`, found `()`
+
 error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0307, E0308.
diff --git a/tests/ui/const-generics/opaque_types.stderr b/tests/ui/const-generics/opaque_types.stderr
index 847f1da16f6..a060488b328 100644
--- a/tests/ui/const-generics/opaque_types.stderr
+++ b/tests/ui/const-generics/opaque_types.stderr
@@ -1,3 +1,11 @@
+error: `Foo` is forbidden as the type of a const generic parameter
+  --> $DIR/opaque_types.rs:7:17
+   |
+LL | fn foo<const C: Foo>() {}
+   |                 ^^^
+   |
+   = note: the only supported types are integers, `bool`, and `char`
+
 error: item does not constrain `Foo::{opaque#0}`, but has it in its signature
   --> $DIR/opaque_types.rs:7:4
    |
@@ -68,14 +76,6 @@ LL | type Foo = impl Sized;
    |            ^^^^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
-error: `Foo` is forbidden as the type of a const generic parameter
-  --> $DIR/opaque_types.rs:7:17
-   |
-LL | fn foo<const C: Foo>() {}
-   |                 ^^^
-   |
-   = note: the only supported types are integers, `bool`, and `char`
-
 error[E0391]: cycle detected when computing type of opaque `Foo::{opaque#0}`
   --> $DIR/opaque_types.rs:3:12
    |
diff --git a/tests/ui/delegation/unsupported.stderr b/tests/ui/delegation/unsupported.stderr
index 03ded300bb4..6a627be3b64 100644
--- a/tests/ui/delegation/unsupported.stderr
+++ b/tests/ui/delegation/unsupported.stderr
@@ -3,22 +3,6 @@ error: using `#![feature(effects)]` without enabling next trait solver globally
    = note: the next trait solver must be enabled globally for the effects feature to work correctly
    = help: use `-Znext-solver` to enable
 
-warning: this function depends on never type fallback being `()`
-  --> $DIR/unsupported.rs:20:9
-   |
-LL |         fn opaque_ret() -> impl Trait { unimplemented!() }
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
-   = help: specify the types explicitly
-note: in edition 2024, the requirement `!: opaque::Trait` will fail
-  --> $DIR/unsupported.rs:20:28
-   |
-LL |         fn opaque_ret() -> impl Trait { unimplemented!() }
-   |                            ^^^^^^^^^^
-   = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
-
 error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:26:5: 26:24>::{synthetic#0}`
   --> $DIR/unsupported.rs:27:25
    |
@@ -52,6 +36,22 @@ note: in edition 2024, the requirement `!: opaque::Trait` will fail
    |
 LL |         pub fn opaque_ret() -> impl Trait { unimplemented!() }
    |                                ^^^^^^^^^^
+   = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
+
+warning: this function depends on never type fallback being `()`
+  --> $DIR/unsupported.rs:20:9
+   |
+LL |         fn opaque_ret() -> impl Trait { unimplemented!() }
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
+   = help: specify the types explicitly
+note: in edition 2024, the requirement `!: opaque::Trait` will fail
+  --> $DIR/unsupported.rs:20:28
+   |
+LL |         fn opaque_ret() -> impl Trait { unimplemented!() }
+   |                            ^^^^^^^^^^
 
 error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:29:5: 29:25>::{synthetic#0}`
   --> $DIR/unsupported.rs:30:24
diff --git a/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr b/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr
index d8a85c8838d..7dfd79c7286 100644
--- a/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr
+++ b/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr
@@ -18,14 +18,6 @@ LL |     type Bop = impl std::fmt::Debug;
    = help: add `#![feature(impl_trait_in_assoc_type)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: unconstrained opaque type
-  --> $DIR/feature-gate-impl_trait_in_assoc_type.rs:6:16
-   |
-LL |     type Bar = impl std::fmt::Debug;
-   |                ^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `Bar` must be used in combination with a concrete type within the same impl
-
 error[E0658]: inherent associated types are unstable
   --> $DIR/feature-gate-impl_trait_in_assoc_type.rs:14:5
    |
@@ -37,6 +29,14 @@ LL |     type Bop = impl std::fmt::Debug;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error: unconstrained opaque type
+  --> $DIR/feature-gate-impl_trait_in_assoc_type.rs:6:16
+   |
+LL |     type Bar = impl std::fmt::Debug;
+   |                ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `Bar` must be used in combination with a concrete type within the same impl
+
+error: unconstrained opaque type
   --> $DIR/feature-gate-impl_trait_in_assoc_type.rs:14:16
    |
 LL |     type Bop = impl std::fmt::Debug;
diff --git a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr
index 50a9f3ebeab..91550f0e284 100644
--- a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr
+++ b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr
@@ -19,7 +19,10 @@ error[E0720]: cannot resolve opaque type
   --> $DIR/impl-fn-predefined-lifetimes.rs:4:35
    |
 LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
-   |                                   ^^^^^^^^^^^^^^^ cannot resolve opaque type
+   |                                   ^^^^^^^^^^^^^^^ recursive opaque type
+...
+LL |     |x| x
+   |     ----- returning here with type `{closure@$DIR/impl-fn-predefined-lifetimes.rs:7:5: 7:8}`
 
 error: aborting due to 2 previous errors; 1 warning emitted
 
diff --git a/tests/ui/impl-trait/issues/issue-78722-2.stderr b/tests/ui/impl-trait/issues/issue-78722-2.stderr
index dc5579c1c82..2cf6b94dd9d 100644
--- a/tests/ui/impl-trait/issues/issue-78722-2.stderr
+++ b/tests/ui/impl-trait/issues/issue-78722-2.stderr
@@ -1,9 +1,3 @@
-error[E0271]: expected `{async block@$DIR/issue-78722-2.rs:13:13: 13:18}` to be a future that resolves to `u8`, but it resolves to `()`
-  --> $DIR/issue-78722-2.rs:11:30
-   |
-LL |         fn concrete_use() -> F {
-   |                              ^ expected `()`, found `u8`
-
 error[E0308]: mismatched types
   --> $DIR/issue-78722-2.rs:16:20
    |
@@ -18,6 +12,12 @@ LL |         let f: F = async { 1 };
    = note: expected opaque type `F`
             found `async` block `{async block@$DIR/issue-78722-2.rs:16:20: 16:25}`
 
+error[E0271]: expected `{async block@$DIR/issue-78722-2.rs:13:13: 13:18}` to be a future that resolves to `u8`, but it resolves to `()`
+  --> $DIR/issue-78722-2.rs:11:30
+   |
+LL |         fn concrete_use() -> F {
+   |                              ^ expected `()`, found `u8`
+
 error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0271, E0308.
diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
index 3692cc77b0f..6485aa20710 100644
--- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
+++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
@@ -1,24 +1,3 @@
-error: item does not constrain `a::Foo::{opaque#0}`, but has it in its signature
-  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:10:12
-   |
-LL |         fn eq(&self, _other: &(Foo, i32)) -> bool {
-   |            ^^
-   |
-   = note: consider moving the opaque type's declaration and defining uses into a separate module
-note: this opaque type is in the signature
-  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:4:16
-   |
-LL |     type Foo = impl PartialEq<(Foo, i32)>;
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: unconstrained opaque type
-  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:4:16
-   |
-LL |     type Foo = impl PartialEq<(Foo, i32)>;
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `Foo` must be used in combination with a concrete type within the same module
-
 error[E0053]: method `eq` has an incompatible type for trait
   --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:10:30
    |
@@ -35,8 +14,21 @@ help: change the parameter type to match the trait
 LL |         fn eq(&self, _other: &(a::Bar, i32)) -> bool {
    |                              ~~~~~~~~~~~~~~
 
+error: item does not constrain `a::Foo::{opaque#0}`, but has it in its signature
+  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:10:12
+   |
+LL |         fn eq(&self, _other: &(Foo, i32)) -> bool {
+   |            ^^
+   |
+   = note: consider moving the opaque type's declaration and defining uses into a separate module
+note: this opaque type is in the signature
+  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:4:16
+   |
+LL |     type Foo = impl PartialEq<(Foo, i32)>;
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 error: unconstrained opaque type
-  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:19:16
+  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:4:16
    |
 LL |     type Foo = impl PartialEq<(Foo, i32)>;
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -64,6 +56,14 @@ help: change the parameter type to match the trait
 LL |         fn eq(&self, _other: &(b::Foo, i32)) -> bool {
    |                              ~~~~~~~~~~~~~~
 
+error: unconstrained opaque type
+  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:19:16
+   |
+LL |     type Foo = impl PartialEq<(Foo, i32)>;
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `Foo` must be used in combination with a concrete type within the same module
+
 error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0053`.
diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr
index 2770a6cc40e..13f50fcea7b 100644
--- a/tests/ui/impl-trait/where-allowed.stderr
+++ b/tests/ui/impl-trait/where-allowed.stderr
@@ -342,6 +342,47 @@ LL |     let _in_return_in_local_variable = || -> impl Fn() { || {} };
    |
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
+error[E0053]: method `in_trait_impl_return` has an incompatible type for trait
+  --> $DIR/where-allowed.rs:128:34
+   |
+LL |     type Out = impl Debug;
+   |                ---------- the expected opaque type
+...
+LL |     fn in_trait_impl_return() -> impl Debug { () }
+   |                                  ^^^^^^^^^^ expected opaque type, found a different opaque type
+   |
+note: type in trait
+  --> $DIR/where-allowed.rs:118:34
+   |
+LL |     fn in_trait_impl_return() -> Self::Out;
+   |                                  ^^^^^^^^^
+   = note: expected signature `fn() -> <() as DummyTrait>::Out`
+              found signature `fn() -> impl Debug`
+   = note: distinct uses of `impl Trait` result in different opaque types
+help: change the output type to match the trait
+   |
+LL |     fn in_trait_impl_return() -> <() as DummyTrait>::Out { () }
+   |                                  ~~~~~~~~~~~~~~~~~~~~~~~
+
+error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
+  --> $DIR/where-allowed.rs:245:36
+   |
+LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
+   |                                    ^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
+   = note: `#[deny(invalid_type_param_default)]` on by default
+
+error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
+  --> $DIR/where-allowed.rs:238:7
+   |
+LL | impl <T = impl Debug> T {}
+   |       ^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
+
 error[E0283]: type annotations needed
   --> $DIR/where-allowed.rs:46:57
    |
@@ -362,16 +403,6 @@ LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { pani
            - impl<Args, F, A> Fn<Args> for Box<F, A>
              where Args: Tuple, F: Fn<Args>, A: Allocator, F: ?Sized;
 
-error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
-  --> $DIR/where-allowed.rs:238:7
-   |
-LL | impl <T = impl Debug> T {}
-   |       ^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
-   = note: `#[deny(invalid_type_param_default)]` on by default
-
 error[E0118]: no nominal type found for inherent implementation
   --> $DIR/where-allowed.rs:238:1
    |
@@ -380,28 +411,6 @@ LL | impl <T = impl Debug> T {}
    |
    = note: either implement a trait on it or create a newtype to wrap it instead
 
-error[E0053]: method `in_trait_impl_return` has an incompatible type for trait
-  --> $DIR/where-allowed.rs:128:34
-   |
-LL |     type Out = impl Debug;
-   |                ---------- the expected opaque type
-...
-LL |     fn in_trait_impl_return() -> impl Debug { () }
-   |                                  ^^^^^^^^^^ expected opaque type, found a different opaque type
-   |
-note: type in trait
-  --> $DIR/where-allowed.rs:118:34
-   |
-LL |     fn in_trait_impl_return() -> Self::Out;
-   |                                  ^^^^^^^^^
-   = note: expected signature `fn() -> <() as DummyTrait>::Out`
-              found signature `fn() -> impl Debug`
-   = note: distinct uses of `impl Trait` result in different opaque types
-help: change the output type to match the trait
-   |
-LL |     fn in_trait_impl_return() -> <() as DummyTrait>::Out { () }
-   |                                  ~~~~~~~~~~~~~~~~~~~~~~~
-
 error: unconstrained opaque type
   --> $DIR/where-allowed.rs:121:16
    |
@@ -410,25 +419,16 @@ LL |     type Out = impl Debug;
    |
    = note: `Out` must be used in combination with a concrete type within the same impl
 
-error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
-  --> $DIR/where-allowed.rs:245:36
-   |
-LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
-   |                                    ^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
-
 error: aborting due to 49 previous errors
 
 Some errors have detailed explanations: E0053, E0118, E0283, E0562, E0658, E0666.
 For more information about an error, try `rustc --explain E0053`.
 Future incompatibility report: Future breakage diagnostic:
 error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
-  --> $DIR/where-allowed.rs:238:7
+  --> $DIR/where-allowed.rs:245:36
    |
-LL | impl <T = impl Debug> T {}
-   |       ^^^^^^^^^^^^^^
+LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
+   |                                    ^^^^^^^^^^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
@@ -436,10 +436,10 @@ LL | impl <T = impl Debug> T {}
 
 Future breakage diagnostic:
 error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
-  --> $DIR/where-allowed.rs:245:36
+  --> $DIR/where-allowed.rs:238:7
    |
-LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
-   |                                    ^^^^^^^^^^^^^^
+LL | impl <T = impl Debug> T {}
+   |       ^^^^^^^^^^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
diff --git a/tests/ui/privacy/private-type-in-interface.rs b/tests/ui/privacy/private-type-in-interface.rs
index 2e8be28d76e..9eadd09867d 100644
--- a/tests/ui/privacy/private-type-in-interface.rs
+++ b/tests/ui/privacy/private-type-in-interface.rs
@@ -26,7 +26,5 @@ type A = <m::Alias as m::Trait>::X; //~ ERROR type `Priv` is private
 trait Tr2<T> {}
 impl<T> Tr2<T> for u8 {}
 fn g() -> impl Tr2<m::Alias> { 0 } //~ ERROR type `Priv` is private
-                                   //~| ERROR type `Priv` is private
 fn g_ext() -> impl Tr2<ext::Alias> { 0 } //~ ERROR type `ext::Priv` is private
-                                         //~| ERROR type `ext::Priv` is private
 fn main() {}
diff --git a/tests/ui/privacy/private-type-in-interface.stderr b/tests/ui/privacy/private-type-in-interface.stderr
index 091cae42dea..03225d84fdb 100644
--- a/tests/ui/privacy/private-type-in-interface.stderr
+++ b/tests/ui/privacy/private-type-in-interface.stderr
@@ -46,23 +46,11 @@ error: type `Priv` is private
 LL | fn g() -> impl Tr2<m::Alias> { 0 }
    |           ^^^^^^^^^^^^^^^^^^ private type
 
-error: type `Priv` is private
-  --> $DIR/private-type-in-interface.rs:28:11
-   |
-LL | fn g() -> impl Tr2<m::Alias> { 0 }
-   |           ^^^^^^^^^^^^^^^^^^ private type
-
-error: type `ext::Priv` is private
-  --> $DIR/private-type-in-interface.rs:30:15
-   |
-LL | fn g_ext() -> impl Tr2<ext::Alias> { 0 }
-   |               ^^^^^^^^^^^^^^^^^^^^ private type
-
 error: type `ext::Priv` is private
-  --> $DIR/private-type-in-interface.rs:30:15
+  --> $DIR/private-type-in-interface.rs:29:15
    |
 LL | fn g_ext() -> impl Tr2<ext::Alias> { 0 }
    |               ^^^^^^^^^^^^^^^^^^^^ private type
 
-error: aborting due to 11 previous errors
+error: aborting due to 9 previous errors
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr
index b59c6d1eed8..1040af7541c 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr
@@ -68,76 +68,76 @@ LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
    |                                                ^^^^^^^^
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:25:29
+  --> $DIR/const-impl-trait.rs:29:29
    |
-LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
+LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
    |                             ^^^^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:25:48
+  --> $DIR/const-impl-trait.rs:29:48
    |
-LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
+LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
    |                                                ^^^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:25:29
+  --> $DIR/const-impl-trait.rs:29:29
    |
-LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
+LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
    |                             ^^^^^^^^^
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:25:48
+  --> $DIR/const-impl-trait.rs:29:48
    |
-LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
+LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
    |                                                ^^^^^^^^
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:29:29
+  --> $DIR/const-impl-trait.rs:50:41
    |
-LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
-   |                             ^^^^^^^^^
+LL | const fn apit(_: impl ~const T + ~const Destruct) {}
+   |                                         ^^^^^^^^
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:29:48
+  --> $DIR/const-impl-trait.rs:54:73
    |
-LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
-   |                                                ^^^^^^^^
+LL | const fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T> + ~const Destruct) {}
+   |                                                                         ^^^^^^^^
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:29:29
+  --> $DIR/const-impl-trait.rs:25:29
    |
-LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
+LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
    |                             ^^^^^^^^^
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:29:48
+  --> $DIR/const-impl-trait.rs:25:48
    |
-LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
+LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
    |                                                ^^^^^^^^
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:50:41
+  --> $DIR/const-impl-trait.rs:25:29
    |
-LL | const fn apit(_: impl ~const T + ~const Destruct) {}
-   |                                         ^^^^^^^^
+LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
+   |                             ^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:54:73
+  --> $DIR/const-impl-trait.rs:25:48
    |
-LL | const fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T> + ~const Destruct) {}
-   |                                                                         ^^^^^^^^
+LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
+   |                                                ^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
   --> $DIR/const-impl-trait.rs:25:29
diff --git a/tests/ui/self/arbitrary-self-opaque.stderr b/tests/ui/self/arbitrary-self-opaque.stderr
index 5ccc076bfaf..5634b3d6e64 100644
--- a/tests/ui/self/arbitrary-self-opaque.stderr
+++ b/tests/ui/self/arbitrary-self-opaque.stderr
@@ -1,3 +1,12 @@
+error[E0307]: invalid `self` parameter type: `Bar`
+  --> $DIR/arbitrary-self-opaque.rs:8:18
+   |
+LL |     fn foo(self: Bar) {}
+   |                  ^^^
+   |
+   = note: type of `self` must be `Self` or a type that dereferences to it
+   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
 error: item does not constrain `Bar::{opaque#0}`, but has it in its signature
   --> $DIR/arbitrary-self-opaque.rs:8:8
    |
@@ -19,15 +28,6 @@ LL | type Bar = impl Sized;
    |
    = note: `Bar` must be used in combination with a concrete type within the same module
 
-error[E0307]: invalid `self` parameter type: `Bar`
-  --> $DIR/arbitrary-self-opaque.rs:8:18
-   |
-LL |     fn foo(self: Bar) {}
-   |                  ^^^
-   |
-   = note: type of `self` must be `Self` or a type that dereferences to it
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
-
 error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0307`.
diff --git a/tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr b/tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr
index b00260fa0ef..f3393830eeb 100644
--- a/tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr
+++ b/tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr
@@ -9,8 +9,8 @@ LL |     async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn a<'a>(self: Pin<&'a Foo>, f: &'a Foo) -> &Foo { f }
-   |               ++++            ++           ++
+LL |     async fn a<'a>(self: Pin<&Foo>, f: &'a Foo) -> &'a Foo { f }
+   |               ++++                      ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:75
@@ -23,8 +23,8 @@ LL |     async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn c<'a>(self: Pin<&'a Self>, f: &'a Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
-   |               ++++            ++            ++
+LL |     async fn c<'a>(self: Pin<&Self>, f: &'a Foo, g: &Foo) -> (Pin<&'a Foo>, &'a Foo) { (self, f) }
+   |               ++++                       ++                        ++        ++
 
 error: lifetime may not live long enough
   --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:64
@@ -37,8 +37,8 @@ LL |     async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
    |
 help: consider reusing a named lifetime parameter and update trait if needed
    |
-LL |     async fn bar<'a>(self: Alias<&'a Self>, arg: &'a ()) -> &() { arg }
-   |                                   ++
+LL |     async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &'a () { arg }
+   |                                                           ++
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/self/elision/lt-ref-self-async.fixed b/tests/ui/self/elision/lt-ref-self-async.fixed
index 914511641b8..aae94f7a6cc 100644
--- a/tests/ui/self/elision/lt-ref-self-async.fixed
+++ b/tests/ui/self/elision/lt-ref-self-async.fixed
@@ -11,34 +11,34 @@ struct Struct<'a> {
 impl<'a> Struct<'a> {
     // Test using `&self` sugar:
 
-    async fn ref_self<'b>(&'b self, f: &'b u32) -> &u32 {
+    async fn ref_self<'b>(&self, f: &'b u32) -> &'b u32 {
         f
         //~^ ERROR lifetime may not live long enough
     }
 
     // Test using `&Self` explicitly:
 
-    async fn ref_Self<'b>(self: &'b Self, f: &'b u32) -> &u32 {
+    async fn ref_Self<'b>(self: &Self, f: &'b u32) -> &'b u32 {
         f
         //~^ ERROR lifetime may not live long enough
     }
 
-    async fn box_ref_Self<'b>(self: Box<&'b Self>, f: &'b u32) -> &u32 {
+    async fn box_ref_Self<'b>(self: Box<&Self>, f: &'b u32) -> &'b u32 {
         f
         //~^ ERROR lifetime may not live long enough
     }
 
-    async fn pin_ref_Self<'b>(self: Pin<&'b Self>, f: &'b u32) -> &u32 {
+    async fn pin_ref_Self<'b>(self: Pin<&Self>, f: &'b u32) -> &'b u32 {
         f
         //~^ ERROR lifetime may not live long enough
     }
 
-    async fn box_box_ref_Self<'b>(self: Box<Box<&'b Self>>, f: &'b u32) -> &u32 {
+    async fn box_box_ref_Self<'b>(self: Box<Box<&Self>>, f: &'b u32) -> &'b u32 {
         f
         //~^ ERROR lifetime may not live long enough
     }
 
-    async fn box_pin_Self<'b>(self: Box<Pin<&'b Self>>, f: &'b u32) -> &u32 {
+    async fn box_pin_Self<'b>(self: Box<Pin<&Self>>, f: &'b u32) -> &'b u32 {
         f
         //~^ ERROR lifetime may not live long enough
     }
diff --git a/tests/ui/self/elision/lt-ref-self-async.stderr b/tests/ui/self/elision/lt-ref-self-async.stderr
index b84044f7548..c43ff49d508 100644
--- a/tests/ui/self/elision/lt-ref-self-async.stderr
+++ b/tests/ui/self/elision/lt-ref-self-async.stderr
@@ -10,8 +10,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn ref_self<'b>(&'b self, f: &'b u32) -> &u32 {
-   |                      ++++  ++           ++
+LL |     async fn ref_self<'b>(&self, f: &'b u32) -> &'b u32 {
+   |                      ++++            ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/lt-ref-self-async.rs:22:9
@@ -25,8 +25,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn ref_Self<'b>(self: &'b Self, f: &'b u32) -> &u32 {
-   |                      ++++        ++           ++
+LL |     async fn ref_Self<'b>(self: &Self, f: &'b u32) -> &'b u32 {
+   |                      ++++                  ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/lt-ref-self-async.rs:27:9
@@ -40,8 +40,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn box_ref_Self<'b>(self: Box<&'b Self>, f: &'b u32) -> &u32 {
-   |                          ++++            ++            ++
+LL |     async fn box_ref_Self<'b>(self: Box<&Self>, f: &'b u32) -> &'b u32 {
+   |                          ++++                       ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/lt-ref-self-async.rs:32:9
@@ -55,8 +55,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn pin_ref_Self<'b>(self: Pin<&'b Self>, f: &'b u32) -> &u32 {
-   |                          ++++            ++            ++
+LL |     async fn pin_ref_Self<'b>(self: Pin<&Self>, f: &'b u32) -> &'b u32 {
+   |                          ++++                       ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/lt-ref-self-async.rs:37:9
@@ -70,8 +70,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn box_box_ref_Self<'b>(self: Box<Box<&'b Self>>, f: &'b u32) -> &u32 {
-   |                              ++++                ++             ++
+LL |     async fn box_box_ref_Self<'b>(self: Box<Box<&Self>>, f: &'b u32) -> &'b u32 {
+   |                              ++++                            ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/lt-ref-self-async.rs:42:9
@@ -85,8 +85,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn box_pin_Self<'b>(self: Box<Pin<&'b Self>>, f: &'b u32) -> &u32 {
-   |                          ++++                ++             ++
+LL |     async fn box_pin_Self<'b>(self: Box<Pin<&Self>>, f: &'b u32) -> &'b u32 {
+   |                          ++++                            ++          ++
 
 error: aborting due to 6 previous errors
 
diff --git a/tests/ui/self/elision/ref-assoc-async.stderr b/tests/ui/self/elision/ref-assoc-async.stderr
index cf54a86b45f..9f2768d5e69 100644
--- a/tests/ui/self/elision/ref-assoc-async.stderr
+++ b/tests/ui/self/elision/ref-assoc-async.stderr
@@ -10,8 +10,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn ref_AssocType<'a>(self: &'a <Struct as Trait>::AssocType, f: &'a u32) -> &u32 {
-   |                           ++++        ++                                   ++
+LL |     async fn ref_AssocType<'a>(self: &<Struct as Trait>::AssocType, f: &'a u32) -> &'a u32 {
+   |                           ++++                                          ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/ref-assoc-async.rs:24:9
@@ -25,8 +25,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn box_ref_AssocType<'a>(self: Box<&'a <Struct as Trait>::AssocType>, f: &'a u32) -> &u32 {
-   |                               ++++            ++                                    ++
+LL |     async fn box_ref_AssocType<'a>(self: Box<&<Struct as Trait>::AssocType>, f: &'a u32) -> &'a u32 {
+   |                               ++++                                               ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/ref-assoc-async.rs:29:9
@@ -40,8 +40,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn pin_ref_AssocType<'a>(self: Pin<&'a <Struct as Trait>::AssocType>, f: &'a u32) -> &u32 {
-   |                               ++++            ++                                    ++
+LL |     async fn pin_ref_AssocType<'a>(self: Pin<&<Struct as Trait>::AssocType>, f: &'a u32) -> &'a u32 {
+   |                               ++++                                               ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/ref-assoc-async.rs:34:9
@@ -55,8 +55,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn box_box_ref_AssocType<'a>(self: Box<Box<&'a <Struct as Trait>::AssocType>>, f: &'a u32) -> &u32 {
-   |                                   ++++                ++                                     ++
+LL |     async fn box_box_ref_AssocType<'a>(self: Box<Box<&<Struct as Trait>::AssocType>>, f: &'a u32) -> &'a u32 {
+   |                                   ++++                                                    ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/ref-assoc-async.rs:39:9
@@ -70,8 +70,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn box_pin_ref_AssocType<'a>(self: Box<Pin<&'a <Struct as Trait>::AssocType>>, f: &'a u32) -> &u32 {
-   |                                   ++++                ++                                     ++
+LL |     async fn box_pin_ref_AssocType<'a>(self: Box<Pin<&<Struct as Trait>::AssocType>>, f: &'a u32) -> &'a u32 {
+   |                                   ++++                                                    ++          ++
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/self/elision/ref-mut-self-async.stderr b/tests/ui/self/elision/ref-mut-self-async.stderr
index 62543ba5339..945fb5e0282 100644
--- a/tests/ui/self/elision/ref-mut-self-async.stderr
+++ b/tests/ui/self/elision/ref-mut-self-async.stderr
@@ -10,8 +10,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn ref_self<'a>(&'a mut self, f: &'a u32) -> &u32 {
-   |                      ++++  ++               ++
+LL |     async fn ref_self<'a>(&mut self, f: &'a u32) -> &'a u32 {
+   |                      ++++                ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/ref-mut-self-async.rs:20:9
@@ -25,8 +25,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn ref_Self<'a>(self: &'a mut Self, f: &'a u32) -> &u32 {
-   |                      ++++        ++               ++
+LL |     async fn ref_Self<'a>(self: &mut Self, f: &'a u32) -> &'a u32 {
+   |                      ++++                      ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/ref-mut-self-async.rs:25:9
@@ -40,8 +40,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn box_ref_Self<'a>(self: Box<&'a mut Self>, f: &'a u32) -> &u32 {
-   |                          ++++            ++                ++
+LL |     async fn box_ref_Self<'a>(self: Box<&mut Self>, f: &'a u32) -> &'a u32 {
+   |                          ++++                           ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/ref-mut-self-async.rs:30:9
@@ -55,8 +55,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn pin_ref_Self<'a>(self: Pin<&'a mut Self>, f: &'a u32) -> &u32 {
-   |                          ++++            ++                ++
+LL |     async fn pin_ref_Self<'a>(self: Pin<&mut Self>, f: &'a u32) -> &'a u32 {
+   |                          ++++                           ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/ref-mut-self-async.rs:35:9
@@ -70,8 +70,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn box_box_ref_Self<'a>(self: Box<Box<&'a mut Self>>, f: &'a u32) -> &u32 {
-   |                              ++++                ++                 ++
+LL |     async fn box_box_ref_Self<'a>(self: Box<Box<&mut Self>>, f: &'a u32) -> &'a u32 {
+   |                              ++++                                ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/ref-mut-self-async.rs:40:9
@@ -85,8 +85,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn box_pin_ref_Self<'a>(self: Box<Pin<&'a mut Self>>, f: &'a u32) -> &u32 {
-   |                              ++++                ++                 ++
+LL |     async fn box_pin_ref_Self<'a>(self: Box<Pin<&mut Self>>, f: &'a u32) -> &'a u32 {
+   |                              ++++                                ++          ++
 
 error: aborting due to 6 previous errors
 
diff --git a/tests/ui/self/elision/ref-mut-struct-async.stderr b/tests/ui/self/elision/ref-mut-struct-async.stderr
index f8fb2e4a138..149ab01045c 100644
--- a/tests/ui/self/elision/ref-mut-struct-async.stderr
+++ b/tests/ui/self/elision/ref-mut-struct-async.stderr
@@ -10,8 +10,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn ref_Struct<'a>(self: &'a mut Struct, f: &'a u32) -> &u32 {
-   |                        ++++        ++                 ++
+LL |     async fn ref_Struct<'a>(self: &mut Struct, f: &'a u32) -> &'a u32 {
+   |                        ++++                        ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/ref-mut-struct-async.rs:18:9
@@ -25,8 +25,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn box_ref_Struct<'a>(self: Box<&'a mut Struct>, f: &'a u32) -> &u32 {
-   |                            ++++            ++                  ++
+LL |     async fn box_ref_Struct<'a>(self: Box<&mut Struct>, f: &'a u32) -> &'a u32 {
+   |                            ++++                             ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/ref-mut-struct-async.rs:23:9
@@ -40,8 +40,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn pin_ref_Struct<'a>(self: Pin<&'a mut Struct>, f: &'a u32) -> &u32 {
-   |                            ++++            ++                  ++
+LL |     async fn pin_ref_Struct<'a>(self: Pin<&mut Struct>, f: &'a u32) -> &'a u32 {
+   |                            ++++                             ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/ref-mut-struct-async.rs:28:9
@@ -55,8 +55,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn box_box_ref_Struct<'a>(self: Box<Box<&'a mut Struct>>, f: &'a u32) -> &u32 {
-   |                                ++++                ++                   ++
+LL |     async fn box_box_ref_Struct<'a>(self: Box<Box<&mut Struct>>, f: &'a u32) -> &'a u32 {
+   |                                ++++                                  ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/ref-mut-struct-async.rs:33:9
@@ -70,8 +70,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn box_pin_ref_Struct<'a>(self: Box<Pin<&'a mut Struct>>, f: &'a u32) -> &u32 {
-   |                                ++++                ++                   ++
+LL |     async fn box_pin_ref_Struct<'a>(self: Box<Pin<&mut Struct>>, f: &'a u32) -> &'a u32 {
+   |                                ++++                                  ++          ++
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/self/elision/ref-self-async.stderr b/tests/ui/self/elision/ref-self-async.stderr
index 010d281b002..a75ece5f2c7 100644
--- a/tests/ui/self/elision/ref-self-async.stderr
+++ b/tests/ui/self/elision/ref-self-async.stderr
@@ -10,8 +10,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn ref_self<'a>(&'a self, f: &'a u32) -> &u32 {
-   |                      ++++  ++           ++
+LL |     async fn ref_self<'a>(&self, f: &'a u32) -> &'a u32 {
+   |                      ++++            ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/ref-self-async.rs:30:9
@@ -25,8 +25,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn ref_Self<'a>(self: &'a Self, f: &'a u32) -> &u32 {
-   |                      ++++        ++           ++
+LL |     async fn ref_Self<'a>(self: &Self, f: &'a u32) -> &'a u32 {
+   |                      ++++                  ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/ref-self-async.rs:35:9
@@ -40,8 +40,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn box_ref_Self<'a>(self: Box<&'a Self>, f: &'a u32) -> &u32 {
-   |                          ++++            ++            ++
+LL |     async fn box_ref_Self<'a>(self: Box<&Self>, f: &'a u32) -> &'a u32 {
+   |                          ++++                       ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/ref-self-async.rs:40:9
@@ -55,8 +55,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn pin_ref_Self<'a>(self: Pin<&'a Self>, f: &'a u32) -> &u32 {
-   |                          ++++            ++            ++
+LL |     async fn pin_ref_Self<'a>(self: Pin<&Self>, f: &'a u32) -> &'a u32 {
+   |                          ++++                       ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/ref-self-async.rs:45:9
@@ -70,8 +70,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn box_box_ref_Self<'a>(self: Box<Box<&'a Self>>, f: &'a u32) -> &u32 {
-   |                              ++++                ++             ++
+LL |     async fn box_box_ref_Self<'a>(self: Box<Box<&Self>>, f: &'a u32) -> &'a u32 {
+   |                              ++++                            ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/ref-self-async.rs:50:9
@@ -85,8 +85,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn box_pin_ref_Self<'a>(self: Box<Pin<&'a Self>>, f: &'a u32) -> &u32 {
-   |                              ++++                ++             ++
+LL |     async fn box_pin_ref_Self<'a>(self: Box<Pin<&Self>>, f: &'a u32) -> &'a u32 {
+   |                              ++++                            ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/ref-self-async.rs:55:9
@@ -100,8 +100,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn wrap_ref_Self_Self<'a>(self: Wrap<&'a Self, Self>, f: &'a u8) -> &u8 {
-   |                                ++++             ++                  ++
+LL |     async fn wrap_ref_Self_Self<'a>(self: Wrap<&Self, Self>, f: &'a u8) -> &'a u8 {
+   |                                ++++                              ++         ++
 
 error: aborting due to 7 previous errors
 
diff --git a/tests/ui/self/elision/ref-struct-async.stderr b/tests/ui/self/elision/ref-struct-async.stderr
index c9376d58f90..6bdc145223a 100644
--- a/tests/ui/self/elision/ref-struct-async.stderr
+++ b/tests/ui/self/elision/ref-struct-async.stderr
@@ -10,8 +10,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn ref_Struct<'a>(self: &'a Struct, f: &'a u32) -> &u32 {
-   |                        ++++        ++             ++
+LL |     async fn ref_Struct<'a>(self: &Struct, f: &'a u32) -> &'a u32 {
+   |                        ++++                    ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/ref-struct-async.rs:18:9
@@ -25,8 +25,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn box_ref_Struct<'a>(self: Box<&'a Struct>, f: &'a u32) -> &u32 {
-   |                            ++++            ++              ++
+LL |     async fn box_ref_Struct<'a>(self: Box<&Struct>, f: &'a u32) -> &'a u32 {
+   |                            ++++                         ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/ref-struct-async.rs:23:9
@@ -40,8 +40,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn pin_ref_Struct<'a>(self: Pin<&'a Struct>, f: &'a u32) -> &u32 {
-   |                            ++++            ++              ++
+LL |     async fn pin_ref_Struct<'a>(self: Pin<&Struct>, f: &'a u32) -> &'a u32 {
+   |                            ++++                         ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/ref-struct-async.rs:28:9
@@ -55,8 +55,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn box_box_ref_Struct<'a>(self: Box<Box<&'a Struct>>, f: &'a u32) -> &u32 {
-   |                                ++++                ++               ++
+LL |     async fn box_box_ref_Struct<'a>(self: Box<Box<&Struct>>, f: &'a u32) -> &'a u32 {
+   |                                ++++                              ++          ++
 
 error: lifetime may not live long enough
   --> $DIR/ref-struct-async.rs:33:9
@@ -70,8 +70,8 @@ LL |         f
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
-LL |     async fn box_pin_Struct<'a>(self: Box<Pin<&'a Struct>>, f: &'a u32) -> &u32 {
-   |                            ++++                ++               ++
+LL |     async fn box_pin_Struct<'a>(self: Box<Pin<&Struct>>, f: &'a u32) -> &'a u32 {
+   |                            ++++                              ++          ++
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.rs b/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.rs
new file mode 100644
index 00000000000..df589473a84
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.rs
@@ -0,0 +1,18 @@
+#![feature(type_alias_impl_trait)]
+
+trait Captures<'a> {}
+impl<T> Captures<'_> for T {}
+
+fn dyn_hoops<T: Sized>() -> dyn for<'a> Iterator<Item = impl Captures<'a>> {
+    //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
+    loop {}
+}
+
+pub fn main() {
+    //~^ ERROR item does not constrain `Opaque::{opaque#0}`, but has it in its signature
+    type Opaque = impl Sized;
+    fn define() -> Opaque {
+        let x: Opaque = dyn_hoops::<()>();
+        x
+    }
+}
diff --git a/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.stderr b/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.stderr
new file mode 100644
index 00000000000..59d9ff86c6e
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.stderr
@@ -0,0 +1,28 @@
+error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
+  --> $DIR/bound-lifetime-through-dyn-trait.rs:6:71
+   |
+LL | fn dyn_hoops<T: Sized>() -> dyn for<'a> Iterator<Item = impl Captures<'a>> {
+   |                                                                       ^^
+   |
+note: lifetime declared here
+  --> $DIR/bound-lifetime-through-dyn-trait.rs:6:37
+   |
+LL | fn dyn_hoops<T: Sized>() -> dyn for<'a> Iterator<Item = impl Captures<'a>> {
+   |                                     ^^
+
+error: item does not constrain `Opaque::{opaque#0}`, but has it in its signature
+  --> $DIR/bound-lifetime-through-dyn-trait.rs:11:8
+   |
+LL | pub fn main() {
+   |        ^^^^
+   |
+   = note: consider moving the opaque type's declaration and defining uses into a separate module
+note: this opaque type is in the signature
+  --> $DIR/bound-lifetime-through-dyn-trait.rs:13:19
+   |
+LL |     type Opaque = impl Sized;
+   |                   ^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0657`.
diff --git a/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr b/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr
index b526ab49d8d..ec8a51b0818 100644
--- a/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr
+++ b/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr
@@ -1,3 +1,11 @@
+error: `Bar` is forbidden as the type of a const generic parameter
+  --> $DIR/const_generic_type.rs:8:24
+   |
+LL | async fn test<const N: crate::Bar>() {
+   |                        ^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool`, and `char`
+
 error: item does not constrain `Bar::{opaque#0}`, but has it in its signature
   --> $DIR/const_generic_type.rs:8:10
    |
@@ -39,13 +47,5 @@ LL | type Bar = impl std::fmt::Display;
    |
    = note: `Bar` must be used in combination with a concrete type within the same module
 
-error: `Bar` is forbidden as the type of a const generic parameter
-  --> $DIR/const_generic_type.rs:8:24
-   |
-LL | async fn test<const N: crate::Bar>() {
-   |                        ^^^^^^^^^^
-   |
-   = note: the only supported types are integers, `bool`, and `char`
-
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/type-alias-impl-trait/constrain_inputs.stderr b/tests/ui/type-alias-impl-trait/constrain_inputs.stderr
index 2468fb7480b..436326e66c3 100644
--- a/tests/ui/type-alias-impl-trait/constrain_inputs.stderr
+++ b/tests/ui/type-alias-impl-trait/constrain_inputs.stderr
@@ -7,19 +7,6 @@ LL |     fn execute(ty: Ty<'_>) -> &str { todo!() }
    = note: lifetimes appearing in an associated or opaque type are not considered constrained
    = note: consider introducing a named lifetime parameter
 
-error: item does not constrain `lifetime_params::Ty::{opaque#0}`, but has it in its signature
-  --> $DIR/constrain_inputs.rs:6:8
-   |
-LL |     fn execute(ty: Ty<'_>) -> &str { todo!() }
-   |        ^^^^^^^
-   |
-   = note: consider moving the opaque type's declaration and defining uses into a separate module
-note: this opaque type is in the signature
-  --> $DIR/constrain_inputs.rs:4:19
-   |
-LL |     type Ty<'a> = impl Sized;
-   |                   ^^^^^^^^^^
-
 error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
   --> $DIR/constrain_inputs.rs:10:35
    |
@@ -38,6 +25,19 @@ LL |     type BadTraitRef = dyn Fn(Ty<'_>) -> &str;
    = note: lifetimes appearing in an associated or opaque type are not considered constrained
    = note: consider introducing a named lifetime parameter
 
+error: item does not constrain `lifetime_params::Ty::{opaque#0}`, but has it in its signature
+  --> $DIR/constrain_inputs.rs:6:8
+   |
+LL |     fn execute(ty: Ty<'_>) -> &str { todo!() }
+   |        ^^^^^^^
+   |
+   = note: consider moving the opaque type's declaration and defining uses into a separate module
+note: this opaque type is in the signature
+  --> $DIR/constrain_inputs.rs:4:19
+   |
+LL |     type Ty<'a> = impl Sized;
+   |                   ^^^^^^^^^^
+
 error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
   --> $DIR/constrain_inputs.rs:19:31
    |
diff --git a/tests/ui/type-alias-impl-trait/generic_underconstrained.stderr b/tests/ui/type-alias-impl-trait/generic_underconstrained.stderr
index be9b07823ae..88529b370f1 100644
--- a/tests/ui/type-alias-impl-trait/generic_underconstrained.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_underconstrained.stderr
@@ -1,13 +1,8 @@
 error[E0277]: the trait bound `T: Trait` is not satisfied
-  --> $DIR/generic_underconstrained.rs:9:51
+  --> $DIR/generic_underconstrained.rs:9:31
    |
-LL |   fn underconstrain<T>(_: T) -> Underconstrained<T> {
-   |  ___________________________________________________^
-LL | |
-LL | |
-LL | |     unimplemented!()
-LL | | }
-   | |_^ the trait `Trait` is not implemented for `T`
+LL | fn underconstrain<T>(_: T) -> Underconstrained<T> {
+   |                               ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T`
    |
 note: required by a bound on the type alias `Underconstrained`
   --> $DIR/generic_underconstrained.rs:6:26
@@ -20,10 +15,15 @@ LL | fn underconstrain<T: Trait>(_: T) -> Underconstrained<T> {
    |                    +++++++
 
 error[E0277]: the trait bound `T: Trait` is not satisfied
-  --> $DIR/generic_underconstrained.rs:9:31
+  --> $DIR/generic_underconstrained.rs:9:51
    |
-LL | fn underconstrain<T>(_: T) -> Underconstrained<T> {
-   |                               ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T`
+LL |   fn underconstrain<T>(_: T) -> Underconstrained<T> {
+   |  ___________________________________________________^
+LL | |
+LL | |
+LL | |     unimplemented!()
+LL | | }
+   | |_^ the trait `Trait` is not implemented for `T`
    |
 note: required by a bound on the type alias `Underconstrained`
   --> $DIR/generic_underconstrained.rs:6:26
diff --git a/tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr b/tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr
index 15d96191ba9..b3b9cbca968 100644
--- a/tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr
@@ -1,13 +1,8 @@
 error[E0277]: `U` doesn't implement `Debug`
-  --> $DIR/generic_underconstrained2.rs:8:53
+  --> $DIR/generic_underconstrained2.rs:8:33
    |
-LL |   fn underconstrained<U>(_: U) -> Underconstrained<U> {
-   |  _____________________________________________________^
-LL | |
-LL | |
-LL | |     5u32
-LL | | }
-   | |_^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+LL | fn underconstrained<U>(_: U) -> Underconstrained<U> {
+   |                                 ^^^^^^^^^^^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
 note: required by a bound on the type alias `Underconstrained`
   --> $DIR/generic_underconstrained2.rs:5:26
@@ -20,15 +15,10 @@ LL | fn underconstrained<U: std::fmt::Debug>(_: U) -> Underconstrained<U> {
    |                      +++++++++++++++++
 
 error[E0277]: `V` doesn't implement `Debug`
-  --> $DIR/generic_underconstrained2.rs:17:64
+  --> $DIR/generic_underconstrained2.rs:17:43
    |
-LL |   fn underconstrained2<U, V>(_: U, _: V) -> Underconstrained2<V> {
-   |  ________________________________________________________________^
-LL | |
-LL | |
-LL | |     5u32
-LL | | }
-   | |_^ `V` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+LL | fn underconstrained2<U, V>(_: U, _: V) -> Underconstrained2<V> {
+   |                                           ^^^^^^^^^^^^^^^^^^^^ `V` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
 note: required by a bound on the type alias `Underconstrained2`
   --> $DIR/generic_underconstrained2.rs:14:27
@@ -41,10 +31,15 @@ LL | fn underconstrained2<U, V: std::fmt::Debug>(_: U, _: V) -> Underconstrained
    |                          +++++++++++++++++
 
 error[E0277]: `U` doesn't implement `Debug`
-  --> $DIR/generic_underconstrained2.rs:8:33
+  --> $DIR/generic_underconstrained2.rs:8:53
    |
-LL | fn underconstrained<U>(_: U) -> Underconstrained<U> {
-   |                                 ^^^^^^^^^^^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+LL |   fn underconstrained<U>(_: U) -> Underconstrained<U> {
+   |  _____________________________________________________^
+LL | |
+LL | |
+LL | |     5u32
+LL | | }
+   | |_^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
 note: required by a bound on the type alias `Underconstrained`
   --> $DIR/generic_underconstrained2.rs:5:26
@@ -57,10 +52,15 @@ LL | fn underconstrained<U: std::fmt::Debug>(_: U) -> Underconstrained<U> {
    |                      +++++++++++++++++
 
 error[E0277]: `V` doesn't implement `Debug`
-  --> $DIR/generic_underconstrained2.rs:17:43
+  --> $DIR/generic_underconstrained2.rs:17:64
    |
-LL | fn underconstrained2<U, V>(_: U, _: V) -> Underconstrained2<V> {
-   |                                           ^^^^^^^^^^^^^^^^^^^^ `V` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+LL |   fn underconstrained2<U, V>(_: U, _: V) -> Underconstrained2<V> {
+   |  ________________________________________________________________^
+LL | |
+LL | |
+LL | |     5u32
+LL | | }
+   | |_^ `V` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
 note: required by a bound on the type alias `Underconstrained2`
   --> $DIR/generic_underconstrained2.rs:14:27
diff --git a/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr b/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr
index 22c776e171c..eace96317dc 100644
--- a/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr
+++ b/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr
@@ -1,3 +1,9 @@
+error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
+  --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:41:6
+   |
+LL | impl<T: MyFrom<Phantom2<DummyT<U>>>, U> MyIndex<DummyT<T>> for Scope<U> {
+   |      ^ unconstrained type parameter
+
 error: item does not constrain `DummyT::{opaque#0}`, but has it in its signature
   --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:28:8
    |
@@ -24,12 +30,6 @@ note: this opaque type is in the signature
 LL | type DummyT<T> = impl F;
    |                  ^^^^^^
 
-error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:41:6
-   |
-LL | impl<T: MyFrom<Phantom2<DummyT<U>>>, U> MyIndex<DummyT<T>> for Scope<U> {
-   |      ^ unconstrained type parameter
-
 error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0207`.
diff --git a/tests/ui/type-alias-impl-trait/in-where-clause.stderr b/tests/ui/type-alias-impl-trait/in-where-clause.stderr
index f1361b47c56..5ac09e20b02 100644
--- a/tests/ui/type-alias-impl-trait/in-where-clause.stderr
+++ b/tests/ui/type-alias-impl-trait/in-where-clause.stderr
@@ -1,14 +1,25 @@
-error[E0391]: cycle detected when computing type of `Bar::{opaque#0}`
-  --> $DIR/in-where-clause.rs:5:12
+error[E0283]: type annotations needed: cannot satisfy `Bar: Send`
+  --> $DIR/in-where-clause.rs:12:9
    |
-LL | type Bar = impl Sized;
-   |            ^^^^^^^^^^
+LL |     [0; 1 + 2]
+   |         ^^^^^
    |
-note: ...which requires computing type of opaque `Bar::{opaque#0}`...
+   = note: cannot satisfy `Bar: Send`
+note: required by a bound in `foo`
+  --> $DIR/in-where-clause.rs:10:10
+   |
+LL | fn foo() -> Bar
+   |    --- required by a bound in this function
+LL | where
+LL |     Bar: Send,
+   |          ^^^^ required by this bound in `foo`
+
+error[E0391]: cycle detected when computing type of opaque `Bar::{opaque#0}`
   --> $DIR/in-where-clause.rs:5:12
    |
 LL | type Bar = impl Sized;
    |            ^^^^^^^^^^
+   |
 note: ...which requires type-checking `foo`...
   --> $DIR/in-where-clause.rs:8:1
    |
@@ -17,30 +28,15 @@ LL | | where
 LL | |     Bar: Send,
    | |______________^
    = note: ...which requires revealing opaque types in `[Binder { value: TraitPredicate(<Bar as core::marker::Send>, polarity:Positive), bound_vars: [] }]`...
-   = note: ...which again requires computing type of `Bar::{opaque#0}`, completing the cycle
-note: cycle used when checking that `Bar::{opaque#0}` is well-formed
+note: ...which requires computing type of `Bar::{opaque#0}`...
   --> $DIR/in-where-clause.rs:5:12
    |
 LL | type Bar = impl Sized;
    |            ^^^^^^^^^^
+   = note: ...which again requires computing type of opaque `Bar::{opaque#0}`, completing the cycle
+   = note: cycle used when evaluating trait selection obligation `Bar: core::marker::Send`
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
-error[E0283]: type annotations needed: cannot satisfy `Bar: Send`
-  --> $DIR/in-where-clause.rs:12:9
-   |
-LL |     [0; 1 + 2]
-   |         ^^^^^
-   |
-   = note: cannot satisfy `Bar: Send`
-note: required by a bound in `foo`
-  --> $DIR/in-where-clause.rs:10:10
-   |
-LL | fn foo() -> Bar
-   |    --- required by a bound in this function
-LL | where
-LL |     Bar: Send,
-   |          ^^^^ required by this bound in `foo`
-
 error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0283, E0391.
diff --git a/tests/ui/type-alias-impl-trait/issue-53092-2.rs b/tests/ui/type-alias-impl-trait/issue-53092-2.rs
index 2adfad4fc5b..2383008d042 100644
--- a/tests/ui/type-alias-impl-trait/issue-53092-2.rs
+++ b/tests/ui/type-alias-impl-trait/issue-53092-2.rs
@@ -1,15 +1,14 @@
 #![feature(type_alias_impl_trait)]
 #![allow(dead_code)]
 
-type Bug<T, U> = impl Fn(T) -> U + Copy; //~ ERROR cycle detected
+type Bug<T, U> = impl Fn(T) -> U + Copy;
 
 const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
-//~^ ERROR: non-defining opaque type use
-//~| ERROR: item does not constrain
-//~| ERROR: item does not constrain
+//~^ ERROR cycle detected
+//~| ERROR: non-defining opaque type use
 
 fn make_bug<T, U: From<T>>() -> Bug<T, U> {
-    |x| x.into() //~ ERROR the trait bound `U: From<T>` is not satisfied
+    |x| x.into()
 }
 
 fn main() {
diff --git a/tests/ui/type-alias-impl-trait/issue-53092-2.stderr b/tests/ui/type-alias-impl-trait/issue-53092-2.stderr
index 121f765e667..ac580866704 100644
--- a/tests/ui/type-alias-impl-trait/issue-53092-2.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-53092-2.stderr
@@ -10,75 +10,33 @@ note: for this opaque type
 LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
    |                  ^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0391]: cycle detected when computing type of `Bug::{opaque#0}`
-  --> $DIR/issue-53092-2.rs:4:18
-   |
-LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
-   |                  ^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: ...which requires computing type of opaque `Bug::{opaque#0}`...
-  --> $DIR/issue-53092-2.rs:4:18
-   |
-LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
-   |                  ^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires type-checking `CONST_BUG`...
+error[E0391]: cycle detected when type-checking `CONST_BUG`
   --> $DIR/issue-53092-2.rs:6:1
    |
 LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
    = note: ...which requires computing layout of `Bug<u8, ()>`...
    = note: ...which requires normalizing `Bug<u8, ()>`...
-   = note: ...which again requires computing type of `Bug::{opaque#0}`, completing the cycle
-note: cycle used when checking that `Bug::{opaque#0}` is well-formed
+note: ...which requires computing type of `Bug::{opaque#0}`...
   --> $DIR/issue-53092-2.rs:4:18
    |
 LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
    |                  ^^^^^^^^^^^^^^^^^^^^^^
-   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
-
-error: item does not constrain `Bug::{opaque#0}`, but has it in its signature
-  --> $DIR/issue-53092-2.rs:6:7
-   |
-LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
-   |       ^^^^^^^^^
-   |
-   = note: consider moving the opaque type's declaration and defining uses into a separate module
-note: this opaque type is in the signature
+note: ...which requires computing type of opaque `Bug::{opaque#0}`...
   --> $DIR/issue-53092-2.rs:4:18
    |
 LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
    |                  ^^^^^^^^^^^^^^^^^^^^^^
-
-error: item does not constrain `Bug::{opaque#0}`, but has it in its signature
-  --> $DIR/issue-53092-2.rs:6:61
+   = note: ...which again requires type-checking `CONST_BUG`, completing the cycle
+note: cycle used when checking that `CONST_BUG` is well-formed
+  --> $DIR/issue-53092-2.rs:6:1
    |
 LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
-   |                                                             ^^^^^^^
-   |
-   = note: consider moving the opaque type's declaration and defining uses into a separate module
-note: this opaque type is in the signature
-  --> $DIR/issue-53092-2.rs:4:18
-   |
-LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
-   |                  ^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0277]: the trait bound `U: From<T>` is not satisfied
-  --> $DIR/issue-53092-2.rs:12:5
-   |
-LL |     |x| x.into()
-   |     ^^^^^^^^^^^^ the trait `From<T>` is not implemented for `U`
-   |
-note: required by a bound in `make_bug`
-  --> $DIR/issue-53092-2.rs:11:19
-   |
-LL | fn make_bug<T, U: From<T>>() -> Bug<T, U> {
-   |                   ^^^^^^^ required by this bound in `make_bug`
-help: consider restricting type parameter `U`
-   |
-LL | type Bug<T, U: std::convert::From<T>> = impl Fn(T) -> U + Copy;
-   |              +++++++++++++++++++++++
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
-error: aborting due to 5 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0277, E0391, E0792.
-For more information about an error, try `rustc --explain E0277`.
+Some errors have detailed explanations: E0391, E0792.
+For more information about an error, try `rustc --explain E0391`.
diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr
index 2b064dcfc31..ec7b9e0e12b 100644
--- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr
@@ -1,3 +1,12 @@
+error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
+  --> $DIR/issue-84660-unsoundness.rs:29:1
+   |
+LL | impl<In, Out> Trait<Bar, In> for Out {
+   | ------------------------------------ first implementation here
+...
+LL | impl<In, Out> Trait<(), In> for Out {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
+
 error: item does not constrain `Bar::{opaque#0}`, but has it in its signature
   --> $DIR/issue-84660-unsoundness.rs:22:8
    |
@@ -11,15 +20,6 @@ note: this opaque type is in the signature
 LL | type Bar = impl Foo;
    |            ^^^^^^^^
 
-error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
-  --> $DIR/issue-84660-unsoundness.rs:29:1
-   |
-LL | impl<In, Out> Trait<Bar, In> for Out {
-   | ------------------------------------ first implementation here
-...
-LL | impl<In, Out> Trait<(), In> for Out {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
-
 error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr
index 5a728a00138..e33102f687c 100644
--- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr
@@ -1,3 +1,12 @@
+error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
+  --> $DIR/issue-84660-unsoundness.rs:29:1
+   |
+LL | impl<In, Out> Trait<Bar, In> for Out {
+   | ------------------------------------ first implementation here
+...
+LL | impl<In, Out> Trait<(), In> for Out {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
+
 error[E0284]: type annotations needed: cannot satisfy `Bar == _`
   --> $DIR/issue-84660-unsoundness.rs:22:37
    |
@@ -9,15 +18,6 @@ LL | |         unreachable!();
 LL | |     }
    | |_____^ cannot satisfy `Bar == _`
 
-error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
-  --> $DIR/issue-84660-unsoundness.rs:29:1
-   |
-LL | impl<In, Out> Trait<Bar, In> for Out {
-   | ------------------------------------ first implementation here
-...
-LL | impl<In, Out> Trait<(), In> for Out {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
-
 error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0119, E0284.
diff --git a/tests/ui/type-alias-impl-trait/nested-in-anon-const.stderr b/tests/ui/type-alias-impl-trait/nested-in-anon-const.stderr
index d0fe920b35f..aa0c1076117 100644
--- a/tests/ui/type-alias-impl-trait/nested-in-anon-const.stderr
+++ b/tests/ui/type-alias-impl-trait/nested-in-anon-const.stderr
@@ -1,11 +1,3 @@
-error: unconstrained opaque type
-  --> $DIR/nested-in-anon-const.rs:13:33
-   |
-LL |                     type B<Z> = impl Sized;
-   |                                 ^^^^^^^^^^
-   |
-   = note: `B` must be used in combination with a concrete type within the same item
-
 error[E0308]: mismatched types
   --> $DIR/nested-in-anon-const.rs:12:17
    |
@@ -15,6 +7,14 @@ LL | |
 LL | |                 },
    | |_________________^ expected `usize`, found `()`
 
+error: unconstrained opaque type
+  --> $DIR/nested-in-anon-const.rs:13:33
+   |
+LL |                     type B<Z> = impl Sized;
+   |                                 ^^^^^^^^^^
+   |
+   = note: `B` must be used in combination with a concrete type within the same item
+
 error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs b/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs
new file mode 100644
index 00000000000..dda42580e0f
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs
@@ -0,0 +1,13 @@
+#![allow(incomplete_features)]
+#![feature(non_lifetime_binders)]
+
+trait Trait<T: ?Sized> {}
+
+fn produce() -> impl for<T> Trait<(), Assoc = impl Trait<T>> {
+    //~^ ERROR associated type `Assoc` not found for `Trait`
+    //~| ERROR associated type `Assoc` not found for `Trait`
+    //~| the trait bound `{integer}: Trait<()>` is not satisfied
+    16
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr b/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr
new file mode 100644
index 00000000000..fa3306ff11f
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr
@@ -0,0 +1,30 @@
+error[E0220]: associated type `Assoc` not found for `Trait`
+  --> $DIR/non-lifetime-binder-in-constraint.rs:6:39
+   |
+LL | fn produce() -> impl for<T> Trait<(), Assoc = impl Trait<T>> {
+   |                                       ^^^^^ associated type `Assoc` not found
+
+error[E0220]: associated type `Assoc` not found for `Trait`
+  --> $DIR/non-lifetime-binder-in-constraint.rs:6:39
+   |
+LL | fn produce() -> impl for<T> Trait<(), Assoc = impl Trait<T>> {
+   |                                       ^^^^^ associated type `Assoc` not found
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0277]: the trait bound `{integer}: Trait<()>` is not satisfied
+  --> $DIR/non-lifetime-binder-in-constraint.rs:6:17
+   |
+LL | fn produce() -> impl for<T> Trait<(), Assoc = impl Trait<T>> {
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<()>` is not implemented for `{integer}`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/non-lifetime-binder-in-constraint.rs:4:1
+   |
+LL | trait Trait<T: ?Sized> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0220, E0277.
+For more information about an error, try `rustc --explain E0220`.
diff --git a/tests/ui/type-alias-impl-trait/non-lifetime-binder.rs b/tests/ui/type-alias-impl-trait/non-lifetime-binder.rs
new file mode 100644
index 00000000000..23951c34270
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/non-lifetime-binder.rs
@@ -0,0 +1,10 @@
+#![allow(incomplete_features)]
+#![feature(non_lifetime_binders)]
+
+trait Trait<T> {}
+
+fn f() -> impl for<T> Trait<impl Trait<T>> {}
+//~^ ERROR nested `impl Trait` is not allowed
+//~| ERROR the trait bound `(): Trait<impl Trait<T>>` is not satisfied
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/non-lifetime-binder.stderr b/tests/ui/type-alias-impl-trait/non-lifetime-binder.stderr
new file mode 100644
index 00000000000..5859d952b75
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/non-lifetime-binder.stderr
@@ -0,0 +1,25 @@
+error[E0666]: nested `impl Trait` is not allowed
+  --> $DIR/non-lifetime-binder.rs:6:29
+   |
+LL | fn f() -> impl for<T> Trait<impl Trait<T>> {}
+   |           ------------------^^^^^^^^^^^^^-
+   |           |                 |
+   |           |                 nested `impl Trait` here
+   |           outer `impl Trait`
+
+error[E0277]: the trait bound `(): Trait<impl Trait<T>>` is not satisfied
+  --> $DIR/non-lifetime-binder.rs:6:11
+   |
+LL | fn f() -> impl for<T> Trait<impl Trait<T>> {}
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<impl Trait<T>>` is not implemented for `()`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/non-lifetime-binder.rs:4:1
+   |
+LL | trait Trait<T> {}
+   | ^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0277, E0666.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-4.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-4.stderr
index aedb78bf5e7..99646aa4d1b 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-4.stderr
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-4.stderr
@@ -11,18 +11,6 @@ LL |     Ty: Id<Assoc = Ty>,
    |         ^^^^^^^^^^^^^^ required by this bound
 
 error[E0275]: overflow evaluating the requirement `Ty: Id`
-  --> $DIR/type-alias-impl-trait-with-cycle-error-4.rs:15:19
-   |
-LL | fn define() -> Ty {}
-   |                   ^^
-   |
-note: required by a bound on the type alias `Ty`
-  --> $DIR/type-alias-impl-trait-with-cycle-error-4.rs:13:9
-   |
-LL |     Ty: Id<Assoc = Ty>,
-   |         ^^^^^^^^^^^^^^ required by this bound
-
-error[E0275]: overflow evaluating the requirement `Ty: Id`
   --> $DIR/type-alias-impl-trait-with-cycle-error-4.rs:15:16
    |
 LL | fn define() -> Ty {}
@@ -34,6 +22,6 @@ note: required by a bound on the type alias `Ty`
 LL |     Ty: Id<Assoc = Ty>,
    |         ^^^^^^^^^^^^^^ required by this bound
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/typeck/typeck_type_placeholder_item.rs b/tests/ui/typeck/typeck_type_placeholder_item.rs
index 29a21a1f45f..437a1aed403 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item.rs
+++ b/tests/ui/typeck/typeck_type_placeholder_item.rs
@@ -160,7 +160,7 @@ impl BadTrait<_> for BadStruct<_> {}
 //~^ ERROR the placeholder `_` is not allowed within types on item signatures for implementations
 
 fn impl_trait() -> impl BadTrait<_> {
-//~^ ERROR the placeholder `_` is not allowed within types on item signatures for opaque types
+//~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions
     unimplemented!()
 }
 
@@ -180,7 +180,7 @@ struct Struct;
 trait Trait<T> {}
 impl Trait<usize> for Struct {}
 type Y = impl Trait<_>;
-//~^ ERROR the placeholder `_` is not allowed within types on item signatures for opaque types
+//~^ ERROR the placeholder `_` is not allowed within types on item signatures for type aliases
 fn foo() -> Y {
     Struct
 }
diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr
index 2c064fbb19f..8a765c21624 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item.stderr
+++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr
@@ -484,11 +484,16 @@ help: use type parameters instead
 LL | impl<T> BadTrait<T> for BadStruct<T> {}
    |     +++          ~                ~
 
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for opaque types
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
   --> $DIR/typeck_type_placeholder_item.rs:162:34
    |
 LL | fn impl_trait() -> impl BadTrait<_> {
    |                                  ^ not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL | fn impl_trait<T>() -> impl BadTrait<T> {
+   |              +++                    ~
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs
   --> $DIR/typeck_type_placeholder_item.rs:167:25
@@ -518,33 +523,17 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
 LL | type X = Box<_>;
    |              ^ not allowed in type signatures
 
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for opaque types
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for type aliases
   --> $DIR/typeck_type_placeholder_item.rs:182:21
    |
 LL | type Y = impl Trait<_>;
    |                     ^ not allowed in type signatures
 
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
-  --> $DIR/typeck_type_placeholder_item.rs:44:27
-   |
-LL |     fn test10(&self, _x : _) { }
-   |                           ^ not allowed in type signatures
-   |
-help: use type parameters instead
-   |
-LL |     fn test10<T>(&self, _x : T) { }
-   |              +++             ~
-
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
-  --> $DIR/typeck_type_placeholder_item.rs:110:34
-   |
-LL |         fn fn_test10(&self, _x : _) { }
-   |                                  ^ not allowed in type signatures
-   |
-help: use type parameters instead
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
+  --> $DIR/typeck_type_placeholder_item.rs:206:14
    |
-LL |         fn fn_test10<T>(&self, _x : T) { }
-   |                     +++             ~
+LL |     const C: _;
+   |              ^ not allowed in type signatures
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
   --> $DIR/typeck_type_placeholder_item.rs:194:14
@@ -555,6 +544,21 @@ LL |     const D: _ = 42;
    |              not allowed in type signatures
    |              help: replace with the correct type: `i32`
 
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
+  --> $DIR/typeck_type_placeholder_item.rs:209:14
+   |
+LL |     const D: _ = 42;
+   |              ^ not allowed in type signatures
+
+error[E0046]: not all trait items implemented, missing: `F`
+  --> $DIR/typeck_type_placeholder_item.rs:200:1
+   |
+LL |     type F: std::ops::Fn(_);
+   |     ----------------------- `F` from trait
+...
+LL | impl Qux for Struct {
+   | ^^^^^^^^^^^^^^^^^^^ missing `F` in implementation
+
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
   --> $DIR/typeck_type_placeholder_item.rs:217:31
    |
@@ -573,27 +577,6 @@ LL | const _: Option<_> = map(value);
    |          not allowed in type signatures
    |          help: replace with the correct type: `Option<u8>`
 
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
-  --> $DIR/typeck_type_placeholder_item.rs:206:14
-   |
-LL |     const C: _;
-   |              ^ not allowed in type signatures
-
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
-  --> $DIR/typeck_type_placeholder_item.rs:209:14
-   |
-LL |     const D: _ = 42;
-   |              ^ not allowed in type signatures
-
-error[E0046]: not all trait items implemented, missing: `F`
-  --> $DIR/typeck_type_placeholder_item.rs:200:1
-   |
-LL |     type F: std::ops::Fn(_);
-   |     ----------------------- `F` from trait
-...
-LL | impl Qux for Struct {
-   | ^^^^^^^^^^^^^^^^^^^ missing `F` in implementation
-
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
   --> $DIR/typeck_type_placeholder_item.rs:225:31
    |
@@ -624,6 +607,17 @@ LL |     fn test9(&self) -> _ { () }
    |                        not allowed in type signatures
    |                        help: replace with the correct return type: `()`
 
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
+  --> $DIR/typeck_type_placeholder_item.rs:44:27
+   |
+LL |     fn test10(&self, _x : _) { }
+   |                           ^ not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL |     fn test10<T>(&self, _x : T) { }
+   |              +++             ~
+
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
   --> $DIR/typeck_type_placeholder_item.rs:107:31
    |
@@ -633,6 +627,17 @@ LL |         fn fn_test9(&self) -> _ { () }
    |                               not allowed in type signatures
    |                               help: replace with the correct return type: `()`
 
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
+  --> $DIR/typeck_type_placeholder_item.rs:110:34
+   |
+LL |         fn fn_test10(&self, _x : _) { }
+   |                                  ^ not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL |         fn fn_test10<T>(&self, _x : T) { }
+   |                     +++             ~
+
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types
   --> $DIR/typeck_type_placeholder_item.rs:202:14
    |