Skip to content

Commit 2283a5e

Browse files
committed
rustc_metadata: Add constructors to module children at encoding time
instead of decoding time.
1 parent c6bd7e2 commit 2283a5e

File tree

2 files changed

+53
-50
lines changed

2 files changed

+53
-50
lines changed

compiler/rustc_metadata/src/rmeta/decoder.rs

+35-44
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,15 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
773773
}
774774

775775
fn opt_item_name(self, item_index: DefIndex) -> Option<Symbol> {
776-
self.def_key(item_index).disambiguated_data.data.get_opt_name()
776+
let def_key = self.def_key(item_index);
777+
def_key.disambiguated_data.data.get_opt_name().or_else(|| {
778+
if def_key.disambiguated_data.data == DefPathData::Ctor {
779+
let parent_index = def_key.parent.expect("no parent for a constructor");
780+
self.def_key(parent_index).disambiguated_data.data.get_opt_name()
781+
} else {
782+
None
783+
}
784+
})
777785
}
778786

779787
fn item_name(self, item_index: DefIndex) -> Symbol {
@@ -905,7 +913,13 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
905913
.get(self, item_id)
906914
.unwrap_or_else(LazyArray::empty)
907915
.decode(self)
908-
.map(|index| self.get_variant(&self.def_kind(index), index, did))
916+
.filter_map(|index| {
917+
let kind = self.def_kind(index);
918+
match kind {
919+
DefKind::Ctor(..) => None,
920+
_ => Some(self.get_variant(&kind, index, did)),
921+
}
922+
})
909923
.collect()
910924
} else {
911925
std::iter::once(self.get_variant(&kind, item_id, did)).collect()
@@ -1029,50 +1043,27 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
10291043

10301044
callback(ModChild { ident, res, vis, span, macro_rules });
10311045

1032-
// For non-re-export structs and variants add their constructors to children.
1033-
// Re-export lists automatically contain constructors when necessary.
1034-
match kind {
1035-
DefKind::Struct => {
1036-
if let Some((ctor_def_id, ctor_kind)) =
1037-
self.get_ctor_def_id_and_kind(child_index)
1038-
{
1039-
let ctor_res =
1040-
Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id);
1041-
let vis = self.get_visibility(ctor_def_id.index);
1042-
callback(ModChild {
1043-
ident,
1044-
res: ctor_res,
1045-
vis,
1046-
span,
1047-
macro_rules: false,
1048-
});
1049-
}
1050-
}
1051-
DefKind::Variant => {
1052-
// Braced variants, unlike structs, generate unusable names in
1053-
// value namespace, they are reserved for possible future use.
1054-
// It's ok to use the variant's id as a ctor id since an
1055-
// error will be reported on any use of such resolution anyway.
1056-
let (ctor_def_id, ctor_kind) = self
1057-
.get_ctor_def_id_and_kind(child_index)
1058-
.unwrap_or((def_id, CtorKind::Fictive));
1059-
let ctor_res =
1060-
Res::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id);
1061-
let mut vis = self.get_visibility(ctor_def_id.index);
1062-
if ctor_def_id == def_id && vis.is_public() {
1063-
// For non-exhaustive variants lower the constructor visibility to
1064-
// within the crate. We only need this for fictive constructors,
1065-
// for other constructors correct visibilities
1066-
// were already encoded in metadata.
1067-
let mut attrs = self.get_item_attrs(def_id.index, sess);
1068-
if attrs.any(|item| item.has_name(sym::non_exhaustive)) {
1069-
let crate_def_id = self.local_def_id(CRATE_DEF_INDEX);
1070-
vis = ty::Visibility::Restricted(crate_def_id);
1071-
}
1046+
// For non-reexport variants add their fictive constructors to children.
1047+
// Braced variants, unlike structs, generate unusable names in value namespace,
1048+
// they are reserved for possible future use. It's ok to use the variant's id as
1049+
// a ctor id since an error will be reported on any use of such resolution anyway.
1050+
// Reexport lists automatically contain such constructors when necessary.
1051+
if kind == DefKind::Variant && self.get_ctor_def_id_and_kind(child_index).is_none()
1052+
{
1053+
let ctor_res =
1054+
Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fictive), def_id);
1055+
let mut vis = vis;
1056+
if vis.is_public() {
1057+
// For non-exhaustive variants lower the constructor visibility to
1058+
// within the crate. We only need this for fictive constructors,
1059+
// for other constructors correct visibilities
1060+
// were already encoded in metadata.
1061+
let mut attrs = self.get_item_attrs(def_id.index, sess);
1062+
if attrs.any(|item| item.has_name(sym::non_exhaustive)) {
1063+
vis = ty::Visibility::Restricted(self.local_def_id(CRATE_DEF_INDEX));
10721064
}
1073-
callback(ModChild { ident, res: ctor_res, vis, span, macro_rules: false });
10741065
}
1075-
_ => {}
1066+
callback(ModChild { ident, res: ctor_res, vis, span, macro_rules: false });
10761067
}
10771068
}
10781069
}

compiler/rustc_metadata/src/rmeta/encoder.rs

+18-6
Original file line numberDiff line numberDiff line change
@@ -1335,6 +1335,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
13351335
// Only encode named non-reexport children, reexports are encoded
13361336
// separately and unnamed items are not used by name resolution.
13371337
hir::ItemKind::ExternCrate(..) => continue,
1338+
hir::ItemKind::Struct(ref vdata, _) => {
1339+
yield item_id.def_id.def_id.local_def_index;
1340+
// Encode constructors which take a separate slot in value namespace.
1341+
if let Some(ctor_hir_id) = vdata.ctor_hir_id() {
1342+
yield tcx.hir().local_def_id(ctor_hir_id).local_def_index;
1343+
}
1344+
}
13381345
_ if tcx.def_key(item_id.def_id.to_def_id()).get_opt_name().is_some() => {
13391346
yield item_id.def_id.def_id.local_def_index;
13401347
}
@@ -1646,12 +1653,17 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
16461653
};
16471654
// FIXME(eddyb) there should be a nicer way to do this.
16481655
match item.kind {
1649-
hir::ItemKind::Enum(..) => record_array!(self.tables.children[def_id] <-
1650-
self.tcx.adt_def(def_id).variants().iter().map(|v| {
1651-
assert!(v.def_id.is_local());
1652-
v.def_id.index
1653-
})
1654-
),
1656+
hir::ItemKind::Enum(..) => {
1657+
record_array!(self.tables.children[def_id] <- iter::from_generator(||
1658+
for variant in tcx.adt_def(def_id).variants() {
1659+
yield variant.def_id.index;
1660+
// Encode constructors which take a separate slot in value namespace.
1661+
if let Some(ctor_def_id) = variant.ctor_def_id {
1662+
yield ctor_def_id.index;
1663+
}
1664+
}
1665+
))
1666+
}
16551667
hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => {
16561668
record_array!(self.tables.children[def_id] <-
16571669
self.tcx.adt_def(def_id).non_enum_variant().fields.iter().map(|f| {

0 commit comments

Comments
 (0)