rustc_metadata: Encode/decode some LazyArrays without an Option

Also add asserts to decoding `LazyArray`s with `Option`
This commit is contained in:
Vadim Petrochenkov 2023-02-05 16:28:12 +04:00
parent eb5f2d3980
commit c60cc43985
5 changed files with 45 additions and 35 deletions

View File

@ -864,7 +864,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.tables
.children
.get(self, index)
.unwrap_or_else(LazyArray::default)
.expect("fields are not encoded for a variant")
.decode(self)
.map(|index| ty::FieldDef {
did: self.local_def_id(index),
@ -896,7 +896,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.tables
.children
.get(self, item_id)
.unwrap_or_else(LazyArray::default)
.expect("variants are not encoded for an enum")
.decode(self)
.filter_map(|index| {
let kind = self.def_kind(index);
@ -1045,7 +1045,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.tables
.fn_arg_names
.get(self, id)
.unwrap_or_else(LazyArray::default)
.expect("argument names not encoded for a function")
.decode((self, sess))
.nth(0)
.map_or(false, |ident| ident.name == kw::SelfLower)
@ -1060,7 +1060,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.tables
.children
.get(self, id)
.unwrap_or_else(LazyArray::default)
.expect("associated items not encoded for an item")
.decode((self, sess))
.map(move |child_index| self.local_def_id(child_index))
}
@ -1068,13 +1068,12 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
fn get_associated_item(self, id: DefIndex, sess: &'a Session) -> ty::AssocItem {
let name = self.item_name(id);
let kind = match self.def_kind(id) {
DefKind::AssocConst => ty::AssocKind::Const,
DefKind::AssocFn => ty::AssocKind::Fn,
DefKind::AssocTy => ty::AssocKind::Type,
let (kind, has_self) = match self.def_kind(id) {
DefKind::AssocConst => (ty::AssocKind::Const, false),
DefKind::AssocFn => (ty::AssocKind::Fn, self.get_fn_has_self_parameter(id, sess)),
DefKind::AssocTy => (ty::AssocKind::Type, false),
_ => bug!("cannot get associated-item of `{:?}`", self.def_key(id)),
};
let has_self = self.get_fn_has_self_parameter(id, sess);
let container = self.root.tables.assoc_container.get(self, id).unwrap();
ty::AssocItem {
@ -1131,7 +1130,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.tables
.children
.get(self, id)
.unwrap_or_else(LazyArray::default)
.expect("fields not encoded for a struct")
.decode(self)
.map(move |index| respan(self.get_span(index, sess), self.item_name(index)))
}
@ -1144,7 +1143,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.tables
.children
.get(self, id)
.unwrap_or_else(LazyArray::default)
.expect("fields not encoded for a struct")
.decode(self)
.map(move |field_index| self.get_visibility(field_index))
}
@ -1159,7 +1158,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.tables
.inherent_impls
.get(self, id)
.unwrap_or_else(LazyArray::default)
.decode(self)
.map(|index| self.local_def_id(index)),
)
@ -1174,7 +1172,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.tables
.inherent_impls
.get(self, ty_index)
.unwrap_or_else(LazyArray::default)
.decode(self)
.map(move |impl_index| (ty_def_id, self.local_def_id(impl_index)))
})

View File

@ -1,6 +1,7 @@
use crate::creader::{CStore, LoadedMacro};
use crate::foreign_modules;
use crate::native_libs;
use crate::rmeta::table::IsDefault;
use crate::rmeta::AttrFlags;
use rustc_ast as ast;
@ -88,6 +89,14 @@ macro_rules! provide_one {
}
}
};
($tcx:ident, $def_id:ident, $other:ident, $cdata:ident, $name:ident => { table_defaulted_array }) => {
provide_one! {
$tcx, $def_id, $other, $cdata, $name => {
let lazy = $cdata.root.tables.$name.get($cdata, $def_id.index);
if lazy.is_default() { &[] } else { $tcx.arena.alloc_from_iter(lazy.decode(($cdata, $tcx))) }
}
}
};
($tcx:ident, $def_id:ident, $other:ident, $cdata:ident, $name:ident => { table_direct }) => {
provide_one! {
$tcx, $def_id, $other, $cdata, $name => {
@ -187,10 +196,10 @@ impl IntoArgs for (CrateNum, SimplifiedType) {
}
provide! { tcx, def_id, other, cdata,
explicit_item_bounds => { table }
explicit_item_bounds => { table_defaulted_array }
explicit_predicates_of => { table }
generics_of => { table }
inferred_outlives_of => { table }
inferred_outlives_of => { table_defaulted_array }
super_predicates_of => { table }
type_of => { table }
variances_of => { table }

View File

@ -389,6 +389,16 @@ macro_rules! record_array {
}};
}
macro_rules! record_defaulted_array {
($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{
{
let value = $value;
let lazy = $self.lazy_array(value);
$self.$tables.$table.set($def_id.index, lazy);
}
}};
}
impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
fn emit_lazy_distance(&mut self, position: NonZeroUsize) {
let pos = position.get();
@ -1190,9 +1200,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
record!(self.tables.generics_of[def_id] <- g);
record!(self.tables.explicit_predicates_of[def_id] <- self.tcx.explicit_predicates_of(def_id));
let inferred_outlives = self.tcx.inferred_outlives_of(def_id);
if !inferred_outlives.is_empty() {
record_array!(self.tables.inferred_outlives_of[def_id] <- inferred_outlives);
}
record_defaulted_array!(self.tables.inferred_outlives_of[def_id] <- inferred_outlives);
}
if should_encode_type(tcx, local_id, def_kind) {
record!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id));
@ -1213,15 +1221,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
record!(self.tables.trait_impl_trait_tys[def_id] <- table);
}
}
let inherent_impls = tcx.with_stable_hashing_context(|hcx| {
tcx.crate_inherent_impls(()).inherent_impls.to_sorted(&hcx, true)
});
for (def_id, implementations) in inherent_impls {
if implementations.is_empty() {
continue;
}
record_array!(self.tables.inherent_impls[def_id.to_def_id()] <- implementations.iter().map(|&def_id| {
for (def_id, impls) in inherent_impls {
record_defaulted_array!(self.tables.inherent_impls[def_id.to_def_id()] <- impls.iter().map(|def_id| {
assert!(def_id.is_local());
def_id.index
}));
@ -1330,9 +1335,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
fn encode_explicit_item_bounds(&mut self, def_id: DefId) {
debug!("EncodeContext::encode_explicit_item_bounds({:?})", def_id);
let bounds = self.tcx.explicit_item_bounds(def_id);
if !bounds.is_empty() {
record_array!(self.tables.explicit_item_bounds[def_id] <- bounds);
}
record_defaulted_array!(self.tables.explicit_item_bounds[def_id] <- bounds);
}
fn encode_info_for_trait_item(&mut self, def_id: DefId) {

View File

@ -350,6 +350,9 @@ define_tables! {
is_macro_rules: Table<DefIndex, bool>,
is_type_alias_impl_trait: Table<DefIndex, bool>,
attr_flags: Table<DefIndex, AttrFlags>,
explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Predicate<'static>, Span)>>,
inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
- optional:
attributes: Table<DefIndex, LazyArray<ast::Attribute>>,
@ -362,12 +365,8 @@ define_tables! {
lookup_const_stability: Table<DefIndex, LazyValue<attr::ConstStability>>,
lookup_default_body_stability: Table<DefIndex, LazyValue<attr::DefaultBodyStability>>,
lookup_deprecation_entry: Table<DefIndex, LazyValue<attr::Deprecation>>,
// As an optimization, a missing entry indicates an empty `&[]`.
explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Predicate<'static>, Span)>>,
explicit_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>,
generics_of: Table<DefIndex, LazyValue<ty::Generics>>,
// As an optimization, a missing entry indicates an empty `&[]`.
inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
super_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>,
type_of: Table<DefIndex, LazyValue<Ty<'static>>>,
variances_of: Table<DefIndex, LazyArray<ty::Variance>>,
@ -395,7 +394,6 @@ define_tables! {
generator_kind: Table<DefIndex, LazyValue<hir::GeneratorKind>>,
trait_def: Table<DefIndex, LazyValue<ty::TraitDef>>,
trait_item_def_id: Table<DefIndex, RawDefId>,
inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
expn_that_defined: Table<DefIndex, LazyValue<ExpnId>>,
unused_generic_params: Table<DefIndex, LazyValue<UnusedGenericParams>>,
params_in_repr: Table<DefIndex, LazyValue<BitSet<u32>>>,

View File

@ -22,14 +22,17 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] {
hir::ItemKind::Impl(ref impl_) => tcx.arena.alloc_from_iter(
impl_.items.iter().map(|impl_item_ref| impl_item_ref.id.owner_id.to_def_id()),
),
hir::ItemKind::TraitAlias(..) => &[],
_ => span_bug!(item.span, "associated_item_def_ids: not impl or trait"),
}
}
fn associated_items(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItems<'_> {
let items = tcx.associated_item_def_ids(def_id).iter().map(|did| tcx.associated_item(*did));
ty::AssocItems::new(items)
if tcx.is_trait_alias(def_id) {
ty::AssocItems::new(Vec::new())
} else {
let items = tcx.associated_item_def_ids(def_id).iter().map(|did| tcx.associated_item(*did));
ty::AssocItems::new(items)
}
}
fn impl_item_implementor_ids(tcx: TyCtxt<'_>, impl_id: DefId) -> FxHashMap<DefId, DefId> {