diff options
Diffstat (limited to 'compiler/rustc_metadata')
| -rw-r--r-- | compiler/rustc_metadata/src/native_libs.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/decoder.rs | 64 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/encoder.rs | 126 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/mod.rs | 1 |
5 files changed, 135 insertions, 68 deletions
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index fe29f9d177f..5b33678b25a 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -132,7 +132,7 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> { impl Collector<'tcx> { fn register_native_lib(&mut self, span: Option<Span>, lib: NativeLib) { - if lib.name.as_ref().map(|&s| s == kw::Invalid).unwrap_or(false) { + if lib.name.as_ref().map(|&s| s == kw::Empty).unwrap_or(false) { match span { Some(span) => { struct_span_err!( @@ -192,13 +192,13 @@ impl Collector<'tcx> { fn process_command_line(&mut self) { // First, check for errors let mut renames = FxHashSet::default(); - for &(ref name, ref new_name, _) in &self.tcx.sess.opts.libs { - if let &Some(ref new_name) = new_name { + for (name, new_name, _) in &self.tcx.sess.opts.libs { + if let Some(ref new_name) = new_name { let any_duplicate = self .libs .iter() .filter_map(|lib| lib.name.as_ref()) - .any(|n| n.as_str() == *name); + .any(|n| &n.as_str() == name); if new_name.is_empty() { self.tcx.sess.err(&format!( "an empty renaming target was specified for library `{}`", @@ -240,7 +240,7 @@ impl Collector<'tcx> { if kind != NativeLibKind::Unspecified { lib.kind = kind; } - if let &Some(ref new_name) = new_name { + if let Some(new_name) = new_name { lib.name = Some(Symbol::intern(new_name)); } return true; diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 43f7b2a9928..eace1747577 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -11,6 +11,7 @@ use rustc_data_structures::fingerprint::{Fingerprint, FingerprintDecoder}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::{AtomicCell, Lock, LockGuard, Lrc, OnceCell}; +use rustc_data_structures::unhash::UnhashMap; use rustc_errors::ErrorReported; use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind}; use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, ProcMacroDerive}; @@ -80,7 +81,7 @@ crate struct CrateMetadata { /// For every definition in this crate, maps its `DefPathHash` to its /// `DefIndex`. See `raw_def_id_to_def_id` for more details about how /// this is used. - def_path_hash_map: OnceCell<FxHashMap<DefPathHash, DefIndex>>, + def_path_hash_map: OnceCell<UnhashMap<DefPathHash, DefIndex>>, /// Used for decoding interpret::AllocIds in a cached & thread-safe manner. alloc_decoding_state: AllocDecodingState, /// The `DepNodeIndex` of the `DepNode` representing this upstream crate. @@ -1055,19 +1056,15 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { // Iterate over all children. let macros_only = self.dep_kind.lock().macros_only(); - let children = self.root.tables.children.get(self, id).unwrap_or_else(Lazy::empty); - for child_index in children.decode((self, sess)) { - if macros_only { - continue; - } - - // Get the item. - if let Some(child_kind) = self.maybe_kind(child_index) { - match child_kind { - EntryKind::MacroDef(..) => {} - _ if macros_only => continue, - _ => {} - } + if !macros_only { + let children = self.root.tables.children.get(self, id).unwrap_or_else(Lazy::empty); + + for child_index in children.decode((self, sess)) { + // Get the item. + let child_kind = match self.maybe_kind(child_index) { + Some(child_kind) => child_kind, + None => continue, + }; // Hand off the item to the callback. match child_kind { @@ -1102,8 +1099,8 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } let def_key = self.def_key(child_index); - let span = self.get_span(child_index, sess); if def_key.disambiguated_data.data.get_opt_name().is_some() { + let span = self.get_span(child_index, sess); let kind = self.def_kind(child_index); let ident = self.item_ident(child_index, sess); let vis = self.get_visibility(child_index); @@ -1137,9 +1134,8 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { // within the crate. We only need this for fictive constructors, // for other constructors correct visibilities // were already encoded in metadata. - let attrs: Vec<_> = - self.get_item_attrs(def_id.index, sess).collect(); - if sess.contains_name(&attrs, sym::non_exhaustive) { + let mut attrs = self.get_item_attrs(def_id.index, sess); + if attrs.any(|item| item.has_name(sym::non_exhaustive)) { let crate_def_id = self.local_def_id(CRATE_DEF_INDEX); vis = ty::Visibility::Restricted(crate_def_id); } @@ -1164,6 +1160,10 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } } + fn is_ctfe_mir_available(&self, id: DefIndex) -> bool { + self.root.tables.mir_for_ctfe.get(self, id).is_some() + } + fn is_item_mir_available(&self, id: DefIndex) -> bool { self.root.tables.mir.get(self, id).is_some() } @@ -1187,6 +1187,17 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .decode((self, tcx)) } + fn get_mir_for_ctfe(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> Body<'tcx> { + self.root + .tables + .mir_for_ctfe + .get(self, id) + .unwrap_or_else(|| { + bug!("get_mir_for_ctfe: missing MIR for `{:?}`", self.local_def_id(id)) + }) + .decode((self, tcx)) + } + fn get_mir_abstract_const( &self, tcx: TyCtxt<'tcx>, @@ -1345,15 +1356,14 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { return &[]; } - // Do a reverse lookup beforehand to avoid touching the crate_num - // hash map in the loop below. - let filter = match filter.map(|def_id| self.reverse_translate_def_id(def_id)) { - Some(Some(def_id)) => Some((def_id.krate.as_u32(), def_id.index)), - Some(None) => return &[], - None => None, - }; + if let Some(def_id) = filter { + // Do a reverse lookup beforehand to avoid touching the crate_num + // hash map in the loop below. + let filter = match self.reverse_translate_def_id(def_id) { + Some(def_id) => (def_id.krate.as_u32(), def_id.index), + None => return &[], + }; - if let Some(filter) = filter { if let Some(impls) = self.trait_impls.get(&filter) { tcx.arena.alloc_from_iter( impls.decode(self).map(|(idx, simplified_self_ty)| { @@ -1560,7 +1570,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { // stored in this crate. let map = self.cdata.def_path_hash_map.get_or_init(|| { let end_id = self.root.tables.def_path_hashes.size() as u32; - let mut map = FxHashMap::with_capacity_and_hasher(end_id as usize, Default::default()); + let mut map = UnhashMap::with_capacity_and_hasher(end_id as usize, Default::default()); for i in 0..end_id { let def_index = DefIndex::from_u32(i); // There may be gaps in the encoded table if we're decoding a proc-macro crate diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index b7f22885217..96db0157422 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -115,6 +115,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, }) } optimized_mir => { tcx.arena.alloc(cdata.get_optimized_mir(tcx, def_id.index)) } + mir_for_ctfe => { tcx.arena.alloc(cdata.get_mir_for_ctfe(tcx, def_id.index)) } promoted_mir => { tcx.arena.alloc(cdata.get_promoted_mir(tcx, def_id.index)) } mir_abstract_const => { cdata.get_mir_abstract_const(tcx, def_id.index) } unused_generic_params => { cdata.get_unused_generic_params(def_id.index) } @@ -145,6 +146,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, impl_parent => { cdata.get_parent_impl(def_id.index) } trait_of_item => { cdata.get_trait_of_item(def_id.index) } is_mir_available => { cdata.is_item_mir_available(def_id.index) } + is_ctfe_mir_available => { cdata.is_ctfe_mir_available(def_id.index) } dylib_dependency_formats => { cdata.get_dylib_dependency_formats(tcx) } is_panic_runtime => { cdata.root.panic_runtime } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 4dfe3e84877..ccaee8608b6 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -308,7 +308,7 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span { impl<'a, 'tcx> FingerprintEncoder for EncodeContext<'a, 'tcx> { fn encode_fingerprint(&mut self, f: &Fingerprint) -> Result<(), Self::Error> { - f.encode_opaque(&mut self.opaque) + self.opaque.encode_fingerprint(f) } } @@ -694,7 +694,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { println!(" lang item bytes: {}", lang_item_bytes); println!(" diagnostic item bytes: {}", diagnostic_item_bytes); println!(" native bytes: {}", native_lib_bytes); - println!(" source_map bytes: {}", source_map_bytes); + println!(" source_map bytes: {}", source_map_bytes); println!(" impl bytes: {}", impl_bytes); println!(" exp. symbols bytes: {}", exported_symbols_bytes); println!(" def-path table bytes: {}", def_path_table_bytes); @@ -758,8 +758,6 @@ impl EncodeContext<'a, 'tcx> { self.encode_generics(def_id); self.encode_explicit_predicates(def_id); self.encode_inferred_outlives(def_id); - self.encode_optimized_mir(def_id.expect_local()); - self.encode_promoted_mir(def_id.expect_local()); } fn encode_enum_variant_ctor(&mut self, def: &ty::AdtDef, index: VariantIdx) { @@ -789,6 +787,7 @@ impl EncodeContext<'a, 'tcx> { self.encode_generics(def_id); self.encode_explicit_predicates(def_id); self.encode_inferred_outlives(def_id); + self.encode_mir_for_ctfe(def_id.expect_local()); self.encode_optimized_mir(def_id.expect_local()); self.encode_promoted_mir(def_id.expect_local()); } @@ -897,6 +896,7 @@ impl EncodeContext<'a, 'tcx> { self.encode_explicit_predicates(def_id); self.encode_inferred_outlives(def_id); self.encode_optimized_mir(def_id.expect_local()); + self.encode_mir_for_ctfe(def_id.expect_local()); self.encode_promoted_mir(def_id.expect_local()); } @@ -1015,8 +1015,21 @@ impl EncodeContext<'a, 'tcx> { self.encode_inferred_outlives(def_id); // This should be kept in sync with `PrefetchVisitor.visit_trait_item`. - self.encode_optimized_mir(def_id.expect_local()); - self.encode_promoted_mir(def_id.expect_local()); + match trait_item.kind { + ty::AssocKind::Type => {} + ty::AssocKind::Const => { + if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id.expect_local()) { + self.encode_mir_for_ctfe(def_id.expect_local()); + self.encode_promoted_mir(def_id.expect_local()); + } + } + ty::AssocKind::Fn => { + if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id.expect_local()) { + self.encode_optimized_mir(def_id.expect_local()); + self.encode_promoted_mir(def_id.expect_local()); + } + } + } } fn metadata_output_only(&self) -> bool { @@ -1089,8 +1102,8 @@ impl EncodeContext<'a, 'tcx> { // The following part should be kept in sync with `PrefetchVisitor.visit_impl_item`. - let mir = match ast_item.kind { - hir::ImplItemKind::Const(..) => true, + let (mir, mir_const) = match ast_item.kind { + hir::ImplItemKind::Const(..) => (false, true), hir::ImplItemKind::Fn(ref sig, _) => { let generics = self.tcx.generics_of(def_id); let needs_inline = (generics.requires_monomorphization(self.tcx) @@ -1098,14 +1111,19 @@ impl EncodeContext<'a, 'tcx> { && !self.metadata_output_only(); let is_const_fn = sig.header.constness == hir::Constness::Const; let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir; - needs_inline || is_const_fn || always_encode_mir + (needs_inline || always_encode_mir, is_const_fn) } - hir::ImplItemKind::TyAlias(..) => false, + hir::ImplItemKind::TyAlias(..) => (false, false), }; if mir { self.encode_optimized_mir(def_id.expect_local()); + } + if mir || mir_const { self.encode_promoted_mir(def_id.expect_local()); } + if mir_const { + self.encode_mir_for_ctfe(def_id.expect_local()); + } } fn encode_fn_param_names_for_body(&mut self, body_id: hir::BodyId) -> Lazy<[Ident]> { @@ -1116,28 +1134,34 @@ impl EncodeContext<'a, 'tcx> { self.lazy(param_names.iter()) } - fn encode_optimized_mir(&mut self, def_id: LocalDefId) { - debug!("EntryBuilder::encode_mir({:?})", def_id); - if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id) { - record!(self.tables.mir[def_id.to_def_id()] <- self.tcx.optimized_mir(def_id)); + fn encode_mir_for_ctfe(&mut self, def_id: LocalDefId) { + debug!("EntryBuilder::encode_mir_for_ctfe({:?})", def_id); + record!(self.tables.mir_for_ctfe[def_id.to_def_id()] <- self.tcx.mir_for_ctfe(def_id)); - let unused = self.tcx.unused_generic_params(def_id); - if !unused.is_empty() { - record!(self.tables.unused_generic_params[def_id.to_def_id()] <- unused); - } + let unused = self.tcx.unused_generic_params(def_id); + if !unused.is_empty() { + record!(self.tables.unused_generic_params[def_id.to_def_id()] <- unused); + } - let abstract_const = self.tcx.mir_abstract_const(def_id); - if let Ok(Some(abstract_const)) = abstract_const { - record!(self.tables.mir_abstract_consts[def_id.to_def_id()] <- abstract_const); - } + let abstract_const = self.tcx.mir_abstract_const(def_id); + if let Ok(Some(abstract_const)) = abstract_const { + record!(self.tables.mir_abstract_consts[def_id.to_def_id()] <- abstract_const); + } + } + + fn encode_optimized_mir(&mut self, def_id: LocalDefId) { + debug!("EntryBuilder::encode_optimized_mir({:?})", def_id); + record!(self.tables.mir[def_id.to_def_id()] <- self.tcx.optimized_mir(def_id)); + + let unused = self.tcx.unused_generic_params(def_id); + if !unused.is_empty() { + record!(self.tables.unused_generic_params[def_id.to_def_id()] <- unused); } } fn encode_promoted_mir(&mut self, def_id: LocalDefId) { debug!("EncodeContext::encode_promoted_mir({:?})", def_id); - if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id) { - 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()] <- self.tcx.promoted_mir(def_id)); } // Encodes the inherent implementations of a structure, enumeration, or trait. @@ -1406,22 +1430,31 @@ impl EncodeContext<'a, 'tcx> { // The following part should be kept in sync with `PrefetchVisitor.visit_item`. - let mir = match item.kind { - hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => true, + let (mir, const_mir) = match item.kind { + hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => (false, true), hir::ItemKind::Fn(ref sig, ..) => { let generics = tcx.generics_of(def_id); let needs_inline = (generics.requires_monomorphization(tcx) || tcx.codegen_fn_attrs(def_id).requests_inline()) && !self.metadata_output_only(); + + let is_const_fn = sig.header.constness == hir::Constness::Const; let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir; - needs_inline || sig.header.constness == hir::Constness::Const || always_encode_mir + let mir = needs_inline || always_encode_mir; + // We don't need the optimized MIR for const fns. + (mir, is_const_fn) } - _ => false, + _ => (false, false), }; if mir { self.encode_optimized_mir(def_id.expect_local()); + } + if mir || const_mir { self.encode_promoted_mir(def_id.expect_local()); } + if const_mir { + self.encode_mir_for_ctfe(def_id.expect_local()); + } } /// Serialize the text of exported macros @@ -1486,7 +1519,7 @@ impl EncodeContext<'a, 'tcx> { self.encode_generics(def_id.to_def_id()); self.encode_explicit_predicates(def_id.to_def_id()); self.encode_inferred_outlives(def_id.to_def_id()); - self.encode_optimized_mir(def_id); + self.encode_mir_for_ctfe(def_id); self.encode_promoted_mir(def_id); } @@ -1834,7 +1867,7 @@ impl EncodeContext<'a, 'tcx> { EntryKind::ConstParam, true, ); - // FIXME(const_generics:defaults) + // FIXME(const_generics_defaults) } } } @@ -1951,6 +1984,12 @@ struct PrefetchVisitor<'tcx> { } impl<'tcx> PrefetchVisitor<'tcx> { + fn prefetch_ctfe_mir(&self, def_id: LocalDefId) { + if self.mir_keys.contains(&def_id) { + self.tcx.ensure().mir_for_ctfe(def_id); + self.tcx.ensure().promoted_mir(def_id); + } + } fn prefetch_mir(&self, def_id: LocalDefId) { if self.mir_keys.contains(&def_id) { self.tcx.ensure().optimized_mir(def_id); @@ -1965,16 +2004,19 @@ impl<'tcx, 'v> ParItemLikeVisitor<'v> for PrefetchVisitor<'tcx> { let tcx = self.tcx; match item.kind { hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => { - self.prefetch_mir(tcx.hir().local_def_id(item.hir_id)) + self.prefetch_ctfe_mir(tcx.hir().local_def_id(item.hir_id)) } hir::ItemKind::Fn(ref sig, ..) => { let def_id = tcx.hir().local_def_id(item.hir_id); let generics = tcx.generics_of(def_id.to_def_id()); let needs_inline = generics.requires_monomorphization(tcx) || tcx.codegen_fn_attrs(def_id.to_def_id()).requests_inline(); - if needs_inline || sig.header.constness == hir::Constness::Const { + if needs_inline { self.prefetch_mir(def_id) } + if sig.header.constness == hir::Constness::Const { + self.prefetch_ctfe_mir(def_id); + } } _ => (), } @@ -1982,7 +2024,16 @@ impl<'tcx, 'v> ParItemLikeVisitor<'v> for PrefetchVisitor<'tcx> { fn visit_trait_item(&self, trait_item: &'v hir::TraitItem<'v>) { // This should be kept in sync with `encode_info_for_trait_item`. - self.prefetch_mir(self.tcx.hir().local_def_id(trait_item.hir_id)); + let def_id = self.tcx.hir().local_def_id(trait_item.hir_id); + match trait_item.kind { + hir::TraitItemKind::Type(..) => {} + hir::TraitItemKind::Const(..) => { + self.prefetch_ctfe_mir(def_id); + } + hir::TraitItemKind::Fn(..) => { + self.prefetch_mir(def_id); + } + } } fn visit_impl_item(&self, impl_item: &'v hir::ImplItem<'v>) { @@ -1990,7 +2041,7 @@ impl<'tcx, 'v> ParItemLikeVisitor<'v> for PrefetchVisitor<'tcx> { let tcx = self.tcx; match impl_item.kind { hir::ImplItemKind::Const(..) => { - self.prefetch_mir(tcx.hir().local_def_id(impl_item.hir_id)) + self.prefetch_ctfe_mir(tcx.hir().local_def_id(impl_item.hir_id)) } hir::ImplItemKind::Fn(ref sig, _) => { let def_id = tcx.hir().local_def_id(impl_item.hir_id); @@ -1998,9 +2049,12 @@ impl<'tcx, 'v> ParItemLikeVisitor<'v> for PrefetchVisitor<'tcx> { let needs_inline = generics.requires_monomorphization(tcx) || tcx.codegen_fn_attrs(def_id.to_def_id()).requests_inline(); let is_const_fn = sig.header.constness == hir::Constness::Const; - if needs_inline || is_const_fn { + if needs_inline { self.prefetch_mir(def_id) } + if is_const_fn { + self.prefetch_ctfe_mir(def_id); + } } hir::ImplItemKind::TyAlias(..) => (), } diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 53606178909..59a8bc7fac1 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -302,6 +302,7 @@ define_tables! { // As an optimization, a missing entry indicates an empty `&[]`. explicit_item_bounds: Table<DefIndex, Lazy!([(ty::Predicate<'tcx>, Span)])>, mir: Table<DefIndex, Lazy!(mir::Body<'tcx>)>, + mir_for_ctfe: Table<DefIndex, Lazy!(mir::Body<'tcx>)>, promoted_mir: Table<DefIndex, Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>, mir_abstract_consts: Table<DefIndex, Lazy!(&'tcx [mir::abstract_const::Node<'tcx>])>, unused_generic_params: Table<DefIndex, Lazy<FiniteBitSet<u32>>>, |
