Skip to content

Commit 5a4ee43

Browse files
committed
Auto merge of #129244 - cjgillot:opaque-hir, r=compiler-errors
Make opaque types regular HIR nodes Having opaque types as HIR owner introduces all sorts of complications. This PR proposes to make them regular HIR nodes instead. I haven't gone through all the test changes yet, so there may be a few surprises. Many thanks to `@camelid` for the first draft. Fixes #129023 Fixes #129099 Fixes #125843 Fixes #119716 Fixes #121422
2 parents d30c392 + ef17eb7 commit 5a4ee43

File tree

105 files changed

+1016
-1072
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

105 files changed

+1016
-1072
lines changed

compiler/rustc_ast_lowering/src/index.rs

+8
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,14 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
226226
});
227227
}
228228

229+
fn visit_opaque_ty(&mut self, opaq: &'hir OpaqueTy<'hir>) {
230+
self.insert(opaq.span, opaq.hir_id, Node::OpaqueTy(opaq));
231+
232+
self.with_parent(opaq.hir_id, |this| {
233+
intravisit::walk_opaque_ty(this, opaq);
234+
});
235+
}
236+
229237
fn visit_anon_const(&mut self, constant: &'hir AnonConst) {
230238
// FIXME: use real span?
231239
self.insert(DUMMY_SP, constant.hir_id, Node::AnonConst(constant));

compiler/rustc_ast_lowering/src/lib.rs

+9-18
Original file line numberDiff line numberDiff line change
@@ -1603,7 +1603,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16031603
lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>],
16041604
) -> hir::TyKind<'hir> {
16051605
let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
1606-
debug!(?opaque_ty_def_id);
1606+
let opaque_ty_hir_id = self.lower_node_id(opaque_ty_node_id);
1607+
debug!(?opaque_ty_def_id, ?opaque_ty_hir_id);
16071608

16081609
// Map from captured (old) lifetime to synthetic (new) lifetime.
16091610
// Used to resolve lifetimes in the bounds of the opaque.
@@ -1676,7 +1677,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16761677
}
16771678
}
16781679

