summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_metadata/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
commitdc0db358abe19481e475e10c32149b53370f1a1c (patch)
treeab8ce99c4b255ce46f99ef402c27916055b899ee /compiler/rustc_metadata/src
parentReleasing progress-linux version 1.71.1+dfsg1-2~progress7.99u1. (diff)
downloadrustc-dc0db358abe19481e475e10c32149b53370f1a1c.tar.xz
rustc-dc0db358abe19481e475e10c32149b53370f1a1c.zip
Merging upstream version 1.72.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_metadata/src')
-rw-r--r--compiler/rustc_metadata/src/creader.rs20
-rw-r--r--compiler/rustc_metadata/src/errors.rs11
-rw-r--r--compiler/rustc_metadata/src/fs.rs43
-rw-r--r--compiler/rustc_metadata/src/lib.rs2
-rw-r--r--compiler/rustc_metadata/src/locator.rs17
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs71
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs18
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs524
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs41
-rw-r--r--compiler/rustc_metadata/src/rmeta/table.rs2
11 files changed, 392 insertions, 359 deletions
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index aaf72ab94..b3976d756 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -365,6 +365,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
lib: Library,
dep_kind: CrateDepKind,
name: Symbol,
+ private_dep: Option<bool>,
) -> Result<CrateNum, CrateError> {
let _prof_timer = self.sess.prof.generic_activity("metadata_register_crate");
@@ -372,8 +373,13 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
let crate_root = metadata.get_root();
let host_hash = host_lib.as_ref().map(|lib| lib.metadata.get_root().hash());
- let private_dep =
- self.sess.opts.externs.get(name.as_str()).is_some_and(|e| e.is_private_dep);
+ let private_dep = self
+ .sess
+ .opts
+ .externs
+ .get(name.as_str())
+ .map_or(private_dep.unwrap_or(false), |e| e.is_private_dep)
+ && private_dep.unwrap_or(true);
// Claim this crate number and cache it
let cnum = self.cstore.intern_stable_crate_id(&crate_root)?;
@@ -518,15 +524,16 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
if !name.as_str().is_ascii() {
return Err(CrateError::NonAsciiName(name));
}
- let (root, hash, host_hash, extra_filename, path_kind) = match dep {
+ let (root, hash, host_hash, extra_filename, path_kind, private_dep) = match dep {
Some((root, dep)) => (
Some(root),
Some(dep.hash),
dep.host_hash,
Some(&dep.extra_filename[..]),
PathKind::Dependency,
+ Some(dep.is_private),
),
- None => (None, None, None, None, PathKind::Crate),
+ None => (None, None, None, None, PathKind::Crate, None),
};
let result = if let Some(cnum) = self.existing_match(name, hash, path_kind) {
(LoadResult::Previous(cnum), None)
@@ -562,10 +569,13 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
dep_kind = CrateDepKind::MacrosOnly;
}
data.update_dep_kind(|data_dep_kind| cmp::max(data_dep_kind, dep_kind));
+ if let Some(private_dep) = private_dep {
+ data.update_and_private_dep(private_dep);
+ }
Ok(cnum)
}
(LoadResult::Loaded(library), host_library) => {
- self.register_crate(host_library, root, library, dep_kind, name)
+ self.register_crate(host_library, root, library, dep_kind, name, private_dep)
}
_ => panic!(),
}
diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs
index a44c1dd58..fca06c0f4 100644
--- a/compiler/rustc_metadata/src/errors.rs
+++ b/compiler/rustc_metadata/src/errors.rs
@@ -396,6 +396,17 @@ pub struct FailedWriteError {
}
#[derive(Diagnostic)]
+#[diag(metadata_failed_copy_to_stdout)]
+pub struct FailedCopyToStdout {
+ pub filename: PathBuf,
+ pub err: Error,
+}
+
+#[derive(Diagnostic)]
+#[diag(metadata_binary_output_to_tty)]
+pub struct BinaryOutputToTty;
+
+#[derive(Diagnostic)]
#[diag(metadata_missing_native_library)]
pub struct MissingNativeLibrary<'a> {
libname: &'a str,
diff --git a/compiler/rustc_metadata/src/fs.rs b/compiler/rustc_metadata/src/fs.rs
index 08de828fb..238f963ed 100644
--- a/compiler/rustc_metadata/src/fs.rs
+++ b/compiler/rustc_metadata/src/fs.rs
@@ -1,18 +1,19 @@
use crate::errors::{
- FailedCreateEncodedMetadata, FailedCreateFile, FailedCreateTempdir, FailedWriteError,
+ BinaryOutputToTty, FailedCopyToStdout, FailedCreateEncodedMetadata, FailedCreateFile,
+ FailedCreateTempdir, FailedWriteError,
};
use crate::{encode_metadata, EncodedMetadata};
use rustc_data_structures::temp_dir::MaybeTempDir;
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_middle::ty::TyCtxt;
-use rustc_session::config::OutputType;
+use rustc_session::config::{OutFileName, OutputType};
use rustc_session::output::filename_for_metadata;
use rustc_session::{MetadataKind, Session};
use tempfile::Builder as TempFileBuilder;
-use std::fs;
use std::path::{Path, PathBuf};
+use std::{fs, io};
// FIXME(eddyb) maybe include the crate name in this?
pub const METADATA_FILENAME: &str = "lib.rmeta";
@@ -74,23 +75,37 @@ pub fn encode_and_write_metadata(tcx: TyCtxt<'_>) -> (EncodedMetadata, bool) {
// this file always exists.
let need_metadata_file = tcx.sess.opts.output_types.contains_key(&OutputType::Metadata);
let (metadata_filename, metadata_tmpdir) = if need_metadata_file {
- if let Err(err) = non_durable_rename(&metadata_filename, &out_filename) {
- tcx.sess.emit_fatal(FailedWriteError { filename: out_filename, err });
- }
+ let filename = match out_filename {
+ OutFileName::Real(ref path) => {
+ if let Err(err) = non_durable_rename(&metadata_filename, path) {
+ tcx.sess.emit_fatal(FailedWriteError { filename: path.to_path_buf(), err });
+ }
+ path.clone()
+ }
+ OutFileName::Stdout => {
+ if out_filename.is_tty() {
+ tcx.sess.emit_err(BinaryOutputToTty);
+ } else if let Err(err) = copy_to_stdout(&metadata_filename) {
+ tcx.sess
+ .emit_err(FailedCopyToStdout { filename: metadata_filename.clone(), err });
+ }
+ metadata_filename
+ }
+ };
if tcx.sess.opts.json_artifact_notifications {
tcx.sess
.parse_sess
.span_diagnostic
- .emit_artifact_notification(&out_filename, "metadata");
+ .emit_artifact_notification(&out_filename.as_path(), "metadata");
}
- (out_filename, None)
+ (filename, None)
} else {
(metadata_filename, Some(metadata_tmpdir))
};
// Load metadata back to memory: codegen may need to include it in object files.
- let metadata =
- EncodedMetadata::from_path(metadata_filename, metadata_tmpdir).unwrap_or_else(|err| {
+ let metadata = EncodedMetadata::from_path(metadata_filename.clone(), metadata_tmpdir)
+ .unwrap_or_else(|err| {
tcx.sess.emit_fatal(FailedCreateEncodedMetadata { err });
});
@@ -116,3 +131,11 @@ pub fn non_durable_rename(src: &Path, dst: &Path) -> std::io::Result<()> {
let _ = std::fs::remove_file(dst);
std::fs::rename(src, dst)
}
+
+pub fn copy_to_stdout(from: &Path) -> io::Result<()> {
+ let file = fs::File::open(from)?;
+ let mut reader = io::BufReader::new(file);
+ let mut stdout = io::stdout();
+ io::copy(&mut reader, &mut stdout)?;
+ Ok(())
+}
diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs
index 9f664d0f0..87373d997 100644
--- a/compiler/rustc_metadata/src/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
@@ -1,6 +1,6 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(decl_macro)]
-#![feature(drain_filter)]
+#![feature(extract_if)]
#![feature(generators)]
#![feature(iter_from_generator)]
#![feature(let_chains)]
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index ceb348f34..a89d7b464 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -666,31 +666,30 @@ impl<'a> CrateLocator<'a> {
return None;
}
- let root = metadata.get_root();
- if root.is_proc_macro_crate() != self.is_proc_macro {
+ let header = metadata.get_header();
+ if header.is_proc_macro_crate != self.is_proc_macro {
info!(
"Rejecting via proc macro: expected {} got {}",
- self.is_proc_macro,
- root.is_proc_macro_crate(),
+ self.is_proc_macro, header.is_proc_macro_crate,
);
return None;
}
- if self.exact_paths.is_empty() && self.crate_name != root.name() {
+ if self.exact_paths.is_empty() && self.crate_name != header.name {
info!("Rejecting via crate name");
return None;
}
- if root.triple() != &self.triple {
- info!("Rejecting via crate triple: expected {} got {}", self.triple, root.triple());
+ if header.triple != self.triple {
+ info!("Rejecting via crate triple: expected {} got {}", self.triple, header.triple);
self.crate_rejections.via_triple.push(CrateMismatch {
path: libpath.to_path_buf(),
- got: root.triple().to_string(),
+ got: header.triple.to_string(),
});
return None;
}
- let hash = root.hash();
+ let hash = header.hash;
if let Some(expected_hash) = self.hash {
if hash != expected_hash {
info!("Rejecting via hash: expected {} got {}", expected_hash, hash);
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index c83c47e72..0dd7b1197 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -425,7 +425,7 @@ impl<'tcx> Collector<'tcx> {
// can move them to the end of the list below.
let mut existing = self
.libs
- .drain_filter(|lib| {
+ .extract_if(|lib| {
if lib.name.as_str() == passed_lib.name {
// FIXME: This whole logic is questionable, whether modifiers are
// involved or not, library reordering and kind overriding without
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index cc4e60cf6..b9318aee5 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -9,7 +9,7 @@ use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::owned_slice::OwnedSlice;
use rustc_data_structures::svh::Svh;
-use rustc_data_structures::sync::{AppendOnlyVec, Lock, Lrc, OnceCell};
+use rustc_data_structures::sync::{AppendOnlyVec, AtomicBool, Lock, Lrc, OnceCell};
use rustc_data_structures::unhash::UnhashMap;
use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, DeriveProcMacro};
@@ -25,7 +25,7 @@ use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
use rustc_middle::ty::codec::TyDecoder;
use rustc_middle::ty::fast_reject::SimplifiedType;
use rustc_middle::ty::GeneratorDiagnosticData;
-use rustc_middle::ty::{self, ParameterizedOverTcx, Predicate, Ty, TyCtxt, Visibility};
+use rustc_middle::ty::{self, ParameterizedOverTcx, Ty, TyCtxt, Visibility};
use rustc_serialize::opaque::MemDecoder;
use rustc_serialize::{Decodable, Decoder};
use rustc_session::cstore::{
@@ -40,6 +40,7 @@ use proc_macro::bridge::client::ProcMacro;
use std::iter::TrustedLen;
use std::num::NonZeroUsize;
use std::path::Path;
+use std::sync::atomic::Ordering;
use std::{io, iter, mem};
pub(super) use cstore_impl::provide;
@@ -74,6 +75,7 @@ pub(crate) struct CrateMetadata {
blob: MetadataBlob,
// --- Some data pre-decoded from the metadata blob, usually for performance ---
+ /// Data about the top-level items in a crate, as well as various crate-level metadata.
root: CrateRoot,
/// Trait impl data.
/// FIXME: Used only from queries and can use query cache,
@@ -111,9 +113,10 @@ pub(crate) struct CrateMetadata {
dep_kind: Lock<CrateDepKind>,
/// Filesystem location of this crate.
source: Lrc<CrateSource>,
- /// Whether or not this crate should be consider a private dependency
- /// for purposes of the 'exported_private_dependencies' lint
- private_dep: bool,
+ /// Whether or not this crate should be consider a private dependency.
+ /// Used by the 'exported_private_dependencies' lint, and for determining
+ /// whether to emit suggestions that reference this crate.
+ private_dep: AtomicBool,
/// The hash for the host proc macro. Used to support `-Z dual-proc-macro`.
host_hash: Option<Svh>,
@@ -449,7 +452,7 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for SyntaxContext {
You need to explicitly pass `(crate_metadata_ref, tcx)` to `decode` instead of just `crate_metadata_ref`.");
};
- let cname = cdata.root.name;
+ let cname = cdata.root.name();
rustc_span::hygiene::decode_syntax_context(decoder, &cdata.hygiene_context, |_, id| {
debug!("SpecializedDecoder<SyntaxContext>: decoding {}", id);
cdata
@@ -564,7 +567,7 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
let cnum = u32::decode(decoder);
panic!(
"Decoding of crate {:?} tried to access proc-macro dep {:?}",
- decoder.cdata().root.name,
+ decoder.cdata().root.header.name,
cnum
);
}
@@ -633,7 +636,7 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Symbol {
}
}
-impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [(ty::Predicate<'tcx>, Span)] {
+impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [(ty::Clause<'tcx>, Span)] {
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Self {
ty::codec::RefDecodable::decode(d)
}
@@ -671,6 +674,16 @@ impl MetadataBlob {
.decode(self)
}
+ pub(crate) fn get_header(&self) -> CrateHeader {
+ let slice = &self.blob()[..];
+ let offset = METADATA_HEADER.len();
+
+ let pos_bytes = slice[offset..][..4].try_into().unwrap();
+ let pos = u32::from_be_bytes(pos_bytes) as usize;
+
+ LazyValue::<CrateHeader>::from_position(NonZeroUsize::new(pos).unwrap()).decode(self)
+ }
+
pub(crate) fn get_root(&self) -> CrateRoot {
let slice = &self.blob()[..];
let offset = METADATA_HEADER.len();
@@ -684,18 +697,19 @@ impl MetadataBlob {
pub(crate) fn list_crate_metadata(&self, out: &mut dyn io::Write) -> io::Result<()> {
let root = self.get_root();
writeln!(out, "Crate info:")?;
- writeln!(out, "name {}{}", root.name, root.extra_filename)?;
- writeln!(out, "hash {} stable_crate_id {:?}", root.hash, root.stable_crate_id)?;
+ writeln!(out, "name {}{}", root.name(), root.extra_filename)?;
+ writeln!(out, "hash {} stable_crate_id {:?}", root.hash(), root.stable_crate_id)?;
writeln!(out, "proc_macro {:?}", root.proc_macro_data.is_some())?;
writeln!(out, "=External Dependencies=")?;
for (i, dep) in root.crate_deps.decode(self).enumerate() {
- let CrateDep { name, extra_filename, hash, host_hash, kind } = dep;
+ let CrateDep { name, extra_filename, hash, host_hash, kind, is_private } = dep;
let number = i + 1;
writeln!(
out,
- "{number} {name}{extra_filename} hash {hash} host_hash {host_hash:?} kind {kind:?}"
+ "{number} {name}{extra_filename} hash {hash} host_hash {host_hash:?} kind {kind:?} {privacy}",
+ privacy = if is_private { "private" } else { "public" }
)?;
}
write!(out, "\n")?;
@@ -709,21 +723,17 @@ impl CrateRoot {
}
pub(crate) fn name(&self) -> Symbol {
- self.name
+ self.header.name
}
pub(crate) fn hash(&self) -> Svh {
- self.hash
+ self.header.hash
}
pub(crate) fn stable_crate_id(&self) -> StableCrateId {
self.stable_crate_id
}
- pub(crate) fn triple(&self) -> &TargetTriple {
- &self.triple
- }
-
pub(crate) fn decode_crate_deps<'a>(
&self,
metadata: &'a MetadataBlob,
@@ -794,7 +804,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
bug!(
"CrateMetadata::def_kind({:?}): id not found, in crate {:?} with number {}",
item_id,
- self.root.name,
+ self.root.name(),
self.cnum,
)
})
@@ -844,14 +854,14 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
self,
index: DefIndex,
tcx: TyCtxt<'tcx>,
- ) -> ty::EarlyBinder<&'tcx [(Predicate<'tcx>, Span)]> {
+ ) -> ty::EarlyBinder<&'tcx [(ty::Clause<'tcx>, Span)]> {
let lazy = self.root.tables.explicit_item_bounds.get(self, index);
let output = if lazy.is_default() {
&mut []
} else {
tcx.arena.alloc_from_iter(lazy.decode((self, tcx)))
};
- ty::EarlyBinder(&*output)
+ ty::EarlyBinder::bind(&*output)
}
fn get_variant(
@@ -985,6 +995,15 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
)
}
+ fn get_stripped_cfg_items(self, cnum: CrateNum, tcx: TyCtxt<'tcx>) -> &'tcx [StrippedCfgItem] {
+ let item_names = self
+ .root
+ .stripped_cfg_items
+ .decode((self, tcx))
+ .map(|item| item.map_mod_id(|index| DefId { krate: cnum, index }));
+ tcx.arena.alloc_from_iter(item_names)
+ }
+
/// Iterates over the diagnostic items in the given crate.
fn get_diagnostic_items(self) -> DiagnosticItems {
let mut id_to_name = FxHashMap::default();
@@ -1617,7 +1636,7 @@ impl CrateMetadata {
dependencies,
dep_kind: Lock::new(dep_kind),
source: Lrc::new(source),
- private_dep,
+ private_dep: AtomicBool::new(private_dep),
host_hash,
extern_crate: Lock::new(None),
hygiene_context: Default::default(),
@@ -1665,6 +1684,10 @@ impl CrateMetadata {
self.dep_kind.with_lock(|dep_kind| *dep_kind = f(*dep_kind))
}
+ pub(crate) fn update_and_private_dep(&self, private_dep: bool) {
+ self.private_dep.fetch_and(private_dep, Ordering::SeqCst);
+ }
+
pub(crate) fn required_panic_strategy(&self) -> Option<PanicStrategy> {
self.root.required_panic_strategy
}
@@ -1702,11 +1725,11 @@ impl CrateMetadata {
}
pub(crate) fn name(&self) -> Symbol {
- self.root.name
+ self.root.header.name
}
pub(crate) fn hash(&self) -> Svh {
- self.root.hash
+ self.root.header.hash
}
fn num_def_ids(&self) -> usize {
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 7425963d3..848535fb3 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -218,6 +218,7 @@ provide! { tcx, def_id, other, cdata,
thir_abstract_const => { table }
optimized_mir => { table }
mir_for_ctfe => { table }
+ closure_saved_names_of_captured_variables => { table }
mir_generator_witnesses => { table }
promoted_mir => { table }
def_span => { table }
@@ -231,7 +232,7 @@ provide! { tcx, def_id, other, cdata,
opt_def_kind => { table_direct }
impl_parent => { table }
impl_polarity => { table_direct }
- impl_defaultness => { table_direct }
+ defaultness => { table_direct }
constness => { table_direct }
coerce_unsized_info => { table }
mir_const_qualif => { table }
@@ -285,7 +286,13 @@ provide! { tcx, def_id, other, cdata,
is_ctfe_mir_available => { cdata.is_ctfe_mir_available(def_id.index) }
dylib_dependency_formats => { cdata.get_dylib_dependency_formats(tcx) }
- is_private_dep => { cdata.private_dep }
+ is_private_dep => {
+ // Parallel compiler needs to synchronize type checking and linting (which use this flag)
+ // so that they happen strictly crate loading. Otherwise, the full list of available
+ // impls aren't loaded yet.
+ use std::sync::atomic::Ordering;
+ cdata.private_dep.load(Ordering::Acquire)
+ }
is_panic_runtime => { cdata.root.panic_runtime }
is_compiler_builtins => { cdata.root.compiler_builtins }
has_global_allocator => { cdata.root.has_global_allocator }
@@ -317,9 +324,9 @@ provide! { tcx, def_id, other, cdata,
}
native_libraries => { cdata.get_native_libraries(tcx.sess).collect() }
foreign_modules => { cdata.get_foreign_modules(tcx.sess).map(|m| (m.def_id, m)).collect() }
- crate_hash => { cdata.root.hash }
+ crate_hash => { cdata.root.header.hash }
crate_host_hash => { cdata.host_hash }
- crate_name => { cdata.root.name }
+ crate_name => { cdata.root.header.name }
extra_filename => { cdata.root.extra_filename.clone() }
@@ -339,6 +346,7 @@ provide! { tcx, def_id, other, cdata,
stability_implications => {
cdata.get_stability_implications(tcx).iter().copied().collect()
}
+ stripped_cfg_items => { cdata.get_stripped_cfg_items(cdata.cnum, tcx) }
is_intrinsic => { cdata.get_is_intrinsic(def_id.index) }
defined_lang_items => { cdata.get_lang_items(tcx) }
diagnostic_items => { cdata.get_diagnostic_items() }
@@ -581,7 +589,7 @@ impl CrateStore for CStore {
}
fn crate_name(&self, cnum: CrateNum) -> Symbol {
- self.get_crate_data(cnum).root.name
+ self.get_crate_data(cnum).root.header.name
}
fn stable_crate_id(&self, cnum: CrateNum) -> StableCrateId {
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index f067bca4b..541c19c35 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -3,6 +3,7 @@ use crate::rmeta::def_path_hash_map::DefPathHashMapRef;
use crate::rmeta::table::TableBuilder;
use crate::rmeta::*;
+use rustc_ast::expand::StrippedCfgItem;
use rustc_ast::Attribute;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
@@ -16,9 +17,8 @@ use rustc_hir::def_id::{
CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE,
};
use rustc_hir::definitions::DefPathData;
-use rustc_hir::intravisit::{self, Visitor};
+use rustc_hir::intravisit;
use rustc_hir::lang_items::LangItem;
-use rustc_middle::hir::nested_filter;
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
use rustc_middle::middle::dependency_format::Linkage;
use rustc_middle::middle::exported_symbols::{
@@ -30,7 +30,7 @@ use rustc_middle::query::Providers;
use rustc_middle::traits::specialization_graph;
use rustc_middle::ty::codec::TyEncoder;
use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams};
-use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt};
+use rustc_middle::ty::{self, AssocItemContainer, SymbolName, Ty, TyCtxt};
use rustc_middle::util::common::to_readable_str;
use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder};
use rustc_session::config::{CrateType, OptLevel};
@@ -449,18 +449,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
LazyArray::from_position_and_num_elems(pos, len)
}
- fn encode_info_for_items(&mut self) {
- self.encode_info_for_mod(CRATE_DEF_ID);
-
- // Proc-macro crates only export proc-macro items, which are looked
- // up using `proc_macro_data`
- if self.is_proc_macro {
- return;
- }
-
- self.tcx.hir().visit_all_item_likes_in_crate(self);
- }
-
fn encode_def_path_table(&mut self) {
let table = self.tcx.def_path_table();
if self.is_proc_macro {
@@ -584,6 +572,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
(self.encode_lang_items(), self.encode_lang_items_missing())
});
+ let stripped_cfg_items = stat!("stripped-cfg-items", || self.encode_stripped_cfg_items());
+
let diagnostic_items = stat!("diagnostic-items", || self.encode_diagnostic_items());
let native_libraries = stat!("native-libs", || self.encode_native_libraries());
@@ -604,8 +594,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
_ = stat!("def-ids", || self.encode_def_ids());
- _ = stat!("items", || self.encode_info_for_items());
-
let interpret_alloc_index = stat!("interpret-alloc-index", || {
let mut interpret_alloc_index = Vec::new();
let mut n = 0;
@@ -662,10 +650,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let root = stat!("final", || {
let attrs = tcx.hir().krate_attrs();
self.lazy(CrateRoot {
- name: tcx.crate_name(LOCAL_CRATE),
+ header: CrateHeader {
+ name: tcx.crate_name(LOCAL_CRATE),
+ triple: tcx.sess.opts.target_triple.clone(),
+ hash: tcx.crate_hash(LOCAL_CRATE),
+ is_proc_macro_crate: proc_macro_data.is_some(),
+ },
extra_filename: tcx.sess.opts.cg.extra_filename.clone(),
- triple: tcx.sess.opts.target_triple.clone(),
- hash: tcx.crate_hash(LOCAL_CRATE),
stable_crate_id: tcx.def_path_hash(LOCAL_CRATE.as_def_id()).stable_crate_id(),
required_panic_strategy: tcx.required_panic_strategy(LOCAL_CRATE),
panic_in_drop_strategy: tcx.sess.opts.unstable_opts.panic_in_drop,
@@ -691,6 +682,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
lang_items,
diagnostic_items,
lang_items_missing,
+ stripped_cfg_items,
native_libraries,
foreign_modules,
source_map,
@@ -1131,8 +1123,8 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
| DefKind::InlineConst => true,
DefKind::OpaqueTy => {
- let opaque = tcx.hir().expect_item(def_id).expect_opaque_ty();
- if let hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = opaque.origin
+ let origin = tcx.opaque_type_origin(def_id);
+ if let hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin
&& let hir::Node::TraitItem(trait_item) = tcx.hir().get_by_def_id(fn_def_id)
&& let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
{
@@ -1159,10 +1151,10 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
let assoc_item = tcx.associated_item(def_id);
match assoc_item.container {
ty::AssocItemContainer::ImplContainer => true,
- // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty) always encode RPITITs,
- // since we need to be able to "project" from an RPITIT associated item
- // to an opaque when installing the default projection predicates in
- // default trait methods with RPITITs.
+ // Always encode RPITITs, since we need to be able to project
+ // from an RPITIT associated item to an opaque when installing
+ // the default projection predicates in default trait methods
+ // with RPITITs.
ty::AssocItemContainer::TraitContainer => {
assoc_item.defaultness(tcx).has_value() || assoc_item.opt_rpitit_info.is_some()
}
@@ -1186,9 +1178,85 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
}
}
+fn should_encode_fn_sig(def_kind: DefKind) -> bool {
+ match def_kind {
+ DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fn) => true,
+
+ DefKind::Struct
+ | DefKind::Union
+ | DefKind::Enum
+ | DefKind::Variant
+ | DefKind::Field
+ | DefKind::Const
+ | DefKind::Static(..)
+ | DefKind::Ctor(..)
+ | DefKind::TyAlias
+ | DefKind::OpaqueTy
+ | DefKind::ImplTraitPlaceholder
+ | DefKind::ForeignTy
+ | DefKind::Impl { .. }
+ | DefKind::AssocConst
+ | DefKind::Closure
+ | DefKind::Generator
+ | DefKind::ConstParam
+ | DefKind::AnonConst
+ | 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,
+ }
+}
+
+fn should_encode_constness(def_kind: DefKind) -> bool {
+ match def_kind {
+ DefKind::Fn
+ | DefKind::AssocFn
+ | DefKind::Closure
+ | DefKind::Impl { of_trait: true }
+ | DefKind::Variant
+ | DefKind::Ctor(..) => true,
+
+ DefKind::Struct
+ | DefKind::Union
+ | DefKind::Enum
+ | DefKind::Field
+ | DefKind::Const
+ | DefKind::AssocConst
+ | DefKind::AnonConst
+ | DefKind::Static(..)
+ | DefKind::TyAlias
+ | DefKind::OpaqueTy
+ | DefKind::Impl { of_trait: false }
+ | DefKind::ImplTraitPlaceholder
+ | DefKind::ForeignTy
+ | 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,
+ }
+}
+
fn should_encode_const(def_kind: DefKind) -> bool {
match def_kind {
- DefKind::Const | DefKind::AssocConst | DefKind::AnonConst => true,
+ DefKind::Const | DefKind::AssocConst | DefKind::AnonConst | DefKind::InlineConst => true,
DefKind::Struct
| DefKind::Union
@@ -1207,7 +1275,6 @@ fn should_encode_const(def_kind: DefKind) -> bool {
| DefKind::Closure
| DefKind::Generator
| DefKind::ConstParam
- | DefKind::InlineConst
| DefKind::AssocTy
| DefKind::TyParam
| DefKind::Trait
@@ -1259,10 +1326,16 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
fn encode_def_ids(&mut self) {
+ self.encode_info_for_mod(CRATE_DEF_ID);
+
+ // Proc-macro crates only export proc-macro items, which are looked
+ // up using `proc_macro_data`
if self.is_proc_macro {
return;
}
+
let tcx = self.tcx;
+
for local_id in tcx.iter_local_def_id() {
let def_id = local_id.to_def_id();
let def_kind = tcx.opt_def_kind(local_id);
@@ -1299,30 +1372,84 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let v = self.tcx.variances_of(def_id);
record_array!(self.tables.variances_of[def_id] <- v);
}
+ if should_encode_fn_sig(def_kind) {
+ record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
+ }
if should_encode_generics(def_kind) {
let g = tcx.generics_of(def_id);
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);
record_defaulted_array!(self.tables.inferred_outlives_of[def_id] <- inferred_outlives);
+
+ for param in &g.params {
+ if let ty::GenericParamDefKind::Const { has_default: true, .. } = param.kind {
+ let default = self.tcx.const_param_default(param.def_id);
+ record!(self.tables.const_param_default[param.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 should_encode_constness(def_kind) {
+ self.tables.constness.set_some(def_id.index, self.tcx.constness(def_id));
+ }
+ if let DefKind::Fn | DefKind::AssocFn = def_kind {
+ self.tables.asyncness.set_some(def_id.index, tcx.asyncness(def_id));
+ record_array!(self.tables.fn_arg_names[def_id] <- tcx.fn_arg_names(def_id));
+ self.tables.is_intrinsic.set(def_id.index, tcx.is_intrinsic(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 = def_kind {
+ record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id));
record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id));
+
+ let module_children = self.tcx.module_children_local(local_id);
+ record_array!(self.tables.module_children_non_reexports[def_id] <-
+ module_children.iter().map(|child| child.res.def_id().index));
}
if let DefKind::TraitAlias = def_kind {
+ record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id));
record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id));
record!(self.tables.implied_predicates_of[def_id] <- self.tcx.implied_predicates_of(def_id));
}
+ if let DefKind::Trait | DefKind::Impl { .. } = def_kind {
+ let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id);
+ record_array!(self.tables.associated_item_or_field_def_ids[def_id] <-
+ associated_item_def_ids.iter().map(|&def_id| {
+ assert!(def_id.is_local());
+ def_id.index
+ })
+ );
+ for &def_id in associated_item_def_ids {
+ self.encode_info_for_assoc_item(def_id);
+ }
+ }
+ if let DefKind::Generator = def_kind {
+ self.encode_info_for_generator(local_id);
+ }
if let DefKind::Enum | DefKind::Struct | DefKind::Union = def_kind {
self.encode_info_for_adt(local_id);
}
+ if let DefKind::Mod = def_kind {
+ self.encode_info_for_mod(local_id);
+ }
+ if let DefKind::Macro(_) = def_kind {
+ self.encode_info_for_macro(local_id);
+ }
+ if let DefKind::OpaqueTy = def_kind {
+ self.encode_explicit_item_bounds(def_id);
+ self.tables
+ .is_type_alias_impl_trait
+ .set(def_id.index, self.tcx.is_type_alias_impl_trait(def_id));
+ }
+ if let DefKind::ImplTraitPlaceholder = def_kind {
+ self.encode_explicit_item_bounds(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)
{
@@ -1383,26 +1510,23 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
};
record!(self.tables.variant_data[variant.def_id] <- data);
- self.tables.constness.set_some(variant.def_id.index, hir::Constness::Const);
record_array!(self.tables.associated_item_or_field_def_ids[variant.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 {
- 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);
}
}
}
+ #[instrument(level = "debug", skip(self))]
fn encode_info_for_mod(&mut self, local_def_id: LocalDefId) {
let tcx = self.tcx;
let def_id = local_def_id.to_def_id();
- debug!("EncodeContext::encode_info_for_mod({:?})", def_id);
// If we are encoding a proc-macro crates, `encode_info_for_mod` will
// only ever get called for the crate root. We still want to encode
@@ -1430,70 +1554,28 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
record_defaulted_array!(self.tables.explicit_item_bounds[def_id] <- bounds);
}
- fn encode_info_for_trait_item(&mut self, def_id: DefId) {
- debug!("EncodeContext::encode_info_for_trait_item({:?})", def_id);
+ #[instrument(level = "debug", skip(self))]
+ fn encode_info_for_assoc_item(&mut self, def_id: DefId) {
let tcx = self.tcx;
+ let item = tcx.associated_item(def_id);
- let impl_defaultness = tcx.impl_defaultness(def_id.expect_local());
- self.tables.impl_defaultness.set_some(def_id.index, impl_defaultness);
- let trait_item = tcx.associated_item(def_id);
- self.tables.assoc_container.set_some(def_id.index, trait_item.container);
+ self.tables.defaultness.set_some(def_id.index, item.defaultness(tcx));
+ self.tables.assoc_container.set_some(def_id.index, 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_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);
+ match item.container {
+ AssocItemContainer::TraitContainer => {
+ if let ty::AssocKind::Type = item.kind {
+ self.encode_explicit_item_bounds(def_id);
+ }
}
- }
- if trait_item.kind == ty::AssocKind::Fn {
- record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
- }
- if let Some(rpitit_info) = trait_item.opt_rpitit_info {
- let rpitit_info = self.lazy(rpitit_info);
- self.tables.opt_rpitit_info.set_some(def_id.index, rpitit_info);
- }
- }
-
- fn encode_info_for_impl_item(&mut self, def_id: DefId) {
- debug!("EncodeContext::encode_info_for_impl_item({:?})", def_id);
- let tcx = self.tcx;
-
- let defaultness = self.tcx.impl_defaultness(def_id.expect_local());
- self.tables.impl_defaultness.set_some(def_id.index, defaultness);
- let impl_item = self.tcx.associated_item(def_id);
- self.tables.assoc_container.set_some(def_id.index, impl_item.container);
-
- match impl_item.kind {
- ty::AssocKind::Fn => {
- let (sig, body) =
- self.tcx.hir().expect_impl_item(def_id.expect_local()).expect_fn();
- 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) {
- hir::Constness::Const
- } else {
- hir::Constness::NotConst
- };
- self.tables.constness.set_some(def_id.index, constness);
+ AssocItemContainer::ImplContainer => {
+ if let Some(trait_item_def_id) = item.trait_item_def_id {
+ self.tables.trait_item_def_id.set_some(def_id.index, trait_item_def_id.into());
+ }
}
- 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_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));
- self.tables.is_intrinsic.set(def_id.index, tcx.is_intrinsic(def_id));
}
- if let Some(rpitit_info) = impl_item.opt_rpitit_info {
- let rpitit_info = self.lazy(rpitit_info);
- self.tables.opt_rpitit_info.set_some(def_id.index, rpitit_info);
+ if let Some(rpitit_info) = item.opt_rpitit_info {
+ record!(self.tables.opt_rpitit_info[def_id] <- rpitit_info);
}
}
@@ -1514,6 +1596,8 @@ 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));
+ record!(self.tables.closure_saved_names_of_captured_variables[def_id.to_def_id()]
+ <- tcx.closure_saved_names_of_captured_variables(def_id));
if tcx.sess.opts.unstable_opts.drop_tracking_mir
&& let DefKind::Generator = self.tcx.def_kind(def_id)
@@ -1564,9 +1648,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
}
+ #[instrument(level = "debug", skip(self))]
fn encode_stability(&mut self, def_id: DefId) {
- debug!("EncodeContext::encode_stability({:?})", def_id);
-
// The query lookup can take a measurable amount of time in crates with many items. Check if
// the stability attributes are even enabled before using their queries.
if self.feat.staged_api || self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked {
@@ -1576,9 +1659,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
}
+ #[instrument(level = "debug", skip(self))]
fn encode_const_stability(&mut self, def_id: DefId) {
- debug!("EncodeContext::encode_const_stability({:?})", def_id);
-
// The query lookup can take a measurable amount of time in crates with many items. Check if
// the stability attributes are even enabled before using their queries.
if self.feat.staged_api || self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked {
@@ -1588,9 +1670,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
}
+ #[instrument(level = "debug", skip(self))]
fn encode_default_body_stability(&mut self, def_id: DefId) {
- debug!("EncodeContext::encode_default_body_stability({:?})", def_id);
-
// The query lookup can take a measurable amount of time in crates with many items. Check if
// the stability attributes are even enabled before using their queries.
if self.feat.staged_api || self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked {
@@ -1600,8 +1681,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
}
+ #[instrument(level = "debug", skip(self))]
fn encode_deprecation(&mut self, def_id: DefId) {
- debug!("EncodeContext::encode_deprecation({:?})", def_id);
if let Some(depr) = self.tcx.lookup_deprecation(def_id) {
record!(self.tables.lookup_deprecation_entry[def_id] <- depr);
}
@@ -1615,123 +1696,22 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
})
}
- fn encode_info_for_item(&mut self, item: &'tcx hir::Item<'tcx>) {
+ #[instrument(level = "debug", skip(self))]
+ fn encode_info_for_macro(&mut self, def_id: LocalDefId) {
let tcx = self.tcx;
- let def_id = item.owner_id.to_def_id();
- debug!("EncodeContext::encode_info_for_item({:?})", def_id);
-
- let record_associated_item_def_ids = |this: &mut Self, def_ids: &[DefId]| {
- record_array!(this.tables.associated_item_or_field_def_ids[def_id] <- def_ids.iter().map(|&def_id| {
- assert!(def_id.is_local());
- def_id.index
- }))
- };
-
- match item.kind {
- hir::ItemKind::Fn(ref sig, .., body) => {
- 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_some(def_id.index, sig.header.constness);
- record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
- self.tables.is_intrinsic.set(def_id.index, tcx.is_intrinsic(def_id));
- }
- hir::ItemKind::Macro(ref macro_def, _) => {
- 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(..) => {
- self.encode_info_for_mod(item.owner_id.def_id);
- }
- hir::ItemKind::OpaqueTy(ref opaque) => {
- self.encode_explicit_item_bounds(def_id);
- 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_some(def_id.index, *defaultness);
- self.tables.constness.set_some(def_id.index, *constness);
- self.tables.impl_polarity.set_some(def_id.index, self.tcx.impl_polarity(def_id));
-
- if let Some(trait_ref) = self.tcx.impl_trait_ref(def_id) {
- record!(self.tables.impl_trait_ref[def_id] <- 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_some(def_id.index, parent.into());
- }
- }
-
- // if this is an impl of `CoerceUnsized`, create its
- // "unsized info", else just store None
- if Some(trait_ref.def_id) == self.tcx.lang_items().coerce_unsized_trait() {
- let coerce_unsized_info =
- self.tcx.at(item.span).coerce_unsized_info(def_id);
- record!(self.tables.coerce_unsized_info[def_id] <- coerce_unsized_info);
- }
- }
-
- let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id);
- record_associated_item_def_ids(self, associated_item_def_ids);
- for &trait_item_def_id in associated_item_def_ids {
- self.encode_info_for_impl_item(trait_item_def_id);
- }
- }
- hir::ItemKind::Trait(..) => {
- record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id));
- let module_children = tcx.module_children_local(item.owner_id.def_id);
- record_array!(self.tables.module_children_non_reexports[def_id] <-
- module_children.iter().map(|child| child.res.def_id().index));
-
- let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id);
- record_associated_item_def_ids(self, associated_item_def_ids);
- for &item_def_id in associated_item_def_ids {
- self.encode_info_for_trait_item(item_def_id);
- }
- }
- hir::ItemKind::TraitAlias(..) => {
- record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id));
- }
- hir::ItemKind::ExternCrate(_)
- | hir::ItemKind::Use(..)
- | hir::ItemKind::Static(..)
- | hir::ItemKind::Const(..)
- | hir::ItemKind::Enum(..)
- | hir::ItemKind::Struct(..)
- | hir::ItemKind::Union(..)
- | hir::ItemKind::ForeignMod { .. }
- | hir::ItemKind::GlobalAsm(..)
- | hir::ItemKind::TyAlias(..) => {}
- }
+ let hir::ItemKind::Macro(ref macro_def, _) = tcx.hir().expect_item(def_id).kind else { bug!() };
+ self.tables.is_macro_rules.set(def_id.local_def_index, macro_def.macro_rules);
+ record!(self.tables.macro_definition[def_id.to_def_id()] <- &*macro_def.body);
}
#[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`.
+ fn encode_info_for_generator(&mut self, def_id: LocalDefId) {
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);
- match ty.kind() {
- ty::Generator(..) => {
- let data = self.tcx.generator_kind(def_id).unwrap();
- let generator_diagnostic_data = typeck_result.get_generator_diagnostic_data();
- 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(_, substs) => {
- let constness = self.tcx.constness(def_id.to_def_id());
- 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"),
- }
+ let data = self.tcx.generator_kind(def_id).unwrap();
+ let generator_diagnostic_data = typeck_result.get_generator_diagnostic_data();
+ 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);
}
fn encode_native_libraries(&mut self) -> LazyArray<NativeLib> {
@@ -1880,6 +1860,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
host_hash: self.tcx.crate_host_hash(cnum),
kind: self.tcx.dep_kind(cnum),
extra_filename: self.tcx.extra_filename(cnum).clone(),
+ is_private: self.tcx.is_private_dep(cnum),
};
(cnum, dep)
})
@@ -1936,34 +1917,58 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
self.lazy_array(&tcx.lang_items().missing)
}
+ fn encode_stripped_cfg_items(&mut self) -> LazyArray<StrippedCfgItem<DefIndex>> {
+ self.lazy_array(
+ self.tcx
+ .stripped_cfg_items(LOCAL_CRATE)
+ .into_iter()
+ .map(|item| item.clone().map_mod_id(|def_id| def_id.index)),
+ )
+ }
+
fn encode_traits(&mut self) -> LazyArray<DefIndex> {
empty_proc_macro!(self);
self.lazy_array(self.tcx.traits(LOCAL_CRATE).iter().map(|def_id| def_id.index))
}
/// Encodes an index, mapping each trait to its (local) implementations.
+ #[instrument(level = "debug", skip(self))]
fn encode_impls(&mut self) -> LazyArray<TraitImpls> {
- debug!("EncodeContext::encode_traits_and_impls()");
empty_proc_macro!(self);
let tcx = self.tcx;
let mut fx_hash_map: FxHashMap<DefId, Vec<(DefIndex, Option<SimplifiedType>)>> =
FxHashMap::default();
for id in tcx.hir().items() {
- 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();
-
- let simplified_self_ty = fast_reject::simplify_type(
- self.tcx,
- trait_ref.self_ty(),
- TreatParams::AsCandidateKey,
- );
-
- fx_hash_map
- .entry(trait_ref.def_id)
- .or_default()
- .push((id.owner_id.def_id.local_def_index, simplified_self_ty));
+ let DefKind::Impl { of_trait } = tcx.def_kind(id.owner_id) else { continue; };
+ let def_id = id.owner_id.to_def_id();
+
+ self.tables.defaultness.set_some(def_id.index, tcx.defaultness(def_id));
+ self.tables.impl_polarity.set_some(def_id.index, tcx.impl_polarity(def_id));
+
+ if of_trait && let Some(trait_ref) = tcx.impl_trait_ref(def_id) {
+ record!(self.tables.impl_trait_ref[def_id] <- trait_ref);
+
+ let trait_ref = trait_ref.subst_identity();
+ let simplified_self_ty =
+ fast_reject::simplify_type(self.tcx, trait_ref.self_ty(), TreatParams::AsCandidateKey);
+ fx_hash_map
+ .entry(trait_ref.def_id)
+ .or_default()
+ .push((id.owner_id.def_id.local_def_index, simplified_self_ty));
+
+ let trait_def = tcx.trait_def(trait_ref.def_id);
+ if let Some(mut an) = trait_def.ancestors(tcx, def_id).ok() {
+ if let Some(specialization_graph::Node::Impl(parent)) = an.nth(1) {
+ self.tables.impl_parent.set_some(def_id.index, parent.into());
+ }
+ }
+
+ // if this is an impl of `CoerceUnsized`, create its
+ // "unsized info", else just store None
+ if Some(trait_ref.def_id) == tcx.lang_items().coerce_unsized_trait() {
+ let coerce_unsized_info = tcx.coerce_unsized_info(def_id);
+ record!(self.tables.coerce_unsized_info[def_id] <- coerce_unsized_info);
}
}
}
@@ -1991,8 +1996,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
self.lazy_array(&all_impls)
}
+ #[instrument(level = "debug", skip(self))]
fn encode_incoherent_impls(&mut self) -> LazyArray<IncoherentImpls> {
- debug!("EncodeContext::encode_traits_and_impls()");
empty_proc_macro!(self);
let tcx = self.tcx;
let mut all_impls: Vec<_> = tcx.crate_inherent_impls(()).incoherent_impls.iter().collect();
@@ -2061,77 +2066,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
LazyArray::default()
}
-
- fn encode_info_for_foreign_item(&mut self, def_id: DefId, nitem: &hir::ForeignItem<'_>) {
- let tcx = self.tcx;
-
- debug!("EncodeContext::encode_info_for_foreign_item({:?})", def_id);
-
- match nitem.kind {
- hir::ForeignItemKind::Fn(_, ref names, _) => {
- 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_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 {
- self.tables.is_intrinsic.set(def_id.index, tcx.is_intrinsic(def_id));
- }
- }
-}
-
-// FIXME(eddyb) make metadata encoding walk over all definitions, instead of HIR.
-impl<'a, 'tcx> Visitor<'tcx> for EncodeContext<'a, 'tcx> {
- type NestedFilter = nested_filter::OnlyBodies;
-
- fn nested_visit_map(&mut self) -> Self::Map {
- self.tcx.hir()
- }
- fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
- intravisit::walk_expr(self, ex);
- self.encode_info_for_expr(ex);
- }
- fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
- intravisit::walk_item(self, item);
- self.encode_info_for_item(item);
- }
- fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem<'tcx>) {
- intravisit::walk_foreign_item(self, ni);
- self.encode_info_for_foreign_item(ni.owner_id.to_def_id(), ni);
- }
- fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) {
- intravisit::walk_generics(self, generics);
- self.encode_info_for_generics(generics);
- }
-}
-
-impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
- fn encode_info_for_generics(&mut self, generics: &hir::Generics<'tcx>) {
- for param in generics.params {
- match param.kind {
- hir::GenericParamKind::Lifetime { .. } | hir::GenericParamKind::Type { .. } => {}
- hir::GenericParamKind::Const { ref default, .. } => {
- let def_id = param.def_id.to_def_id();
- if default.is_some() {
- record!(self.tables.const_param_default[def_id] <- self.tcx.const_param_default(def_id))
- }
- }
- }
- }
- }
-
- fn encode_info_for_expr(&mut self, expr: &hir::Expr<'_>) {
- if let hir::ExprKind::Closure(closure) = expr.kind {
- self.encode_info_for_closure(closure.def_id);
- }
- }
}
/// Used to prefetch queries which will be needed later by metadata encoding.
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 97e67fcf8..9cffd96f4 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -6,6 +6,7 @@ use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
use table::TableBuilder;
use rustc_ast as ast;
+use rustc_ast::expand::StrippedCfgItem;
use rustc_attr as attr;
use rustc_data_structures::svh::Svh;
use rustc_hir as hir;
@@ -31,7 +32,7 @@ use rustc_span::edition::Edition;
use rustc_span::hygiene::{ExpnIndex, MacroKind};
use rustc_span::symbol::{Ident, Symbol};
use rustc_span::{self, ExpnData, ExpnHash, ExpnId, Span};
-use rustc_target::abi::VariantIdx;
+use rustc_target::abi::{FieldIdx, VariantIdx};
use rustc_target::spec::{PanicStrategy, TargetTriple};
use std::marker::PhantomData;
@@ -56,7 +57,7 @@ pub(crate) fn rustc_version(cfg_version: &'static str) -> String {
/// Metadata encoding version.
/// N.B., increment this if you change the format of metadata such that
/// the rustc version can't be found to compare with `rustc_version()`.
-const METADATA_VERSION: u8 = 7;
+const METADATA_VERSION: u8 = 8;
/// Metadata header which includes `METADATA_VERSION`.
///
@@ -199,7 +200,27 @@ pub(crate) struct ProcMacroData {
macros: LazyArray<DefIndex>,
}
-/// Serialized metadata for a crate.
+/// Serialized crate metadata.
+///
+/// This contains just enough information to determine if we should load the `CrateRoot` or not.
+/// Prefer [`CrateRoot`] whenever possible to avoid ICEs when using `omit-git-hash` locally.
+/// See #76720 for more details.
+///
+/// If you do modify this struct, also bump the [`METADATA_VERSION`] constant.
+#[derive(MetadataEncodable, MetadataDecodable)]
+pub(crate) struct CrateHeader {
+ pub(crate) triple: TargetTriple,
+ pub(crate) hash: Svh,
+ pub(crate) name: Symbol,
+ /// Whether this is the header for a proc-macro crate.
+ ///
+ /// This is separate from [`ProcMacroData`] to avoid having to update [`METADATA_VERSION`] every
+ /// time ProcMacroData changes.
+ pub(crate) is_proc_macro_crate: bool,
+}
+
+/// Serialized `.rmeta` data for a crate.
+///
/// When compiling a proc-macro crate, we encode many of
/// the `LazyArray<T>` fields as `Lazy::empty()`. This serves two purposes:
///
@@ -217,10 +238,10 @@ pub(crate) struct ProcMacroData {
/// to being unused.
#[derive(MetadataEncodable, MetadataDecodable)]
pub(crate) struct CrateRoot {
- name: Symbol,
- triple: TargetTriple,
+ /// A header used to detect if this is the right crate to load.
+ header: CrateHeader,
+
extra_filename: String,
- hash: Svh,
stable_crate_id: StableCrateId,
required_panic_strategy: Option<PanicStrategy>,
panic_in_drop_strategy: PanicStrategy,
@@ -236,6 +257,7 @@ pub(crate) struct CrateRoot {
stability_implications: LazyArray<(Symbol, Symbol)>,
lang_items: LazyArray<(DefIndex, LangItem)>,
lang_items_missing: LazyArray<LangItem>,
+ stripped_cfg_items: LazyArray<StrippedCfgItem<DefIndex>>,
diagnostic_items: LazyArray<(Symbol, DefIndex)>,
native_libraries: LazyArray<NativeLib>,
foreign_modules: LazyArray<ForeignModule>,
@@ -302,6 +324,7 @@ pub(crate) struct CrateDep {
pub host_hash: Option<Svh>,
pub kind: CrateDepKind,
pub extra_filename: String,
+ pub is_private: bool,
}
#[derive(MetadataEncodable, MetadataDecodable)]
@@ -352,7 +375,7 @@ define_tables! {
is_type_alias_impl_trait: Table<DefIndex, bool>,
attr_flags: Table<DefIndex, AttrFlags>,
def_path_hashes: Table<DefIndex, DefPathHash>,
- explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Predicate<'static>, Span)>>,
+ explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
associated_types_for_impl_traits_in_associated_fn: Table<DefIndex, LazyArray<DefId>>,
@@ -393,13 +416,14 @@ define_tables! {
object_lifetime_default: Table<DefIndex, LazyValue<ObjectLifetimeDefault>>,
optimized_mir: Table<DefIndex, LazyValue<mir::Body<'static>>>,
mir_for_ctfe: Table<DefIndex, LazyValue<mir::Body<'static>>>,
+ closure_saved_names_of_captured_variables: Table<DefIndex, LazyValue<IndexVec<FieldIdx, Symbol>>>,
mir_generator_witnesses: Table<DefIndex, LazyValue<mir::GeneratorLayout<'static>>>,
promoted_mir: Table<DefIndex, LazyValue<IndexVec<mir::Promoted, mir::Body<'static>>>>,
thir_abstract_const: Table<DefIndex, LazyValue<ty::EarlyBinder<ty::Const<'static>>>>,
impl_parent: Table<DefIndex, RawDefId>,
impl_polarity: Table<DefIndex, ty::ImplPolarity>,
constness: Table<DefIndex, hir::Constness>,
- impl_defaultness: Table<DefIndex, hir::Defaultness>,
+ defaultness: Table<DefIndex, hir::Defaultness>,
// FIXME(eddyb) perhaps compute this on the fly if cheap enough?
coerce_unsized_info: Table<DefIndex, LazyValue<ty::adjustment::CoerceUnsizedInfo>>,
mir_const_qualif: Table<DefIndex, LazyValue<mir::ConstQualifs>>,
@@ -465,6 +489,7 @@ trivially_parameterized_over_tcx! {
RawDefId,
TraitImpls,
IncoherentImpls,
+ CrateHeader,
CrateRoot,
CrateDep,
AttrFlags,
diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs
index dda30bce2..f002d7f97 100644
--- a/compiler/rustc_metadata/src/rmeta/table.rs
+++ b/compiler/rustc_metadata/src/rmeta/table.rs
@@ -439,7 +439,7 @@ where
/// Given the metadata, extract out the value at a particular index (if any).
#[inline(never)]
pub(super) fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(&self, metadata: M, i: I) -> T::Value<'tcx> {
- debug!("LazyTable::lookup: index={:?} len={:?}", i, self.encoded_size);
+ trace!("LazyTable::lookup: index={:?} len={:?}", i, self.encoded_size);
let start = self.position.get();
let bytes = &metadata.blob()[start..start + self.encoded_size];