summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_metadata
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:29 +0000
commit631cd5845e8de329d0e227aaa707d7ea228b8f8f (patch)
treea1b87c8f8cad01cf18f7c5f57a08f102771ed303 /compiler/rustc_metadata
parentAdding debian version 1.69.0+dfsg1-1. (diff)
downloadrustc-631cd5845e8de329d0e227aaa707d7ea228b8f8f.tar.xz
rustc-631cd5845e8de329d0e227aaa707d7ea228b8f8f.zip
Merging upstream version 1.70.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_metadata')
-rw-r--r--compiler/rustc_metadata/Cargo.toml1
-rw-r--r--compiler/rustc_metadata/messages.ftl (renamed from compiler/rustc_metadata/locales/en-US.ftl)0
-rw-r--r--compiler/rustc_metadata/src/creader.rs131
-rw-r--r--compiler/rustc_metadata/src/fs.rs26
-rw-r--r--compiler/rustc_metadata/src/lib.rs5
-rw-r--r--compiler/rustc_metadata/src/locator.rs46
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs76
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs204
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs111
-rw-r--r--compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs14
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs402
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs21
-rw-r--r--compiler/rustc_metadata/src/rmeta/table.rs27
13 files changed, 541 insertions, 523 deletions
diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml
index bee5c8541..4d7c133e0 100644
--- a/compiler/rustc_metadata/Cargo.toml
+++ b/compiler/rustc_metadata/Cargo.toml
@@ -18,6 +18,7 @@ rustc_attr = { path = "../rustc_attr" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" }
+rustc_fs_util = { path = "../rustc_fs_util" }
rustc_hir = { path = "../rustc_hir" }
rustc_hir_pretty = { path = "../rustc_hir_pretty" }
rustc_target = { path = "../rustc_target" }
diff --git a/compiler/rustc_metadata/locales/en-US.ftl b/compiler/rustc_metadata/messages.ftl
index 79b8b4172..79b8b4172 100644
--- a/compiler/rustc_metadata/locales/en-US.ftl
+++ b/compiler/rustc_metadata/messages.ftl
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index b05626311..23aceca06 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -6,11 +6,11 @@ use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob
use rustc_ast::expand::allocator::AllocatorKind;
use rustc_ast::{self as ast, *};
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::svh::Svh;
-use rustc_data_structures::sync::MappedReadGuard;
+use rustc_data_structures::sync::{MappedReadGuard, MappedWriteGuard, ReadGuard, WriteGuard};
use rustc_expand::base::SyntaxExtension;
-use rustc_hir::def_id::{CrateNum, LocalDefId, StableCrateId, LOCAL_CRATE};
+use rustc_hir::def_id::{CrateNum, LocalDefId, StableCrateId, StableCrateIdMap, LOCAL_CRATE};
use rustc_hir::definitions::Definitions;
use rustc_index::vec::IndexVec;
use rustc_middle::ty::TyCtxt;
@@ -46,9 +46,8 @@ pub struct CStore {
/// This crate has a `#[alloc_error_handler]` item.
has_alloc_error_handler: bool,
- /// This map is used to verify we get no hash conflicts between
- /// `StableCrateId` values.
- pub(crate) stable_crate_ids: FxHashMap<StableCrateId, CrateNum>,
+ /// The interned [StableCrateId]s.
+ pub(crate) stable_crate_ids: StableCrateIdMap,
/// Unused externs of the crate
unused_externs: Vec<Symbol>,
@@ -133,14 +132,32 @@ impl<'a> std::fmt::Debug for CrateDump<'a> {
impl CStore {
pub fn from_tcx(tcx: TyCtxt<'_>) -> MappedReadGuard<'_, CStore> {
- MappedReadGuard::map(tcx.cstore_untracked(), |c| {
- c.as_any().downcast_ref::<CStore>().expect("`tcx.cstore` is not a `CStore`")
+ ReadGuard::map(tcx.untracked().cstore.read(), |cstore| {
+ cstore.as_any().downcast_ref::<CStore>().expect("`tcx.cstore` is not a `CStore`")
})
}
- fn alloc_new_crate_num(&mut self) -> CrateNum {
- self.metas.push(None);
- CrateNum::new(self.metas.len() - 1)
+ pub fn from_tcx_mut(tcx: TyCtxt<'_>) -> MappedWriteGuard<'_, CStore> {
+ WriteGuard::map(tcx.untracked().cstore.write(), |cstore| {
+ cstore.untracked_as_any().downcast_mut().expect("`tcx.cstore` is not a `CStore`")
+ })
+ }
+
+ fn intern_stable_crate_id(&mut self, root: &CrateRoot) -> Result<CrateNum, CrateError> {
+ assert_eq!(self.metas.len(), self.stable_crate_ids.len());
+ let num = CrateNum::new(self.stable_crate_ids.len());
+ if let Some(&existing) = self.stable_crate_ids.get(&root.stable_crate_id()) {
+ let crate_name0 = root.name();
+ if let Some(crate_name1) = self.metas[existing].as_ref().map(|data| data.name()) {
+ Err(CrateError::StableCrateIdCollision(crate_name0, crate_name1))
+ } else {
+ Err(CrateError::SymbolConflictsCurrent(crate_name0))
+ }
+ } else {
+ self.metas.push(None);
+ self.stable_crate_ids.insert(root.stable_crate_id(), num);
+ Ok(num)
+ }
}
pub fn has_crate_data(&self, cnum: CrateNum) -> bool {
@@ -168,7 +185,7 @@ impl CStore {
fn push_dependencies_in_postorder(&self, deps: &mut Vec<CrateNum>, cnum: CrateNum) {
if !deps.contains(&cnum) {
let data = self.get_crate_data(cnum);
- for &dep in data.dependencies().iter() {
+ for dep in data.dependencies() {
if dep != cnum {
self.push_dependencies_in_postorder(deps, dep);
}
@@ -241,7 +258,7 @@ impl CStore {
}
pub fn new(sess: &Session) -> CStore {
- let mut stable_crate_ids = FxHashMap::default();
+ let mut stable_crate_ids = StableCrateIdMap::default();
stable_crate_ids.insert(sess.local_stable_crate_id(), LOCAL_CRATE);
CStore {
// We add an empty entry for LOCAL_CRATE (which maps to zero) in
@@ -268,9 +285,6 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
) -> Self {
CrateLoader { tcx, cstore, used_extern_options }
}
- pub fn cstore(&self) -> &CStore {
- &self.cstore
- }
fn existing_match(&self, name: Symbol, hash: Option<Svh>, kind: PathKind) -> Option<CrateNum> {
for (cnum, data) in self.cstore.iter_crate_data() {
@@ -339,42 +353,6 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
None
}
- fn verify_no_symbol_conflicts(&self, root: &CrateRoot) -> Result<(), CrateError> {
- // Check for (potential) conflicts with the local crate
- if self.sess.local_stable_crate_id() == root.stable_crate_id() {
- return Err(CrateError::SymbolConflictsCurrent(root.name()));
- }
-
- // Check for conflicts with any crate loaded so far
- for (_, other) in self.cstore.iter_crate_data() {
- // Same stable crate id but different SVH
- if other.stable_crate_id() == root.stable_crate_id() && other.hash() != root.hash() {
- bug!(
- "Previously returned E0523 here. \
- See https://github.com/rust-lang/rust/pull/100599 for additional discussion.\
- root.name() = {}.",
- root.name()
- );
- }
- }
-
- Ok(())
- }
-
- fn verify_no_stable_crate_id_hash_conflicts(
- &mut self,
- root: &CrateRoot,
- cnum: CrateNum,
- ) -> Result<(), CrateError> {
- if let Some(existing) = self.cstore.stable_crate_ids.insert(root.stable_crate_id(), cnum) {
- let crate_name0 = root.name();
- let crate_name1 = self.cstore.get_crate_data(existing).name();
- return Err(CrateError::StableCrateIdCollision(crate_name0, crate_name1));
- }
-
- Ok(())
- }
-
fn register_crate(
&mut self,
host_lib: Option<Library>,
@@ -393,7 +371,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
self.sess.opts.externs.get(name.as_str()).map_or(false, |e| e.is_private_dep);
// Claim this crate number and cache it
- let cnum = self.cstore.alloc_new_crate_num();
+ let cnum = self.cstore.intern_stable_crate_id(&crate_root)?;
info!(
"register crate `{}` (cnum = {}. private_dep = {})",
@@ -429,14 +407,6 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
None
};
- // Perform some verification *after* resolve_crate_deps() above is
- // known to have been successful. It seems that - in error cases - the
- // cstore can be in a temporarily invalid state between cnum allocation
- // and dependency resolution and the verification code would produce
- // ICEs in that case (see #83045).
- self.verify_no_symbol_conflicts(&crate_root)?;
- self.verify_no_stable_crate_id_hash_conflicts(&crate_root, cnum)?;
-
let crate_metadata = CrateMetadata::new(
self.sess,
&self.cstore,
@@ -635,7 +605,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
if cmeta.update_extern_crate(extern_crate) {
// Propagate the extern crate info to dependencies if it was updated.
let extern_crate = ExternCrate { dependency_of: cnum, ..extern_crate };
- for &dep_cnum in cmeta.dependencies().iter() {
+ for dep_cnum in cmeta.dependencies() {
self.update_extern_crate(dep_cnum, extern_crate);
}
}
@@ -717,8 +687,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
// compilation mode also comes into play.
let desired_strategy = self.sess.panic_strategy();
let mut runtime_found = false;
- let mut needs_panic_runtime =
- self.sess.contains_name(&krate.attrs, sym::needs_panic_runtime);
+ let mut needs_panic_runtime = attr::contains_name(&krate.attrs, sym::needs_panic_runtime);
for (cnum, data) in self.cstore.iter_crate_data() {
needs_panic_runtime = needs_panic_runtime || data.needs_panic_runtime();
@@ -786,7 +755,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
info!("loading profiler");
let name = Symbol::intern(&self.sess.opts.unstable_opts.profiler_runtime);
- if name == sym::profiler_builtins && self.sess.contains_name(&krate.attrs, sym::no_core) {
+ if name == sym::profiler_builtins && attr::contains_name(&krate.attrs, sym::no_core) {
self.sess.emit_err(errors::ProfilerBuiltinsNeedsCore);
}
@@ -800,14 +769,14 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
}
fn inject_allocator_crate(&mut self, krate: &ast::Crate) {
- self.cstore.has_global_allocator = match &*global_allocator_spans(&self.sess, krate) {
+ self.cstore.has_global_allocator = match &*global_allocator_spans(krate) {
[span1, span2, ..] => {
self.sess.emit_err(errors::NoMultipleGlobalAlloc { span2: *span2, span1: *span1 });
true
}
spans => !spans.is_empty(),
};
- self.cstore.has_alloc_error_handler = match &*alloc_error_handler_spans(&self.sess, krate) {
+ self.cstore.has_alloc_error_handler = match &*alloc_error_handler_spans(krate) {
[span1, span2, ..] => {
self.sess
.emit_err(errors::NoMultipleAllocErrorHandler { span2: *span2, span1: *span1 });
@@ -819,7 +788,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
// Check to see if we actually need an allocator. This desire comes
// about through the `#![needs_allocator]` attribute and is typically
// written down in liballoc.
- if !self.sess.contains_name(&krate.attrs, sym::needs_allocator)
+ if !attr::contains_name(&krate.attrs, sym::needs_allocator)
&& !self.cstore.iter_crate_data().any(|(_, data)| data.needs_allocator())
{
return;
@@ -878,7 +847,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
// allocator. At this point our allocator request is typically fulfilled
// by the standard library, denoted by the `#![default_lib_allocator]`
// attribute.
- if !self.sess.contains_name(&krate.attrs, sym::default_lib_allocator)
+ if !attr::contains_name(&krate.attrs, sym::default_lib_allocator)
&& !self.cstore.iter_crate_data().any(|(_, data)| data.has_default_lib_allocator())
{
self.sess.emit_err(errors::GlobalAllocRequired);
@@ -1000,7 +969,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
}
None => item.ident.name,
};
- let dep_kind = if self.sess.contains_name(&item.attrs, sym::no_link) {
+ let dep_kind = if attr::contains_name(&item.attrs, sym::no_link) {
CrateDepKind::MacrosOnly
} else {
CrateDepKind::Explicit
@@ -1046,16 +1015,15 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
}
}
-fn global_allocator_spans(sess: &Session, krate: &ast::Crate) -> Vec<Span> {
- struct Finder<'a> {
- sess: &'a Session,
+fn global_allocator_spans(krate: &ast::Crate) -> Vec<Span> {
+ struct Finder {
name: Symbol,
spans: Vec<Span>,
}
- impl<'ast, 'a> visit::Visitor<'ast> for Finder<'a> {
+ impl<'ast> visit::Visitor<'ast> for Finder {
fn visit_item(&mut self, item: &'ast ast::Item) {
if item.ident.name == self.name
- && self.sess.contains_name(&item.attrs, sym::rustc_std_internal_symbol)
+ && attr::contains_name(&item.attrs, sym::rustc_std_internal_symbol)
{
self.spans.push(item.span);
}
@@ -1064,21 +1032,20 @@ fn global_allocator_spans(sess: &Session, krate: &ast::Crate) -> Vec<Span> {
}
let name = Symbol::intern(&AllocatorKind::Global.fn_name(sym::alloc));
- let mut f = Finder { sess, name, spans: Vec::new() };
+ let mut f = Finder { name, spans: Vec::new() };
visit::walk_crate(&mut f, krate);
f.spans
}
-fn alloc_error_handler_spans(sess: &Session, krate: &ast::Crate) -> Vec<Span> {
- struct Finder<'a> {
- sess: &'a Session,
+fn alloc_error_handler_spans(krate: &ast::Crate) -> Vec<Span> {
+ struct Finder {
name: Symbol,
spans: Vec<Span>,
}
- impl<'ast, 'a> visit::Visitor<'ast> for Finder<'a> {
+ impl<'ast> visit::Visitor<'ast> for Finder {
fn visit_item(&mut self, item: &'ast ast::Item) {
if item.ident.name == self.name
- && self.sess.contains_name(&item.attrs, sym::rustc_std_internal_symbol)
+ && attr::contains_name(&item.attrs, sym::rustc_std_internal_symbol)
{
self.spans.push(item.span);
}
@@ -1087,7 +1054,7 @@ fn alloc_error_handler_spans(sess: &Session, krate: &ast::Crate) -> Vec<Span> {
}
let name = Symbol::intern(&AllocatorKind::Global.fn_name(sym::oom));
- let mut f = Finder { sess, name, spans: Vec::new() };
+ let mut f = Finder { name, spans: Vec::new() };
visit::walk_crate(&mut f, krate);
f.spans
}
diff --git a/compiler/rustc_metadata/src/fs.rs b/compiler/rustc_metadata/src/fs.rs
index f64318997..08de828fb 100644
--- a/compiler/rustc_metadata/src/fs.rs
+++ b/compiler/rustc_metadata/src/fs.rs
@@ -6,9 +6,9 @@ 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::{CrateType, OutputType};
+use rustc_session::config::OutputType;
use rustc_session::output::filename_for_metadata;
-use rustc_session::Session;
+use rustc_session::{MetadataKind, Session};
use tempfile::Builder as TempFileBuilder;
use std::fs;
@@ -39,27 +39,6 @@ pub fn emit_wrapper_file(
}
pub fn encode_and_write_metadata(tcx: TyCtxt<'_>) -> (EncodedMetadata, bool) {
- #[derive(PartialEq, Eq, PartialOrd, Ord)]
- enum MetadataKind {
- None,
- Uncompressed,
- Compressed,
- }
-
- let metadata_kind = tcx
- .sess
- .crate_types()
- .iter()
- .map(|ty| match *ty {
- CrateType::Executable | CrateType::Staticlib | CrateType::Cdylib => MetadataKind::None,
-
- CrateType::Rlib => MetadataKind::Uncompressed,
-
- CrateType::Dylib | CrateType::ProcMacro => MetadataKind::Compressed,
- })
- .max()
- .unwrap_or(MetadataKind::None);
-
let crate_name = tcx.crate_name(LOCAL_CRATE);
let out_filename = filename_for_metadata(tcx.sess, crate_name, tcx.output_filenames(()));
// To avoid races with another rustc process scanning the output directory,
@@ -76,6 +55,7 @@ pub fn encode_and_write_metadata(tcx: TyCtxt<'_>) -> (EncodedMetadata, bool) {
// Always create a file at `metadata_filename`, even if we have nothing to write to it.
// This simplifies the creation of the output `out_filename` when requested.
+ let metadata_kind = tcx.sess.metadata_kind();
match metadata_kind {
MetadataKind::None => {
std::fs::File::create(&metadata_filename).unwrap_or_else(|err| {
diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs
index 6f6d3731c..81e62eccb 100644
--- a/compiler/rustc_metadata/src/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
@@ -4,7 +4,6 @@
#![feature(generators)]
#![feature(iter_from_generator)]
#![feature(let_chains)]
-#![feature(once_cell)]
#![feature(proc_macro_internals)]
#![feature(macro_metavar_expr)]
#![feature(min_specialization)]
@@ -23,8 +22,6 @@ extern crate proc_macro;
extern crate rustc_macros;
#[macro_use]
extern crate rustc_middle;
-#[macro_use]
-extern crate rustc_data_structures;
#[macro_use]
extern crate tracing;
@@ -47,4 +44,4 @@ pub use fs::{emit_wrapper_file, METADATA_FILENAME};
pub use native_libs::find_native_static_library;
pub use rmeta::{encode_metadata, EncodedMetadata, METADATA_HEADER};
-fluent_messages! { "../locales/en-US.ftl" }
+fluent_messages! { "../messages.ftl" }
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index 755a24253..c6af8d632 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -218,10 +218,11 @@ use crate::rmeta::{rustc_version, MetadataBlob, METADATA_HEADER};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::memmap::Mmap;
-use rustc_data_structures::owning_ref::OwningRef;
+use rustc_data_structures::owned_slice::slice_owned;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::MetadataRef;
use rustc_errors::{DiagnosticArgValue, FatalError, IntoDiagnosticArg};
+use rustc_fs_util::try_canonicalize;
use rustc_session::config::{self, CrateType};
use rustc_session::cstore::{CrateSource, MetadataLoader};
use rustc_session::filesearch::FileSearch;
@@ -235,8 +236,9 @@ use rustc_target::spec::{Target, TargetTriple};
use snap::read::FrameDecoder;
use std::borrow::Cow;
use std::io::{Read, Result as IoResult, Write};
+use std::ops::Deref;
use std::path::{Path, PathBuf};
-use std::{cmp, fmt, fs};
+use std::{cmp, fmt};
#[derive(Clone)]
pub(crate) struct CrateLocator<'a> {
@@ -441,7 +443,7 @@ impl<'a> CrateLocator<'a> {
info!("lib candidate: {}", spf.path.display());
let (rlibs, rmetas, dylibs) = candidates.entry(hash.to_string()).or_default();
- let path = fs::canonicalize(&spf.path).unwrap_or_else(|_| spf.path.clone());
+ let path = try_canonicalize(&spf.path).unwrap_or_else(|_| spf.path.clone());
if seen_paths.contains(&path) {
continue;
};
@@ -636,7 +638,7 @@ impl<'a> CrateLocator<'a> {
// as well.
if let Some((prev, _)) = &ret {
let sysroot = self.sysroot;
- let sysroot = sysroot.canonicalize().unwrap_or_else(|_| sysroot.to_path_buf());
+ let sysroot = try_canonicalize(sysroot).unwrap_or_else(|_| sysroot.to_path_buf());
if prev.starts_with(&sysroot) {
continue;
}
@@ -760,14 +762,14 @@ impl<'a> CrateLocator<'a> {
}
pub(crate) fn into_error(self, root: Option<CratePaths>) -> CrateError {
- CrateError::LocatorCombined(CombinedLocatorError {
+ CrateError::LocatorCombined(Box::new(CombinedLocatorError {
crate_name: self.crate_name,
root,
triple: self.triple,
dll_prefix: self.target.dll_prefix.to_string(),
dll_suffix: self.target.dll_suffix.to_string(),
crate_rejections: self.crate_rejections,
- })
+ }))
}
}
@@ -789,6 +791,9 @@ fn get_metadata_section<'p>(
loader.get_dylib_metadata(target, filename).map_err(MetadataError::LoadFailure)?;
// The header is uncompressed
let header_len = METADATA_HEADER.len();
+ // header + u32 length of data
+ let data_start = header_len + 4;
+
debug!("checking {} bytes of metadata-version stamp", header_len);
let header = &buf[..cmp::min(header_len, buf.len())];
if header != METADATA_HEADER {
@@ -798,21 +803,26 @@ fn get_metadata_section<'p>(
)));
}
+ // Length of the compressed stream - this allows linkers to pad the section if they want
+ let Ok(len_bytes) = <[u8; 4]>::try_from(&buf[header_len..cmp::min(data_start, buf.len())]) else {
+ return Err(MetadataError::LoadFailure("invalid metadata length found".to_string()));
+ };
+ let compressed_len = u32::from_be_bytes(len_bytes) as usize;
+
// Header is okay -> inflate the actual metadata
- let compressed_bytes = &buf[header_len..];
+ let compressed_bytes = &buf[data_start..(data_start + compressed_len)];
debug!("inflating {} bytes of compressed metadata", compressed_bytes.len());
// Assume the decompressed data will be at least the size of the compressed data, so we
// don't have to grow the buffer as much.
let mut inflated = Vec::with_capacity(compressed_bytes.len());
- match FrameDecoder::new(compressed_bytes).read_to_end(&mut inflated) {
- Ok(_) => rustc_erase_owner!(OwningRef::new(inflated).map_owner_box()),
- Err(_) => {
- return Err(MetadataError::LoadFailure(format!(
- "failed to decompress metadata: {}",
- filename.display()
- )));
- }
- }
+ FrameDecoder::new(compressed_bytes).read_to_end(&mut inflated).map_err(|_| {
+ MetadataError::LoadFailure(format!(
+ "failed to decompress metadata: {}",
+ filename.display()
+ ))
+ })?;
+
+ slice_owned(inflated, Deref::deref)
}
CrateFlavor::Rmeta => {
// mmap the file, because only a small fraction of it is read.
@@ -830,7 +840,7 @@ fn get_metadata_section<'p>(
))
})?;
- rustc_erase_owner!(OwningRef::new(mmap).map_owner_box())
+ slice_owned(mmap, Deref::deref)
}
};
let blob = MetadataBlob::new(raw_bytes);
@@ -948,7 +958,7 @@ pub(crate) enum CrateError {
StableCrateIdCollision(Symbol, Symbol),
DlOpen(String),
DlSym(String),
- LocatorCombined(CombinedLocatorError),
+ LocatorCombined(Box<CombinedLocatorError>),
NonDylibPlugin(Symbol),
}
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index d6f68b2e1..b855c8e43 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -46,7 +46,7 @@ pub fn find_native_static_library(
}
fn find_bundled_library(
- name: Option<Symbol>,
+ name: Symbol,
verbatim: Option<bool>,
kind: NativeLibKind,
has_cfg: bool,
@@ -58,7 +58,7 @@ fn find_bundled_library(
{
let verbatim = verbatim.unwrap_or(false);
let search_paths = &sess.target_filesearch(PathKind::Native).search_path_dirs();
- return find_native_static_library(name.unwrap().as_str(), verbatim, search_paths, sess)
+ return find_native_static_library(name.as_str(), verbatim, search_paths, sess)
.file_name()
.and_then(|s| s.to_str())
.map(Symbol::intern);
@@ -336,10 +336,16 @@ impl<'tcx> Collector<'tcx> {
if name.is_some() || kind.is_some() || modifiers.is_some() || cfg.is_some() {
sess.emit_err(errors::IncompatibleWasmLink { span });
}
- } else if name.is_none() {
- sess.emit_err(errors::LinkRequiresName { span: m.span });
}
+ if wasm_import_module.is_some() {
+ (name, kind) = (wasm_import_module, Some(NativeLibKind::WasmImportModule));
+ }
+ let Some((name, name_span)) = name else {
+ sess.emit_err(errors::LinkRequiresName { span: m.span });
+ continue;
+ };
+
// Do this outside of the loop so that `import_name_type` can be specified before `kind`.
if let Some((_, span)) = import_name_type {
if kind != Some(NativeLibKind::RawDylib) {
@@ -349,8 +355,8 @@ impl<'tcx> Collector<'tcx> {
let dll_imports = match kind {
Some(NativeLibKind::RawDylib) => {
- if let Some((name, span)) = name && name.as_str().contains('\0') {
- sess.emit_err(errors::RawDylibNoNul { span });
+ if name.as_str().contains('\0') {
+ sess.emit_err(errors::RawDylibNoNul { span: name_span });
}
foreign_mod_items
.iter()
@@ -389,7 +395,6 @@ impl<'tcx> Collector<'tcx> {
}
};
- let name = name.map(|(name, _)| name);
let kind = kind.unwrap_or(NativeLibKind::Unspecified);
let filename = find_bundled_library(name, verbatim, kind, cfg.is_some(), sess);
self.libs.push(NativeLib {
@@ -398,7 +403,6 @@ impl<'tcx> Collector<'tcx> {
kind,
cfg,
foreign_module: Some(it.owner_id.to_def_id()),
- wasm_import_module: wasm_import_module.map(|(name, _)| name),
verbatim,
dll_imports,
});
@@ -415,11 +419,7 @@ impl<'tcx> Collector<'tcx> {
self.tcx.sess.emit_err(errors::LibFrameworkApple);
}
if let Some(ref new_name) = lib.new_name {
- let any_duplicate = self
- .libs
- .iter()
- .filter_map(|lib| lib.name.as_ref())
- .any(|n| n.as_str() == lib.name);
+ let any_duplicate = self.libs.iter().any(|n| n.name.as_str() == lib.name);
if new_name.is_empty() {
self.tcx.sess.emit_err(errors::EmptyRenamingTarget { lib_name: &lib.name });
} else if !any_duplicate {
@@ -444,33 +444,28 @@ impl<'tcx> Collector<'tcx> {
let mut existing = self
.libs
.drain_filter(|lib| {
- if let Some(lib_name) = lib.name {
- 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
- // explicit `:rename` in particular.
- if lib.has_modifiers() || passed_lib.has_modifiers() {
- match lib.foreign_module {
- Some(def_id) => {
- self.tcx.sess.emit_err(errors::NoLinkModOverride {
- span: Some(self.tcx.def_span(def_id)),
- })
- }
- None => self
- .tcx
- .sess
- .emit_err(errors::NoLinkModOverride { span: None }),
- };
- }
- if passed_lib.kind != NativeLibKind::Unspecified {
- lib.kind = passed_lib.kind;
- }
- if let Some(new_name) = &passed_lib.new_name {
- lib.name = Some(Symbol::intern(new_name));
- }
- lib.verbatim = passed_lib.verbatim;
- return true;
+ 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
+ // explicit `:rename` in particular.
+ if lib.has_modifiers() || passed_lib.has_modifiers() {
+ match lib.foreign_module {
+ Some(def_id) => self.tcx.sess.emit_err(errors::NoLinkModOverride {
+ span: Some(self.tcx.def_span(def_id)),
+ }),
+ None => {
+ self.tcx.sess.emit_err(errors::NoLinkModOverride { span: None })
+ }
+ };
+ }
+ if passed_lib.kind != NativeLibKind::Unspecified {
+ lib.kind = passed_lib.kind;
+ }
+ if let Some(new_name) = &passed_lib.new_name {
+ lib.name = Symbol::intern(new_name);
}
+ lib.verbatim = passed_lib.verbatim;
+ return true;
}
false
})
@@ -478,7 +473,7 @@ impl<'tcx> Collector<'tcx> {
if existing.is_empty() {
// Add if not found
let new_name: Option<&str> = passed_lib.new_name.as_deref();
- let name = Some(Symbol::intern(new_name.unwrap_or(&passed_lib.name)));
+ let name = Symbol::intern(new_name.unwrap_or(&passed_lib.name));
let sess = self.tcx.sess;
let filename =
find_bundled_library(name, passed_lib.verbatim, passed_lib.kind, false, sess);
@@ -488,7 +483,6 @@ impl<'tcx> Collector<'tcx> {
kind: passed_lib.kind,
cfg: None,
foreign_module: None,
- wasm_import_module: None,
verbatim: passed_lib.verbatim,
dll_imports: Vec::new(),
});
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index b1e59b0a4..9f41dc92f 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -1,13 +1,14 @@
// Decoding metadata from a single crate's metadata
use crate::creader::{CStore, CrateMetadataRef};
+use crate::rmeta::table::IsDefault;
use crate::rmeta::*;
use rustc_ast as ast;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::svh::Svh;
-use rustc_data_structures::sync::{Lock, LockGuard, Lrc, OnceCell};
+use rustc_data_structures::sync::{AppendOnlyVec, Lock, Lrc, OnceCell};
use rustc_data_structures::unhash::UnhashMap;
use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, DeriveProcMacro};
@@ -30,7 +31,6 @@ use rustc_session::cstore::{
};
use rustc_session::Session;
use rustc_span::hygiene::ExpnIndex;
-use rustc_span::source_map::{respan, Spanned};
use rustc_span::symbol::{kw, Ident, Symbol};
use rustc_span::{self, BytePos, ExpnId, Pos, Span, SyntaxContext, DUMMY_SP};
@@ -52,12 +52,6 @@ mod cstore_impl;
#[derive(Clone)]
pub(crate) struct MetadataBlob(Lrc<MetadataRef>);
-// This is needed so we can create an OwningRef into the blob.
-// The data behind a `MetadataBlob` has a stable address because it is
-// contained within an Rc/Arc.
-unsafe impl rustc_data_structures::owning_ref::StableAddress for MetadataBlob {}
-
-// This is needed so we can create an OwningRef into the blob.
impl std::ops::Deref for MetadataBlob {
type Target = [u8];
@@ -110,7 +104,7 @@ pub(crate) struct CrateMetadata {
/// IDs as they are seen from the current compilation session.
cnum_map: CrateNumMap,
/// Same ID set as `cnum_map` plus maybe some injected crates like panic runtime.
- dependencies: Lock<Vec<CrateNum>>,
+ dependencies: AppendOnlyVec<CrateNum>,
/// How to link (or not link) this crate to the currently compiled crate.
dep_kind: Lock<CrateDepKind>,
/// Filesystem location of this crate.
@@ -311,8 +305,11 @@ impl<T: ParameterizedOverTcx> LazyArray<T> {
impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
#[inline]
fn tcx(&self) -> TyCtxt<'tcx> {
- debug_assert!(self.tcx.is_some(), "missing TyCtxt in DecodeContext");
- self.tcx.unwrap()
+ let Some(tcx) = self.tcx else {
+ bug!("No TyCtxt found for decoding. \
+ You need to explicitly pass `(crate_metadata_ref, tcx)` to `decode` instead of just `crate_metadata_ref`.");
+ };
+ tcx
}
#[inline]
@@ -454,7 +451,12 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ast::AttrId {
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for SyntaxContext {
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> SyntaxContext {
let cdata = decoder.cdata();
- let sess = decoder.sess.unwrap();
+
+ let Some(sess) = decoder.sess else {
+ bug!("Cannot decode SyntaxContext without Session.\
+ You need to explicitly pass `(crate_metadata_ref, tcx)` to `decode` instead of just `crate_metadata_ref`.");
+ };
+
let cname = cdata.root.name;
rustc_span::hygiene::decode_syntax_context(decoder, &cdata.hygiene_context, |_, id| {
debug!("SpecializedDecoder<SyntaxContext>: decoding {}", id);
@@ -471,7 +473,11 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for SyntaxContext {
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnId {
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> ExpnId {
let local_cdata = decoder.cdata();
- let sess = decoder.sess.unwrap();
+
+ let Some(sess) = decoder.sess else {
+ bug!("Cannot decode ExpnId without Session. \
+ You need to explicitly pass `(crate_metadata_ref, tcx)` to `decode` instead of just `crate_metadata_ref`.");
+ };
let cnum = CrateNum::decode(decoder);
let index = u32::decode(decoder);
@@ -520,7 +526,8 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
let hi = lo + len;
let Some(sess) = decoder.sess else {
- bug!("Cannot decode Span without Session.")
+ bug!("Cannot decode Span without Session. \
+ You need to explicitly pass `(crate_metadata_ref, tcx)` to `decode` instead of just `crate_metadata_ref`.")
};
// Index of the file in the corresponding crate's list of encoded files.
@@ -743,6 +750,10 @@ impl CrateRoot {
}
impl<'a, 'tcx> CrateMetadataRef<'a> {
+ fn missing(self, descr: &str, id: DefIndex) -> ! {
+ bug!("missing `{descr}` for {:?}", self.local_def_id(id))
+ }
+
fn raw_proc_macro(self, id: DefIndex) -> &'a ProcMacro {
// DefIndex's in root.proc_macro_data have a one-to-one correspondence
// with items in 'raw_proc_macros'.
@@ -776,8 +787,13 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
fn opt_item_ident(self, item_index: DefIndex, sess: &Session) -> Option<Ident> {
let name = self.opt_item_name(item_index)?;
- let span =
- self.root.tables.def_ident_span.get(self, item_index).unwrap().decode((self, sess));
+ let span = self
+ .root
+ .tables
+ .def_ident_span
+ .get(self, item_index)
+ .unwrap_or_else(|| self.missing("def_ident_span", item_index))
+ .decode((self, sess));
Some(Ident::new(name, span))
}
@@ -806,7 +822,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.tables
.def_span
.get(self, index)
- .unwrap_or_else(|| panic!("Missing span for {index:?}"))
+ .unwrap_or_else(|| self.missing("def_span", index))
.decode((self, sess))
}
@@ -841,7 +857,12 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
)
}
- fn get_variant(self, kind: &DefKind, index: DefIndex, parent_did: DefId) -> ty::VariantDef {
+ fn get_variant(
+ self,
+ kind: DefKind,
+ index: DefIndex,
+ parent_did: DefId,
+ ) -> (VariantIdx, ty::VariantDef) {
let adt_kind = match kind {
DefKind::Variant => ty::AdtKind::Enum,
DefKind::Struct => ty::AdtKind::Struct,
@@ -855,27 +876,30 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
if adt_kind == ty::AdtKind::Enum { Some(self.local_def_id(index)) } else { None };
let ctor = data.ctor.map(|(kind, index)| (kind, self.local_def_id(index)));
- ty::VariantDef::new(
- self.item_name(index),
- variant_did,
- ctor,
- data.discr,
- self.root
- .tables
- .children
- .get(self, index)
- .expect("fields are not encoded for a variant")
- .decode(self)
- .map(|index| ty::FieldDef {
- did: self.local_def_id(index),
- name: self.item_name(index),
- vis: self.get_visibility(index),
- })
- .collect(),
- adt_kind,
- parent_did,
- false,
- data.is_non_exhaustive,
+ (
+ data.idx,
+ ty::VariantDef::new(
+ self.item_name(index),
+ variant_did,
+ ctor,
+ data.discr,
+ self.root
+ .tables
+ .children
+ .get(self, index)
+ .expect("fields are not encoded for a variant")
+ .decode(self)
+ .map(|index| ty::FieldDef {
+ did: self.local_def_id(index),
+ name: self.item_name(index),
+ vis: self.get_visibility(index),
+ })
+ .collect(),
+ adt_kind,
+ parent_did,
+ false,
+ data.is_non_exhaustive,
+ ),
)
}
@@ -891,7 +915,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
};
let repr = self.root.tables.repr_options.get(self, item_id).unwrap().decode(self);
- let variants = if let ty::AdtKind::Enum = adt_kind {
+ let mut variants: Vec<_> = if let ty::AdtKind::Enum = adt_kind {
self.root
.tables
.children
@@ -902,27 +926,30 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
let kind = self.def_kind(index);
match kind {
DefKind::Ctor(..) => None,
- _ => Some(self.get_variant(&kind, index, did)),
+ _ => Some(self.get_variant(kind, index, did)),
}
})
.collect()
} else {
- std::iter::once(self.get_variant(&kind, item_id, did)).collect()
+ std::iter::once(self.get_variant(kind, item_id, did)).collect()
};
- tcx.mk_adt_def(did, adt_kind, variants, repr)
- }
+ variants.sort_by_key(|(idx, _)| *idx);
- fn get_generics(self, item_id: DefIndex, sess: &Session) -> ty::Generics {
- self.root.tables.generics_of.get(self, item_id).unwrap().decode((self, sess))
+ tcx.mk_adt_def(
+ did,
+ adt_kind,
+ variants.into_iter().map(|(_, variant)| variant).collect(),
+ repr,
+ )
}
- fn get_visibility(self, id: DefIndex) -> ty::Visibility<DefId> {
+ fn get_visibility(self, id: DefIndex) -> Visibility<DefId> {
self.root
.tables
.visibility
.get(self, id)
- .unwrap()
+ .unwrap_or_else(|| self.missing("visibility", id))
.decode(self)
.map_id(|index| self.local_def_id(index))
}
@@ -932,7 +959,12 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
}
fn get_expn_that_defined(self, id: DefIndex, sess: &Session) -> ExpnId {
- self.root.tables.expn_that_defined.get(self, id).unwrap().decode((self, sess))
+ self.root
+ .tables
+ .expn_that_defined
+ .get(self, id)
+ .unwrap_or_else(|| self.missing("expn_that_defined", id))
+ .decode((self, sess))
}
fn get_debugger_visualizers(self) -> Vec<rustc_span::DebuggerVisualizerFile> {
@@ -979,17 +1011,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
fn get_mod_child(self, id: DefIndex, sess: &Session) -> ModChild {
let ident = self.item_ident(id, sess);
- let kind = self.def_kind(id);
- let def_id = self.local_def_id(id);
- let res = Res::Def(kind, def_id);
+ let res = Res::Def(self.def_kind(id), self.local_def_id(id));
let vis = self.get_visibility(id);
let span = self.get_span(id, sess);
- let macro_rules = match kind {
- DefKind::Macro(..) => self.root.tables.is_macro_rules.get(self, id),
- _ => false,
- };
- ModChild { ident, res, vis, span, macro_rules }
+ ModChild { ident, res, vis, span, reexport_chain: Default::default() }
}
/// Iterates over all named children of the given module,
@@ -1013,10 +1039,14 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
} else {
// Iterate over all children.
for child_index in self.root.tables.children.get(self, id).unwrap().decode(self) {
- yield self.get_mod_child(child_index, sess);
+ // FIXME: Do not encode RPITITs as a part of this list.
+ if self.root.tables.opt_rpitit_info.get(self, child_index).is_none() {
+ yield self.get_mod_child(child_index, sess);
+ }
}
- if let Some(reexports) = self.root.tables.module_reexports.get(self, id) {
+ let reexports = self.root.tables.module_children_reexports.get(self, id);
+ if !reexports.is_default() {
for reexport in reexports.decode((self, sess)) {
yield reexport;
}
@@ -1033,13 +1063,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
self.root.tables.optimized_mir.get(self, id).is_some()
}
- fn module_expansion(self, id: DefIndex, sess: &Session) -> ExpnId {
- match self.def_kind(id) {
- DefKind::Mod | DefKind::Enum | DefKind::Trait => self.get_expn_that_defined(id, sess),
- _ => panic!("Expected module, found {:?}", self.local_def_id(id)),
- }
- }
-
fn get_fn_has_self_parameter(self, id: DefIndex, sess: &'a Session) -> bool {
self.root
.tables
@@ -1066,8 +1089,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
}
fn get_associated_item(self, id: DefIndex, sess: &'a Session) -> ty::AssocItem {
- let name = self.item_name(id);
-
+ let name = if self.root.tables.opt_rpitit_info.get(self, id).is_some() {
+ kw::Empty
+ } else {
+ self.item_name(id)
+ };
let (kind, has_self) = match self.def_kind(id) {
DefKind::AssocConst => (ty::AssocKind::Const, false),
DefKind::AssocFn => (ty::AssocKind::Fn, self.get_fn_has_self_parameter(id, sess)),
@@ -1075,6 +1101,8 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
_ => bug!("cannot get associated-item of `{:?}`", self.def_key(id)),
};
let container = self.root.tables.assoc_container.get(self, id).unwrap();
+ let opt_rpitit_info =
+ self.root.tables.opt_rpitit_info.get(self, id).map(|d| d.decode(self));
ty::AssocItem {
name,
@@ -1083,6 +1111,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
trait_item_def_id: self.get_trait_item_def_id(id),
container,
fn_has_self_parameter: has_self,
+ opt_rpitit_info,
}
}
@@ -1121,33 +1150,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.decode((self, sess))
}
- fn get_struct_field_names(
- self,
- id: DefIndex,
- sess: &'a Session,
- ) -> impl Iterator<Item = Spanned<Symbol>> + 'a {
- self.root
- .tables
- .children
- .get(self, id)
- .expect("fields not encoded for a struct")
- .decode(self)
- .map(move |index| respan(self.get_span(index, sess), self.item_name(index)))
- }
-
- fn get_struct_field_visibilities(
- self,
- id: DefIndex,
- ) -> impl Iterator<Item = Visibility<DefId>> + 'a {
- self.root
- .tables
- .children
- .get(self, id)
- .expect("fields not encoded for a struct")
- .decode(self)
- .map(move |field_index| self.get_visibility(field_index))
- }
-
fn get_inherent_implementations_for_type(
self,
tcx: TyCtxt<'tcx>,
@@ -1612,7 +1614,7 @@ impl CrateMetadata {
.collect();
let alloc_decoding_state =
AllocDecodingState::new(root.interpret_alloc_index.decode(&blob).collect());
- let dependencies = Lock::new(cnum_map.iter().cloned().collect());
+ let dependencies = cnum_map.iter().copied().collect();
// Pre-decode the DefPathHash->DefIndex table. This is a cheap operation
// that does not copy any data. It just does some data verification.
@@ -1652,12 +1654,12 @@ impl CrateMetadata {
cdata
}
- pub(crate) fn dependencies(&self) -> LockGuard<'_, Vec<CrateNum>> {
- self.dependencies.borrow()
+ pub(crate) fn dependencies(&self) -> impl Iterator<Item = CrateNum> + '_ {
+ self.dependencies.iter()
}
pub(crate) fn add_dependency(&self, cnum: CrateNum) {
- self.dependencies.borrow_mut().push(cnum);
+ self.dependencies.push(cnum);
}
pub(crate) fn update_extern_crate(&self, new_extern_crate: ExternCrate) -> bool {
@@ -1721,10 +1723,6 @@ impl CrateMetadata {
self.root.name
}
- pub(crate) fn stable_crate_id(&self) -> StableCrateId {
- self.root.stable_crate_id
- }
-
pub(crate) fn hash(&self) -> Svh {
self.root.hash
}
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 83a0e833e..31798afb8 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -13,14 +13,15 @@ use rustc_middle::arena::ArenaAllocatable;
use rustc_middle::metadata::ModChild;
use rustc_middle::middle::exported_symbols::ExportedSymbol;
use rustc_middle::middle::stability::DeprecationEntry;
+use rustc_middle::query::LocalCrate;
use rustc_middle::ty::fast_reject::SimplifiedType;
use rustc_middle::ty::query::{ExternProviders, Providers};
-use rustc_middle::ty::{self, TyCtxt, Visibility};
-use rustc_session::cstore::{CrateSource, CrateStore};
+use rustc_middle::ty::{self, TyCtxt};
+use rustc_session::cstore::CrateStore;
use rustc_session::{Session, StableCrateId};
use rustc_span::hygiene::{ExpnHash, ExpnId};
-use rustc_span::source_map::{Span, Spanned};
use rustc_span::symbol::{kw, Symbol};
+use rustc_span::Span;
use rustc_data_structures::sync::Lrc;
use std::any::Any;
@@ -226,7 +227,7 @@ provide! { tcx, def_id, other, cdata,
lookup_default_body_stability => { table }
lookup_deprecation_entry => { table }
params_in_repr => { table }
- unused_generic_params => { table }
+ unused_generic_params => { cdata.root.tables.unused_generic_params.get(cdata, def_id.index) }
opt_def_kind => { table_direct }
impl_parent => { table }
impl_polarity => { table_direct }
@@ -252,9 +253,21 @@ provide! { tcx, def_id, other, cdata,
.get(cdata, def_id.index)
.map(|lazy| lazy.decode((cdata, tcx)))
.process_decoded(tcx, || panic!("{def_id:?} does not have trait_impl_trait_tys")))
- }
+ }
+ implied_predicates_of => {
+ cdata
+ .root
+ .tables
+ .implied_predicates_of
+ .get(cdata, def_id.index)
+ .map(|lazy| lazy.decode((cdata, tcx)))
+ .unwrap_or_else(|| {
+ debug_assert_eq!(tcx.def_kind(def_id), DefKind::Trait);
+ tcx.super_predicates_of(def_id)
+ })
+ }
- associated_items_for_impl_trait_in_trait => { table_defaulted_array }
+ associated_types_for_impl_traits_in_associated_fn => { table_defaulted_array }
visibility => { cdata.get_visibility(def_id.index) }
adt_def => { cdata.get_adt_def(def_id.index, tcx) }
@@ -367,10 +380,7 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
*providers = Providers {
allocator_kind: |tcx, ()| CStore::from_tcx(tcx).allocator_kind(),
alloc_error_handler_kind: |tcx, ()| CStore::from_tcx(tcx).alloc_error_handler_kind(),
- is_private_dep: |_tcx, cnum| {
- assert_eq!(cnum, LOCAL_CRATE);
- false
- },
+ is_private_dep: |_tcx, LocalCrate| false,
native_library: |tcx, id| {
tcx.native_libraries(id.krate)
.iter()
@@ -386,12 +396,8 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
.contains(&id)
})
},
- native_libraries: |tcx, cnum| {
- assert_eq!(cnum, LOCAL_CRATE);
- native_libs::collect(tcx)
- },
- foreign_modules: |tcx, cnum| {
- assert_eq!(cnum, LOCAL_CRATE);
+ native_libraries: |tcx, LocalCrate| native_libs::collect(tcx),
+ foreign_modules: |tcx, LocalCrate| {
foreign_modules::collect(tcx).into_iter().map(|m| (m.def_id, m)).collect()
},
@@ -489,47 +495,27 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
},
dependency_formats: |tcx, ()| Lrc::new(crate::dependency_format::calculate(tcx)),
- has_global_allocator: |tcx, cnum| {
- assert_eq!(cnum, LOCAL_CRATE);
- CStore::from_tcx(tcx).has_global_allocator()
- },
- has_alloc_error_handler: |tcx, cnum| {
- assert_eq!(cnum, LOCAL_CRATE);
- CStore::from_tcx(tcx).has_alloc_error_handler()
- },
+ has_global_allocator: |tcx, LocalCrate| CStore::from_tcx(tcx).has_global_allocator(),
+ has_alloc_error_handler: |tcx, LocalCrate| CStore::from_tcx(tcx).has_alloc_error_handler(),
postorder_cnums: |tcx, ()| {
tcx.arena
.alloc_slice(&CStore::from_tcx(tcx).crate_dependencies_in_postorder(LOCAL_CRATE))
},
- crates: |tcx, ()| tcx.arena.alloc_from_iter(CStore::from_tcx(tcx).crates_untracked()),
+ crates: |tcx, ()| {
+ // The list of loaded crates is now frozen in query cache,
+ // so make sure cstore is not mutably accessed from here on.
+ tcx.untracked().cstore.leak();
+ tcx.arena.alloc_from_iter(CStore::from_tcx(tcx).iter_crate_data().map(|(cnum, _)| cnum))
+ },
..*providers
};
}
impl CStore {
- pub fn struct_field_names_untracked<'a>(
- &'a self,
- def: DefId,
- sess: &'a Session,
- ) -> impl Iterator<Item = Spanned<Symbol>> + 'a {
- self.get_crate_data(def.krate).get_struct_field_names(def.index, sess)
- }
-
- pub fn struct_field_visibilities_untracked(
- &self,
- def: DefId,
- ) -> impl Iterator<Item = Visibility<DefId>> + '_ {
- self.get_crate_data(def.krate).get_struct_field_visibilities(def.index)
- }
-
pub fn ctor_untracked(&self, def: DefId) -> Option<(CtorKind, DefId)> {
self.get_crate_data(def.krate).get_ctor(def.index)
}
- pub fn visibility_untracked(&self, def: DefId) -> Visibility<DefId> {
- self.get_crate_data(def.krate).get_visibility(def.index)
- }
-
pub fn module_children_untracked<'a>(
&'a self,
def_id: DefId,
@@ -566,32 +552,16 @@ impl CStore {
)
}
- pub fn fn_has_self_parameter_untracked(&self, def: DefId, sess: &Session) -> bool {
- self.get_crate_data(def.krate).get_fn_has_self_parameter(def.index, sess)
- }
-
- pub fn crate_source_untracked(&self, cnum: CrateNum) -> Lrc<CrateSource> {
- self.get_crate_data(cnum).source.clone()
- }
-
- pub fn get_span_untracked(&self, def_id: DefId, sess: &Session) -> Span {
+ pub fn def_span_untracked(&self, def_id: DefId, sess: &Session) -> Span {
self.get_crate_data(def_id.krate).get_span(def_id.index, sess)
}
- pub fn def_kind(&self, def: DefId) -> DefKind {
+ pub fn def_kind_untracked(&self, def: DefId) -> DefKind {
self.get_crate_data(def.krate).def_kind(def.index)
}
- pub fn crates_untracked(&self) -> impl Iterator<Item = CrateNum> + '_ {
- self.iter_crate_data().map(|(cnum, _)| cnum)
- }
-
- pub fn item_generics_num_lifetimes(&self, def_id: DefId, sess: &Session) -> usize {
- self.get_crate_data(def_id.krate).get_generics(def_id.index, sess).own_counts().lifetimes
- }
-
- pub fn module_expansion_untracked(&self, def_id: DefId, sess: &Session) -> ExpnId {
- self.get_crate_data(def_id.krate).module_expansion(def_id.index, sess)
+ pub fn expn_that_defined_untracked(&self, def_id: DefId, sess: &Session) -> ExpnId {
+ self.get_crate_data(def_id.krate).get_expn_that_defined(def_id.index, sess)
}
/// Only public-facing way to traverse all the definitions in a non-local crate.
@@ -601,14 +571,6 @@ impl CStore {
self.get_crate_data(cnum).num_def_ids()
}
- pub fn item_attrs_untracked<'a>(
- &'a self,
- def_id: DefId,
- sess: &'a Session,
- ) -> impl Iterator<Item = ast::Attribute> + 'a {
- self.get_crate_data(def_id.krate).get_item_attrs(def_id.index, sess)
- }
-
pub fn get_proc_macro_quoted_span_untracked(
&self,
cnum: CrateNum,
@@ -636,7 +598,10 @@ impl CrateStore for CStore {
}
fn stable_crate_id_to_crate_num(&self, stable_crate_id: StableCrateId) -> CrateNum {
- self.stable_crate_ids[&stable_crate_id]
+ *self
+ .stable_crate_ids
+ .get(&stable_crate_id)
+ .unwrap_or_else(|| bug!("uninterned StableCrateId: {stable_crate_id:?}"))
}
/// Returns the `DefKey` for a given `DefId`. This indicates the
diff --git a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs
index a6133f1b4..02cab561b 100644
--- a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs
+++ b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs
@@ -1,14 +1,14 @@
use crate::rmeta::DecodeContext;
use crate::rmeta::EncodeContext;
-use crate::rmeta::MetadataBlob;
-use rustc_data_structures::owning_ref::OwningRef;
+use rustc_data_structures::owned_slice::slice_owned;
+use rustc_data_structures::owned_slice::OwnedSlice;
use rustc_hir::def_path_hash_map::{Config as HashMapConfig, DefPathHashMap};
use rustc_middle::parameterized_over_tcx;
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use rustc_span::def_id::{DefIndex, DefPathHash};
pub(crate) enum DefPathHashMapRef<'tcx> {
- OwnedFromMetadata(odht::HashTable<HashMapConfig, OwningRef<MetadataBlob, [u8]>>),
+ OwnedFromMetadata(odht::HashTable<HashMapConfig, OwnedSlice>),
BorrowedFromTcx(&'tcx DefPathHashMap),
}
@@ -50,11 +50,11 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for DefPathHashMapRef<'static>
let len = d.read_usize();
let pos = d.position();
- let o = OwningRef::new(d.blob().clone()).map(|x| &x[pos..pos + len]);
+ let o = slice_owned(d.blob().clone(), |blob| &blob[pos..pos + len]);
- // Although we already have the data we need via the OwningRef, we still need
- // to advance the DecodeContext's position so it's in a valid state after
- // the method. We use read_raw_bytes() for that.
+ // Although we already have the data we need via the `OwnedSlice`, we still need
+ // to advance the `DecodeContext`'s position so it's in a valid state after
+ // the method. We use `read_raw_bytes()` for that.
let _ = d.read_raw_bytes(len);
let inner = odht::HashTable::from_raw_bytes(o).unwrap_or_else(|e| {
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 3ab01f780..e44b133a9 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -24,6 +24,7 @@ use rustc_middle::middle::exported_symbols::{
metadata_symbol_name, ExportedSymbol, SymbolExportInfo,
};
use rustc_middle::mir::interpret;
+use rustc_middle::query::LocalCrate;
use rustc_middle::traits::specialization_graph;
use rustc_middle::ty::codec::TyEncoder;
use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams};
@@ -42,7 +43,6 @@ use std::borrow::Borrow;
use std::collections::hash_map::Entry;
use std::hash::Hash;
use std::io::{Read, Seek, Write};
-use std::iter;
use std::num::NonZeroUsize;
use std::path::{Path, PathBuf};
@@ -111,8 +111,6 @@ impl<'a, 'tcx> Encoder for EncodeContext<'a, 'tcx> {
emit_i8(i8);
emit_bool(bool);
- emit_f64(f64);
- emit_f32(f32);
emit_char(char);
emit_str(&str);
emit_raw_bytes(&[u8]);
@@ -457,7 +455,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
fn encode_info_for_items(&mut self) {
- self.encode_info_for_mod(CRATE_DEF_ID, self.tcx.hir().root_module());
+ self.encode_info_for_mod(CRATE_DEF_ID);
// Proc-macro crates only export proc-macro items, which are looked
// up using `proc_macro_data`
@@ -609,10 +607,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
_ = stat!("mir", || self.encode_mir());
- _ = stat!("items", || {
- self.encode_def_ids();
- self.encode_info_for_items();
- });
+ _ = 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();
@@ -681,17 +678,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
has_global_allocator: tcx.has_global_allocator(LOCAL_CRATE),
has_alloc_error_handler: tcx.has_alloc_error_handler(LOCAL_CRATE),
has_panic_handler: tcx.has_panic_handler(LOCAL_CRATE),
- has_default_lib_allocator: tcx
- .sess
- .contains_name(&attrs, sym::default_lib_allocator),
+ has_default_lib_allocator: attr::contains_name(&attrs, sym::default_lib_allocator),
proc_macro_data,
debugger_visualizers,
- compiler_builtins: tcx.sess.contains_name(&attrs, sym::compiler_builtins),
- needs_allocator: tcx.sess.contains_name(&attrs, sym::needs_allocator),
- needs_panic_runtime: tcx.sess.contains_name(&attrs, sym::needs_panic_runtime),
- no_builtins: tcx.sess.contains_name(&attrs, sym::no_builtins),
- panic_runtime: tcx.sess.contains_name(&attrs, sym::panic_runtime),
- profiler_runtime: tcx.sess.contains_name(&attrs, sym::profiler_runtime),
+ compiler_builtins: attr::contains_name(&attrs, sym::compiler_builtins),
+ needs_allocator: attr::contains_name(&attrs, sym::needs_allocator),
+ needs_panic_runtime: attr::contains_name(&attrs, sym::needs_panic_runtime),
+ no_builtins: attr::contains_name(&attrs, sym::no_builtins),
+ panic_runtime: attr::contains_name(&attrs, sym::panic_runtime),
+ profiler_runtime: attr::contains_name(&attrs, sym::profiler_runtime),
symbol_mangling_version: tcx.sess.opts.get_symbol_mangling_version(),
crate_deps,
@@ -815,7 +810,7 @@ fn analyze_attr(attr: &Attribute, state: &mut AnalyzeAttrState) -> bool {
should_encode
}
-fn should_encode_visibility(def_kind: DefKind) -> bool {
+fn should_encode_span(def_kind: DefKind) -> bool {
match def_kind {
DefKind::Mod
| DefKind::Struct
@@ -827,25 +822,136 @@ fn should_encode_visibility(def_kind: DefKind) -> bool {
| DefKind::ForeignTy
| DefKind::TraitAlias
| DefKind::AssocTy
+ | DefKind::TyParam
+ | DefKind::ConstParam
+ | DefKind::LifetimeParam
| DefKind::Fn
| DefKind::Const
- | DefKind::Static(..)
+ | DefKind::Static(_)
| DefKind::Ctor(..)
| DefKind::AssocFn
| DefKind::AssocConst
- | DefKind::Macro(..)
+ | DefKind::Macro(_)
+ | DefKind::AnonConst
+ | DefKind::InlineConst
+ | DefKind::OpaqueTy
+ | DefKind::Field
+ | DefKind::Impl { .. }
+ | DefKind::Closure
+ | DefKind::Generator => true,
+ DefKind::ExternCrate
| DefKind::Use
| DefKind::ForeignMod
+ | DefKind::ImplTraitPlaceholder
+ | DefKind::GlobalAsm => false,
+ }
+}
+
+fn should_encode_attrs(def_kind: DefKind) -> bool {
+ match def_kind {
+ DefKind::Mod
+ | DefKind::Struct
+ | DefKind::Union
+ | DefKind::Enum
+ | DefKind::Variant
+ | DefKind::Trait
+ | DefKind::TyAlias
+ | DefKind::ForeignTy
+ | DefKind::TraitAlias
+ | DefKind::AssocTy
+ | DefKind::Fn
+ | DefKind::Const
+ | DefKind::Static(_)
+ | DefKind::AssocFn
+ | DefKind::AssocConst
+ | DefKind::Macro(_)
+ | DefKind::Field
+ | DefKind::Impl { .. } => true,
+ DefKind::TyParam
+ | DefKind::ConstParam
+ | DefKind::Ctor(..)
+ | DefKind::ExternCrate
+ | DefKind::Use
+ | DefKind::ForeignMod
+ | DefKind::AnonConst
+ | DefKind::InlineConst
| DefKind::OpaqueTy
| DefKind::ImplTraitPlaceholder
- | DefKind::Impl { .. }
+ | DefKind::LifetimeParam
+ | DefKind::GlobalAsm
+ | DefKind::Closure
+ | DefKind::Generator => false,
+ }
+}
+
+fn should_encode_expn_that_defined(def_kind: DefKind) -> bool {
+ match def_kind {
+ DefKind::Mod
+ | DefKind::Struct
+ | DefKind::Union
+ | DefKind::Enum
+ | DefKind::Variant
+ | DefKind::Trait
+ | DefKind::Impl { .. } => true,
+ DefKind::TyAlias
+ | DefKind::ForeignTy
+ | DefKind::TraitAlias
+ | DefKind::AssocTy
+ | DefKind::TyParam
+ | DefKind::Fn
+ | DefKind::Const
+ | DefKind::ConstParam
+ | DefKind::Static(_)
+ | DefKind::Ctor(..)
+ | DefKind::AssocFn
+ | DefKind::AssocConst
+ | DefKind::Macro(_)
+ | DefKind::ExternCrate
+ | DefKind::Use
+ | DefKind::ForeignMod
+ | DefKind::AnonConst
+ | DefKind::InlineConst
+ | DefKind::OpaqueTy
+ | DefKind::ImplTraitPlaceholder
+ | DefKind::Field
+ | DefKind::LifetimeParam
+ | DefKind::GlobalAsm
+ | DefKind::Closure
+ | DefKind::Generator => false,
+ }
+}
+
+fn should_encode_visibility(def_kind: DefKind) -> bool {
+ match def_kind {
+ DefKind::Mod
+ | DefKind::Struct
+ | DefKind::Union
+ | DefKind::Enum
+ | DefKind::Variant
+ | DefKind::Trait
+ | DefKind::TyAlias
+ | DefKind::ForeignTy
+ | DefKind::TraitAlias
+ | DefKind::AssocTy
+ | DefKind::Fn
+ | DefKind::Const
+ | DefKind::Static(..)
+ | DefKind::Ctor(..)
+ | DefKind::AssocFn
+ | DefKind::AssocConst
+ | DefKind::Macro(..)
| DefKind::Field => true,
- DefKind::TyParam
+ DefKind::Use
+ | DefKind::ForeignMod
+ | DefKind::TyParam
| DefKind::ConstParam
| DefKind::LifetimeParam
| DefKind::AnonConst
| DefKind::InlineConst
+ | DefKind::OpaqueTy
+ | DefKind::ImplTraitPlaceholder
| DefKind::GlobalAsm
+ | DefKind::Impl { .. }
| DefKind::Closure
| DefKind::Generator
| DefKind::ExternCrate => false,
@@ -1016,7 +1122,6 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
| DefKind::Const
| DefKind::Static(..)
| DefKind::TyAlias
- | DefKind::OpaqueTy
| DefKind::ForeignTy
| DefKind::Impl { .. }
| DefKind::AssocFn
@@ -1027,8 +1132,20 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
| DefKind::AnonConst
| 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 hir::Node::TraitItem(trait_item) = tcx.hir().get_by_def_id(fn_def_id)
+ && let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
+ {
+ false
+ } else {
+ true
+ }
+ }
+
DefKind::ImplTraitPlaceholder => {
- let parent_def_id = tcx.impl_trait_in_trait_parent(def_id.to_def_id());
+ let parent_def_id = tcx.impl_trait_in_trait_parent_fn(def_id.to_def_id());
let assoc_item = tcx.associated_item(parent_def_id);
match assoc_item.container {
// Always encode an RPIT in an impl fn, since it always has a body
@@ -1044,7 +1161,13 @@ 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,
- ty::AssocItemContainer::TraitContainer => assoc_item.defaultness(tcx).has_value(),
+ // 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.
+ ty::AssocItemContainer::TraitContainer => {
+ assoc_item.defaultness(tcx).has_value() || assoc_item.opt_rpitit_info.is_some()
+ }
}
}
DefKind::TyParam => {
@@ -1104,7 +1227,7 @@ fn should_encode_const(def_kind: DefKind) -> bool {
// 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
+ if tcx.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
@@ -1147,11 +1270,17 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let def_kind = tcx.opt_def_kind(local_id);
let Some(def_kind) = def_kind else { continue };
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);
- record!(self.tables.expn_that_defined[def_id] <- self.tcx.expn_that_defined(def_id));
- if let Some(ident_span) = tcx.def_ident_span(def_id) {
+ if should_encode_span(def_kind) {
+ let def_span = tcx.def_span(local_id);
+ record!(self.tables.def_span[def_id] <- def_span);
+ }
+ if should_encode_attrs(def_kind) {
+ self.encode_attrs(local_id);
+ }
+ if should_encode_expn_that_defined(def_kind) {
+ record!(self.tables.expn_that_defined[def_id] <- self.tcx.expn_that_defined(def_id));
+ }
+ if should_encode_span(def_kind) && let Some(ident_span) = tcx.def_ident_span(def_id) {
record!(self.tables.def_ident_span[def_id] <- ident_span);
}
if def_kind.has_codegen_attrs() {
@@ -1186,11 +1315,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let default = self.tcx.object_lifetime_default(def_id);
record!(self.tables.object_lifetime_default[def_id] <- default);
}
- if let DefKind::Trait | DefKind::TraitAlias = def_kind {
+ if let DefKind::Trait = def_kind {
record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id));
}
+ if let DefKind::TraitAlias = def_kind {
+ 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::Enum | DefKind::Struct | DefKind::Union = def_kind {
- self.encode_info_for_adt(def_id);
+ self.encode_info_for_adt(local_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)
@@ -1198,8 +1331,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
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 table = tcx.associated_types_for_impl_traits_in_associated_fn(def_id);
+ record_defaulted_array!(self.tables.associated_types_for_impl_traits_in_associated_fn[def_id] <- table);
}
}
@@ -1223,7 +1356,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
#[instrument(level = "trace", skip(self))]
- fn encode_info_for_adt(&mut self, def_id: DefId) {
+ fn encode_info_for_adt(&mut self, local_def_id: LocalDefId) {
+ let def_id = local_def_id.to_def_id();
let tcx = self.tcx;
let adt_def = tcx.adt_def(def_id);
record!(self.tables.repr_options[def_id] <- adt_def.repr());
@@ -1232,15 +1366,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
record!(self.tables.params_in_repr[def_id] <- params_in_repr);
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;
- }
- }
- ));
+ let module_children = tcx.module_children_non_reexports(local_def_id);
+ record_array!(self.tables.children[def_id] <-
+ module_children.iter().map(|def_id| def_id.local_def_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);
@@ -1248,9 +1376,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
// Therefore, the loop over variants will encode its fields as the adt's children.
}
- for variant in adt_def.variants().iter() {
+ for (idx, variant) in adt_def.variants().iter_enumerated() {
let data = VariantData {
discr: variant.discr,
+ idx,
ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)),
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
};
@@ -1272,7 +1401,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
}
- fn encode_info_for_mod(&mut self, local_def_id: LocalDefId, md: &hir::Mod<'_>) {
+ 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);
@@ -1286,38 +1415,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
// Encode this here because we don't do it in encode_def_ids.
record!(self.tables.expn_that_defined[def_id] <- tcx.expn_that_defined(local_def_id));
} else {
- record_array!(self.tables.children[def_id] <- iter::from_generator(|| {
- for item_id in md.item_ids {
- match tcx.hir().item(*item_id).kind {
- // Foreign items are planted into their parent modules
- // from name resolution point of view.
- hir::ItemKind::ForeignMod { items, .. } => {
- for foreign_item in items {
- yield foreign_item.id.owner_id.def_id.local_def_index;
- }
- }
- // Only encode named non-reexport children, reexports are encoded
- // separately and unnamed items are not used by name resolution.
- hir::ItemKind::ExternCrate(..) => continue,
- 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_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() => {
- yield item_id.owner_id.def_id.local_def_index;
- }
- _ => continue,
- }
- }
- }));
+ let non_reexports = tcx.module_children_non_reexports(local_def_id);
+ record_array!(self.tables.children[def_id] <-
+ non_reexports.iter().map(|def_id| def_id.local_def_index));
- if let Some(reexports) = tcx.module_reexports(local_def_id) {
- assert!(!reexports.is_empty());
- record_array!(self.tables.module_reexports[def_id] <- reexports);
- }
+ record_defaulted_array!(self.tables.module_children_reexports[def_id] <-
+ tcx.module_children_reexports(local_def_id));
}
}
@@ -1350,19 +1453,24 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
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 ast_item = self.tcx.hir().expect_impl_item(def_id.expect_local());
- self.tables.impl_defaultness.set_some(def_id.index, ast_item.defaultness);
+ 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 ast_item = self.tcx.hir().expect_impl_item(def_id.expect_local());
let hir::ImplItemKind::Fn(ref sig, body) = ast_item.kind else { bug!() };
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));
@@ -1383,6 +1491,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
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);
+ }
}
fn encode_mir(&mut self) {
@@ -1431,9 +1543,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let instance =
ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id.to_def_id()));
let unused = tcx.unused_generic_params(instance);
- if !unused.all_used() {
- record!(self.tables.unused_generic_params[def_id.to_def_id()] <- unused);
- }
+ self.tables.unused_generic_params.set(def_id.local_def_index, unused);
}
// Encode all the deduced parameter attributes for everything that has MIR, even for items
@@ -1503,23 +1613,32 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
})
}
- fn encode_info_for_item(&mut self, def_id: DefId, item: &'tcx hir::Item<'tcx>) {
+ fn encode_info_for_item(&mut self, item: &'tcx hir::Item<'tcx>) {
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.children[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(ref m) => {
- return self.encode_info_for_mod(item.owner_id.def_id, m);
+ 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);
@@ -1530,9 +1649,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
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 = 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) {
@@ -1550,21 +1671,27 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
}
- let polarity = self.tcx.impl_polarity(def_id);
- self.tables.impl_polarity.set_some(def_id.index, polarity);
+ 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(..) => {
- let trait_def = self.tcx.trait_def(def_id);
- record!(self.tables.trait_def[def_id] <- trait_def);
+ record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id));
+
+ 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(..) => {
- let trait_def = self.tcx.trait_def(def_id);
- record!(self.tables.trait_def[def_id] <- trait_def);
+ record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id));
}
- hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) => {
- bug!("cannot encode info for item {:?}", item)
- }
- hir::ItemKind::Static(..)
+ hir::ItemKind::ExternCrate(_)
+ | hir::ItemKind::Use(..)
+ | hir::ItemKind::Static(..)
| hir::ItemKind::Const(..)
| hir::ItemKind::Enum(..)
| hir::ItemKind::Struct(..)
@@ -1572,49 +1699,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
| 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::Impl { .. } | hir::ItemKind::Trait(..) => {
- let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id);
- record_array!(self.tables.children[def_id] <-
- associated_item_def_ids.iter().map(|&def_id| {
- assert!(def_id.is_local());
- def_id.index
- })
- );
- }
- _ => {}
- }
- if let hir::ItemKind::Fn(..) = item.kind {
- 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 hir::ItemKind::Impl { .. } = item.kind {
- if let Some(trait_ref) = self.tcx.impl_trait_ref(def_id) {
- record!(self.tables.impl_trait_ref[def_id] <- trait_ref);
- }
- }
- // In some cases, along with the item itself, we also
- // encode some sub-items. Usually we want some info from the item
- // so it's easier to do that here then to wait until we would encounter
- // normally in the visitor walk.
- match item.kind {
- hir::ItemKind::Impl { .. } => {
- for &trait_item_def_id in
- self.tcx.associated_item_def_ids(item.owner_id.to_def_id()).iter()
- {
- self.encode_info_for_impl_item(trait_item_def_id);
- }
- }
- hir::ItemKind::Trait(..) => {
- for &item_def_id in
- self.tcx.associated_item_def_ids(item.owner_id.to_def_id()).iter()
- {
- self.encode_info_for_trait_item(item_def_id);
- }
- }
- _ => {}
}
}
@@ -1690,8 +1774,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let stability = tcx.lookup_stability(CRATE_DEF_ID);
let macros =
self.lazy_array(tcx.resolutions(()).proc_macros.iter().map(|p| p.local_def_index));
- let spans = self.tcx.sess.parse_sess.proc_macro_quoted_spans();
- for (i, span) in spans.into_iter().enumerate() {
+ for (i, span) in self.tcx.sess.parse_sess.proc_macro_quoted_spans() {
let span = self.lazy(span);
self.tables.proc_macro_quoted_spans.set_some(i, span);
}
@@ -1723,11 +1806,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
// Proc-macros may have attributes like `#[allow_internal_unstable]`,
// so downstream crates need access to them.
let attrs = hir.attrs(proc_macro);
- let macro_kind = if tcx.sess.contains_name(attrs, sym::proc_macro) {
+ let macro_kind = if attr::contains_name(attrs, sym::proc_macro) {
MacroKind::Bang
- } else if tcx.sess.contains_name(attrs, sym::proc_macro_attribute) {
+ } else if attr::contains_name(attrs, sym::proc_macro_attribute) {
MacroKind::Attr
- } else if let Some(attr) = tcx.sess.find_by_name(attrs, sym::proc_macro_derive) {
+ } else if let Some(attr) = attr::find_by_name(attrs, sym::proc_macro_derive) {
// This unwrap chain should have been checked by the proc-macro harness.
name = attr.meta_item_list().unwrap()[0]
.meta_item()
@@ -1858,7 +1941,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let simplified_self_ty = fast_reject::simplify_type(
self.tcx,
trait_ref.self_ty(),
- TreatParams::AsInfer,
+ TreatParams::AsCandidateKey,
);
fx_hash_map
@@ -2001,10 +2084,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EncodeContext<'a, 'tcx> {
}
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
intravisit::walk_item(self, item);
- match item.kind {
- hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) => {} // ignore these
- _ => self.encode_info_for_item(item.owner_id.to_def_id(), item),
- }
+ self.encode_info_for_item(item);
}
fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem<'tcx>) {
intravisit::walk_foreign_item(self, ni);
@@ -2050,13 +2130,13 @@ fn prefetch_mir(tcx: TyCtxt<'_>) {
let (encode_const, encode_opt) = should_encode_mir(tcx, def_id);
if encode_const {
- tcx.ensure().mir_for_ctfe(def_id);
+ tcx.ensure_with_value().mir_for_ctfe(def_id);
}
if encode_opt {
- tcx.ensure().optimized_mir(def_id);
+ tcx.ensure_with_value().optimized_mir(def_id);
}
if encode_opt || encode_const {
- tcx.ensure().promoted_mir(def_id);
+ tcx.ensure_with_value().promoted_mir(def_id);
}
})
}
@@ -2224,18 +2304,16 @@ pub fn provide(providers: &mut Providers) {
doc_link_resolutions: |tcx, def_id| {
tcx.resolutions(())
.doc_link_resolutions
- .get(&def_id.expect_local())
+ .get(&def_id)
.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())
+ .get(&def_id)
.expect("no traits in scope for a doc link")
},
- traits_in_crate: |tcx, cnum| {
- assert_eq!(cnum, LOCAL_CRATE);
-
+ traits_in_crate: |tcx, LocalCrate| {
let mut traits = Vec::new();
for id in tcx.hir().items() {
if matches!(tcx.def_kind(id.owner_id), DefKind::Trait | DefKind::TraitAlias) {
@@ -2247,9 +2325,7 @@ 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);
-
+ trait_impls_in_crate: |tcx, LocalCrate| {
let mut trait_impls = Vec::new();
for id in tcx.hir().items() {
if matches!(tcx.def_kind(id.owner_id), DefKind::Impl { .. })
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index a7ec2d790..67710054c 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -31,6 +31,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::spec::{PanicStrategy, TargetTriple};
use std::marker::PhantomData;
@@ -55,13 +56,13 @@ pub(crate) fn rustc_version() -> 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 = 6;
+const METADATA_VERSION: u8 = 7;
/// Metadata header which includes `METADATA_VERSION`.
///
-/// This header is followed by the position of the `CrateRoot`,
-/// which is encoded as a 32-bit big-endian unsigned integer,
-/// and further followed by the rustc version string.
+/// This header is followed by the length of the compressed data, then
+/// the position of the `CrateRoot`, which is encoded as a 32-bit big-endian
+/// unsigned integer, and further followed by the rustc version string.
pub const METADATA_HEADER: &[u8] = &[b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION];
/// A value of type T referred to by its absolute position
@@ -354,7 +355,10 @@ define_tables! {
explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Predicate<'static>, Span)>>,
inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
- associated_items_for_impl_trait_in_trait: Table<DefIndex, LazyArray<DefId>>,
+ associated_types_for_impl_traits_in_associated_fn: Table<DefIndex, LazyArray<DefId>>,
+ opt_rpitit_info: Table<DefIndex, Option<LazyValue<ty::ImplTraitInTraitData>>>,
+ unused_generic_params: Table<DefIndex, UnusedGenericParams>,
+ module_children_reexports: Table<DefIndex, LazyArray<ModChild>>,
- optional:
attributes: Table<DefIndex, LazyArray<ast::Attribute>>,
@@ -370,6 +374,9 @@ define_tables! {
explicit_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>,
generics_of: Table<DefIndex, LazyValue<ty::Generics>>,
super_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>,
+ // As an optimization, we only store this for trait aliases,
+ // since it's identical to super_predicates_of for traits.
+ implied_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>,
type_of: Table<DefIndex, LazyValue<ty::EarlyBinder<Ty<'static>>>>,
variances_of: Table<DefIndex, LazyArray<ty::Variance>>,
fn_sig: Table<DefIndex, LazyValue<ty::EarlyBinder<ty::PolyFnSig<'static>>>>,
@@ -381,7 +388,6 @@ define_tables! {
mir_for_ctfe: Table<DefIndex, LazyValue<mir::Body<'static>>>,
mir_generator_witnesses: Table<DefIndex, LazyValue<mir::GeneratorLayout<'static>>>,
promoted_mir: Table<DefIndex, LazyValue<IndexVec<mir::Promoted, mir::Body<'static>>>>,
- // FIXME(compiler-errors): Why isn't this a LazyArray?
thir_abstract_const: Table<DefIndex, LazyValue<ty::Const<'static>>>,
impl_parent: Table<DefIndex, RawDefId>,
impl_polarity: Table<DefIndex, ty::ImplPolarity>,
@@ -397,7 +403,6 @@ define_tables! {
trait_def: Table<DefIndex, LazyValue<ty::TraitDef>>,
trait_item_def_id: Table<DefIndex, RawDefId>,
expn_that_defined: Table<DefIndex, LazyValue<ExpnId>>,
- unused_generic_params: Table<DefIndex, LazyValue<UnusedGenericParams>>,
params_in_repr: Table<DefIndex, LazyValue<BitSet<u32>>>,
repr_options: Table<DefIndex, LazyValue<ReprOptions>>,
// `def_keys` and `def_path_hashes` represent a lazy version of a
@@ -411,7 +416,6 @@ define_tables! {
assoc_container: Table<DefIndex, ty::AssocItemContainer>,
macro_definition: Table<DefIndex, LazyValue<ast::DelimArgs>>,
proc_macro: Table<DefIndex, MacroKind>,
- module_reexports: Table<DefIndex, LazyArray<ModChild>>,
deduced_param_attrs: Table<DefIndex, LazyArray<DeducedParamAttrs>>,
trait_impl_trait_tys: Table<DefIndex, LazyValue<FxHashMap<DefId, Ty<'static>>>>,
doc_link_resolutions: Table<DefIndex, LazyValue<DocLinkResMap>>,
@@ -420,6 +424,7 @@ define_tables! {
#[derive(TyEncodable, TyDecodable)]
struct VariantData {
+ idx: VariantIdx,
discr: ty::VariantDiscr,
/// If this is unit or tuple-variant/struct, then this is the index of the ctor id.
ctor: Option<(CtorKind, DefIndex)>,
diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs
index b89d48ec1..364fa74ab 100644
--- a/compiler/rustc_metadata/src/rmeta/table.rs
+++ b/compiler/rustc_metadata/src/rmeta/table.rs
@@ -3,7 +3,7 @@ use crate::rmeta::*;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_hir::def::{CtorKind, CtorOf};
use rustc_index::vec::Idx;
-use rustc_middle::ty::ParameterizedOverTcx;
+use rustc_middle::ty::{ParameterizedOverTcx, UnusedGenericParams};
use rustc_serialize::opaque::FileEncoder;
use rustc_serialize::Encoder as _;
use rustc_span::hygiene::MacroKind;
@@ -50,6 +50,16 @@ impl IsDefault for DefPathHash {
}
}
+impl IsDefault for UnusedGenericParams {
+ fn is_default(&self) -> bool {
+ // UnusedGenericParams encodes the *un*usedness as a bitset.
+ // This means that 0 corresponds to all bits used, which is indeed the default.
+ let is_default = self.bits() == 0;
+ debug_assert_eq!(is_default, self.all_used());
+ is_default
+ }
+}
+
/// Helper trait, for encoding to, and decoding from, a fixed number of bytes.
/// Used mainly for Lazy positions and lengths.
/// Unchecked invariant: `Self::default()` should encode as `[0; BYTE_LEN]`,
@@ -271,6 +281,21 @@ impl FixedSizeEncoding for bool {
}
}
+impl FixedSizeEncoding for UnusedGenericParams {
+ type ByteArray = [u8; 4];
+
+ #[inline]
+ fn from_bytes(b: &[u8; 4]) -> Self {
+ let x: u32 = u32::from_bytes(b);
+ UnusedGenericParams::from_bits(x)
+ }
+
+ #[inline]
+ fn write_to_bytes(self, b: &mut [u8; 4]) {
+ self.bits().write_to_bytes(b);
+ }
+}
+
// NOTE(eddyb) there could be an impl for `usize`, which would enable a more
// generic `LazyValue<T>` impl, but in the general case we might not need / want
// to fit every `usize` in `u32`.