Skip to content

Commit b64686e

Browse files
committed
Auto merge of rust-lang#129244 - cjgillot:opaque-hir, r=<try>
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 rust-lang#129023 Fixes rust-lang#129099 Fixes rust-lang#125843 Fixes rust-lang#119716 Fixes rust-lang#121422
2 parents 5ad98b4 + b66cc38 commit b64686e

File tree

111 files changed

+1024
-1050
lines changed

Some content is hidden

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

111 files changed

+1024
-1050
lines changed

compiler/rustc_ast_lowering/src/index.rs

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

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

compiler/rustc_ast_lowering/src/lib.rs

+10-20
Original file line numberDiff line numberDiff line change
@@ -1620,13 +1620,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16201620
lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>],
16211621
) -> hir::TyKind<'hir> {
16221622
let opaque_ty_def_id = self.create_def(
1623-
self.current_hir_id_owner.def_id, // FIXME: should this use self.current_def_id_parent?
1623+
self.current_def_id_parent,
16241624
opaque_ty_node_id,
16251625
kw::Empty,
16261626
DefKind::OpaqueTy,
16271627
opaque_ty_span,
16281628
);
1629-
debug!(?opaque_ty_def_id);
1629+
let opaque_ty_hir_id = self.lower_node_id(opaque_ty_node_id);
1630+
debug!(?opaque_ty_def_id, ?opaque_ty_hir_id);
16301631

16311632
// Map from captured (old) lifetime to synthetic (new) lifetime.
16321633
// Used to resolve lifetimes in the bounds of the opaque.
@@ -1699,7 +1700,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16991700
}
17001701
}
17011702

