summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_metadata/src/rmeta/encoder.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_metadata/src/rmeta/encoder.rs')
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs459
1 files changed, 221 insertions, 238 deletions
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 8f7a61b72..3ab01f780 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -38,7 +38,6 @@ use rustc_span::symbol::{sym, Symbol};
use rustc_span::{
self, DebuggerVisualizerFile, ExternalSource, FileName, SourceFile, Span, SyntaxContext,
};
-use rustc_target::abi::VariantIdx;
use std::borrow::Borrow;
use std::collections::hash_map::Entry;
use std::hash::Hash;
@@ -76,13 +75,13 @@ pub(super) struct EncodeContext<'a, 'tcx> {
symbol_table: FxHashMap<Symbol, usize>,
}
-/// If the current crate is a proc-macro, returns early with `LazyArray::empty()`.
+/// If the current crate is a proc-macro, returns early with `LazyArray::default()`.
/// This is useful for skipping the encoding of things that aren't needed
/// for proc-macro crates.
macro_rules! empty_proc_macro {
($self:ident) => {
if $self.is_proc_macro {
- return LazyArray::empty();
+ return LazyArray::default();
}
};
}
@@ -365,25 +364,35 @@ impl<'a, 'tcx> TyEncoder for EncodeContext<'a, 'tcx> {
}
}
-// Shorthand for `$self.$tables.$table.set($def_id.index, $self.lazy_value($value))`, which would
+// Shorthand for `$self.$tables.$table.set_some($def_id.index, $self.lazy_value($value))`, which would
// normally need extra variables to avoid errors about multiple mutable borrows.
macro_rules! record {
($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{
{
let value = $value;
let lazy = $self.lazy(value);
- $self.$tables.$table.set($def_id.index, lazy);
+ $self.$tables.$table.set_some($def_id.index, lazy);
}
}};
}
-// Shorthand for `$self.$tables.$table.set($def_id.index, $self.lazy_value($value))`, which would
+// Shorthand for `$self.$tables.$table.set_some($def_id.index, $self.lazy_value($value))`, which would
// normally need extra variables to avoid errors about multiple mutable borrows.
macro_rules! record_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_some($def_id.index, lazy);
+ }
+ }};
+}
+
+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);
}
}};
@@ -467,13 +476,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
{
let def_key = self.lazy(table.def_key(def_index));
let def_path_hash = table.def_path_hash(def_index);
- self.tables.def_keys.set(def_index, def_key);
+ self.tables.def_keys.set_some(def_index, def_key);
self.tables.def_path_hashes.set(def_index, def_path_hash);
}
} else {
for (def_index, def_key, def_path_hash) in table.enumerated_keys_and_path_hashes() {
let def_key = self.lazy(def_key);
- self.tables.def_keys.set(def_index, def_key);
+ self.tables.def_keys.set_some(def_index, def_key);
self.tables.def_path_hashes.set(def_index, *def_path_hash);
}
}
@@ -483,7 +492,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
self.lazy(DefPathHashMapRef::BorrowedFromTcx(self.tcx.def_path_hash_to_def_index_map()))
}
- fn encode_source_map(&mut self) -> LazyTable<u32, LazyValue<rustc_span::SourceFile>> {
+ fn encode_source_map(&mut self) -> LazyTable<u32, Option<LazyValue<rustc_span::SourceFile>>> {
let source_map = self.tcx.sess.source_map();
let all_source_files = source_map.files();
@@ -548,7 +557,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let on_disk_index: u32 =
on_disk_index.try_into().expect("cannot export more than U32_MAX files");
- adapted.set(on_disk_index, self.lazy(source_file));
+ adapted.set_some(on_disk_index, self.lazy(source_file));
}
adapted.encode(&mut self.opaque)
@@ -760,36 +769,50 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
}
+struct AnalyzeAttrState {
+ is_exported: bool,
+ is_doc_hidden: bool,
+}
+
/// Returns whether an attribute needs to be recorded in metadata, that is, if it's usable and
/// useful in downstream crates. Local-only attributes are an obvious example, but some
/// rustdoc-specific attributes can equally be of use while documenting the current crate only.
///
/// Removing these superfluous attributes speeds up compilation by making the metadata smaller.
///
-/// Note: the `is_def_id_public` parameter is used to cache whether the given `DefId` has a public
+/// Note: the `is_exported` parameter is used to cache whether the given `DefId` has a public
/// visibility: this is a piece of data that can be computed once per defid, and not once per
/// attribute. Some attributes would only be usable downstream if they are public.
#[inline]
-fn should_encode_attr(
- tcx: TyCtxt<'_>,
- attr: &Attribute,
- def_id: LocalDefId,
- is_def_id_public: &mut Option<bool>,
-) -> bool {
+fn analyze_attr(attr: &Attribute, state: &mut AnalyzeAttrState) -> bool {
+ let mut should_encode = false;
if rustc_feature::is_builtin_only_local(attr.name_or_empty()) {
// Attributes marked local-only don't need to be encoded for downstream crates.
- false
} else if attr.doc_str().is_some() {
- // We keep all public doc comments because they might be "imported" into downstream crates
- // if they use `#[doc(inline)]` to copy an item's documentation into their own.
- *is_def_id_public.get_or_insert_with(|| tcx.effective_visibilities(()).is_exported(def_id))
+ // We keep all doc comments reachable to rustdoc because they might be "imported" into
+ // downstream crates if they use `#[doc(inline)]` to copy an item's documentation into
+ // their own.
+ if state.is_exported {
+ should_encode = true;
+ }
} else if attr.has_name(sym::doc) {
- // If this is a `doc` attribute, and it's marked `inline` (as in `#[doc(inline)]`), we can
- // remove it. It won't be inlinable in downstream crates.
- attr.meta_item_list().map(|l| l.iter().any(|l| !l.has_name(sym::inline))).unwrap_or(false)
+ // If this is a `doc` attribute that doesn't have anything except maybe `inline` (as in
+ // `#[doc(inline)]`), then we can remove it. It won't be inlinable in downstream crates.
+ if let Some(item_list) = attr.meta_item_list() {
+ for item in item_list {
+ if !item.has_name(sym::inline) {
+ should_encode = true;
+ if item.has_name(sym::hidden) {
+ state.is_doc_hidden = true;
+ break;
+ }
+ }
+ }
+ }
} else {
- true
+ should_encode = true;
}
+ should_encode
}
fn should_encode_visibility(def_kind: DefKind) -> bool {
@@ -815,7 +838,7 @@ fn should_encode_visibility(def_kind: DefKind) -> bool {
| DefKind::ForeignMod
| DefKind::OpaqueTy
| DefKind::ImplTraitPlaceholder
- | DefKind::Impl
+ | DefKind::Impl { .. }
| DefKind::Field => true,
DefKind::TyParam
| DefKind::ConstParam
@@ -850,7 +873,7 @@ fn should_encode_stability(def_kind: DefKind) -> bool {
| DefKind::ImplTraitPlaceholder
| DefKind::Enum
| DefKind::Union
- | DefKind::Impl
+ | DefKind::Impl { .. }
| DefKind::Trait
| DefKind::TraitAlias
| DefKind::Macro(..)
@@ -928,7 +951,7 @@ fn should_encode_variances(def_kind: DefKind) -> bool {
| DefKind::Const
| DefKind::ForeignMod
| DefKind::TyAlias
- | DefKind::Impl
+ | DefKind::Impl { .. }
| DefKind::Trait
| DefKind::TraitAlias
| DefKind::Macro(..)
@@ -965,7 +988,7 @@ fn should_encode_generics(def_kind: DefKind) -> bool {
| DefKind::InlineConst
| DefKind::OpaqueTy
| DefKind::ImplTraitPlaceholder
- | DefKind::Impl
+ | DefKind::Impl { .. }
| DefKind::Field
| DefKind::TyParam
| DefKind::Closure
@@ -995,7 +1018,7 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
| DefKind::TyAlias
| DefKind::OpaqueTy
| DefKind::ForeignTy
- | DefKind::Impl
+ | DefKind::Impl { .. }
| DefKind::AssocFn
| DefKind::AssocConst
| DefKind::Closure
@@ -1058,7 +1081,7 @@ fn should_encode_const(def_kind: DefKind) -> bool {
| DefKind::OpaqueTy
| DefKind::ImplTraitPlaceholder
| DefKind::ForeignTy
- | DefKind::Impl
+ | DefKind::Impl { .. }
| DefKind::AssocFn
| DefKind::Closure
| DefKind::Generator
@@ -1078,49 +1101,40 @@ fn should_encode_const(def_kind: DefKind) -> bool {
}
}
-fn should_encode_trait_impl_trait_tys(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
- if tcx.def_kind(def_id) != DefKind::AssocFn {
- return false;
- }
-
- let Some(item) = tcx.opt_associated_item(def_id) else { return false; };
- if item.container != ty::AssocItemContainer::ImplContainer {
- return false;
+// We only encode impl trait in trait when using `lower-impl-trait-in-trait-to-assoc-ty` unstable
+// option.
+fn should_encode_fn_impl_trait_in_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
+ if tcx.sess.opts.unstable_opts.lower_impl_trait_in_trait_to_assoc_ty
+ && let Some(assoc_item) = tcx.opt_associated_item(def_id)
+ && assoc_item.container == ty::AssocItemContainer::TraitContainer
+ && assoc_item.kind == ty::AssocKind::Fn
+ {
+ true
+ } else {
+ false
}
-
- let Some(trait_item_def_id) = item.trait_item_def_id else { return false; };
-
- // FIXME(RPITIT): This does a somewhat manual walk through the signature
- // of the trait fn to look for any RPITITs, but that's kinda doing a lot
- // of work. We can probably remove this when we refactor RPITITs to be
- // associated types.
- tcx.fn_sig(trait_item_def_id).skip_binder().output().walk().any(|arg| {
- if let ty::GenericArgKind::Type(ty) = arg.unpack()
- && let ty::Alias(ty::Projection, data) = ty.kind()
- && tcx.def_kind(data.def_id) == DefKind::ImplTraitPlaceholder
- {
- true
- } else {
- false
- }
- })
}
impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
fn encode_attrs(&mut self, def_id: LocalDefId) {
let tcx = self.tcx;
- let mut is_public: Option<bool> = None;
-
- let mut attrs = tcx
- .hir()
- .attrs(tcx.hir().local_def_id_to_hir_id(def_id))
+ let mut state = AnalyzeAttrState {
+ is_exported: tcx.effective_visibilities(()).is_exported(def_id),
+ is_doc_hidden: false,
+ };
+ let attr_iter = tcx
+ .opt_local_def_id_to_hir_id(def_id)
+ .map_or(Default::default(), |hir_id| tcx.hir().attrs(hir_id))
.iter()
- .filter(move |attr| should_encode_attr(tcx, attr, def_id, &mut is_public));
+ .filter(|attr| analyze_attr(attr, &mut state));
+
+ record_array!(self.tables.attributes[def_id.to_def_id()] <- attr_iter);
- record_array!(self.tables.attributes[def_id.to_def_id()] <- attrs.clone());
- if attrs.any(|attr| attr.may_have_doc_links()) {
- self.tables.may_have_doc_links.set(def_id.local_def_index, ());
+ let mut attr_flags = AttrFlags::empty();
+ if state.is_doc_hidden {
+ attr_flags |= AttrFlags::IS_DOC_HIDDEN;
}
+ self.tables.attr_flags.set(def_id.local_def_index, attr_flags);
}
fn encode_def_ids(&mut self) {
@@ -1132,7 +1146,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let def_id = local_id.to_def_id();
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);
+ self.tables.opt_def_kind.set_some(def_id.index, def_kind);
let def_span = tcx.def_span(local_id);
record!(self.tables.def_span[def_id] <- def_span);
self.encode_attrs(local_id);
@@ -1163,9 +1177,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));
@@ -1178,70 +1190,85 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id));
}
if let DefKind::Enum | DefKind::Struct | DefKind::Union = def_kind {
- let params_in_repr = self.tcx.params_in_repr(def_id);
- record!(self.tables.params_in_repr[def_id] <- params_in_repr);
+ self.encode_info_for_adt(def_id);
}
- if should_encode_trait_impl_trait_tys(tcx, def_id)
+ if tcx.impl_method_has_trait_impl_trait_tys(def_id)
&& let Ok(table) = self.tcx.collect_return_position_impl_trait_in_trait_tys(def_id)
{
record!(self.tables.trait_impl_trait_tys[def_id] <- table);
}
+ if should_encode_fn_impl_trait_in_trait(tcx, def_id) {
+ let table = tcx.associated_items_for_impl_trait_in_trait(def_id);
+ record_defaulted_array!(self.tables.associated_items_for_impl_trait_in_trait[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
}));
}
+
+ for (def_id, res_map) in &tcx.resolutions(()).doc_link_resolutions {
+ record!(self.tables.doc_link_resolutions[def_id.to_def_id()] <- res_map);
+ }
+
+ for (def_id, traits) in &tcx.resolutions(()).doc_link_traits_in_scope {
+ record_array!(self.tables.doc_link_traits_in_scope[def_id.to_def_id()] <- traits);
+ }
}
- fn encode_enum_variant_info(&mut self, def: ty::AdtDef<'tcx>, index: VariantIdx) {
+ #[instrument(level = "trace", skip(self))]
+ fn encode_info_for_adt(&mut self, def_id: DefId) {
let tcx = self.tcx;
- let variant = &def.variant(index);
- let def_id = variant.def_id;
- debug!("EncodeContext::encode_enum_variant_info({:?})", def_id);
-
- let data = VariantData {
- discr: variant.discr,
- ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)),
- is_non_exhaustive: variant.is_field_list_non_exhaustive(),
- };
+ let adt_def = tcx.adt_def(def_id);
+ record!(self.tables.repr_options[def_id] <- adt_def.repr());
+
+ let params_in_repr = self.tcx.params_in_repr(def_id);
+ record!(self.tables.params_in_repr[def_id] <- params_in_repr);
- 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
- }));
- if let Some((CtorKind::Fn, ctor_def_id)) = variant.ctor {
- // FIXME(eddyb) encode signature only in `encode_enum_variant_ctor`.
- record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(ctor_def_id));
+ if adt_def.is_enum() {
+ record_array!(self.tables.children[def_id] <- iter::from_generator(||
+ for variant in tcx.adt_def(def_id).variants() {
+ 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;
+ }
+ }
+ ));
+ } else {
+ // For non-enum, there is only one variant, and its def_id is the adt's.
+ debug_assert_eq!(adt_def.variants().len(), 1);
+ debug_assert_eq!(adt_def.non_enum_variant().def_id, def_id);
+ // Therefore, the loop over variants will encode its fields as the adt's children.
}
- }
- fn encode_enum_variant_ctor(&mut self, def: ty::AdtDef<'tcx>, index: VariantIdx) {
- let variant = &def.variant(index);
- let Some((ctor_kind, def_id)) = variant.ctor else { return };
- debug!("EncodeContext::encode_enum_variant_ctor({:?})", def_id);
+ for variant in adt_def.variants().iter() {
+ let data = VariantData {
+ discr: variant.discr,
+ ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)),
+ is_non_exhaustive: variant.is_field_list_non_exhaustive(),
+ };
+ record!(self.tables.variant_data[variant.def_id] <- data);
- // FIXME(eddyb) encode only the `CtorKind` for constructors.
- let data = VariantData {
- discr: variant.discr,
- ctor: Some((ctor_kind, def_id.index)),
- is_non_exhaustive: variant.is_field_list_non_exhaustive(),
- };
+ self.tables.constness.set_some(variant.def_id.index, hir::Constness::Const);
+ record_array!(self.tables.children[variant.def_id] <- variant.fields.iter().map(|f| {
+ assert!(f.did.is_local());
+ f.did.index
+ }));
- record!(self.tables.variant_data[def_id] <- data);
- self.tables.constness.set(def_id.index, hir::Constness::Const);
- if ctor_kind == CtorKind::Fn {
- record!(self.tables.fn_sig[def_id] <- self.tcx.fn_sig(def_id));
+ if let Some((CtorKind::Fn, ctor_def_id)) = variant.ctor {
+ self.tables.constness.set_some(ctor_def_id.index, hir::Constness::Const);
+ let fn_sig = tcx.fn_sig(ctor_def_id);
+ record!(self.tables.fn_sig[ctor_def_id] <- fn_sig);
+ // FIXME only encode signature for ctor_def_id
+ record!(self.tables.fn_sig[variant.def_id] <- fn_sig);
+ }
}
}
@@ -1275,8 +1302,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
hir::ItemKind::Struct(ref vdata, _) => {
yield item_id.owner_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 let Some(ctor_def_id) = vdata.ctor_def_id() {
+ yield ctor_def_id.local_def_index;
}
}
_ if tcx.def_key(item_id.owner_id.to_def_id()).get_opt_name().is_some() => {
@@ -1294,31 +1321,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
}
- fn encode_struct_ctor(&mut self, adt_def: ty::AdtDef<'tcx>) {
- let variant = adt_def.non_enum_variant();
- let Some((ctor_kind, def_id)) = variant.ctor else { return };
- debug!("EncodeContext::encode_struct_ctor({:?})", def_id);
-
- let data = VariantData {
- discr: variant.discr,
- ctor: Some((ctor_kind, def_id.index)),
- is_non_exhaustive: variant.is_field_list_non_exhaustive(),
- };
-
- 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);
- if ctor_kind == CtorKind::Fn {
- record!(self.tables.fn_sig[def_id] <- self.tcx.fn_sig(def_id));
- }
- }
-
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) {
@@ -1326,16 +1332,16 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let tcx = self.tcx;
let impl_defaultness = tcx.impl_defaultness(def_id.expect_local());
- self.tables.impl_defaultness.set(def_id.index, impl_defaultness);
+ self.tables.impl_defaultness.set_some(def_id.index, impl_defaultness);
let trait_item = tcx.associated_item(def_id);
- self.tables.assoc_container.set(def_id.index, trait_item.container);
+ self.tables.assoc_container.set_some(def_id.index, trait_item.container);
match trait_item.kind {
ty::AssocKind::Const => {}
ty::AssocKind::Fn => {
record_array!(self.tables.fn_arg_names[def_id] <- tcx.fn_arg_names(def_id));
- self.tables.asyncness.set(def_id.index, tcx.asyncness(def_id));
- self.tables.constness.set(def_id.index, hir::Constness::NotConst);
+ self.tables.asyncness.set_some(def_id.index, tcx.asyncness(def_id));
+ self.tables.constness.set_some(def_id.index, hir::Constness::NotConst);
}
ty::AssocKind::Type => {
self.encode_explicit_item_bounds(def_id);
@@ -1351,14 +1357,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let tcx = self.tcx;
let ast_item = self.tcx.hir().expect_impl_item(def_id.expect_local());
- self.tables.impl_defaultness.set(def_id.index, ast_item.defaultness);
+ self.tables.impl_defaultness.set_some(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);
+ self.tables.assoc_container.set_some(def_id.index, impl_item.container);
match impl_item.kind {
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);
+ self.tables.asyncness.set_some(def_id.index, sig.header.asyncness);
record_array!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body));
// Can be inside `impl const Trait`, so using sig.header.constness is not reliable
let constness = if self.tcx.is_const_fn_raw(def_id) {
@@ -1366,18 +1372,16 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
} else {
hir::Constness::NotConst
};
- self.tables.constness.set(def_id.index, constness);
+ self.tables.constness.set_some(def_id.index, constness);
}
ty::AssocKind::Const | ty::AssocKind::Type => {}
}
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());
+ self.tables.trait_item_def_id.set_some(def_id.index, trait_item_def_id.into());
}
if impl_item.kind == ty::AssocKind::Fn {
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, ());
- }
+ self.tables.is_intrinsic.set(def_id.index, tcx.is_intrinsic(def_id));
}
}
@@ -1398,6 +1402,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
debug!("EntryBuilder::encode_mir({:?})", def_id);
if encode_opt {
record!(self.tables.optimized_mir[def_id.to_def_id()] <- tcx.optimized_mir(def_id));
+
+ if tcx.sess.opts.unstable_opts.drop_tracking_mir && let DefKind::Generator = self.tcx.def_kind(def_id) {
+ record!(self.tables.mir_generator_witnesses[def_id.to_def_id()] <- tcx.mir_generator_witnesses(def_id));
+ }
}
if encode_const {
record!(self.tables.mir_for_ctfe[def_id.to_def_id()] <- tcx.mir_for_ctfe(def_id));
@@ -1502,14 +1510,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
match item.kind {
hir::ItemKind::Fn(ref sig, .., body) => {
- self.tables.asyncness.set(def_id.index, sig.header.asyncness);
+ self.tables.asyncness.set_some(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);
+ self.tables.constness.set_some(def_id.index, sig.header.constness);
}
hir::ItemKind::Macro(ref macro_def, _) => {
- if macro_def.macro_rules {
- self.tables.macro_rules.set(def_id.index, ());
- }
+ self.tables.is_macro_rules.set(def_id.index, macro_def.macro_rules);
record!(self.tables.macro_definition[def_id] <- &*macro_def.body);
}
hir::ItemKind::Mod(ref m) => {
@@ -1517,47 +1523,21 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
hir::ItemKind::OpaqueTy(ref opaque) => {
self.encode_explicit_item_bounds(def_id);
- if matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias) {
- self.tables.is_type_alias_impl_trait.set(def_id.index, ());
- }
- }
- hir::ItemKind::Enum(..) => {
- let adt_def = self.tcx.adt_def(def_id);
- record!(self.tables.repr_options[def_id] <- adt_def.repr());
- }
- hir::ItemKind::Struct(..) => {
- let adt_def = self.tcx.adt_def(def_id);
- record!(self.tables.repr_options[def_id] <- adt_def.repr());
- self.tables.constness.set(def_id.index, hir::Constness::Const);
-
- let variant = adt_def.non_enum_variant();
- record!(self.tables.variant_data[def_id] <- VariantData {
- discr: variant.discr,
- ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)),
- 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();
- record!(self.tables.variant_data[def_id] <- VariantData {
- discr: variant.discr,
- ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)),
- is_non_exhaustive: variant.is_field_list_non_exhaustive(),
- });
+ self.tables
+ .is_type_alias_impl_trait
+ .set(def_id.index, matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias));
}
hir::ItemKind::Impl(hir::Impl { defaultness, constness, .. }) => {
- self.tables.impl_defaultness.set(def_id.index, *defaultness);
- self.tables.constness.set(def_id.index, *constness);
+ self.tables.impl_defaultness.set_some(def_id.index, *defaultness);
+ self.tables.constness.set_some(def_id.index, *constness);
- let trait_ref = self.tcx.impl_trait_ref(def_id).map(ty::EarlyBinder::skip_binder);
+ let trait_ref = self.tcx.impl_trait_ref(def_id);
if let Some(trait_ref) = trait_ref {
+ let trait_ref = trait_ref.skip_binder();
let trait_def = self.tcx.trait_def(trait_ref.def_id);
if let Ok(mut an) = trait_def.ancestors(self.tcx, def_id) {
if let Some(specialization_graph::Node::Impl(parent)) = an.nth(1) {
- self.tables.impl_parent.set(def_id.index, parent.into());
+ self.tables.impl_parent.set_some(def_id.index, parent.into());
}
}
@@ -1571,7 +1551,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
let polarity = self.tcx.impl_polarity(def_id);
- self.tables.impl_polarity.set(def_id.index, polarity);
+ self.tables.impl_polarity.set_some(def_id.index, polarity);
}
hir::ItemKind::Trait(..) => {
let trait_def = self.tcx.trait_def(def_id);
@@ -1586,31 +1566,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
hir::ItemKind::Static(..)
| hir::ItemKind::Const(..)
+ | hir::ItemKind::Enum(..)
+ | hir::ItemKind::Struct(..)
+ | hir::ItemKind::Union(..)
| hir::ItemKind::ForeignMod { .. }
| hir::ItemKind::GlobalAsm(..)
| hir::ItemKind::TyAlias(..) => {}
};
// FIXME(eddyb) there should be a nicer way to do this.
match item.kind {
- hir::ItemKind::Enum(..) => {
- record_array!(self.tables.children[def_id] <- iter::from_generator(||
- for variant in tcx.adt_def(def_id).variants() {
- 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(..) => {
- record_array!(self.tables.children[def_id] <-
- self.tcx.adt_def(def_id).non_enum_variant().fields.iter().map(|f| {
- assert!(f.did.is_local());
- f.did.index
- })
- )
- }
hir::ItemKind::Impl { .. } | hir::ItemKind::Trait(..) => {
let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id);
record_array!(self.tables.children[def_id] <-
@@ -1624,9 +1588,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
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) {
- self.tables.is_intrinsic.set(def_id.index, ());
- }
+ self.tables.is_intrinsic.set(def_id.index, tcx.is_intrinsic(def_id));
}
if let hir::ItemKind::Impl { .. } = item.kind {
if let Some(trait_ref) = self.tcx.impl_trait_ref(def_id) {
@@ -1638,17 +1600,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
// 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.owner_id.to_def_id());
- for (i, _) in def.variants().iter_enumerated() {
- self.encode_enum_variant_info(def, i);
- self.encode_enum_variant_ctor(def, i);
- }
- }
- hir::ItemKind::Struct(..) => {
- let def = self.tcx.adt_def(item.owner_id.to_def_id());
- self.encode_struct_ctor(def);
- }
hir::ItemKind::Impl { .. } => {
for &trait_item_def_id in
self.tcx.associated_item_def_ids(item.owner_id.to_def_id()).iter()
@@ -1670,7 +1621,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
#[instrument(level = "debug", skip(self))]
fn encode_info_for_closure(&mut self, def_id: LocalDefId) {
// NOTE(eddyb) `tcx.type_of(def_id)` isn't used because it's fully generic,
- // including on the signature, which is inferred in `typeck.
+ // including on the signature, which is inferred in `typeck`.
let typeck_result: &'tcx ty::TypeckResults<'tcx> = self.tcx.typeck(def_id);
let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
let ty = typeck_result.node_type(hir_id);
@@ -1684,8 +1635,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
ty::Closure(_, substs) => {
let constness = self.tcx.constness(def_id.to_def_id());
- self.tables.constness.set(def_id.to_def_id().index, constness);
- record!(self.tables.fn_sig[def_id.to_def_id()] <- substs.as_closure().sig());
+ self.tables.constness.set_some(def_id.to_def_id().index, constness);
+ record!(self.tables.fn_sig[def_id.to_def_id()] <- ty::EarlyBinder(substs.as_closure().sig()));
}
_ => bug!("closure that is neither generator nor closure"),
@@ -1712,12 +1663,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
self.hygiene_ctxt.encode(
&mut (&mut *self, &mut syntax_contexts, &mut expn_data_table, &mut expn_hash_table),
|(this, syntax_contexts, _, _), index, ctxt_data| {
- syntax_contexts.set(index, this.lazy(ctxt_data));
+ syntax_contexts.set_some(index, this.lazy(ctxt_data));
},
|(this, _, expn_data_table, expn_hash_table), index, expn_data, hash| {
if let Some(index) = index.as_local() {
- expn_data_table.set(index.as_raw(), this.lazy(expn_data));
- expn_hash_table.set(index.as_raw(), this.lazy(hash));
+ expn_data_table.set_some(index.as_raw(), this.lazy(expn_data));
+ expn_hash_table.set_some(index.as_raw(), this.lazy(hash));
}
},
);
@@ -1742,10 +1693,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let spans = self.tcx.sess.parse_sess.proc_macro_quoted_spans();
for (i, span) in spans.into_iter().enumerate() {
let span = self.lazy(span);
- self.tables.proc_macro_quoted_spans.set(i, span);
+ self.tables.proc_macro_quoted_spans.set_some(i, span);
}
- self.tables.opt_def_kind.set(LOCAL_CRATE.as_def_id().index, DefKind::Mod);
+ self.tables.opt_def_kind.set_some(LOCAL_CRATE.as_def_id().index, DefKind::Mod);
record!(self.tables.def_span[LOCAL_CRATE.as_def_id()] <- tcx.def_span(LOCAL_CRATE.as_def_id()));
self.encode_attrs(LOCAL_CRATE.as_def_id().expect_local());
let vis = tcx.local_visibility(CRATE_DEF_ID).map_id(|def_id| def_id.local_def_index);
@@ -1754,6 +1705,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
record!(self.tables.lookup_stability[LOCAL_CRATE.as_def_id()] <- stability);
}
self.encode_deprecation(LOCAL_CRATE.as_def_id());
+ if let Some(res_map) = tcx.resolutions(()).doc_link_resolutions.get(&CRATE_DEF_ID) {
+ record!(self.tables.doc_link_resolutions[LOCAL_CRATE.as_def_id()] <- res_map);
+ }
+ if let Some(traits) = tcx.resolutions(()).doc_link_traits_in_scope.get(&CRATE_DEF_ID) {
+ record_array!(self.tables.doc_link_traits_in_scope[LOCAL_CRATE.as_def_id()] <- traits);
+ }
// Normally, this information is encoded when we walk the items
// defined in this crate. However, we skip doing that for proc-macro crates,
@@ -1787,8 +1744,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
def_key.disambiguated_data.data = DefPathData::MacroNs(name);
let def_id = id.to_def_id();
- self.tables.opt_def_kind.set(def_id.index, DefKind::Macro(macro_kind));
- self.tables.proc_macro.set(def_id.index, macro_kind);
+ self.tables.opt_def_kind.set_some(def_id.index, DefKind::Macro(macro_kind));
+ self.tables.proc_macro.set_some(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);
@@ -1894,7 +1851,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
FxHashMap::default();
for id in tcx.hir().items() {
- if matches!(tcx.def_kind(id.owner_id), DefKind::Impl) {
+ if matches!(tcx.def_kind(id.owner_id), DefKind::Impl { .. }) {
if let Some(trait_ref) = tcx.impl_trait_ref(id.owner_id) {
let trait_ref = trait_ref.subst_identity();
@@ -2003,7 +1960,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
Linkage::Static => Some(LinkagePreference::RequireStatic),
}));
}
- LazyArray::empty()
+ LazyArray::default()
}
fn encode_info_for_foreign_item(&mut self, def_id: DefId, nitem: &hir::ForeignItem<'_>) {
@@ -2013,22 +1970,20 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
match nitem.kind {
hir::ForeignItemKind::Fn(_, ref names, _) => {
- self.tables.asyncness.set(def_id.index, hir::IsAsync::NotAsync);
+ self.tables.asyncness.set_some(def_id.index, hir::IsAsync::NotAsync);
record_array!(self.tables.fn_arg_names[def_id] <- *names);
let constness = if self.tcx.is_const_fn_raw(def_id) {
hir::Constness::Const
} else {
hir::Constness::NotConst
};
- self.tables.constness.set(def_id.index, constness);
+ self.tables.constness.set_some(def_id.index, constness);
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
}
hir::ForeignItemKind::Static(..) | hir::ForeignItemKind::Type => {}
}
if let hir::ForeignItemKind::Fn(..) = nitem.kind {
- if tcx.is_intrinsic(def_id) {
- self.tables.is_intrinsic.set(def_id.index, ());
- }
+ self.tables.is_intrinsic.set(def_id.index, tcx.is_intrinsic(def_id));
}
}
}
@@ -2266,6 +2221,18 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) {
pub fn provide(providers: &mut Providers) {
*providers = Providers {
+ doc_link_resolutions: |tcx, def_id| {
+ tcx.resolutions(())
+ .doc_link_resolutions
+ .get(&def_id.expect_local())
+ .expect("no resolutions for a doc link")
+ },
+ doc_link_traits_in_scope: |tcx, def_id| {
+ tcx.resolutions(())
+ .doc_link_traits_in_scope
+ .get(&def_id.expect_local())
+ .expect("no traits in scope for a doc link")
+ },
traits_in_crate: |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
@@ -2280,6 +2247,22 @@ pub fn provide(providers: &mut Providers) {
traits.sort_by_cached_key(|&def_id| tcx.def_path_hash(def_id));
tcx.arena.alloc_slice(&traits)
},
+ trait_impls_in_crate: |tcx, cnum| {
+ assert_eq!(cnum, LOCAL_CRATE);
+
+ let mut trait_impls = Vec::new();
+ for id in tcx.hir().items() {
+ if matches!(tcx.def_kind(id.owner_id), DefKind::Impl { .. })
+ && tcx.impl_trait_ref(id.owner_id).is_some()
+ {
+ trait_impls.push(id.owner_id.to_def_id())
+ }
+ }
+
+ // Bring everything into deterministic order.
+ trait_impls.sort_by_cached_key(|&def_id| tcx.def_path_hash(def_id));
+ tcx.arena.alloc_slice(&trait_impls)
+ },
..*providers
}