1679-
self.with_hir_id_owner(opaque_ty_node_id, |this| {
1680+
let opaque_ty_def = self.with_def_id_parent(opaque_ty_def_id, |this| {
16801681
// Install the remapping from old to new (if any). This makes sure that
16811682
// any lifetimes that would have resolved to the def-id of captured
16821683
// lifetimes are remapped to the new *synthetic* lifetimes of the opaque.
@@ -1714,7 +1715,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17141715

17151716
let lifetime_mapping = self.arena.alloc_slice(&synthesized_lifetime_args);
17161717

1717-
let opaque_ty_item = hir::OpaqueTy {
1718+
trace!("registering opaque type with id {:#?}", opaque_ty_def_id);
1719+
let opaque_ty_def = hir::OpaqueTy {
1720+
hir_id: opaque_ty_hir_id,
1721+
def_id: opaque_ty_def_id,
17181722
generics: this.arena.alloc(hir::Generics {
17191723
params: generic_params,
17201724
predicates: &[],
@@ -1725,19 +1729,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17251729
bounds,
17261730
origin,
17271731
lifetime_mapping,
1728-
};
1729-
1730-
// Generate an `type Foo = impl Trait;` declaration.
1731-
trace!("registering opaque type with id {:#?}", opaque_ty_def_id);
1732-
let opaque_ty_item = hir::Item {
1733-
owner_id: hir::OwnerId { def_id: opaque_ty_def_id },
1734-
ident: Ident::empty(),
1735-
kind: hir::ItemKind::OpaqueTy(this.arena.alloc(opaque_ty_item)),
1736-
vis_span: this.lower_span(span.shrink_to_lo()),
17371732
span: this.lower_span(opaque_ty_span),
17381733
};
1739-
1740-
hir::OwnerNode::Item(this.arena.alloc(opaque_ty_item))
1734+
this.arena.alloc(opaque_ty_def)
17411735
});
17421736

17431737
let generic_args = self.arena.alloc_from_iter(
@@ -1750,10 +1744,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17501744
// Foo = impl Trait` is, internally, created as a child of the
17511745
// async fn, so the *type parameters* are inherited. It's
17521746
// only the lifetime parameters that we must supply.
1753-
hir::TyKind::OpaqueDef(
1754-
hir::ItemId { owner_id: hir::OwnerId { def_id: opaque_ty_def_id } },
1755-
generic_args,
1756-
)
1747+
hir::TyKind::OpaqueDef(opaque_ty_def, generic_args)
17571748
}
17581749

17591750
fn lower_precise_capturing_args(

compiler/rustc_borrowck/src/diagnostics/region_name.rs

+2-8
Original file line numberDiff line numberDiff line change
@@ -830,20 +830,14 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
830830
///
831831
/// [`OpaqueDef`]: hir::TyKind::OpaqueDef
832832
fn get_future_inner_return_ty(&self, hir_ty: &'tcx hir::Ty<'tcx>) -> &'tcx hir::Ty<'tcx> {
833-
let hir = self.infcx.tcx.hir();
834-
835-
let hir::TyKind::OpaqueDef(id, _) = hir_ty.kind else {
833+
let hir::TyKind::OpaqueDef(opaque_ty, _) = hir_ty.kind else {
836834
span_bug!(
837835
hir_ty.span,
838836
"lowered return type of async fn is not OpaqueDef: {:?}",
839837
hir_ty
840838
);
841839
};
842-
let opaque_ty = hir.item(id);
843-
if let hir::ItemKind::OpaqueTy(hir::OpaqueTy {
844-
bounds: [hir::GenericBound::Trait(trait_ref, _)],
845-
..
846-
}) = opaque_ty.kind
840+
if let hir::OpaqueTy { bounds: [hir::GenericBound::Trait(trait_ref, _)], .. } = opaque_ty
847841
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
848842
&& let Some(args) = segment.args
849843
&& let [constraint] = args.constraints

compiler/rustc_borrowck/src/region_infer/opaque_types.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -329,8 +329,8 @@ fn check_opaque_type_well_formed<'tcx>(
329329
) -> Result<Ty<'tcx>, ErrorGuaranteed> {
330330
// Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs`
331331
// on stable and we'd break that.
332-
let opaque_ty_hir = tcx.hir().expect_item(def_id);
333-
let OpaqueTyOrigin::TyAlias { .. } = opaque_ty_hir.expect_opaque_ty().origin else {
332+
let opaque_ty_hir = tcx.hir().expect_opaque_ty(def_id);
333+
let OpaqueTyOrigin::TyAlias { .. } = opaque_ty_hir.origin else {
334334
return Ok(definition_ty);
335335
};
336336
let param_env = tcx.param_env(def_id);

compiler/rustc_hir/src/hir.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -2749,6 +2749,8 @@ pub struct BareFnTy<'hir> {
27492749

27502750
#[derive(Debug, Clone, Copy, HashStable_Generic)]
27512751
pub struct OpaqueTy<'hir> {
2752+
pub hir_id: HirId,
2753+
pub def_id: LocalDefId,
27522754
pub generics: &'hir Generics<'hir>,
27532755
pub bounds: GenericBounds<'hir>,
27542756
pub origin: OpaqueTyOrigin,
@@ -2762,6 +2764,7 @@ pub struct OpaqueTy<'hir> {
27622764
/// This mapping associated a captured lifetime (first parameter) with the new
27632765
/// early-bound lifetime that was generated for the opaque.
27642766
pub lifetime_mapping: &'hir [(&'hir Lifetime, LocalDefId)],
2767+
pub span: Span,
27652768
}
27662769

27672770
#[derive(Debug, Clone, Copy, HashStable_Generic)]
@@ -2868,7 +2871,7 @@ pub enum TyKind<'hir> {
28682871
/// possibly parameters) that are actually bound on the `impl Trait`.
28692872
///
28702873
/// The last parameter specifies whether this opaque appears in a trait definition.
2871-
OpaqueDef(ItemId, &'hir [GenericArg<'hir>]),
2874+
OpaqueDef(&'hir OpaqueTy<'hir>, &'hir [GenericArg<'hir>]),
28722875
/// A trait object type `Bound1 + Bound2 + Bound3`
28732876
/// where `Bound` is a trait or a lifetime.
28742877
TraitObject(
@@ -3337,8 +3340,6 @@ impl<'hir> Item<'hir> {
33373340
expect_ty_alias, (&'hir Ty<'hir>, &'hir Generics<'hir>),
33383341
ItemKind::TyAlias(ty, generics), (ty, generics);
33393342

3340-
expect_opaque_ty, &OpaqueTy<'hir>, ItemKind::OpaqueTy(ty), ty;
3341-
33423343
expect_enum, (&EnumDef<'hir>, &'hir Generics<'hir>), ItemKind::Enum(def, generics), (def, generics);
33433344

33443345
expect_struct, (&VariantData<'hir>, &'hir Generics<'hir>),
@@ -3451,8 +3452,6 @@ pub enum ItemKind<'hir> {
34513452
GlobalAsm(&'hir InlineAsm<'hir>),
34523453
/// A type alias, e.g., `type Foo = Bar<u8>`.
34533454
TyAlias(&'hir Ty<'hir>, &'hir Generics<'hir>),
3454-
/// An opaque `impl Trait` type alias, e.g., `type Foo = impl Bar;`.
3455-
OpaqueTy(&'hir OpaqueTy<'hir>),
34563455
/// An enum definition, e.g., `enum Foo<A, B> {C<A>, D<B>}`.
34573456
Enum(EnumDef<'hir>, &'hir Generics<'hir>),
34583457
/// A struct definition, e.g., `struct Foo<A> {x: A}`.
@@ -3496,7 +3495,6 @@ impl ItemKind<'_> {
34963495
ItemKind::Fn(_, ref generics, _)
34973496
| ItemKind::TyAlias(_, ref generics)
34983497
| ItemKind::Const(_, ref generics, _)
3499-
| ItemKind::OpaqueTy(OpaqueTy { ref generics, .. })
35003498
| ItemKind::Enum(_, ref generics)
35013499
| ItemKind::Struct(_, ref generics)
35023500
| ItemKind::Union(_, ref generics)
@@ -3519,7 +3517,6 @@ impl ItemKind<'_> {
35193517
ItemKind::ForeignMod { .. } => "extern block",
35203518
ItemKind::GlobalAsm(..) => "global asm item",
35213519
ItemKind::TyAlias(..) => "type alias",
3522-
ItemKind::OpaqueTy(..) => "opaque type",
35233520
ItemKind::Enum(..) => "enum",
35243521
ItemKind::Struct(..) => "struct",
35253522
ItemKind::Union(..) => "union",
@@ -3806,6 +3803,7 @@ pub enum Node<'hir> {
38063803
Ty(&'hir Ty<'hir>),
38073804
AssocItemConstraint(&'hir AssocItemConstraint<'hir>),
38083805
TraitRef(&'hir TraitRef<'hir>),
3806+
OpaqueTy(&'hir OpaqueTy<'hir>),
38093807
Pat(&'hir Pat<'hir>),
38103808
PatField(&'hir PatField<'hir>),
38113809
Arm(&'hir Arm<'hir>),
@@ -3871,6 +3869,7 @@ impl<'hir> Node<'hir> {
38713869
| Node::Crate(..)
38723870
| Node::Ty(..)
38733871
| Node::TraitRef(..)
3872+
| Node::OpaqueTy(..)
38743873
| Node::Infer(..)
38753874
| Node::WhereBoundPredicate(..)
38763875
| Node::ArrayLenInfer(..)
@@ -3996,6 +3995,7 @@ impl<'hir> Node<'hir> {
39963995
| Node::TraitItem(TraitItem { generics, .. })
39973996
| Node::ImplItem(ImplItem { generics, .. }) => Some(generics),
39983997
Node::Item(item) => item.kind.generics(),
3998+
Node::OpaqueTy(opaque) => Some(opaque.generics),
39993999
_ => None,
40004000
}
40014001
}
@@ -4055,6 +4055,7 @@ impl<'hir> Node<'hir> {
40554055
expect_ty, &'hir Ty<'hir>, Node::Ty(n), n;
40564056
expect_assoc_item_constraint, &'hir AssocItemConstraint<'hir>, Node::AssocItemConstraint(n), n;
40574057
expect_trait_ref, &'hir TraitRef<'hir>, Node::TraitRef(n), n;
4058+
expect_opaque_ty, &'hir OpaqueTy<'hir>, Node::OpaqueTy(n), n;
40584059
expect_pat, &'hir Pat<'hir>, Node::Pat(n), n;
40594060
expect_pat_field, &'hir PatField<'hir>, Node::PatField(n), n;
40604061
expect_arm, &'hir Arm<'hir>, Node::Arm(n), n;

compiler/rustc_hir/src/intravisit.rs

+18-7
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ impl<'a> FnKind<'a> {
111111
pub trait Map<'hir> {
112112
/// Retrieves the `Node` corresponding to `id`.
113113
fn hir_node(&self, hir_id: HirId) -> Node<'hir>;
114+
fn hir_node_by_def_id(&self, def_id: LocalDefId) -> Node<'hir>;
114115
fn body(&self, id: BodyId) -> &'hir Body<'hir>;
115116
fn item(&self, id: ItemId) -> &'hir Item<'hir>;
116117
fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir>;
@@ -123,6 +124,9 @@ impl<'hir> Map<'hir> for ! {
123124
fn hir_node(&self, _: HirId) -> Node<'hir> {
124125
*self;
125126
}
127+
fn hir_node_by_def_id(&self, _: LocalDefId) -> Node<'hir> {
128+
*self;
129+
}
126130
fn body(&self, _: BodyId) -> &'hir Body<'hir> {
127131
*self;
128132
}
@@ -423,6 +427,9 @@ pub trait Visitor<'v>: Sized {
423427
fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef<'v>) -> Self::Result {
424428
walk_poly_trait_ref(self, t)
425429
}
430+
fn visit_opaque_ty(&mut self, opaque: &'v OpaqueTy<'v>) -> Self::Result {
431+
walk_opaque_ty(self, opaque)
432+
}
426433
fn visit_variant_data(&mut self, s: &'v VariantData<'v>) -> Self::Result {
427434
walk_struct_def(self, s)
428435
}
@@ -536,11 +543,6 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::
536543
try_visit!(visitor.visit_ty(ty));
537544
try_visit!(visitor.visit_generics(generics));
538545
}
539-
ItemKind::OpaqueTy(&OpaqueTy { generics, bounds, .. }) => {
540-
try_visit!(visitor.visit_id(item.hir_id()));
541-
try_visit!(walk_generics(visitor, generics));
542-
walk_list!(visitor, visit_param_bound, bounds);
543-
}
544546
ItemKind::Enum(ref enum_definition, ref generics) => {
545547
try_visit!(visitor.visit_generics(generics));
546548
// `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
894896
TyKind::Path(ref qpath) => {
895897
try_visit!(visitor.visit_qpath(qpath, typ.hir_id, typ.span));
896898
}
897-
TyKind::OpaqueDef(item_id, lifetimes) => {
898-
try_visit!(visitor.visit_nested_item(item_id));
899+
TyKind::OpaqueDef(opaque, lifetimes) => {
900+
try_visit!(visitor.visit_opaque_ty(opaque));
899901
walk_list!(visitor, visit_generic_arg, lifetimes);
900902
}
901903
TyKind::Array(ref ty, ref length) => {
@@ -1185,6 +1187,15 @@ pub fn walk_poly_trait_ref<'v, V: Visitor<'v>>(
11851187
visitor.visit_trait_ref(&trait_ref.trait_ref)
11861188
}
11871189

1190+
pub fn walk_opaque_ty<'v, V: Visitor<'v>>(visitor: &mut V, opaque: &'v OpaqueTy<'v>) -> V::Result {
1191+
let &OpaqueTy { hir_id, def_id: _, generics, bounds, origin: _, lifetime_mapping: _, span: _ } =
1192+
opaque;
1193+
try_visit!(visitor.visit_id(hir_id));
1194+
try_visit!(walk_generics(visitor, generics));
1195+
walk_list!(visitor, visit_param_bound, bounds);
1196+
V::Result::output()
1197+
}
1198+
11881199
pub fn walk_struct_def<'v, V: Visitor<'v>>(
11891200
visitor: &mut V,
11901201
struct_definition: &'v VariantData<'v>,

compiler/rustc_hir/src/target.rs

-5
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ pub enum Target {
3434
ForeignMod,
3535
GlobalAsm,
3636
TyAlias,
37-
OpaqueTy,
3837
Enum,
3938
Variant,
4039
Struct,
@@ -79,7 +78,6 @@ impl Target {
7978
| Target::ForeignMod
8079
| Target::GlobalAsm
8180
| Target::TyAlias
82-
| Target::OpaqueTy
8381
| Target::Enum
8482
| Target::Variant
8583
| Target::Struct
@@ -114,7 +112,6 @@ impl Target {
114112
ItemKind::ForeignMod { .. } => Target::ForeignMod,
115113
ItemKind::GlobalAsm(..) => Target::GlobalAsm,
116114
ItemKind::TyAlias(..) => Target::TyAlias,
117-
ItemKind::OpaqueTy(..) => Target::OpaqueTy,
118115
ItemKind::Enum(..) => Target::Enum,
119116
ItemKind::Struct(..) => Target::Struct,
120117
ItemKind::Union(..) => Target::Union,
@@ -137,7 +134,6 @@ impl Target {
137134
DefKind::ForeignMod => Target::ForeignMod,
138135
DefKind::GlobalAsm => Target::GlobalAsm,
139136
DefKind::TyAlias => Target::TyAlias,
140-
DefKind::OpaqueTy => Target::OpaqueTy,
141137
DefKind::Enum => Target::Enum,
142138
DefKind::Struct => Target::Struct,
143139
DefKind::Union => Target::Union,
@@ -191,7 +187,6 @@ impl Target {
191187
Target::ForeignMod => "foreign module",
192188
Target::GlobalAsm => "global asm",
193189
Target::TyAlias => "type alias",
194-
Target::OpaqueTy => "opaque type",
195190
Target::Enum => "enum",
196191
Target::Variant => "enum variant",
197192
Target::Struct => "struct",

compiler/rustc_hir_analysis/src/check/check.rs

+6-10
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
252252
/// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
253253
/// projections that would result in "inheriting lifetimes".
254254
fn check_opaque(tcx: TyCtxt<'_>, def_id: LocalDefId) {
255-
let item = tcx.hir().expect_item(def_id);
256-
let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item.kind else {
257-
tcx.dcx().span_bug(item.span, "expected opaque item");
258-
};
255+
let hir::OpaqueTy { origin, .. } = tcx.hir().expect_opaque_ty(def_id);
259256

260257
// HACK(jynelson): trying to infer the type of `impl trait` breaks documenting
261258
// `async-std` (and `pub async fn` in general).
@@ -265,16 +262,16 @@ fn check_opaque(tcx: TyCtxt<'_>, def_id: LocalDefId) {
265262
return;
266263
}
267264

268-
let span = tcx.def_span(item.owner_id.def_id);
265+
let span = tcx.def_span(def_id);
269266

270-
if tcx.type_of(item.owner_id.def_id).instantiate_identity().references_error() {
267+
if tcx.type_of(def_id).instantiate_identity().references_error() {
271268
return;
272269
}
273-
if check_opaque_for_cycles(tcx, item.owner_id.def_id, span).is_err() {
270+
if check_opaque_for_cycles(tcx, def_id, span).is_err() {
274271
return;
275272
}
276273

277-
let _ = check_opaque_meets_bounds(tcx, item.owner_id.def_id, span, origin);
274+
let _ = check_opaque_meets_bounds(tcx, def_id, span, origin);
278275
}
279276

280277
/// Checks that an opaque type does not contain cycles.
@@ -481,8 +478,7 @@ fn sanity_check_found_hidden_type<'tcx>(
481478
/// 2. Checking that all lifetimes that are implicitly captured are mentioned.
482479
/// 3. Asserting that all parameters mentioned in the captures list are invariant.
483480
fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDefId) {
484-
let hir::OpaqueTy { bounds, .. } =
485-
*tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty();
481+
let hir::OpaqueTy { bounds, .. } = *tcx.hir_node_by_def_id(opaque_def_id).expect_opaque_ty();
486482
let Some(precise_capturing_args) = bounds.iter().find_map(|bound| match *bound {
487483
hir::GenericBound::Use(bounds, ..) => Some(bounds),
488484
_ => None,

compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
9393
// it's a refinement to a TAIT.
9494
if !tcx.hir().get_if_local(impl_opaque.def_id).is_some_and(|node| {
9595
matches!(
96-
node.expect_item().expect_opaque_ty().origin,
96+
node.expect_opaque_ty().origin,
9797
hir::OpaqueTyOrigin::AsyncFn { parent, .. } | hir::OpaqueTyOrigin::FnReturn { parent, .. }
9898
if parent == impl_m.def_id.expect_local()
9999
)

0 commit comments

Comments
 (0)