Skip to content

Commit 3752b3d

Browse files
committed
Auto merge of #59382 - davidtwco:rfc-2008-refactoring, r=petrochenkov
Separate `DefId`s for variants and their constructors Part of #44109. Split off from #59376. See [Zulip topic](https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/rfc-2008/near/132663140) for previous discussion. r? @petrochenkov
2 parents 0576ac1 + 23cae1d commit 3752b3d

Some content is hidden

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

73 files changed

+859
-780
lines changed

src/librustc/hir/def.rs

+24-13
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@ use crate::ty;
99

1010
use self::Namespace::*;
1111

12+
/// Encodes if a `Def::Ctor` is the constructor of an enum variant or a struct.
13+
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
14+
pub enum CtorOf {
15+
/// This `Def::Ctor` is a synthesized constructor of a tuple or unit struct.
16+
Struct,
17+
/// This `Def::Ctor` is a synthesized constructor of a tuple or unit variant.
18+
Variant,
19+
}
20+
1221
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
1322
pub enum CtorKind {
1423
/// Constructor function automatically created by a tuple struct/variant.
@@ -37,9 +46,11 @@ pub enum NonMacroAttrKind {
3746
pub enum Def {
3847
// Type namespace
3948
Mod(DefId),
40-
Struct(DefId), // `DefId` refers to `NodeId` of the struct itself
49+
/// `DefId` refers to the struct itself, `Def::Ctor` refers to its constructor if it exists.
50+
Struct(DefId),
4151
Union(DefId),
4252
Enum(DefId),
53+
/// `DefId` refers to the variant itself, `Def::Ctor` refers to its constructor if it exists.
4354
Variant(DefId),
4455
Trait(DefId),
4556
/// `existential type Foo: Bar;`
@@ -61,8 +72,8 @@ pub enum Def {
6172
Const(DefId),
6273
ConstParam(DefId),
6374
Static(DefId, bool /* is_mutbl */),
64-
StructCtor(DefId, CtorKind), // `DefId` refers to `NodeId` of the struct's constructor
65-
VariantCtor(DefId, CtorKind), // `DefId` refers to the enum variant
75+
/// `DefId` refers to the struct or enum variant's constructor.
76+
Ctor(DefId, CtorOf, CtorKind),
6677
SelfCtor(DefId /* impl */), // `DefId` refers to the impl
6778
Method(DefId),
6879
AssociatedConst(DefId),
@@ -265,10 +276,9 @@ impl Def {
265276
pub fn opt_def_id(&self) -> Option<DefId> {
266277
match *self {
267278
Def::Fn(id) | Def::Mod(id) | Def::Static(id, _) |
268-
Def::Variant(id) | Def::VariantCtor(id, ..) | Def::Enum(id) |
279+
Def::Variant(id) | Def::Ctor(id, ..) | Def::Enum(id) |
269280
Def::TyAlias(id) | Def::TraitAlias(id) |
270281
Def::AssociatedTy(id) | Def::TyParam(id) | Def::ConstParam(id) | Def::Struct(id) |
271-
Def::StructCtor(id, ..) |
272282
Def::Union(id) | Def::Trait(id) | Def::Method(id) | Def::Const(id) |
273283
Def::AssociatedConst(id) | Def::Macro(id, ..) |
274284
Def::Existential(id) | Def::AssociatedExistential(id) | Def::ForeignTy(id) => {
@@ -303,20 +313,21 @@ impl Def {
303313
Def::Fn(..) => "function",
304314
Def::Mod(..) => "module",
305315
Def::Static(..) => "static",
306-
Def::Variant(..) => "variant",
307-
Def::VariantCtor(.., CtorKind::Fn) => "tuple variant",
308-
Def::VariantCtor(.., CtorKind::Const) => "unit variant",
309-
Def::VariantCtor(.., CtorKind::Fictive) => "struct variant",
310316
Def::Enum(..) => "enum",
317+
Def::Variant(..) => "variant",
318+
Def::Ctor(_, CtorOf::Variant, CtorKind::Fn) => "tuple variant",
319+
Def::Ctor(_, CtorOf::Variant, CtorKind::Const) => "unit variant",
320+
Def::Ctor(_, CtorOf::Variant, CtorKind::Fictive) => "struct variant",
321+
Def::Struct(..) => "struct",
322+
Def::Ctor(_, CtorOf::Struct, CtorKind::Fn) => "tuple struct",
323+
Def::Ctor(_, CtorOf::Struct, CtorKind::Const) => "unit struct",
324+
Def::Ctor(_, CtorOf::Struct, CtorKind::Fictive) =>
325+
bug!("impossible struct constructor"),
311326
Def::Existential(..) => "existential type",
312327
Def::TyAlias(..) => "type alias",
313328
Def::TraitAlias(..) => "trait alias",
314329
Def::AssociatedTy(..) => "associated type",
315330
Def::AssociatedExistential(..) => "associated existential type",
316-
Def::Struct(..) => "struct",
317-
Def::StructCtor(.., CtorKind::Fn) => "tuple struct",
318-
Def::StructCtor(.., CtorKind::Const) => "unit struct",
319-
Def::StructCtor(.., CtorKind::Fictive) => bug!("impossible struct constructor"),
320331
Def::SelfCtor(..) => "self constructor",
321332
Def::Union(..) => "union",
322333
Def::Trait(..) => "trait",

src/librustc/hir/intravisit.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,7 @@ pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V,
559559
generics: &'v Generics,
560560
parent_item_id: HirId) {
561561
visitor.visit_ident(variant.node.ident);
562+
visitor.visit_id(variant.node.id);
562563
visitor.visit_variant_data(&variant.node.data,
563564
variant.node.ident.name,
564565
generics,
@@ -923,7 +924,9 @@ pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, impl_item_ref: &'
923924

924925

925926
pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V, struct_definition: &'v VariantData) {
926-
visitor.visit_id(struct_definition.hir_id());
927+
if let Some(ctor_hir_id) = struct_definition.ctor_hir_id() {
928+
visitor.visit_id(ctor_hir_id);
929+
}
927930
walk_list!(visitor, visit_struct_field, struct_definition.fields());
928931
}
929932

src/librustc/hir/lowering.rs

+6-14
Original file line numberDiff line numberDiff line change
@@ -1615,9 +1615,11 @@ impl<'a> LoweringContext<'a> {
16151615
}
16161616

16171617
fn lower_variant(&mut self, v: &Variant) -> hir::Variant {
1618+
let LoweredNodeId { node_id: _, hir_id } = self.lower_node_id(v.node.id);
16181619
Spanned {
16191620
node: hir::VariantKind {
16201621
ident: v.node.ident,
1622+
id: hir_id,
16211623
attrs: self.lower_attrs(&v.node.attrs),
16221624
data: self.lower_variant_data(&v.node.data),
16231625
disr_expr: v.node.disr_expr.as_ref().map(|e| self.lower_anon_const(e)),
@@ -2669,19 +2671,10 @@ impl<'a> LoweringContext<'a> {
26692671

26702672
fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData {
26712673
match *vdata {
2672-
VariantData::Struct(ref fields, id, recovered) => {
2673-
let LoweredNodeId { node_id: _, hir_id } = self.lower_node_id(id);
2674-
2675-
hir::VariantData::Struct(
2676-
fields
2677-
.iter()
2678-
.enumerate()
2679-
.map(|f| self.lower_struct_field(f))
2680-
.collect(),
2681-
hir_id,
2682-
recovered,
2683-
)
2684-
},
2674+
VariantData::Struct(ref fields, recovered) => hir::VariantData::Struct(
2675+
fields.iter().enumerate().map(|f| self.lower_struct_field(f)).collect(),
2676+
recovered,
2677+
),
26852678
VariantData::Tuple(ref fields, id) => {
26862679
let LoweredNodeId { node_id: _, hir_id } = self.lower_node_id(id);
26872680

@@ -2696,7 +2689,6 @@ impl<'a> LoweringContext<'a> {
26962689
},
26972690
VariantData::Unit(id) => {
26982691
let LoweredNodeId { node_id: _, hir_id } = self.lower_node_id(id);
2699-
27002692
hir::VariantData::Unit(hir_id)
27012693
},
27022694
}

src/librustc/hir/map/collector.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -360,9 +360,9 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
360360
this.insert(i.span, i.hir_id, Node::Item(i));
361361
this.with_parent(i.hir_id, |this| {
362362
if let ItemKind::Struct(ref struct_def, _) = i.node {
363-
// If this is a tuple-like struct, register the constructor.
364-
if !struct_def.is_struct() {
365-
this.insert(i.span, struct_def.hir_id(), Node::StructCtor(struct_def));
363+
// If this is a tuple or unit-like struct, register the constructor.
364+
if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
365+
this.insert(i.span, ctor_hir_id, Node::Ctor(struct_def));
366366
}
367367
}
368368
intravisit::walk_item(this, i);
@@ -515,8 +515,12 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
515515
}
516516

517517
fn visit_variant(&mut self, v: &'hir Variant, g: &'hir Generics, item_id: HirId) {
518-
self.insert(v.span, v.node.data.hir_id(), Node::Variant(v));
519-
self.with_parent(v.node.data.hir_id(), |this| {
518+
self.insert(v.span, v.node.id, Node::Variant(v));
519+
self.with_parent(v.node.id, |this| {
520+
// Register the constructor of this variant.
521+
if let Some(ctor_hir_id) = v.node.data.ctor_hir_id() {
522+
this.insert(v.span, ctor_hir_id, Node::Ctor(&v.node.data));
523+
}
520524
intravisit::walk_variant(this, v, g, item_id);
521525
});
522526
}

src/librustc/hir/map/def_collector.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -158,12 +158,9 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
158158
self.with_parent(def, |this| {
159159
match i.node {
160160
ItemKind::Struct(ref struct_def, _) | ItemKind::Union(ref struct_def, _) => {
161-
// If this is a tuple-like struct, register the constructor.
162-
if !struct_def.is_struct() {
163-
this.create_def(struct_def.id(),
164-
DefPathData::StructCtor,
165-
REGULAR_SPACE,
166-
i.span);
161+
// If this is a unit or tuple-like struct, register the constructor.
162+
if let Some(ctor_hir_id) = struct_def.ctor_id() {
163+
this.create_def(ctor_hir_id, DefPathData::Ctor, REGULAR_SPACE, i.span);
167164
}
168165
}
169166
_ => {}
@@ -193,11 +190,16 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
193190
}
194191

195192
fn visit_variant(&mut self, v: &'a Variant, g: &'a Generics, item_id: NodeId) {
196-
let def = self.create_def(v.node.data.id(),
193+
let def = self.create_def(v.node.id,
197194
DefPathData::EnumVariant(v.node.ident.as_interned_str()),
198195
REGULAR_SPACE,
199196
v.span);
200-
self.with_parent(def, |this| visit::walk_variant(this, v, g, item_id));
197+
self.with_parent(def, |this| {
198+
if let Some(ctor_hir_id) = v.node.data.ctor_id() {
199+
this.create_def(ctor_hir_id, DefPathData::Ctor, REGULAR_SPACE, v.span);
200+
}
201+
visit::walk_variant(this, v, g, item_id)
202+
});
201203
}
202204

203205
fn visit_variant_data(&mut self, data: &'a VariantData, _: Ident,

src/librustc/hir/map/definitions.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -366,8 +366,8 @@ pub enum DefPathData {
366366
EnumVariant(InternedString),
367367
/// A struct field
368368
Field(InternedString),
369-
/// Implicit ctor for a tuple-like struct
370-
StructCtor,
369+
/// Implicit ctor for a unit or tuple-like struct or enum variant.
370+
Ctor,
371371
/// A constant expression (see {ast,hir}::AnonConst).
372372
AnonConst,
373373
/// An `impl Trait` type node
@@ -652,7 +652,7 @@ impl DefPathData {
652652
CrateRoot |
653653
Misc |
654654
ClosureExpr |
655-
StructCtor |
655+
Ctor |
656656
AnonConst |
657657
ImplTrait => None
658658
}
@@ -683,7 +683,7 @@ impl DefPathData {
683683
Impl => "{{impl}}",
684684
Misc => "{{misc}}",
685685
ClosureExpr => "{{closure}}",
686-
StructCtor => "{{constructor}}",
686+
Ctor => "{{constructor}}",
687687
AnonConst => "{{constant}}",
688688
ImplTrait => "{{opaque}}",
689689
};

src/librustc/hir/map/mod.rs

+24-15
Original file line numberDiff line numberDiff line change
@@ -366,12 +366,18 @@ impl<'hir> Map<'hir> {
366366
}
367367
}
368368
Node::Variant(variant) => {
369-
let def_id = self.local_def_id_from_hir_id(variant.node.data.hir_id());
369+
let def_id = self.local_def_id_from_hir_id(variant.node.id);
370370
Some(Def::Variant(def_id))
371371
}
372-
Node::StructCtor(variant) => {
373-
let def_id = self.local_def_id_from_hir_id(variant.hir_id());
374-
Some(Def::StructCtor(def_id, def::CtorKind::from_hir(variant)))
372+
Node::Ctor(variant_data) => {
373+
let ctor_of = match self.find(self.get_parent_node(node_id)) {
374+
Some(Node::Item(..)) => def::CtorOf::Struct,
375+
Some(Node::Variant(..)) => def::CtorOf::Variant,
376+
_ => unreachable!(),
377+
};
378+
variant_data.ctor_hir_id()
379+
.map(|hir_id| self.local_def_id_from_hir_id(hir_id))
380+
.map(|def_id| Def::Ctor(def_id, ctor_of, def::CtorKind::from_hir(variant_data)))
375381
}
376382
Node::AnonConst(_) |
377383
Node::Field(_) |
@@ -516,8 +522,7 @@ impl<'hir> Map<'hir> {
516522
Node::AnonConst(_) => {
517523
BodyOwnerKind::Const
518524
}
519-
Node::Variant(&Spanned { node: VariantKind { data: VariantData::Tuple(..), .. }, .. }) |
520-
Node::StructCtor(..) |
525+
Node::Ctor(..) |
521526
Node::Item(&Item { node: ItemKind::Fn(..), .. }) |
522527
Node::TraitItem(&TraitItem { node: TraitItemKind::Method(..), .. }) |
523528
Node::ImplItem(&ImplItem { node: ImplItemKind::Method(..), .. }) => {
@@ -948,8 +953,8 @@ impl<'hir> Map<'hir> {
948953
_ => bug!("struct ID bound to non-struct {}", self.hir_to_string(id))
949954
}
950955
}
951-
Some(Node::StructCtor(data)) => data,
952956
Some(Node::Variant(variant)) => &variant.node.data,
957+
Some(Node::Ctor(data)) => data,
953958
_ => bug!("expected struct or variant, found {}", self.hir_to_string(id))
954959
}
955960
}
@@ -993,7 +998,7 @@ impl<'hir> Map<'hir> {
993998
Node::Lifetime(lt) => lt.name.ident().name,
994999
Node::GenericParam(param) => param.name.ident().name,
9951000
Node::Binding(&Pat { node: PatKind::Binding(_, _, l, _), .. }) => l.name,
996-
Node::StructCtor(_) => self.name(self.get_parent(id)),
1001+
Node::Ctor(..) => self.name(self.get_parent(id)),
9971002
_ => bug!("no name for {}", self.node_to_string(id))
9981003
}
9991004
}
@@ -1019,9 +1024,9 @@ impl<'hir> Map<'hir> {
10191024
Some(Node::Expr(ref e)) => Some(&*e.attrs),
10201025
Some(Node::Stmt(ref s)) => Some(s.node.attrs()),
10211026
Some(Node::GenericParam(param)) => Some(&param.attrs[..]),
1022-
// unit/tuple structs take the attributes straight from
1023-
// the struct definition.
1024-
Some(Node::StructCtor(_)) => return self.attrs(self.get_parent(id)),
1027+
// Unit/tuple structs/variants take the attributes straight from
1028+
// the struct/variant definition.
1029+
Some(Node::Ctor(..)) => return self.attrs(self.get_parent(id)),
10251030
_ => None
10261031
};
10271032
attrs.unwrap_or(&[])
@@ -1068,7 +1073,11 @@ impl<'hir> Map<'hir> {
10681073
Some(Node::Binding(pat)) => pat.span,
10691074
Some(Node::Pat(pat)) => pat.span,
10701075
Some(Node::Block(block)) => block.span,
1071-
Some(Node::StructCtor(_)) => self.expect_item(self.get_parent(id)).span,
1076+
Some(Node::Ctor(..)) => match self.find(self.get_parent_node(id)) {
1077+
Some(Node::Item(item)) => item.span,
1078+
Some(Node::Variant(variant)) => variant.span,
1079+
_ => unreachable!(),
1080+
}
10721081
Some(Node::Lifetime(lifetime)) => lifetime.span,
10731082
Some(Node::GenericParam(param)) => param.span,
10741083
Some(Node::Visibility(&Spanned {
@@ -1324,7 +1333,7 @@ impl<'a> print::State<'a> {
13241333
// these cases do not carry enough information in the
13251334
// hir_map to reconstruct their full structure for pretty
13261335
// printing.
1327-
Node::StructCtor(_) => bug!("cannot print isolated StructCtor"),
1336+
Node::Ctor(..) => bug!("cannot print isolated Ctor"),
13281337
Node::Local(a) => self.print_local_decl(&a),
13291338
Node::MacroDef(_) => bug!("cannot print MacroDef"),
13301339
Node::Crate => bug!("cannot print Crate"),
@@ -1443,8 +1452,8 @@ fn node_id_to_string(map: &Map<'_>, id: NodeId, include_id: bool) -> String {
14431452
Some(Node::Local(_)) => {
14441453
format!("local {}{}", map.node_to_pretty_string(id), id_str)
14451454
}
1446-
Some(Node::StructCtor(_)) => {
1447-
format!("struct_ctor {}{}", path_str(), id_str)
1455+
Some(Node::Ctor(..)) => {
1456+
format!("ctor {}{}", path_str(), id_str)
14481457
}
14491458
Some(Node::Lifetime(_)) => {
14501459
format!("lifetime {}{}", map.node_to_pretty_string(id), id_str)

0 commit comments

Comments
 (0)