diff options
Diffstat (limited to 'compiler/rustc_metadata')
| -rw-r--r-- | compiler/rustc_metadata/Cargo.toml | 2 | ||||
| -rw-r--r-- | compiler/rustc_metadata/messages.ftl | 3 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/creader.rs | 237 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/errors.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/foreign_modules.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/locator.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/decoder.rs | 43 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/encoder.rs | 25 |
9 files changed, 220 insertions, 116 deletions
diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml index 0b9fdbbd3da..a8821640f04 100644 --- a/compiler/rustc_metadata/Cargo.toml +++ b/compiler/rustc_metadata/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_metadata" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl index 6fc84b06647..df0a25712cc 100644 --- a/compiler/rustc_metadata/messages.ftl +++ b/compiler/rustc_metadata/messages.ftl @@ -47,6 +47,9 @@ metadata_crate_dep_rustc_driver = metadata_crate_location_unknown_type = extern location for {$crate_name} is of an unknown type: {$path} +metadata_crate_not_compiler_builtins = + the crate `{$crate_name}` resolved as `compiler_builtins` but is not `#![compiler_builtins]` + metadata_crate_not_panic_runtime = the crate `{$crate_name}` is not a panic runtime diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 6bad8312790..12503ffd1a6 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -32,7 +32,7 @@ use rustc_session::lint::{self, BuiltinLintDiag}; use rustc_session::output::validate_crate_name; use rustc_session::search_paths::PathKind; use rustc_span::edition::Edition; -use rustc_span::{DUMMY_SP, Ident, STDLIB_STABLE_CRATES, Span, Symbol, sym}; +use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym}; use rustc_target::spec::{PanicStrategy, Target, TargetTuple}; use tracing::{debug, info, trace}; @@ -147,6 +147,7 @@ impl<'a> std::fmt::Debug for CrateDump<'a> { writeln!(fmt, " cnum: {cnum}")?; writeln!(fmt, " hash: {}", data.hash())?; writeln!(fmt, " reqd: {:?}", data.dep_kind())?; + writeln!(fmt, " priv: {:?}", data.is_private_dep())?; let CrateSource { dylib, rlib, rmeta } = data.source(); if let Some(dylib) = dylib { writeln!(fmt, " dylib: {}", dylib.0.display())?; @@ -162,6 +163,53 @@ impl<'a> std::fmt::Debug for CrateDump<'a> { } } +/// Reason that a crate is being sourced as a dependency. +#[derive(Clone, Copy)] +enum CrateOrigin<'a> { + /// This crate was a dependency of another crate. + IndirectDependency { + /// Where this dependency was included from. + dep_root: &'a CratePaths, + /// True if the parent is private, meaning the dependent should also be private. + parent_private: bool, + /// Dependency info about this crate. + dep: &'a CrateDep, + }, + /// Injected by `rustc`. + Injected, + /// Provided by `extern crate foo` or as part of the extern prelude. + Extern, +} + +impl<'a> CrateOrigin<'a> { + /// Return the dependency root, if any. + fn dep_root(&self) -> Option<&'a CratePaths> { + match self { + CrateOrigin::IndirectDependency { dep_root, .. } => Some(dep_root), + _ => None, + } + } + + /// Return dependency information, if any. + fn dep(&self) -> Option<&'a CrateDep> { + match self { + CrateOrigin::IndirectDependency { dep, .. } => Some(dep), + _ => None, + } + } + + /// `Some(true)` if the dependency is private or its parent is private, `Some(false)` if the + /// dependency is not private, `None` if it could not be determined. + fn private_dep(&self) -> Option<bool> { + match self { + CrateOrigin::IndirectDependency { parent_private, dep, .. } => { + Some(dep.is_private || *parent_private) + } + _ => None, + } + } +} + impl CStore { pub fn from_tcx(tcx: TyCtxt<'_>) -> FreezeReadGuard<'_, CStore> { FreezeReadGuard::map(tcx.untracked().cstore.read(), |cstore| { @@ -497,25 +545,13 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { &self, name: Symbol, private_dep: Option<bool>, - dep_root: Option<&CratePaths>, + origin: CrateOrigin<'_>, ) -> bool { - // Standard library crates are never private. - if STDLIB_STABLE_CRATES.contains(&name) { - tracing::info!("returning false for {name} is private"); - return false; - } - - let extern_private = self.sess.opts.externs.get(name.as_str()).map(|e| e.is_private_dep); - - // Any descendants of `std` should be private. These crates are usually not marked - // private in metadata, so we ignore that field. - if extern_private.is_none() - && let Some(dep) = dep_root - && STDLIB_STABLE_CRATES.contains(&dep.name) - { + if matches!(origin, CrateOrigin::Injected) { return true; } + let extern_private = self.sess.opts.externs.get(name.as_str()).map(|e| e.is_private_dep); match (extern_private, private_dep) { // Explicit non-private via `--extern`, explicit non-private from metadata, or // unspecified with default to public. @@ -528,7 +564,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { fn register_crate( &mut self, host_lib: Option<Library>, - dep_root: Option<&CratePaths>, + origin: CrateOrigin<'_>, lib: Library, dep_kind: CrateDepKind, name: Symbol, @@ -540,7 +576,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { let Library { source, metadata } = lib; let crate_root = metadata.get_root(); let host_hash = host_lib.as_ref().map(|lib| lib.metadata.get_root().hash()); - let private_dep = self.is_private_dep(name, private_dep, dep_root); + let private_dep = self.is_private_dep(name, private_dep, origin); // Claim this crate number and cache it let feed = self.cstore.intern_stable_crate_id(&crate_root, self.tcx)?; @@ -556,14 +592,15 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { // Maintain a reference to the top most crate. // Stash paths for top-most crate locally if necessary. let crate_paths; - let dep_root = if let Some(dep_root) = dep_root { + let dep_root = if let Some(dep_root) = origin.dep_root() { dep_root } else { crate_paths = CratePaths::new(crate_root.name(), source.clone()); &crate_paths }; - let cnum_map = self.resolve_crate_deps(dep_root, &crate_root, &metadata, cnum, dep_kind)?; + let cnum_map = + self.resolve_crate_deps(dep_root, &crate_root, &metadata, cnum, dep_kind, private_dep)?; let raw_proc_macros = if crate_root.is_proc_macro_crate() { let temp_root; @@ -664,17 +701,19 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { name: Symbol, span: Span, dep_kind: CrateDepKind, + origin: CrateOrigin<'_>, ) -> Option<CrateNum> { self.used_extern_options.insert(name); - match self.maybe_resolve_crate(name, dep_kind, None) { + match self.maybe_resolve_crate(name, dep_kind, origin) { Ok(cnum) => { self.cstore.set_used_recursively(cnum); Some(cnum) } Err(err) => { debug!("failed to resolve crate {} {:?}", name, dep_kind); - let missing_core = - self.maybe_resolve_crate(sym::core, CrateDepKind::Explicit, None).is_err(); + let missing_core = self + .maybe_resolve_crate(sym::core, CrateDepKind::Explicit, CrateOrigin::Extern) + .is_err(); err.report(self.sess, span, missing_core); None } @@ -685,20 +724,20 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { &'b mut self, name: Symbol, mut dep_kind: CrateDepKind, - dep_of: Option<(&'b CratePaths, &'b CrateDep)>, + origin: CrateOrigin<'b>, ) -> Result<CrateNum, CrateError> { info!("resolving crate `{}`", name); if !name.as_str().is_ascii() { return Err(CrateError::NonAsciiName(name)); } - let dep_root = dep_of.map(|d| d.0); - let dep = dep_of.map(|d| d.1); + let dep_root = origin.dep_root(); + let dep = origin.dep(); let hash = dep.map(|d| d.hash); let host_hash = dep.map(|d| d.host_hash).flatten(); let extra_filename = dep.map(|d| &d.extra_filename[..]); let path_kind = if dep.is_some() { PathKind::Dependency } else { PathKind::Crate }; - let private_dep = dep.map(|d| d.is_private); + let private_dep = origin.private_dep(); let result = if let Some(cnum) = self.existing_match(name, hash, path_kind) { (LoadResult::Previous(cnum), None) @@ -731,12 +770,12 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { match result { (LoadResult::Previous(cnum), None) => { - info!("library for `{}` was loaded previously", name); + info!("library for `{}` was loaded previously, cnum {cnum}", name); // When `private_dep` is none, it indicates the directly dependent crate. If it is // not specified by `--extern` on command line parameters, it may be // `private-dependency` when `register_crate` is called for the first time. Then it must be updated to // `public-dependency` here. - let private_dep = self.is_private_dep(name, private_dep, dep_root); + let private_dep = self.is_private_dep(name, private_dep, origin); let data = self.cstore.get_crate_data_mut(cnum); if data.is_proc_macro_crate() { dep_kind = CrateDepKind::MacrosOnly; @@ -747,7 +786,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { } (LoadResult::Loaded(library), host_library) => { info!("register newly loaded library for `{}`", name); - self.register_crate(host_library, dep_root, library, dep_kind, name, private_dep) + self.register_crate(host_library, origin, library, dep_kind, name, private_dep) } _ => panic!(), } @@ -762,29 +801,17 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { // against a hash, we could load a crate which has the same hash // as an already loaded crate. If this is the case prevent // duplicates by just using the first crate. - // - // Note that we only do this for target triple crates, though, as we - // don't want to match a host crate against an equivalent target one - // already loaded. let root = library.metadata.get_root(); - // FIXME: why is this condition necessary? It was adding in #33625 but I - // don't know why and the original author doesn't remember ... - let can_reuse_cratenum = - locator.tuple == self.sess.opts.target_triple || locator.is_proc_macro; - Ok(Some(if can_reuse_cratenum { - let mut result = LoadResult::Loaded(library); - for (cnum, data) in self.cstore.iter_crate_data() { - if data.name() == root.name() && root.hash() == data.hash() { - assert!(locator.hash.is_none()); - info!("load success, going to previous cnum: {}", cnum); - result = LoadResult::Previous(cnum); - break; - } + let mut result = LoadResult::Loaded(library); + for (cnum, data) in self.cstore.iter_crate_data() { + if data.name() == root.name() && root.hash() == data.hash() { + assert!(locator.hash.is_none()); + info!("load success, going to previous cnum: {}", cnum); + result = LoadResult::Previous(cnum); + break; } - result - } else { - LoadResult::Loaded(library) - })) + } + Ok(Some(result)) } /// Go through the crate metadata and load any crates that it references. @@ -795,6 +822,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { metadata: &MetadataBlob, krate: CrateNum, dep_kind: CrateDepKind, + parent_is_private: bool, ) -> Result<CrateNumMap, CrateError> { debug!( "resolving deps of external crate `{}` with dep root `{}`", @@ -813,17 +841,26 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { crate_num_map.push(krate); for dep in deps { info!( - "resolving dep `{}`->`{}` hash: `{}` extra filename: `{}`", + "resolving dep `{}`->`{}` hash: `{}` extra filename: `{}` private {}", crate_root.name(), dep.name, dep.hash, - dep.extra_filename + dep.extra_filename, + dep.is_private, ); let dep_kind = match dep_kind { CrateDepKind::MacrosOnly => CrateDepKind::MacrosOnly, _ => dep.kind, }; - let cnum = self.maybe_resolve_crate(dep.name, dep_kind, Some((dep_root, &dep)))?; + let cnum = self.maybe_resolve_crate( + dep.name, + dep_kind, + CrateOrigin::IndirectDependency { + dep_root, + parent_private: parent_is_private, + dep: &dep, + }, + )?; crate_num_map.push(cnum); } @@ -917,7 +954,9 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { }; info!("panic runtime not found -- loading {}", name); - let Some(cnum) = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit) else { + let Some(cnum) = + self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit, CrateOrigin::Injected) + else { return; }; let data = self.cstore.get_crate_data(cnum); @@ -946,7 +985,9 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { info!("loading profiler"); let name = Symbol::intern(&self.sess.opts.unstable_opts.profiler_runtime); - let Some(cnum) = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit) else { + let Some(cnum) = + self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit, CrateOrigin::Injected) + else { return; }; let data = self.cstore.get_crate_data(cnum); @@ -1059,12 +1100,54 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { if entry.force { let name_interned = Symbol::intern(name); if !self.used_extern_options.contains(&name_interned) { - self.resolve_crate(name_interned, DUMMY_SP, CrateDepKind::Explicit); + self.resolve_crate( + name_interned, + DUMMY_SP, + CrateDepKind::Explicit, + CrateOrigin::Extern, + ); } } } } + /// Inject the `compiler_builtins` crate if it is not already in the graph. + fn inject_compiler_builtins(&mut self, krate: &ast::Crate) { + // `compiler_builtins` does not get extern builtins, nor do `#![no_core]` crates + if attr::contains_name(&krate.attrs, sym::compiler_builtins) + || attr::contains_name(&krate.attrs, sym::no_core) + { + info!("`compiler_builtins` unneeded"); + return; + } + + // If a `#![compiler_builtins]` crate already exists, avoid injecting it twice. This is + // the common case since usually it appears as a dependency of `std` or `alloc`. + for (cnum, cmeta) in self.cstore.iter_crate_data() { + if cmeta.is_compiler_builtins() { + info!("`compiler_builtins` already exists (cnum = {cnum}); skipping injection"); + return; + } + } + + // `compiler_builtins` is not yet in the graph; inject it. Error on resolution failure. + let Some(cnum) = self.resolve_crate( + sym::compiler_builtins, + krate.spans.inner_span.shrink_to_lo(), + CrateDepKind::Explicit, + CrateOrigin::Injected, + ) else { + info!("`compiler_builtins` not resolved"); + return; + }; + + // Sanity check that the loaded crate is `#![compiler_builtins]` + let cmeta = self.cstore.get_crate_data(cnum); + if !cmeta.is_compiler_builtins() { + self.dcx().emit_err(errors::CrateNotCompilerBuiltins { crate_name: cmeta.name() }); + } + } + fn inject_dependency_if( &mut self, krate: CrateNum, @@ -1174,6 +1257,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { } pub fn postprocess(&mut self, krate: &ast::Crate) { + self.inject_compiler_builtins(krate); self.inject_forced_externs(); self.inject_profiler_runtime(); self.inject_allocator_crate(krate); @@ -1185,6 +1269,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { info!("{:?}", CrateDump(self.cstore)); } + /// Process an `extern crate foo` AST node. pub fn process_extern_crate( &mut self, item: &ast::Item, @@ -1210,15 +1295,18 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { CrateDepKind::Explicit }; - let cnum = self.resolve_crate(name, item.span, dep_kind)?; + let cnum = self.resolve_crate(name, item.span, dep_kind, CrateOrigin::Extern)?; let path_len = definitions.def_path(def_id).data.len(); - self.cstore.update_extern_crate(cnum, ExternCrate { - src: ExternCrateSource::Extern(def_id.to_def_id()), - span: item.span, - path_len, - dependency_of: LOCAL_CRATE, - }); + self.cstore.update_extern_crate( + cnum, + ExternCrate { + src: ExternCrateSource::Extern(def_id.to_def_id()), + span: item.span, + path_len, + dependency_of: LOCAL_CRATE, + }, + ); Some(cnum) } _ => bug!(), @@ -1226,21 +1314,24 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { } pub fn process_path_extern(&mut self, name: Symbol, span: Span) -> Option<CrateNum> { - let cnum = self.resolve_crate(name, span, CrateDepKind::Explicit)?; + let cnum = self.resolve_crate(name, span, CrateDepKind::Explicit, CrateOrigin::Extern)?; - self.cstore.update_extern_crate(cnum, ExternCrate { - src: ExternCrateSource::Path, - span, - // to have the least priority in `update_extern_crate` - path_len: usize::MAX, - dependency_of: LOCAL_CRATE, - }); + self.cstore.update_extern_crate( + cnum, + ExternCrate { + src: ExternCrateSource::Path, + span, + // to have the least priority in `update_extern_crate` + path_len: usize::MAX, + dependency_of: LOCAL_CRATE, + }, + ); Some(cnum) } pub fn maybe_process_path_extern(&mut self, name: Symbol) -> Option<CrateNum> { - self.maybe_resolve_crate(name, CrateDepKind::Explicit, None).ok() + self.maybe_resolve_crate(name, CrateDepKind::Explicit, CrateOrigin::Extern).ok() } } diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index a77f9bc623b..2ad6389c0b4 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -333,6 +333,12 @@ pub struct CrateNotPanicRuntime { } #[derive(Diagnostic)] +#[diag(metadata_crate_not_compiler_builtins)] +pub struct CrateNotCompilerBuiltins { + pub crate_name: Symbol, +} + +#[derive(Diagnostic)] #[diag(metadata_no_panic_strategy)] pub struct NoPanicStrategy { pub crate_name: Symbol, diff --git a/compiler/rustc_metadata/src/foreign_modules.rs b/compiler/rustc_metadata/src/foreign_modules.rs index 154eb684f11..24689ea61d0 100644 --- a/compiler/rustc_metadata/src/foreign_modules.rs +++ b/compiler/rustc_metadata/src/foreign_modules.rs @@ -10,13 +10,13 @@ pub(crate) fn collect(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> FxIndexMap<Def let mut modules = FxIndexMap::default(); // We need to collect all the `ForeignMod`, even if they are empty. - for id in tcx.hir().items() { + for id in tcx.hir_free_items() { if !matches!(tcx.def_kind(id.owner_id), DefKind::ForeignMod) { continue; } let def_id = id.owner_id.to_def_id(); - let item = tcx.hir().item(id); + let item = tcx.hir_item(id); if let hir::ItemKind::ForeignMod { abi, items } = item.kind { let foreign_items = items.iter().map(|it| it.id.owner_id.to_def_id()).collect(); diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index 2ddabeb49f7..3f3e58384cb 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -260,7 +260,7 @@ pub(crate) struct CrateLocator<'a> { crate_rejections: CrateRejections, } -#[derive(Clone)] +#[derive(Clone, Debug)] pub(crate) struct CratePaths { pub(crate) name: Symbol, source: CrateSource, @@ -272,7 +272,7 @@ impl CratePaths { } } -#[derive(Copy, Clone, PartialEq)] +#[derive(Copy, Clone, Debug, PartialEq)] pub(crate) enum CrateFlavor { Rlib, Rmeta, @@ -893,13 +893,13 @@ fn get_flavor_from_path(path: &Path) -> CrateFlavor { // ------------------------------------------ Error reporting ------------------------------------- -#[derive(Clone)] +#[derive(Clone, Debug)] struct CrateMismatch { path: PathBuf, got: String, } -#[derive(Clone, Default)] +#[derive(Clone, Debug, Default)] struct CrateRejections { via_hash: Vec<CrateMismatch>, via_triple: Vec<CrateMismatch>, @@ -912,6 +912,7 @@ struct CrateRejections { /// Candidate rejection reasons collected during crate search. /// If no candidate is accepted, then these reasons are presented to the user, /// otherwise they are ignored. +#[derive(Debug)] pub(crate) struct CombinedLocatorError { crate_name: Symbol, dep_root: Option<CratePaths>, @@ -921,6 +922,7 @@ pub(crate) struct CombinedLocatorError { crate_rejections: CrateRejections, } +#[derive(Debug)] pub(crate) enum CrateError { NonAsciiName(Symbol), ExternLocationNotExist(Symbol, PathBuf), diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 2ae4a6a6066..591c8ed50d5 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -2,16 +2,16 @@ use std::iter::TrustedLen; use std::path::Path; +use std::sync::Arc; use std::{io, iter, mem}; pub(super) use cstore_impl::provide; use proc_macro::bridge::client::ProcMacro; use rustc_ast as ast; -use rustc_data_structures::captures::Captures; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::owned_slice::OwnedSlice; -use rustc_data_structures::sync::{Lock, Lrc, OnceLock}; +use rustc_data_structures::sync::{Lock, OnceLock}; use rustc_data_structures::unhash::UnhashMap; use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind}; use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, DeriveProcMacro}; @@ -117,7 +117,7 @@ pub(crate) struct CrateMetadata { /// How to link (or not link) this crate to the currently compiled crate. dep_kind: CrateDepKind, /// Filesystem location of this crate. - source: Lrc<CrateSource>, + source: Arc<CrateSource>, /// 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. @@ -149,7 +149,7 @@ struct ImportedSourceFile { /// The end of this SourceFile within the source_map of its original crate original_end_pos: rustc_span::BytePos, /// The imported SourceFile's representation within the local source_map - translated_source_file: Lrc<rustc_span::SourceFile>, + translated_source_file: Arc<rustc_span::SourceFile>, } pub(super) struct DecodeContext<'a, 'tcx> { @@ -962,14 +962,14 @@ impl CrateRoot { pub(crate) fn decode_crate_deps<'a>( &self, metadata: &'a MetadataBlob, - ) -> impl ExactSizeIterator<Item = CrateDep> + Captures<'a> { + ) -> impl ExactSizeIterator<Item = CrateDep> { self.crate_deps.decode(metadata) } pub(crate) fn decode_target_modifiers<'a>( &self, metadata: &'a MetadataBlob, - ) -> impl ExactSizeIterator<Item = TargetModifier> + Captures<'a> { + ) -> impl ExactSizeIterator<Item = TargetModifier> { self.target_modifiers.decode(metadata) } } @@ -1275,7 +1275,7 @@ impl<'a> CrateMetadataRef<'a> { self, id: DefIndex, sess: &'a Session, - ) -> impl Iterator<Item = ModChild> + 'a { + ) -> impl Iterator<Item = ModChild> { iter::from_coroutine( #[coroutine] move || { @@ -1325,10 +1325,7 @@ impl<'a> CrateMetadataRef<'a> { .is_some_and(|ident| ident.name == kw::SelfLower) } - fn get_associated_item_or_field_def_ids( - self, - id: DefIndex, - ) -> impl Iterator<Item = DefId> + 'a { + fn get_associated_item_or_field_def_ids(self, id: DefIndex) -> impl Iterator<Item = DefId> { self.root .tables .associated_item_or_field_def_ids @@ -1379,7 +1376,7 @@ impl<'a> CrateMetadataRef<'a> { self, id: DefIndex, sess: &'a Session, - ) -> impl Iterator<Item = hir::Attribute> + 'a { + ) -> impl Iterator<Item = hir::Attribute> { self.root .tables .attributes @@ -1416,12 +1413,12 @@ impl<'a> CrateMetadataRef<'a> { } /// Decodes all traits in the crate (for rustdoc and rustc diagnostics). - fn get_traits(self) -> impl Iterator<Item = DefId> + 'a { + fn get_traits(self) -> impl Iterator<Item = DefId> { self.root.traits.decode(self).map(move |index| self.local_def_id(index)) } /// Decodes all trait impls in the crate (for rustdoc). - fn get_trait_impls(self) -> impl Iterator<Item = DefId> + 'a { + fn get_trait_impls(self) -> impl Iterator<Item = DefId> { self.cdata.trait_impls.values().flat_map(move |impls| { impls.decode(self).map(move |(impl_index, _)| self.local_def_id(impl_index)) }) @@ -1462,7 +1459,7 @@ impl<'a> CrateMetadataRef<'a> { } } - fn get_native_libraries(self, sess: &'a Session) -> impl Iterator<Item = NativeLib> + 'a { + fn get_native_libraries(self, sess: &'a Session) -> impl Iterator<Item = NativeLib> { self.root.native_libraries.decode((self, sess)) } @@ -1475,7 +1472,7 @@ impl<'a> CrateMetadataRef<'a> { .decode((self, sess)) } - fn get_foreign_modules(self, sess: &'a Session) -> impl Iterator<Item = ForeignModule> + 'a { + fn get_foreign_modules(self, sess: &'a Session) -> impl Iterator<Item = ForeignModule> { self.root.foreign_modules.decode((self, sess)) } @@ -1815,7 +1812,7 @@ impl<'a> CrateMetadataRef<'a> { .decode(self) } - fn get_doc_link_traits_in_scope(self, index: DefIndex) -> impl Iterator<Item = DefId> + 'a { + fn get_doc_link_traits_in_scope(self, index: DefIndex) -> impl Iterator<Item = DefId> { self.root .tables .doc_link_traits_in_scope @@ -1866,7 +1863,7 @@ impl CrateMetadata { cnum_map, dependencies, dep_kind, - source: Lrc::new(source), + source: Arc::new(source), private_dep, host_hash, used: false, @@ -1886,7 +1883,7 @@ impl CrateMetadata { cdata } - pub(crate) fn dependencies(&self) -> impl Iterator<Item = CrateNum> + '_ { + pub(crate) fn dependencies(&self) -> impl Iterator<Item = CrateNum> { self.dependencies.iter().copied() } @@ -1935,6 +1932,10 @@ impl CrateMetadata { self.root.needs_panic_runtime } + pub(crate) fn is_private_dep(&self) -> bool { + self.private_dep + } + pub(crate) fn is_panic_runtime(&self) -> bool { self.root.panic_runtime } @@ -1943,6 +1944,10 @@ impl CrateMetadata { self.root.profiler_runtime } + pub(crate) fn is_compiler_builtins(&self) -> bool { + self.root.compiler_builtins + } + pub(crate) fn needs_allocator(&self) -> bool { self.root.needs_allocator } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 028ff56155f..776b081a463 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -1,8 +1,8 @@ use std::any::Any; use std::mem; +use std::sync::Arc; use rustc_attr_parsing::Deprecation; -use rustc_data_structures::sync::Lrc; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash}; @@ -409,7 +409,7 @@ provide! { tcx, def_id, other, cdata, matches!(cdata.extern_crate, Some(extern_crate) if !extern_crate.is_direct()) } - used_crate_source => { Lrc::clone(&cdata.source) } + used_crate_source => { Arc::clone(&cdata.source) } debugger_visualizers => { cdata.get_debugger_visualizers() } exported_symbols => { @@ -548,7 +548,7 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) { visible_parent_map }, - dependency_formats: |tcx, ()| Lrc::new(crate::dependency_format::calculate(tcx)), + dependency_formats: |tcx, ()| Arc::new(crate::dependency_format::calculate(tcx)), 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, ()| { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index db41a33dcc5..88a88847e6b 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -3,11 +3,12 @@ use std::collections::hash_map::Entry; use std::fs::File; use std::io::{Read, Seek, Write}; use std::path::{Path, PathBuf}; +use std::sync::Arc; use rustc_ast::attr::AttributeExt; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::memmap::{Mmap, MmapMut}; -use rustc_data_structures::sync::{Lrc, join, par_for_each_in}; +use rustc_data_structures::sync::{join, par_for_each_in}; use rustc_data_structures::temp_dir::MaybeTempDir; use rustc_data_structures::thousands::format_with_underscores; use rustc_feature::Features; @@ -52,7 +53,7 @@ pub(super) struct EncodeContext<'a, 'tcx> { // This is used to speed up Span encoding. // The `usize` is an index into the `MonotonicVec` // that stores the `SourceFile` - source_file_cache: (Lrc<SourceFile>, usize), + source_file_cache: (Arc<SourceFile>, usize), // The indices (into the `SourceMap`'s `MonotonicVec`) // of all of the `SourceFiles` that we need to serialize. // When we serialize a `Span`, we insert the index of its @@ -278,7 +279,7 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for SpanData { let source_map = s.tcx.sess.source_map(); let source_file_index = source_map.lookup_source_file_idx(self.lo); s.source_file_cache = - (Lrc::clone(&source_map.files()[source_file_index]), source_file_index); + (Arc::clone(&source_map.files()[source_file_index]), source_file_index); } let (ref source_file, source_file_index) = s.source_file_cache; debug_assert!(source_file.contains(self.lo)); @@ -695,7 +696,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let target_modifiers = stat!("target-modifiers", || self.encode_target_modifiers()); let root = stat!("final", || { - let attrs = tcx.hir().krate_attrs(); + let attrs = tcx.hir_krate_attrs(); self.lazy(CrateRoot { header: CrateHeader { name: tcx.crate_name(LOCAL_CRATE), @@ -1762,7 +1763,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if should_encode_const(tcx.def_kind(def_id)) { let qualifs = tcx.mir_const_qualif(def_id); record!(self.tables.mir_const_qualif[def_id.to_def_id()] <- qualifs); - let body = tcx.hir().maybe_body_owned_by(def_id); + let body = tcx.hir_maybe_body_owned_by(def_id); if let Some(body) = body { let const_data = rendered_const(self.tcx, &body, def_id); record!(self.tables.rendered_const[def_id.to_def_id()] <- const_data); @@ -1939,7 +1940,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { bug!("Unknown proc-macro type for item {:?}", id); }; - let mut def_key = self.tcx.hir().def_key(id); + let mut def_key = self.tcx.hir_def_key(id); def_key.disambiguated_data.data = DefPathData::MacroNs(name); let def_id = id.to_def_id(); @@ -2075,7 +2076,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let mut trait_impls: FxIndexMap<DefId, Vec<(DefIndex, Option<SimplifiedType>)>> = FxIndexMap::default(); - for id in tcx.hir().items() { + for id in tcx.hir_free_items() { let DefKind::Impl { of_trait } = tcx.def_kind(id.owner_id) else { continue; }; @@ -2271,10 +2272,7 @@ impl<D: Decoder> Decodable<D> for EncodedMetadata { let len = d.read_usize(); let mmap = if len > 0 { let mut mmap = MmapMut::map_anon(len).unwrap(); - for _ in 0..len { - (&mut mmap[..]).write_all(&[d.read_u8()]).unwrap(); - } - mmap.flush().unwrap(); + mmap.copy_from_slice(d.read_raw_bytes(len)); Some(mmap.make_read_only().unwrap()) } else { None @@ -2306,7 +2304,7 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path) { encoder.emit_raw_bytes(&0u64.to_le_bytes()); let source_map_files = tcx.sess.source_map().files(); - let source_file_cache = (Lrc::clone(&source_map_files[0]), 0); + let source_file_cache = (Arc::clone(&source_map_files[0]), 0); let required_source_files = Some(FxIndexSet::default()); drop(source_map_files); @@ -2412,7 +2410,6 @@ pub(crate) fn provide(providers: &mut Providers) { /// use a different method for pretty-printing. Ideally this function /// should only ever be used as a fallback. pub fn rendered_const<'tcx>(tcx: TyCtxt<'tcx>, body: &hir::Body<'_>, def_id: LocalDefId) -> String { - let hir = tcx.hir(); let value = body.value; #[derive(PartialEq, Eq)] @@ -2469,7 +2466,7 @@ pub fn rendered_const<'tcx>(tcx: TyCtxt<'tcx>, body: &hir::Body<'_>, def_id: Loc // Otherwise we prefer pretty-printing to get rid of extraneous whitespace, comments and // other formatting artifacts. - Literal | Simple => id_to_string(&hir, body.id().hir_id), + Literal | Simple => id_to_string(&tcx, body.id().hir_id), // FIXME: Omit the curly braces if the enclosing expression is an array literal // with a repeated element (an `ExprKind::Repeat`) as in such case it |
