about summary refs log tree commit diff
path: root/compiler/rustc_hir_analysis/src
diff options
context:
space:
mode:
authorNoah Lev <camelidcamel@gmail.com>2024-08-09 20:43:30 -0700
committerCamille GILLOT <gillot.camille@gmail.com>2024-10-04 23:28:22 +0000
commitd6f247f3d52f529e7145eb355ac9660a49d0d8c9 (patch)
tree40a82d7ef14a8c598b863abac21d78796fa98558 /compiler/rustc_hir_analysis/src
parent4ec7839afa30aae41ee01326b0273ca1ba8e027b (diff)
downloadrust-d6f247f3d52f529e7145eb355ac9660a49d0d8c9.tar.gz
rust-d6f247f3d52f529e7145eb355ac9660a49d0d8c9.zip
rm `ItemKind::OpaqueTy`
This introduce an additional collection of opaques on HIR, as they can no
longer be listed using the free item list.
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
-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/collect.rs40
-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.rs73
-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
11 files changed, 145 insertions, 211 deletions
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/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 93b021be245..bb517eec64d 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -260,8 +260,8 @@ 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),
+        // FIXME: how to handle opaque types since no longer items
+        hir::ItemKind::TyAlias(_, generics) => (generics, false),
         // `static`, `fn` and `const` are handled elsewhere to suggest appropriate type.
         _ => return,
     };
@@ -731,18 +731,8 @@ 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);
-        }
-
+        // FIXME: ok to ignore opaque tys in collection?
+        //
         hir::ItemKind::TyAlias(..) => {
             tcx.ensure().generics_of(def_id);
             tcx.ensure().type_of(def_id);
@@ -1852,12 +1842,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 +1856,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..513d4e9b4a5 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -487,6 +487,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 +538,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)
@@ -689,17 +682,14 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                 };
                 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.
@@ -722,9 +712,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 +728,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)
                     };
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;
         }