+use crate::errors::{FailCreateFileEncoder, FailSeekFile, FailWriteFile};
use crate::rmeta::def_path_hash_map::DefPathHashMapRef;
use crate::rmeta::table::TableBuilder;
use crate::rmeta::*;
use rustc_hir::definitions::DefPathData;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::lang_items;
-use rustc_hir::{AnonConst, GenericParamKind};
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::dependency_format::Linkage;
use rustc_middle::middle::exported_symbols::{
}
}
+fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) -> bool {
+ match def_kind {
+ DefKind::Struct
+ | DefKind::Union
+ | DefKind::Enum
+ | DefKind::Variant
+ | DefKind::Ctor(..)
+ | DefKind::Field
+ | DefKind::Fn
+ | DefKind::Const
+ | DefKind::Static(..)
+ | DefKind::TyAlias
+ | DefKind::OpaqueTy
+ | DefKind::ForeignTy
+ | DefKind::Impl
+ | DefKind::AssocFn
+ | DefKind::AssocConst
+ | DefKind::Closure
+ | DefKind::Generator
+ | DefKind::ConstParam
+ | DefKind::AnonConst
+ | DefKind::InlineConst => true,
+
+ DefKind::AssocTy => {
+ let assoc_item = tcx.associated_item(def_id);
+ match assoc_item.container {
+ ty::AssocItemContainer::ImplContainer => true,
+ ty::AssocItemContainer::TraitContainer => assoc_item.defaultness(tcx).has_value(),
+ }
+ }
+ DefKind::TyParam => {
+ let hir::Node::GenericParam(param) = tcx.hir().get_by_def_id(def_id) else { bug!() };
+ let hir::GenericParamKind::Type { default, .. } = param.kind else { bug!() };
+ default.is_some()
+ }
+
+ DefKind::Trait
+ | DefKind::TraitAlias
+ | DefKind::Mod
+ | DefKind::ForeignMod
+ | DefKind::Macro(..)
+ | DefKind::Use
+ | DefKind::LifetimeParam
+ | DefKind::GlobalAsm
+ | DefKind::ExternCrate => false,
+ }
+}
+
+fn should_encode_const(def_kind: DefKind) -> bool {
+ match def_kind {
+ DefKind::Const | DefKind::AssocConst | DefKind::AnonConst => true,
+
+ DefKind::Struct
+ | DefKind::Union
+ | DefKind::Enum
+ | DefKind::Variant
+ | DefKind::Ctor(..)
+ | DefKind::Field
+ | DefKind::Fn
+ | DefKind::Static(..)
+ | DefKind::TyAlias
+ | DefKind::OpaqueTy
+ | DefKind::ForeignTy
+ | DefKind::Impl
+ | DefKind::AssocFn
+ | DefKind::Closure
+ | DefKind::Generator
+ | DefKind::ConstParam
+ | DefKind::InlineConst
+ | DefKind::AssocTy
+ | DefKind::TyParam
+ | DefKind::Trait
+ | DefKind::TraitAlias
+ | DefKind::Mod
+ | DefKind::ForeignMod
+ | DefKind::Macro(..)
+ | DefKind::Use
+ | DefKind::LifetimeParam
+ | DefKind::GlobalAsm
+ | DefKind::ExternCrate => false,
+ }
+}
+
impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
fn encode_attrs(&mut self, def_id: LocalDefId) {
let mut attrs = self
let def_kind = tcx.opt_def_kind(local_id);
let Some(def_kind) = def_kind else { continue };
self.tables.opt_def_kind.set(def_id.index, def_kind);
- record!(self.tables.def_span[def_id] <- tcx.def_span(def_id));
+ let def_span = tcx.def_span(local_id);
+ record!(self.tables.def_span[def_id] <- def_span);
self.encode_attrs(local_id);
record!(self.tables.expn_that_defined[def_id] <- self.tcx.expn_that_defined(def_id));
if let Some(ident_span) = tcx.def_ident_span(def_id) {
record_array!(self.tables.inferred_outlives_of[def_id] <- inferred_outlives);
}
}
- if let DefKind::TyParam | DefKind::ConstParam = def_kind {
- if let Some(default) = self.tcx.object_lifetime_default(def_id) {
- record!(self.tables.object_lifetime_default[def_id] <- default);
- }
+ if should_encode_type(tcx, local_id, def_kind) {
+ record!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id));
+ }
+ if let DefKind::TyParam = def_kind {
+ let default = self.tcx.object_lifetime_default(def_id);
+ record!(self.tables.object_lifetime_default[def_id] <- default);
}
if let DefKind::Trait | DefKind::TraitAlias = def_kind {
record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id));
}
}
- fn encode_item_type(&mut self, def_id: DefId) {
- debug!("EncodeContext::encode_item_type({:?})", def_id);
- record!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id));
- }
-
fn encode_enum_variant_info(&mut self, def: ty::AdtDef<'tcx>, index: VariantIdx) {
let tcx = self.tcx;
let variant = &def.variant(index);
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
};
- record!(self.tables.kind[def_id] <- EntryKind::Variant(self.lazy(data)));
+ record!(self.tables.variant_data[def_id] <- data);
self.tables.constness.set(def_id.index, hir::Constness::Const);
record_array!(self.tables.children[def_id] <- variant.fields.iter().map(|f| {
assert!(f.did.is_local());
f.did.index
}));
- self.encode_item_type(def_id);
if variant.ctor_kind == CtorKind::Fn {
// FIXME(eddyb) encode signature only in `encode_enum_variant_ctor`.
if let Some(ctor_def_id) = variant.ctor_def_id {
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
};
- record!(self.tables.kind[def_id] <- EntryKind::Variant(self.lazy(data)));
+ record!(self.tables.variant_data[def_id] <- data);
self.tables.constness.set(def_id.index, hir::Constness::Const);
- self.encode_item_type(def_id);
if variant.ctor_kind == CtorKind::Fn {
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
}
// code uses it). However, we skip encoding anything relating to child
// items - we encode information about proc-macros later on.
let reexports = if !self.is_proc_macro {
- match tcx.module_reexports(local_def_id) {
- Some(exports) => self.lazy_array(exports),
- _ => LazyArray::empty(),
- }
+ tcx.module_reexports(local_def_id).unwrap_or(&[])
} else {
- LazyArray::empty()
+ &[]
};
- record!(self.tables.kind[def_id] <- EntryKind::Mod(reexports));
+ record_array!(self.tables.module_reexports[def_id] <- reexports);
if self.is_proc_macro {
// Encode this here because we don't do it in encode_def_ids.
record!(self.tables.expn_that_defined[def_id] <- tcx.expn_that_defined(local_def_id));
}
}
- fn encode_field(
- &mut self,
- adt_def: ty::AdtDef<'tcx>,
- variant_index: VariantIdx,
- field_index: usize,
- ) {
- let variant = &adt_def.variant(variant_index);
- let field = &variant.fields[field_index];
-
- let def_id = field.did;
- debug!("EncodeContext::encode_field({:?})", def_id);
-
- record!(self.tables.kind[def_id] <- EntryKind::Field);
- self.encode_item_type(def_id);
- }
-
fn encode_struct_ctor(&mut self, adt_def: ty::AdtDef<'tcx>, def_id: DefId) {
debug!("EncodeContext::encode_struct_ctor({:?})", def_id);
let tcx = self.tcx;
};
record!(self.tables.repr_options[def_id] <- adt_def.repr());
+ record!(self.tables.variant_data[def_id] <- data);
self.tables.constness.set(def_id.index, hir::Constness::Const);
- record!(self.tables.kind[def_id] <- EntryKind::Struct(self.lazy(data)));
- self.encode_item_type(def_id);
if variant.ctor_kind == CtorKind::Fn {
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
}
let ast_item = tcx.hir().expect_trait_item(def_id.expect_local());
self.tables.impl_defaultness.set(def_id.index, ast_item.defaultness);
let trait_item = tcx.associated_item(def_id);
+ self.tables.assoc_container.set(def_id.index, trait_item.container);
match trait_item.kind {
- ty::AssocKind::Const => {
- let rendered = rustc_hir_pretty::to_string(
- &(&self.tcx.hir() as &dyn intravisit::Map<'_>),
- |s| s.print_trait_item(ast_item),
- );
-
- record!(self.tables.kind[def_id] <- EntryKind::AssocConst(ty::AssocItemContainer::TraitContainer));
- record!(self.tables.mir_const_qualif[def_id] <- mir::ConstQualifs::default());
- record!(self.tables.rendered_const[def_id] <- rendered);
- }
+ ty::AssocKind::Const => {}
ty::AssocKind::Fn => {
let hir::TraitItemKind::Fn(m_sig, m) = &ast_item.kind else { bug!() };
match *m {
};
self.tables.asyncness.set(def_id.index, m_sig.header.asyncness);
self.tables.constness.set(def_id.index, hir::Constness::NotConst);
- record!(self.tables.kind[def_id] <- EntryKind::AssocFn {
- container: ty::AssocItemContainer::TraitContainer,
- has_self: trait_item.fn_has_self_parameter,
- });
}
ty::AssocKind::Type => {
self.encode_explicit_item_bounds(def_id);
- record!(self.tables.kind[def_id] <- EntryKind::AssocType(ty::AssocItemContainer::TraitContainer));
- }
- }
- match trait_item.kind {
- ty::AssocKind::Const | ty::AssocKind::Fn => {
- self.encode_item_type(def_id);
- }
- ty::AssocKind::Type => {
- if ast_item.defaultness.has_value() {
- self.encode_item_type(def_id);
- }
}
}
if trait_item.kind == ty::AssocKind::Fn {
let ast_item = self.tcx.hir().expect_impl_item(def_id.expect_local());
self.tables.impl_defaultness.set(def_id.index, ast_item.defaultness);
let impl_item = self.tcx.associated_item(def_id);
+ self.tables.assoc_container.set(def_id.index, impl_item.container);
match impl_item.kind {
- ty::AssocKind::Const => {
- if let hir::ImplItemKind::Const(_, body_id) = ast_item.kind {
- let qualifs = self.tcx.at(ast_item.span).mir_const_qualif(def_id);
- let const_data = self.encode_rendered_const_for_body(body_id);
-
- record!(self.tables.kind[def_id] <- EntryKind::AssocConst(ty::AssocItemContainer::ImplContainer));
- record!(self.tables.mir_const_qualif[def_id] <- qualifs);
- record!(self.tables.rendered_const[def_id] <- const_data);
- } else {
- bug!()
- }
- }
ty::AssocKind::Fn => {
let hir::ImplItemKind::Fn(ref sig, body) = ast_item.kind else { bug!() };
self.tables.asyncness.set(def_id.index, sig.header.asyncness);
hir::Constness::NotConst
};
self.tables.constness.set(def_id.index, constness);
- record!(self.tables.kind[def_id] <- EntryKind::AssocFn {
- container: ty::AssocItemContainer::ImplContainer,
- has_self: impl_item.fn_has_self_parameter,
- });
- }
- ty::AssocKind::Type => {
- record!(self.tables.kind[def_id] <- EntryKind::AssocType(ty::AssocItemContainer::ImplContainer));
}
+ ty::AssocKind::Const | ty::AssocKind::Type => {}
}
- self.encode_item_type(def_id);
if let Some(trait_item_def_id) = impl_item.trait_item_def_id {
self.tables.trait_item_def_id.set(def_id.index, trait_item_def_id.into());
}
return;
}
- let keys_and_jobs = self
- .tcx
- .mir_keys(())
- .iter()
- .filter_map(|&def_id| {
- let (encode_const, encode_opt) = should_encode_mir(self.tcx, def_id);
- if encode_const || encode_opt {
- Some((def_id, encode_const, encode_opt))
- } else {
- None
- }
- })
- .collect::<Vec<_>>();
- for (def_id, encode_const, encode_opt) in keys_and_jobs.into_iter() {
+ let tcx = self.tcx;
+
+ let keys_and_jobs = tcx.mir_keys(()).iter().filter_map(|&def_id| {
+ let (encode_const, encode_opt) = should_encode_mir(tcx, def_id);
+ if encode_const || encode_opt { Some((def_id, encode_const, encode_opt)) } else { None }
+ });
+ for (def_id, encode_const, encode_opt) in keys_and_jobs {
debug_assert!(encode_const || encode_opt);
debug!("EntryBuilder::encode_mir({:?})", def_id);
if encode_opt {
- record!(self.tables.optimized_mir[def_id.to_def_id()] <- self.tcx.optimized_mir(def_id));
+ record!(self.tables.optimized_mir[def_id.to_def_id()] <- tcx.optimized_mir(def_id));
}
if encode_const {
- record!(self.tables.mir_for_ctfe[def_id.to_def_id()] <- self.tcx.mir_for_ctfe(def_id));
+ record!(self.tables.mir_for_ctfe[def_id.to_def_id()] <- tcx.mir_for_ctfe(def_id));
// FIXME(generic_const_exprs): this feels wrong to have in `encode_mir`
- let abstract_const = self.tcx.thir_abstract_const(def_id);
+ let abstract_const = tcx.thir_abstract_const(def_id);
if let Ok(Some(abstract_const)) = abstract_const {
record!(self.tables.thir_abstract_const[def_id.to_def_id()] <- abstract_const);
}
+
+ if should_encode_const(tcx.def_kind(def_id)) {
+ let qualifs = tcx.mir_const_qualif(def_id);
+ record!(self.tables.mir_const_qualif[def_id.to_def_id()] <- qualifs);
+ let body_id = tcx.hir().maybe_body_owned_by(def_id);
+ if let Some(body_id) = body_id {
+ let const_data = self.encode_rendered_const_for_body(body_id);
+ record!(self.tables.rendered_const[def_id.to_def_id()] <- const_data);
+ }
+ }
}
- record!(self.tables.promoted_mir[def_id.to_def_id()] <- self.tcx.promoted_mir(def_id));
+ record!(self.tables.promoted_mir[def_id.to_def_id()] <- tcx.promoted_mir(def_id));
let instance =
ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id.to_def_id()));
- let unused = self.tcx.unused_generic_params(instance);
+ let unused = tcx.unused_generic_params(instance);
if !unused.is_empty() {
record!(self.tables.unused_generic_params[def_id.to_def_id()] <- unused);
}
debug!("EncodeContext::encode_info_for_item({:?})", def_id);
- let entry_kind = match item.kind {
- hir::ItemKind::Static(..) => EntryKind::Static,
- hir::ItemKind::Const(_, body_id) => {
- let qualifs = self.tcx.at(item.span).mir_const_qualif(def_id);
- let const_data = self.encode_rendered_const_for_body(body_id);
- record!(self.tables.mir_const_qualif[def_id] <- qualifs);
- record!(self.tables.rendered_const[def_id] <- const_data);
- EntryKind::Const
- }
+ match item.kind {
hir::ItemKind::Fn(ref sig, .., body) => {
self.tables.asyncness.set(def_id.index, sig.header.asyncness);
record_array!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body));
self.tables.constness.set(def_id.index, sig.header.constness);
- EntryKind::Fn
}
hir::ItemKind::Macro(ref macro_def, _) => {
- EntryKind::MacroDef(self.lazy(&*macro_def.body), macro_def.macro_rules)
+ if macro_def.macro_rules {
+ self.tables.macro_rules.set(def_id.index, ());
+ }
+ record!(self.tables.macro_definition[def_id] <- &*macro_def.body);
}
hir::ItemKind::Mod(ref m) => {
return self.encode_info_for_mod(item.def_id, m);
}
- hir::ItemKind::ForeignMod { .. } => EntryKind::ForeignMod,
- hir::ItemKind::GlobalAsm(..) => EntryKind::GlobalAsm,
- hir::ItemKind::TyAlias(..) => EntryKind::Type,
hir::ItemKind::OpaqueTy(..) => {
self.encode_explicit_item_bounds(def_id);
- EntryKind::OpaqueTy
}
hir::ItemKind::Enum(..) => {
let adt_def = self.tcx.adt_def(def_id);
record!(self.tables.repr_options[def_id] <- adt_def.repr());
- EntryKind::Enum
}
hir::ItemKind::Struct(ref struct_def, _) => {
let adt_def = self.tcx.adt_def(def_id);
.map(|ctor_hir_id| self.tcx.hir().local_def_id(ctor_hir_id).local_def_index);
let variant = adt_def.non_enum_variant();
- EntryKind::Struct(self.lazy(VariantData {
+ record!(self.tables.variant_data[def_id] <- VariantData {
ctor_kind: variant.ctor_kind,
discr: variant.discr,
ctor,
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
- }))
+ });
}
hir::ItemKind::Union(..) => {
let adt_def = self.tcx.adt_def(def_id);
record!(self.tables.repr_options[def_id] <- adt_def.repr());
let variant = adt_def.non_enum_variant();
- EntryKind::Union(self.lazy(VariantData {
+ record!(self.tables.variant_data[def_id] <- VariantData {
ctor_kind: variant.ctor_kind,
discr: variant.discr,
ctor: None,
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
- }))
+ });
}
hir::ItemKind::Impl(hir::Impl { defaultness, constness, .. }) => {
self.tables.impl_defaultness.set(def_id.index, *defaultness);
let polarity = self.tcx.impl_polarity(def_id);
self.tables.impl_polarity.set(def_id.index, polarity);
-
- EntryKind::Impl
}
hir::ItemKind::Trait(..) => {
let trait_def = self.tcx.trait_def(def_id);
record!(self.tables.trait_def[def_id] <- trait_def);
-
- EntryKind::Trait
}
hir::ItemKind::TraitAlias(..) => {
let trait_def = self.tcx.trait_def(def_id);
record!(self.tables.trait_def[def_id] <- trait_def);
-
- EntryKind::TraitAlias
}
hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) => {
bug!("cannot encode info for item {:?}", item)
}
+ hir::ItemKind::Static(..)
+ | hir::ItemKind::Const(..)
+ | hir::ItemKind::ForeignMod { .. }
+ | hir::ItemKind::GlobalAsm(..)
+ | hir::ItemKind::TyAlias(..) => {}
};
- record!(self.tables.kind[def_id] <- entry_kind);
// FIXME(eddyb) there should be a nicer way to do this.
match item.kind {
hir::ItemKind::Enum(..) => record_array!(self.tables.children[def_id] <-
}
_ => {}
}
- match item.kind {
- hir::ItemKind::Static(..)
- | hir::ItemKind::Const(..)
- | hir::ItemKind::Fn(..)
- | hir::ItemKind::TyAlias(..)
- | hir::ItemKind::OpaqueTy(..)
- | hir::ItemKind::Enum(..)
- | hir::ItemKind::Struct(..)
- | hir::ItemKind::Union(..)
- | hir::ItemKind::Impl { .. } => self.encode_item_type(def_id),
- _ => {}
- }
if let hir::ItemKind::Fn(..) = item.kind {
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
if tcx.is_intrinsic(def_id) {
record!(self.tables.impl_trait_ref[def_id] <- trait_ref);
}
}
- }
+ // In some cases, along with the item itself, we also
+ // encode some sub-items. Usually we want some info from the item
+ // so it's easier to do that here then to wait until we would encounter
+ // normally in the visitor walk.
+ match item.kind {
+ hir::ItemKind::Enum(..) => {
+ let def = self.tcx.adt_def(item.def_id.to_def_id());
+ for (i, variant) in def.variants().iter_enumerated() {
+ self.encode_enum_variant_info(def, i);
- fn encode_info_for_generic_param(&mut self, def_id: DefId, kind: EntryKind, encode_type: bool) {
- record!(self.tables.kind[def_id] <- kind);
- if encode_type {
- self.encode_item_type(def_id);
+ if let Some(_ctor_def_id) = variant.ctor_def_id {
+ self.encode_enum_variant_ctor(def, i);
+ }
+ }
+ }
+ hir::ItemKind::Struct(ref struct_def, _) => {
+ let def = self.tcx.adt_def(item.def_id.to_def_id());
+ // If the struct has a constructor, encode it.
+ if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
+ let ctor_def_id = self.tcx.hir().local_def_id(ctor_hir_id);
+ self.encode_struct_ctor(def, ctor_def_id.to_def_id());
+ }
+ }
+ hir::ItemKind::Impl { .. } => {
+ for &trait_item_def_id in
+ self.tcx.associated_item_def_ids(item.def_id.to_def_id()).iter()
+ {
+ self.encode_info_for_impl_item(trait_item_def_id);
+ }
+ }
+ hir::ItemKind::Trait(..) => {
+ for &item_def_id in self.tcx.associated_item_def_ids(item.def_id.to_def_id()).iter()
+ {
+ self.encode_info_for_trait_item(item_def_id);
+ }
+ }
+ _ => {}
}
}
ty::Generator(..) => {
let data = self.tcx.generator_kind(def_id).unwrap();
let generator_diagnostic_data = typeck_result.get_generator_diagnostic_data();
- record!(self.tables.kind[def_id.to_def_id()] <- EntryKind::Generator);
record!(self.tables.generator_kind[def_id.to_def_id()] <- data);
record!(self.tables.generator_diagnostic_data[def_id.to_def_id()] <- generator_diagnostic_data);
}
- ty::Closure(..) => {
- record!(self.tables.kind[def_id.to_def_id()] <- EntryKind::Closure);
+ ty::Closure(_, substs) => {
+ record!(self.tables.fn_sig[def_id.to_def_id()] <- substs.as_closure().sig());
}
_ => bug!("closure that is neither generator nor closure"),
}
- self.encode_item_type(def_id.to_def_id());
- if let ty::Closure(def_id, substs) = *ty.kind() {
- record!(self.tables.fn_sig[def_id] <- substs.as_closure().sig());
- }
- }
-
- fn encode_info_for_anon_const(&mut self, id: hir::HirId) {
- let def_id = self.tcx.hir().local_def_id(id);
- debug!("EncodeContext::encode_info_for_anon_const({:?})", def_id);
- let body_id = self.tcx.hir().body_owned_by(def_id);
- let const_data = self.encode_rendered_const_for_body(body_id);
- let qualifs = self.tcx.mir_const_qualif(def_id);
-
- record!(self.tables.kind[def_id.to_def_id()] <- EntryKind::AnonConst);
- record!(self.tables.mir_const_qualif[def_id.to_def_id()] <- qualifs);
- record!(self.tables.rendered_const[def_id.to_def_id()] <- const_data);
- self.encode_item_type(def_id.to_def_id());
}
fn encode_native_libraries(&mut self) -> LazyArray<NativeLib> {
let def_id = id.to_def_id();
self.tables.opt_def_kind.set(def_id.index, DefKind::Macro(macro_kind));
- record!(self.tables.kind[def_id] <- EntryKind::ProcMacro(macro_kind));
+ self.tables.proc_macro.set(def_id.index, macro_kind);
self.encode_attrs(id);
record!(self.tables.def_keys[def_id] <- def_key);
record!(self.tables.def_ident_span[def_id] <- span);
hir::Constness::NotConst
};
self.tables.constness.set(def_id.index, constness);
- record!(self.tables.kind[def_id] <- EntryKind::ForeignFn);
- }
- hir::ForeignItemKind::Static(..) => {
- record!(self.tables.kind[def_id] <- EntryKind::ForeignStatic);
- }
- hir::ForeignItemKind::Type => {
- record!(self.tables.kind[def_id] <- EntryKind::ForeignType);
+ record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
}
+ hir::ForeignItemKind::Static(..) | hir::ForeignItemKind::Type => {}
}
- self.encode_item_type(def_id);
if let hir::ForeignItemKind::Fn(..) = nitem.kind {
- record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
if tcx.is_intrinsic(def_id) {
self.tables.is_intrinsic.set(def_id.index, ());
}
intravisit::walk_expr(self, ex);
self.encode_info_for_expr(ex);
}
- fn visit_anon_const(&mut self, c: &'tcx AnonConst) {
- intravisit::walk_anon_const(self, c);
- self.encode_info_for_anon_const(c.hir_id);
- }
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
intravisit::walk_item(self, item);
match item.kind {
hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) => {} // ignore these
_ => self.encode_info_for_item(item.def_id.to_def_id(), item),
}
- self.encode_addl_info_for_item(item);
}
fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem<'tcx>) {
intravisit::walk_foreign_item(self, ni);
}
impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
- fn encode_fields(&mut self, adt_def: ty::AdtDef<'tcx>) {
- for (variant_index, variant) in adt_def.variants().iter_enumerated() {
- for (field_index, _field) in variant.fields.iter().enumerate() {
- self.encode_field(adt_def, variant_index, field_index);
- }
- }
- }
-
fn encode_info_for_generics(&mut self, generics: &hir::Generics<'tcx>) {
for param in generics.params {
let def_id = self.tcx.hir().local_def_id(param.hir_id);
match param.kind {
- GenericParamKind::Lifetime { .. } => continue,
- GenericParamKind::Type { default, .. } => {
- self.encode_info_for_generic_param(
- def_id.to_def_id(),
- EntryKind::TypeParam,
- default.is_some(),
- );
- }
- GenericParamKind::Const { ref default, .. } => {
+ hir::GenericParamKind::Lifetime { .. } | hir::GenericParamKind::Type { .. } => {}
+ hir::GenericParamKind::Const { ref default, .. } => {
let def_id = def_id.to_def_id();
- self.encode_info_for_generic_param(def_id, EntryKind::ConstParam, true);
if default.is_some() {
record!(self.tables.const_param_default[def_id] <- self.tcx.const_param_default(def_id))
}
self.encode_info_for_closure(expr.hir_id);
}
}
-
- /// In some cases, along with the item itself, we also
- /// encode some sub-items. Usually we want some info from the item
- /// so it's easier to do that here then to wait until we would encounter
- /// normally in the visitor walk.
- fn encode_addl_info_for_item(&mut self, item: &hir::Item<'_>) {
- match item.kind {
- hir::ItemKind::Static(..)
- | hir::ItemKind::Const(..)
- | hir::ItemKind::Fn(..)
- | hir::ItemKind::Macro(..)
- | hir::ItemKind::Mod(..)
- | hir::ItemKind::ForeignMod { .. }
- | hir::ItemKind::GlobalAsm(..)
- | hir::ItemKind::ExternCrate(..)
- | hir::ItemKind::Use(..)
- | hir::ItemKind::TyAlias(..)
- | hir::ItemKind::OpaqueTy(..)
- | hir::ItemKind::TraitAlias(..) => {
- // no sub-item recording needed in these cases
- }
- hir::ItemKind::Enum(..) => {
- let def = self.tcx.adt_def(item.def_id.to_def_id());
- self.encode_fields(def);
-
- for (i, variant) in def.variants().iter_enumerated() {
- self.encode_enum_variant_info(def, i);
-
- if let Some(_ctor_def_id) = variant.ctor_def_id {
- self.encode_enum_variant_ctor(def, i);
- }
- }
- }
- hir::ItemKind::Struct(ref struct_def, _) => {
- let def = self.tcx.adt_def(item.def_id.to_def_id());
- self.encode_fields(def);
-
- // If the struct has a constructor, encode it.
- if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
- let ctor_def_id = self.tcx.hir().local_def_id(ctor_hir_id);
- self.encode_struct_ctor(def, ctor_def_id.to_def_id());
- }
- }
- hir::ItemKind::Union(..) => {
- let def = self.tcx.adt_def(item.def_id.to_def_id());
- self.encode_fields(def);
- }
- hir::ItemKind::Impl { .. } => {
- for &trait_item_def_id in
- self.tcx.associated_item_def_ids(item.def_id.to_def_id()).iter()
- {
- self.encode_info_for_impl_item(trait_item_def_id);
- }
- }
- hir::ItemKind::Trait(..) => {
- for &item_def_id in self.tcx.associated_item_def_ids(item.def_id.to_def_id()).iter()
- {
- self.encode_info_for_trait_item(item_def_id);
- }
- }
- }
- }
}
/// Used to prefetch queries which will be needed later by metadata encoding.
fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) {
let mut encoder = opaque::FileEncoder::new(path)
- .unwrap_or_else(|err| tcx.sess.fatal(&format!("failed to create file encoder: {}", err)));
+ .unwrap_or_else(|err| tcx.sess.emit_fatal(FailCreateFileEncoder { err }));
encoder.emit_raw_bytes(METADATA_HEADER);
// Will be filled with the root position after encoding everything.
// Encode the root position.
let header = METADATA_HEADER.len();
file.seek(std::io::SeekFrom::Start(header as u64))
- .unwrap_or_else(|err| tcx.sess.fatal(&format!("failed to seek the file: {}", err)));
+ .unwrap_or_else(|err| tcx.sess.emit_fatal(FailSeekFile { err }));
let pos = root.position.get();
file.write_all(&[(pos >> 24) as u8, (pos >> 16) as u8, (pos >> 8) as u8, (pos >> 0) as u8])
- .unwrap_or_else(|err| tcx.sess.fatal(&format!("failed to write to the file: {}", err)));
+ .unwrap_or_else(|err| tcx.sess.emit_fatal(FailWriteFile { err }));
// Return to the position where we are before writing the root position.
file.seek(std::io::SeekFrom::Start(pos_before_seek)).unwrap();