1702-
self.with_hir_id_owner(opaque_ty_node_id, |this| {
1703+
let opaque_ty_def = self.with_def_id_parent(opaque_ty_def_id, |this| {
17031704
// Install the remapping from old to new (if any). This makes sure that
17041705
// any lifetimes that would have resolved to the def-id of captured
17051706
// lifetimes are remapped to the new *synthetic* lifetimes of the opaque.
@@ -1737,7 +1738,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17371738

17381739
let lifetime_mapping = self.arena.alloc_slice(&synthesized_lifetime_args);
17391740

1740-
let opaque_ty_item = hir::OpaqueTy {
1741+
trace!("registering opaque type with id {:#?}", opaque_ty_def_id);
1742+
let opaque_ty_def = hir::OpaqueTy {
1743+
hir_id: opaque_ty_hir_id,
1744+
def_id: opaque_ty_def_id,
17411745
generics: this.arena.alloc(hir::Generics {
17421746
params: generic_params,
17431747
predicates: &[],
@@ -1749,19 +1753,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17491753
origin,
17501754
lifetime_mapping,
17511755
in_trait,
1752-
};
1753-
1754-
// Generate an `type Foo = impl Trait;` declaration.
1755-
trace!("registering opaque type with id {:#?}", opaque_ty_def_id);
1756-
let opaque_ty_item = hir::Item {
1757-
owner_id: hir::OwnerId { def_id: opaque_ty_def_id },
1758-
ident: Ident::empty(),
1759-
kind: hir::ItemKind::OpaqueTy(this.arena.alloc(opaque_ty_item)),
1760-
vis_span: this.lower_span(span.shrink_to_lo()),
17611756
span: this.lower_span(opaque_ty_span),
17621757
};
1763-
1764-
hir::OwnerNode::Item(this.arena.alloc(opaque_ty_item))
1758+
this.arena.alloc(opaque_ty_def)
17651759
});
17661760

17671761
let generic_args = self.arena.alloc_from_iter(
@@ -1774,11 +1768,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17741768
// Foo = impl Trait` is, internally, created as a child of the
17751769
// async fn, so the *type parameters* are inherited. It's
17761770
// only the lifetime parameters that we must supply.
1777-
hir::TyKind::OpaqueDef(
1778-
hir::ItemId { owner_id: hir::OwnerId { def_id: opaque_ty_def_id } },
1779-
generic_args,
1780-
in_trait,
1781-
)
1771+
hir::TyKind::OpaqueDef(opaque_ty_def, generic_args)
17821772
}
17831773

17841774
fn lower_precise_capturing_args(

compiler/rustc_borrowck/src/diagnostics/region_name.rs

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

compiler/rustc_borrowck/src/region_infer/opaque_types.rs

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

compiler/rustc_hir/src/hir.rs

+9-8
Original file line numberDiff line numberDiff line change
@@ -2610,7 +2610,7 @@ impl<'hir> Ty<'hir> {
26102610
}
26112611
TyKind::Tup(tys) => tys.iter().any(Self::is_suggestable_infer_ty),
26122612
TyKind::Ptr(mut_ty) | TyKind::Ref(_, mut_ty) => mut_ty.ty.is_suggestable_infer_ty(),
2613-
TyKind::OpaqueDef(_, generic_args, _) => are_suggestable_generic_args(generic_args),
2613+
TyKind::OpaqueDef(_, generic_args) => are_suggestable_generic_args(generic_args),
26142614
TyKind::Path(QPath::TypeRelative(ty, segment)) => {
26152615
ty.is_suggestable_infer_ty() || are_suggestable_generic_args(segment.args().args)
26162616
}
@@ -2727,6 +2727,8 @@ pub struct BareFnTy<'hir> {
27272727

27282728
#[derive(Debug, Clone, Copy, HashStable_Generic)]
27292729
pub struct OpaqueTy<'hir> {
2730+
pub hir_id: HirId,
2731+
pub def_id: LocalDefId,
27302732
pub generics: &'hir Generics<'hir>,
27312733
pub bounds: GenericBounds<'hir>,
27322734
pub origin: OpaqueTyOrigin,
@@ -2744,6 +2746,7 @@ pub struct OpaqueTy<'hir> {
27442746
/// originating from a trait method. This makes it so that the opaque is
27452747
/// lowered as an associated type.
27462748
pub in_trait: bool,
2749+
pub span: Span,
27472750
}
27482751

27492752
#[derive(Debug, Clone, Copy, HashStable_Generic)]
@@ -2834,7 +2837,7 @@ pub enum TyKind<'hir> {
28342837
/// possibly parameters) that are actually bound on the `impl Trait`.
28352838
///
28362839
/// The last parameter specifies whether this opaque appears in a trait definition.
2837-
OpaqueDef(ItemId, &'hir [GenericArg<'hir>], bool),
2840+
OpaqueDef(&'hir OpaqueTy<'hir>, &'hir [GenericArg<'hir>]),
28382841
/// A trait object type `Bound1 + Bound2 + Bound3`
28392842
/// where `Bound` is a trait or a lifetime.
28402843
TraitObject(
@@ -3301,8 +3304,6 @@ impl<'hir> Item<'hir> {
33013304
expect_ty_alias, (&'hir Ty<'hir>, &'hir Generics<'hir>),
33023305
ItemKind::TyAlias(ty, generics), (ty, generics);
33033306

3304-
expect_opaque_ty, &OpaqueTy<'hir>, ItemKind::OpaqueTy(ty), ty;
3305-
33063307
expect_enum, (&EnumDef<'hir>, &'hir Generics<'hir>), ItemKind::Enum(def, generics), (def, generics);
33073308

33083309
expect_struct, (&VariantData<'hir>, &'hir Generics<'hir>),
@@ -3415,8 +3416,6 @@ pub enum ItemKind<'hir> {
34153416
GlobalAsm(&'hir InlineAsm<'hir>),
34163417
/// A type alias, e.g., `type Foo = Bar<u8>`.
34173418
TyAlias(&'hir Ty<'hir>, &'hir Generics<'hir>),
3418-
/// An opaque `impl Trait` type alias, e.g., `type Foo = impl Bar;`.
3419-
OpaqueTy(&'hir OpaqueTy<'hir>),
34203419
/// An enum definition, e.g., `enum Foo<A, B> {C<A>, D<B>}`.
34213420
Enum(EnumDef<'hir>, &'hir Generics<'hir>),
34223421
/// A struct definition, e.g., `struct Foo<A> {x: A}`.
@@ -3460,7 +3459,6 @@ impl ItemKind<'_> {
34603459
ItemKind::Fn(_, ref generics, _)
34613460
| ItemKind::TyAlias(_, ref generics)
34623461
| ItemKind::Const(_, ref generics, _)
3463-
| ItemKind::OpaqueTy(OpaqueTy { ref generics, .. })
34643462
| ItemKind::Enum(_, ref generics)
34653463
| ItemKind::Struct(_, ref generics)
34663464
| ItemKind::Union(_, ref generics)
@@ -3483,7 +3481,6 @@ impl ItemKind<'_> {
34833481
ItemKind::ForeignMod { .. } => "extern block",
34843482
ItemKind::GlobalAsm(..) => "global asm item",
34853483
ItemKind::TyAlias(..) => "type alias",
3486-
ItemKind::OpaqueTy(..) => "opaque type",
34873484
ItemKind::Enum(..) => "enum",
34883485
ItemKind::Struct(..) => "struct",
34893486
ItemKind::Union(..) => "union",
@@ -3770,6 +3767,7 @@ pub enum Node<'hir> {
37703767
Ty(&'hir Ty<'hir>),
37713768
AssocItemConstraint(&'hir AssocItemConstraint<'hir>),
37723769
TraitRef(&'hir TraitRef<'hir>),
3770+
OpaqueTy(&'hir OpaqueTy<'hir>),
37733771
Pat(&'hir Pat<'hir>),
37743772
PatField(&'hir PatField<'hir>),
37753773
Arm(&'hir Arm<'hir>),
@@ -3835,6 +3833,7 @@ impl<'hir> Node<'hir> {
38353833
| Node::Crate(..)
38363834
| Node::Ty(..)
38373835
| Node::TraitRef(..)
3836+
| Node::OpaqueTy(..)
38383837
| Node::Infer(..)
38393838
| Node::WhereBoundPredicate(..)
38403839
| Node::ArrayLenInfer(..)
@@ -3960,6 +3959,7 @@ impl<'hir> Node<'hir> {
39603959
| Node::TraitItem(TraitItem { generics, .. })
39613960
| Node::ImplItem(ImplItem { generics, .. }) => Some(generics),
39623961
Node::Item(item) => item.kind.generics(),
3962+
Node::OpaqueTy(opaque) => Some(opaque.generics),
39633963
_ => None,
39643964
}
39653965
}
@@ -4019,6 +4019,7 @@ impl<'hir> Node<'hir> {
40194019
expect_ty, &'hir Ty<'hir>, Node::Ty(n), n;
40204020
expect_assoc_item_constraint, &'hir AssocItemConstraint<'hir>, Node::AssocItemConstraint(n), n;
40214021
expect_trait_ref, &'hir TraitRef<'hir>, Node::TraitRef(n), n;
4022+
expect_opaque_ty, &'hir OpaqueTy<'hir>, Node::OpaqueTy(n), n;
40224023
expect_pat, &'hir Pat<'hir>, Node::Pat(n), n;
40234024
expect_pat_field, &'hir PatField<'hir>, Node::PatField(n), n;
40244025
expect_arm, &'hir Arm<'hir>, Node::Arm(n), n;

compiler/rustc_hir/src/intravisit.rs

+26-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, _in_trait) => {
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,23 @@ 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 {
1192+
hir_id,
1193+
def_id: _,
1194+
generics,
1195+
bounds,
1196+
origin: _,
1197+
lifetime_mapping: _,
1198+
in_trait: _,
1199+
span: _,
1200+
} = opaque;
1201+
try_visit!(visitor.visit_id(hir_id));
1202+
try_visit!(walk_generics(visitor, generics));
1203+
walk_list!(visitor, visit_param_bound, bounds);
1204+
V::Result::output()
1205+
}
1206+
11881207
pub fn walk_struct_def<'v, V: Visitor<'v>>(
11891208
visitor: &mut V,
11901209
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
@@ -251,10 +251,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
251251
/// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
252252
/// projections that would result in "inheriting lifetimes".
253253
fn check_opaque(tcx: TyCtxt<'_>, def_id: LocalDefId) {
254-
let item = tcx.hir().expect_item(def_id);
255-
let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item.kind else {
256-
tcx.dcx().span_bug(item.span, "expected opaque item");
257-
};
254+
let hir::OpaqueTy { origin, .. } = tcx.hir().expect_opaque_ty(def_id);
258255

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

267-
let span = tcx.def_span(item.owner_id.def_id);
264+
let span = tcx.def_span(def_id);
268265

269-
if tcx.type_of(item.owner_id.def_id).instantiate_identity().references_error() {
266+
if tcx.type_of(def_id).instantiate_identity().references_error() {
270267
return;
271268
}
272-
if check_opaque_for_cycles(tcx, item.owner_id.def_id, span).is_err() {
269+
if check_opaque_for_cycles(tcx, def_id, span).is_err() {
273270
return;
274271
}
275272

276-
let _ = check_opaque_meets_bounds(tcx, item.owner_id.def_id, span, origin);
273+
let _ = check_opaque_meets_bounds(tcx, def_id, span, origin);
277274
}
278275

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

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

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

0 commit comments

Comments
 (0)