diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index dfc48b0bd1cd6..43e2031db65af 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -707,6 +707,23 @@ pub macro declare_arena( self.dropless.alloc_str(string) } + #[inline] + pub fn alloc_os_str(&self, os_str: &::std::ffi::OsStr) -> &::std::ffi::OsStr { + use ::std::ffi::OsStr; + if os_str.is_empty() { + return OsStr::new(""); + } + let bytes = self.dropless.alloc_slice(os_str.as_encoded_bytes()); + // SAFETY: These bytes are an exact copy of `os_str.as_encoded_bytes()`. + unsafe { OsStr::from_encoded_bytes_unchecked(bytes) } + } + + #[inline] + pub fn alloc_path(&self, path: &::std::path::Path) -> &::std::path::Path { + use ::std::path::Path; + Path::new(self.alloc_os_str(path.as_os_str())) + } + #[allow(clippy::mut_from_ref)] pub fn alloc_from_iter, C>( &'tcx self, @@ -714,6 +731,18 @@ pub macro declare_arena( ) -> &mut [T] { T::allocate_from_iter(self, iter) } + + #[allow(clippy::mut_from_ref)] + pub fn alloc_index_slice_from_iter( + &'tcx self, + iter: impl ::std::iter::IntoIterator, + ) -> &mut ::rustc_index::IndexSlice + where + I: ::rustc_index::Idx, + T: ArenaAllocatable<'tcx, C>, + { + ::rustc_index::IndexSlice::from_raw_mut(self.alloc_from_iter(iter)) + } } } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 93a7c6cc4d305..ef6995d9c11d6 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -63,7 +63,7 @@ use rustc_hir::{ self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LifetimeSource, LifetimeSyntax, MissingLifetimeKind, ParamName, Target, TraitCandidate, find_attr, }; -use rustc_index::{Idx, IndexVec}; +use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_macros::extension; use rustc_middle::middle::resolve::{ AstOwner, LifetimeRes, PartialRes, PerOwnerResolverData, ResolverAstLowering, @@ -579,7 +579,7 @@ enum TryBlockScope { fn index_ast<'tcx>( tcx: TyCtxt<'tcx>, (): (), -) -> IndexVec>, AstOwner)>> { +) -> &'tcx IndexSlice>, AstOwner)>> { // Queries that borrow `resolver_for_lowering`. tcx.ensure_done().output_filenames(()); tcx.ensure_done().early_lint_checks(()); @@ -601,8 +601,9 @@ fn index_ast<'tcx>( let index = indexer.index; let resolver = Arc::new(resolver); - let index = index.into_iter().map(|owner| Steal::new((Arc::clone(&resolver), owner))).collect(); - return index; + return tcx.arena.alloc_index_slice_from_iter::( + index.into_iter().map(|owner| Steal::new((Arc::clone(&resolver), owner))), + ); struct Indexer<'s, 'hir> { owners: &'s NodeMap>, diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index ebdb82e2b4fe6..159295fb2b05e 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -492,14 +492,7 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) { fn env_var_os<'tcx>(tcx: TyCtxt<'tcx>, key: &'tcx OsStr) -> Option<&'tcx OsStr> { let value = env::var_os(key); - let value_tcx = value.as_ref().map(|value| { - let encoded_bytes = tcx.arena.alloc_slice(value.as_encoded_bytes()); - debug_assert_eq!(value.as_encoded_bytes(), encoded_bytes); - // SAFETY: The bytes came from `as_encoded_bytes`, and we assume that - // `alloc_slice` is implemented correctly, and passes the same bytes - // back (debug asserted above). - unsafe { OsStr::from_encoded_bytes_unchecked(encoded_bytes) } - }); + let value_tcx = value.as_ref().map(|value| tcx.arena.alloc_os_str(value)); // Also add the variable to Cargo's dependency tracking // diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 08053bb2c6a60..f75da94edfe49 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -382,7 +382,7 @@ provide! { tcx, def_id, other, cdata, crate_name => { cdata.root.header.name } num_extern_def_ids => { cdata.num_def_ids() } - extra_filename => { cdata.root.extra_filename.clone() } + extra_filename => { tcx.arena.alloc_str(&cdata.root.extra_filename) } traits => { tcx.arena.alloc_from_iter(cdata.get_traits(tcx)) } trait_impls_in_crate => { tcx.arena.alloc_from_iter(cdata.get_trait_impls(tcx)) } @@ -418,7 +418,9 @@ provide! { tcx, def_id, other, cdata, exported_non_generic_symbols => { cdata.exported_non_generic_symbols(tcx) } exported_generic_symbols => { cdata.exported_generic_symbols(tcx) } - crate_extern_paths => { cdata.source().paths().cloned().collect() } + crate_extern_paths => { + tcx.arena.alloc_from_iter(cdata.source().paths().map(|p| tcx.arena.alloc_path(p))) + } expn_that_defined => { cdata.get_expn_that_defined(tcx, def_id.index) } default_field => { cdata.get_default_field(tcx, def_id.index) } is_doc_hidden => { cdata.get_attr_flags(def_id.index).contains(AttrFlags::IS_DOC_HIDDEN) } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index f55783e60da0c..713671c3a5b47 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -2091,7 +2091,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { hash: self.tcx.crate_hash(cnum), host_hash: self.tcx.crate_host_hash(cnum), kind: self.tcx.crate_dep_kind(cnum), - extra_filename: self.tcx.extra_filename(cnum).clone(), + extra_filename: self.tcx.extra_filename(cnum).to_owned(), is_private: self.tcx.is_private_dep(cnum), }; (cnum, dep) diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 3c973d7d3a5a2..bfaef6157d02c 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -41,13 +41,10 @@ rustc_arena::declare_arena! { rustc_middle::middle::resolve::ResolverAstLowering<'tcx> >, index_ast: - rustc_index::IndexVec< - rustc_span::def_id::LocalDefId, - rustc_data_structures::steal::Steal<( - std::sync::Arc>, - rustc_middle::middle::resolve::AstOwner - )> - >, + rustc_data_structures::steal::Steal<( + std::sync::Arc>, + rustc_middle::middle::resolve::AstOwner + )>, crate_alone: rustc_data_structures::steal::Steal, crate_for_resolver: rustc_data_structures::steal::Steal<(rustc_ast::Crate, rustc_ast::AttrVec)>, resolutions: rustc_middle::middle::resolve::ResolverGlobalCtxt, @@ -139,8 +136,6 @@ rustc_arena::declare_arena! { crate_inherent_impls: rustc_middle::ty::CrateInherentImpls, hir_owner_nodes: rustc_hir::OwnerNodes<'tcx>, token_stream: rustc_ast::tokenstream::TokenStream, - maybe_owner: rustc_middle::hir::ProjectedMaybeOwner<'tcx>, - owner_info: rustc_middle::hir::ProjectedOwnerInfo<'tcx>, parenting: rustc_hir::def_id::LocalDefIdMap, trait_candidates: rustc_hir::ItemLocalMap<&'tcx [rustc_hir::TraitCandidate<'tcx>]>, delayed_lints: rustc_data_structures::steal::Steal, diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index 85602a7d389c5..33719340f5978 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -44,7 +44,7 @@ //! For more details, see the [rustc-dev-guide](https://rustc-dev-guide.rust-lang.org/query.html). use std::ffi::OsStr; -use std::path::PathBuf; +use std::path::Path; use std::sync::Arc; use rustc_abi as abi; @@ -68,7 +68,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdSet, LocalModId}; use rustc_hir::{ItemLocalId, PreciseCapturingArgKind}; -use rustc_index::IndexVec; +use rustc_index::{IndexSlice, IndexVec}; use rustc_lint_defs::{LintId, StableLintExpectationId}; use rustc_macros::rustc_queries; use rustc_session::Limits; @@ -204,14 +204,13 @@ rustc_queries! { desc { "getting the resolver for lowering" } } - query index_ast(_: ()) -> &'tcx IndexVec &'tcx IndexSlice>, AstOwner, )>> { - arena_cache eval_always no_hash desc { "getting the AST for lowering" } @@ -1313,7 +1312,6 @@ rustc_queries! { /// Return the set of (transitive) callees that may result in a recursive call to `key`, /// if we were able to walk all callees. query mir_callgraph_cyclic(key: LocalDefId) -> Option<&'tcx UnordSet> { - arena_cache desc { "computing (transitive) callees of `{}` that may recurse", tcx.def_path_str(key), @@ -1442,7 +1440,6 @@ rustc_queries! { /// Generates a MIR body for the shim. query mir_shims(key: ty::ShimKind<'tcx>) -> &'tcx mir::Body<'tcx> { - arena_cache desc { "generating MIR shim for `{}`, kind={:?}", tcx.def_path_str(key.def_id()), @@ -2070,16 +2067,14 @@ rustc_queries! { /// Gets the extra data to put in each output filename for a crate. /// For example, compiling the `foo` crate with `extra-filename=-a` creates a `libfoo-b.rlib` file. - query extra_filename(_: CrateNum) -> &'tcx String { - arena_cache + query extra_filename(_: CrateNum) -> &'tcx str { eval_always desc { "looking up the extra filename for a crate" } separate_provide_extern } /// Gets the paths where the crate came from in the file system. - query crate_extern_paths(_: CrateNum) -> &'tcx Vec { - arena_cache + query crate_extern_paths(_: CrateNum) -> &'tcx [&'tcx Path] { eval_always desc { "looking up the paths for extern crates" } separate_provide_extern diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 93d4c59e75c00..15a684491dcab 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -13,6 +13,7 @@ use std::mem::MaybeUninit; use rustc_ast::tokenstream::TokenStream; use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{DynSend, DynSync}; +use rustc_index::{Idx, IndexSlice}; use rustc_span::def_id::ModId; use rustc_span::{ErrorGuaranteed, Spanned}; @@ -118,6 +119,10 @@ impl Erasable for &'_ [T] { type Storage = [u8; size_of::<&'_ [()]>()]; } +impl Erasable for &'_ IndexSlice { + type Storage = [u8; size_of::<&'_ [()]>()]; +} + // Note: this impl does not overlap with the impl for `&'_ T` above because `RawList` is unsized // and does not satisfy the implicit `T: Sized` bound. // @@ -170,6 +175,7 @@ macro_rules! impl_erasable_for_types_with_no_type_params { // `[u8; size_of::()]`. ('_ lifetimes are allowed.) impl_erasable_for_types_with_no_type_params! { // tidy-alphabetical-start + &'_ str, (&'_ ty::CrateInherentImpls, Result<(), ErrorGuaranteed>), (), (traits::solve::QueryResult<'_>, &'_ traits::solve::inspect::Probe>, ty::RequiredDepth), diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index 5b6b5203fdafa..3334c31cb1bf5 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -150,7 +150,7 @@ fn process<'tcx>( pub(crate) fn mir_callgraph_cyclic<'tcx>( tcx: TyCtxt<'tcx>, root: LocalDefId, -) -> Option> { +) -> Option<&'tcx UnordSet> { assert!( !tcx.is_constructor(root.to_def_id()), "you should not call `mir_callgraph_reachable` on enum/struct constructor functions" @@ -170,7 +170,7 @@ pub(crate) fn mir_callgraph_cyclic<'tcx>( ty::Instance::new_raw(root.to_def_id(), ty::GenericArgs::identity_for_item(tcx, root)); if !should_recurse(tcx, root_instance) { trace!("cannot walk, skipping"); - return Some(involved.into()); + return Some(tcx.arena.alloc(involved.into())); } match process( tcx, @@ -182,7 +182,7 @@ pub(crate) fn mir_callgraph_cyclic<'tcx>( &mut FxHashMap::default(), recursion_limit, ) { - Some(_) => Some(involved.into()), + Some(_) => Some(tcx.arena.alloc(involved.into())), _ => None, } } diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 426c6cd955fc6..b720e7adedb8a 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -28,7 +28,7 @@ use crate::{ mod async_destructor_ctor; pub(super) fn provide(providers: &mut Providers) { - providers.mir_shims = make_shim; + providers.mir_shims = |tcx, shim| tcx.arena.alloc(make_shim(tcx, shim)); } fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, shim: ty::ShimKind<'tcx>) -> Body<'tcx> {