mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-31 22:41:50 +00:00
rustc_metadata: Add constructors to module children at encoding time
instead of decoding time.
This commit is contained in:
parent
c6bd7e21c6
commit
2283a5e65b
@ -773,7 +773,15 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn opt_item_name(self, item_index: DefIndex) -> Option<Symbol> {
|
fn opt_item_name(self, item_index: DefIndex) -> Option<Symbol> {
|
||||||
self.def_key(item_index).disambiguated_data.data.get_opt_name()
|
let def_key = self.def_key(item_index);
|
||||||
|
def_key.disambiguated_data.data.get_opt_name().or_else(|| {
|
||||||
|
if def_key.disambiguated_data.data == DefPathData::Ctor {
|
||||||
|
let parent_index = def_key.parent.expect("no parent for a constructor");
|
||||||
|
self.def_key(parent_index).disambiguated_data.data.get_opt_name()
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn item_name(self, item_index: DefIndex) -> Symbol {
|
fn item_name(self, item_index: DefIndex) -> Symbol {
|
||||||
@ -905,7 +913,13 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||||||
.get(self, item_id)
|
.get(self, item_id)
|
||||||
.unwrap_or_else(LazyArray::empty)
|
.unwrap_or_else(LazyArray::empty)
|
||||||
.decode(self)
|
.decode(self)
|
||||||
.map(|index| self.get_variant(&self.def_kind(index), index, did))
|
.filter_map(|index| {
|
||||||
|
let kind = self.def_kind(index);
|
||||||
|
match kind {
|
||||||
|
DefKind::Ctor(..) => None,
|
||||||
|
_ => Some(self.get_variant(&kind, index, did)),
|
||||||
|
}
|
||||||
|
})
|
||||||
.collect()
|
.collect()
|
||||||
} else {
|
} else {
|
||||||
std::iter::once(self.get_variant(&kind, item_id, did)).collect()
|
std::iter::once(self.get_variant(&kind, item_id, did)).collect()
|
||||||
@ -1029,51 +1043,28 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||||||
|
|
||||||
callback(ModChild { ident, res, vis, span, macro_rules });
|
callback(ModChild { ident, res, vis, span, macro_rules });
|
||||||
|
|
||||||
// For non-re-export structs and variants add their constructors to children.
|
// For non-reexport variants add their fictive constructors to children.
|
||||||
// Re-export lists automatically contain constructors when necessary.
|
// Braced variants, unlike structs, generate unusable names in value namespace,
|
||||||
match kind {
|
// they are reserved for possible future use. It's ok to use the variant's id as
|
||||||
DefKind::Struct => {
|
// a ctor id since an error will be reported on any use of such resolution anyway.
|
||||||
if let Some((ctor_def_id, ctor_kind)) =
|
// Reexport lists automatically contain such constructors when necessary.
|
||||||
self.get_ctor_def_id_and_kind(child_index)
|
if kind == DefKind::Variant && self.get_ctor_def_id_and_kind(child_index).is_none()
|
||||||
{
|
{
|
||||||
let ctor_res =
|
let ctor_res =
|
||||||
Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id);
|
Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fictive), def_id);
|
||||||
let vis = self.get_visibility(ctor_def_id.index);
|
let mut vis = vis;
|
||||||
callback(ModChild {
|
if vis.is_public() {
|
||||||
ident,
|
|
||||||
res: ctor_res,
|
|
||||||
vis,
|
|
||||||
span,
|
|
||||||
macro_rules: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DefKind::Variant => {
|
|
||||||
// Braced variants, unlike structs, generate unusable names in
|
|
||||||
// value namespace, they are reserved for possible future use.
|
|
||||||
// It's ok to use the variant's id as a ctor id since an
|
|
||||||
// error will be reported on any use of such resolution anyway.
|
|
||||||
let (ctor_def_id, ctor_kind) = self
|
|
||||||
.get_ctor_def_id_and_kind(child_index)
|
|
||||||
.unwrap_or((def_id, CtorKind::Fictive));
|
|
||||||
let ctor_res =
|
|
||||||
Res::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id);
|
|
||||||
let mut vis = self.get_visibility(ctor_def_id.index);
|
|
||||||
if ctor_def_id == def_id && vis.is_public() {
|
|
||||||
// For non-exhaustive variants lower the constructor visibility to
|
// For non-exhaustive variants lower the constructor visibility to
|
||||||
// within the crate. We only need this for fictive constructors,
|
// within the crate. We only need this for fictive constructors,
|
||||||
// for other constructors correct visibilities
|
// for other constructors correct visibilities
|
||||||
// were already encoded in metadata.
|
// were already encoded in metadata.
|
||||||
let mut attrs = self.get_item_attrs(def_id.index, sess);
|
let mut attrs = self.get_item_attrs(def_id.index, sess);
|
||||||
if attrs.any(|item| item.has_name(sym::non_exhaustive)) {
|
if attrs.any(|item| item.has_name(sym::non_exhaustive)) {
|
||||||
let crate_def_id = self.local_def_id(CRATE_DEF_INDEX);
|
vis = ty::Visibility::Restricted(self.local_def_id(CRATE_DEF_INDEX));
|
||||||
vis = ty::Visibility::Restricted(crate_def_id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
callback(ModChild { ident, res: ctor_res, vis, span, macro_rules: false });
|
callback(ModChild { ident, res: ctor_res, vis, span, macro_rules: false });
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1335,6 +1335,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||||||
// Only encode named non-reexport children, reexports are encoded
|
// Only encode named non-reexport children, reexports are encoded
|
||||||
// separately and unnamed items are not used by name resolution.
|
// separately and unnamed items are not used by name resolution.
|
||||||
hir::ItemKind::ExternCrate(..) => continue,
|
hir::ItemKind::ExternCrate(..) => continue,
|
||||||
|
hir::ItemKind::Struct(ref vdata, _) => {
|
||||||
|
yield item_id.def_id.def_id.local_def_index;
|
||||||
|
// Encode constructors which take a separate slot in value namespace.
|
||||||
|
if let Some(ctor_hir_id) = vdata.ctor_hir_id() {
|
||||||
|
yield tcx.hir().local_def_id(ctor_hir_id).local_def_index;
|
||||||
|
}
|
||||||
|
}
|
||||||
_ if tcx.def_key(item_id.def_id.to_def_id()).get_opt_name().is_some() => {
|
_ if tcx.def_key(item_id.def_id.to_def_id()).get_opt_name().is_some() => {
|
||||||
yield item_id.def_id.def_id.local_def_index;
|
yield item_id.def_id.def_id.local_def_index;
|
||||||
}
|
}
|
||||||
@ -1646,12 +1653,17 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||||||
};
|
};
|
||||||
// FIXME(eddyb) there should be a nicer way to do this.
|
// FIXME(eddyb) there should be a nicer way to do this.
|
||||||
match item.kind {
|
match item.kind {
|
||||||
hir::ItemKind::Enum(..) => record_array!(self.tables.children[def_id] <-
|
hir::ItemKind::Enum(..) => {
|
||||||
self.tcx.adt_def(def_id).variants().iter().map(|v| {
|
record_array!(self.tables.children[def_id] <- iter::from_generator(||
|
||||||
assert!(v.def_id.is_local());
|
for variant in tcx.adt_def(def_id).variants() {
|
||||||
v.def_id.index
|
yield variant.def_id.index;
|
||||||
})
|
// Encode constructors which take a separate slot in value namespace.
|
||||||
),
|
if let Some(ctor_def_id) = variant.ctor_def_id {
|
||||||
|
yield ctor_def_id.index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
))
|
||||||
|
}
|
||||||
hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => {
|
hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => {
|
||||||
record_array!(self.tables.children[def_id] <-
|
record_array!(self.tables.children[def_id] <-
|
||||||
self.tcx.adt_def(def_id).non_enum_variant().fields.iter().map(|f| {
|
self.tcx.adt_def(def_id).non_enum_variant().fields.iter().map(|f| {
|
||||||
|
Loading…
Reference in New Issue
Block a user