From 2e00214b3efbdfeefaa0fe9e8b8fd519de7adc35 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:50 +0200 Subject: Merging upstream version 1.69.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_metadata/src/rmeta/encoder.rs | 459 +++++++++++++-------------- 1 file changed, 221 insertions(+), 238 deletions(-) (limited to 'compiler/rustc_metadata/src/rmeta/encoder.rs') 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, } -/// 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,21 +364,31 @@ 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; @@ -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> { + fn encode_source_map(&mut self) -> LazyTable>> { 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 { +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 = 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 } -- cgit v1.2.3