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, 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`. 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 {C, D}`. Enum(EnumDef<'hir>, &'hir Generics<'hir>), /// A struct definition, e.g., `struct Foo {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/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 `::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 @@ -486,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 { @@ -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>, 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) + 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" + ); } - _ => { - span_bug!(item.span, "type_of_opaque: unexpected item type: {:?}", item.kind); - } - }, - - 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); + &hir::TyKind::OpaqueDef(opaque_ty, lifetimes) => { + let local_def_id = opaque_ty.def_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) - } - } + // 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 487cc7e55cd..2c5f8adcb5d 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, foreign_items: Vec, body_owners: Vec, + opaques: Vec, } 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 + '_ { + self.opaques.iter().copied() + } + pub fn definitions(&self) -> impl Iterator + '_ { 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/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 2ffb273cb6f..d6547b51186 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 } } @@ -3031,8 +3033,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 489bd49f3e4..a55ca5a0173 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..36eada4c1d7 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -634,10 +634,8 @@ 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 - { + fn visit_opaque_ty(&mut self, opaque: &'tcx hir::OpaqueTy<'tcx>) { + if self.impl_trait_pass { let should_visit = match opaque.origin { hir::OpaqueTyOrigin::FnReturn { parent, @@ -669,14 +667,16 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { // 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(); + self.reach_through_impl_trait(opaque.def_id, pub_ev).generics().predicates().ty(); return; } } + // Visit nested items. + intravisit::walk_opaque_ty(self, opaque) + } + + fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { // 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 +686,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); 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, - 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_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(";")),