diff --git a/Cargo.lock b/Cargo.lock index 8fd365b8462b7..7ffe5b956959b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2812,6 +2812,7 @@ dependencies = [ "rustc_errors 0.0.0", "rustc_target 0.0.0", "serialize 0.0.0", + "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "syntax 0.0.0", "syntax_ext 0.0.0", diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs index e9751a23f1218..0b3bd0a5c683b 100644 --- a/src/librustc/arena.rs +++ b/src/librustc/arena.rs @@ -14,8 +14,61 @@ macro_rules! arena_types { rustc::hir::def_id::DefId, rustc::ty::subst::SubstsRef<$tcx> )>, - [few] mir_keys: rustc::util::nodemap::DefIdSet, + [few, decode] mir_keys: rustc::util::nodemap::DefIdSet, [decode] specialization_graph: rustc::traits::specialization_graph::Graph, + [few] crate_inherent_impls: rustc::ty::CrateInherentImpls, + [] generic_predicates: rustc::ty::GenericPredicates<'tcx>, + [] region_scope_tree: rustc::middle::region::ScopeTree, + [] item_local_set: rustc::util::nodemap::ItemLocalSet, + [decode] mir_const_qualif: rustc_data_structures::bit_set::BitSet, + [decode] borrowck: rustc::middle::borrowck::BorrowCheckResult, + [] trait_impls_of: rustc::ty::trait_def::TraitImpls, + [few] upstream_monomorphizations: + rustc::util::nodemap::DefIdMap< + rustc_data_structures::fx::FxHashMap< + rustc::ty::subst::SubstsRef<'tcx>, + rustc::hir::def_id::CrateNum + > + >, + [few] resolve_lifetimes: rustc::middle::resolve_lifetime::ResolveLifetimes, + [] dropck_outlives: + rustc::infer::canonical::Canonical<'tcx, + rustc::infer::canonical::QueryResponse<'tcx, + rustc::traits::query::dropck_outlives::DropckOutlivesResult<'tcx> + > + >, + [] normalize_projection_ty: + rustc::infer::canonical::Canonical<'tcx, + rustc::infer::canonical::QueryResponse<'tcx, + rustc::traits::query::normalize::NormalizationResult<'tcx> + > + >, + [] implied_outlives_bounds: + rustc::infer::canonical::Canonical<'tcx, + rustc::infer::canonical::QueryResponse<'tcx, + Vec> + > + >, + [] type_op_subtype: + rustc::infer::canonical::Canonical<'tcx, + rustc::infer::canonical::QueryResponse<'tcx, ()> + >, + [] type_op_normalize_poly_fn_sig: + rustc::infer::canonical::Canonical<'tcx, + rustc::infer::canonical::QueryResponse<'tcx, rustc::ty::PolyFnSig<'tcx>> + >, + [] type_op_normalize_fn_sig: + rustc::infer::canonical::Canonical<'tcx, + rustc::infer::canonical::QueryResponse<'tcx, rustc::ty::FnSig<'tcx>> + >, + [] type_op_normalize_predicate: + rustc::infer::canonical::Canonical<'tcx, + rustc::infer::canonical::QueryResponse<'tcx, rustc::ty::Predicate<'tcx>> + >, + [] type_op_normalize_ty: + rustc::infer::canonical::Canonical<'tcx, + rustc::infer::canonical::QueryResponse<'tcx, rustc::ty::Ty<'tcx>> + >, ], $tcx); ) } diff --git a/src/librustc/infer/canonical/mod.rs b/src/librustc/infer/canonical/mod.rs index 39b84fabff6fb..fe6b8ac1cdc7e 100644 --- a/src/librustc/infer/canonical/mod.rs +++ b/src/librustc/infer/canonical/mod.rs @@ -23,7 +23,6 @@ use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin}; use rustc_data_structures::indexed_vec::IndexVec; -use rustc_data_structures::sync::Lrc; use rustc_macros::HashStable; use serialize::UseSpecializedDecodable; use smallvec::SmallVec; @@ -186,7 +185,7 @@ pub struct QueryResponse<'tcx, R> { pub type Canonicalized<'gcx, V> = Canonical<'gcx, >::Lifted>; pub type CanonicalizedQueryResponse<'gcx, T> = - Lrc>::Lifted>>>; + &'gcx Canonical<'gcx, QueryResponse<'gcx, >::Lifted>>; /// Indicates whether or not we were able to prove the query to be /// true. diff --git a/src/librustc/infer/canonical/query_response.rs b/src/librustc/infer/canonical/query_response.rs index 008882fd50036..e605aae0fae0d 100644 --- a/src/librustc/infer/canonical/query_response.rs +++ b/src/librustc/infer/canonical/query_response.rs @@ -7,6 +7,7 @@ //! //! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html +use crate::arena::ArenaAllocatable; use crate::infer::canonical::substitute::substitute_value; use crate::infer::canonical::{ Canonical, CanonicalVarValues, CanonicalizedQueryResponse, Certainty, @@ -17,7 +18,6 @@ use crate::infer::InferCtxtBuilder; use crate::infer::{InferCtxt, InferOk, InferResult}; use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::indexed_vec::IndexVec; -use rustc_data_structures::sync::Lrc; use std::fmt::Debug; use syntax_pos::DUMMY_SP; use crate::traits::query::{Fallible, NoSolution}; @@ -54,6 +54,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxtBuilder<'cx, 'gcx, 'tcx> { where K: TypeFoldable<'tcx>, R: Debug + Lift<'gcx> + TypeFoldable<'tcx>, + Canonical<'gcx, as Lift<'gcx>>::Lifted>: ArenaAllocatable, { self.enter_with_canonical( DUMMY_SP, @@ -99,6 +100,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { ) -> Fallible> where T: Debug + Lift<'gcx> + TypeFoldable<'tcx>, + Canonical<'gcx, as Lift<'gcx>>::Lifted>: ArenaAllocatable, { let query_response = self.make_query_response(inference_vars, answer, fulfill_cx)?; let canonical_result = self.canonicalize_response(&query_response); @@ -108,7 +110,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { canonical_result ); - Ok(Lrc::new(canonical_result)) + Ok(self.tcx.arena.alloc(canonical_result)) } /// A version of `make_canonicalized_query_response` that does diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 4f630fe9a3911..fc0a20b5f0ded 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -17,7 +17,6 @@ use crate::middle::region; use crate::ty::{self, DefIdTree, TyCtxt, adjustment}; use crate::hir::{self, PatKind}; -use rustc_data_structures::sync::Lrc; use std::rc::Rc; use syntax::ptr::P; use syntax_pos::Span; @@ -272,7 +271,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx, 'tcx> { param_env: ty::ParamEnv<'tcx>, region_scope_tree: &'a region::ScopeTree, tables: &'a ty::TypeckTables<'tcx>, - rvalue_promotable_map: Option>) + rvalue_promotable_map: Option<&'tcx ItemLocalSet>) -> Self { ExprUseVisitor { diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 1a3fef18404e3..8f880e9e81a82 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -77,7 +77,6 @@ use syntax_pos::Span; use std::borrow::Cow; use std::fmt; use std::hash::{Hash, Hasher}; -use rustc_data_structures::sync::Lrc; use rustc_data_structures::indexed_vec::Idx; use std::rc::Rc; use crate::util::nodemap::ItemLocalSet; @@ -290,7 +289,7 @@ pub struct MemCategorizationContext<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { pub tcx: TyCtxt<'a, 'gcx, 'tcx>, pub region_scope_tree: &'a region::ScopeTree, pub tables: &'a ty::TypeckTables<'tcx>, - rvalue_promotable_map: Option>, + rvalue_promotable_map: Option<&'tcx ItemLocalSet>, infcx: Option<&'a InferCtxt<'a, 'gcx, 'tcx>>, } @@ -400,7 +399,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx, 'tcx> { pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, region_scope_tree: &'a region::ScopeTree, tables: &'a ty::TypeckTables<'tcx>, - rvalue_promotable_map: Option>) + rvalue_promotable_map: Option<&'tcx ItemLocalSet>) -> MemCategorizationContext<'a, 'tcx, 'tcx> { MemCategorizationContext { tcx, diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 2b3802388106a..a97b4d7354212 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -12,7 +12,6 @@ use crate::ty; use std::mem; use std::fmt; -use rustc_data_structures::sync::Lrc; use rustc_macros::HashStable; use syntax::source_map; use syntax::ast; @@ -1323,7 +1322,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionResolutionVisitor<'a, 'tcx> { } fn region_scope_tree<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) - -> Lrc + -> &'tcx ScopeTree { let closure_base_def_id = tcx.closure_base_def_id(def_id); if closure_base_def_id != def_id { @@ -1365,7 +1364,7 @@ fn region_scope_tree<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) ScopeTree::default() }; - Lrc::new(scope_tree) + tcx.arena.alloc(scope_tree) } pub fn provide(providers: &mut Providers<'_>) { diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 3306bcae2123d..72ad6525b0c6c 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -15,7 +15,6 @@ use crate::rustc::lint; use crate::session::Session; use crate::util::nodemap::{DefIdMap, FxHashMap, FxHashSet, HirIdMap, HirIdSet}; use errors::{Applicability, DiagnosticBuilder}; -use rustc_data_structures::sync::Lrc; use rustc_macros::HashStable; use std::borrow::Cow; use std::cell::Cell; @@ -211,10 +210,10 @@ struct NamedRegionMap { /// See [`NamedRegionMap`]. #[derive(Default)] pub struct ResolveLifetimes { - defs: FxHashMap>>, - late_bound: FxHashMap>>, + defs: FxHashMap>, + late_bound: FxHashMap>, object_lifetime_defaults: - FxHashMap>>>>, + FxHashMap>>, } impl_stable_hash_for!(struct crate::middle::resolve_lifetime::ResolveLifetimes { @@ -347,7 +346,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { named_region_map: |tcx, id| { let id = LocalDefId::from_def_id(DefId::local(id)); // (*) - tcx.resolve_lifetimes(LOCAL_CRATE).defs.get(&id).cloned() + tcx.resolve_lifetimes(LOCAL_CRATE).defs.get(&id) }, is_late_bound_map: |tcx, id| { @@ -355,7 +354,6 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { tcx.resolve_lifetimes(LOCAL_CRATE) .late_bound .get(&id) - .cloned() }, object_lifetime_defaults_map: |tcx, id| { @@ -363,7 +361,6 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { tcx.resolve_lifetimes(LOCAL_CRATE) .object_lifetime_defaults .get(&id) - .cloned() }, ..*providers @@ -379,7 +376,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { fn resolve_lifetimes<'tcx>( tcx: TyCtxt<'_, 'tcx, 'tcx>, for_krate: CrateNum, -) -> Lrc { +) -> &'tcx ResolveLifetimes { assert_eq!(for_krate, LOCAL_CRATE); let named_region_map = krate(tcx); @@ -388,24 +385,22 @@ fn resolve_lifetimes<'tcx>( for (hir_id, v) in named_region_map.defs { let map = rl.defs.entry(hir_id.owner_local_def_id()).or_default(); - Lrc::get_mut(map).unwrap().insert(hir_id.local_id, v); + map.insert(hir_id.local_id, v); } for hir_id in named_region_map.late_bound { let map = rl.late_bound .entry(hir_id.owner_local_def_id()) .or_default(); - Lrc::get_mut(map).unwrap().insert(hir_id.local_id); + map.insert(hir_id.local_id); } for (hir_id, v) in named_region_map.object_lifetime_defaults { let map = rl.object_lifetime_defaults .entry(hir_id.owner_local_def_id()) .or_default(); - Lrc::get_mut(map) - .unwrap() - .insert(hir_id.local_id, Lrc::new(v)); + map.insert(hir_id.local_id, v); } - Lrc::new(rl) + tcx.arena.alloc(rl) } fn krate<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> NamedRegionMap { diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index d0ad2c90668a5..ac4a6683ed26f 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -61,7 +61,7 @@ rustc_queries! { /// predicate gets in the way of some checks, which are intended /// to operate over only the actual where-clauses written by the /// user.) - query predicates_of(_: DefId) -> Lrc> {} + query predicates_of(_: DefId) -> &'tcx ty::GenericPredicates<'tcx> {} query native_libraries(_: CrateNum) -> Lrc> { desc { "looking up the native libraries of a linked crate" } @@ -91,7 +91,7 @@ rustc_queries! { /// Maps DefId's that have an associated Mir to the result /// of the MIR qualify_consts pass. The actual meaning of /// the value isn't known except to the pass itself. - query mir_const_qualif(key: DefId) -> (u8, Lrc>) { + query mir_const_qualif(key: DefId) -> (u8, &'tcx BitSet) { cache { key.is_local() } } @@ -166,15 +166,15 @@ rustc_queries! { /// equal to the `explicit_predicates_of` predicates plus the /// `inferred_outlives_of` predicates. query predicates_defined_on(_: DefId) - -> Lrc> {} + -> &'tcx ty::GenericPredicates<'tcx> {} /// Returns the predicates written explicit by the user. query explicit_predicates_of(_: DefId) - -> Lrc> {} + -> &'tcx ty::GenericPredicates<'tcx> {} /// Returns the inferred outlives predicates (e.g., for `struct /// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`). - query inferred_outlives_of(_: DefId) -> Lrc>> {} + query inferred_outlives_of(_: DefId) -> &'tcx [ty::Predicate<'tcx>] {} /// Maps from the `DefId` of a trait to the list of /// super-predicates. This is a subset of the full list of @@ -182,14 +182,14 @@ rustc_queries! { /// evaluate them even during type conversion, often before the /// full predicates are available (note that supertraits have /// additional acyclicity requirements). - query super_predicates_of(key: DefId) -> Lrc> { + query super_predicates_of(key: DefId) -> &'tcx ty::GenericPredicates<'tcx> { desc { |tcx| "computing the supertraits of `{}`", tcx.def_path_str(key) } } /// To avoid cycles within the predicates of a single item we compute /// per-type-parameter predicates for resolving `T::AssocTy`. query type_param_predicates(key: (DefId, DefId)) - -> Lrc> { + -> &'tcx ty::GenericPredicates<'tcx> { no_force desc { |tcx| "computing the bounds for type parameter `{}`", { let id = tcx.hir().as_local_hir_id(key.1).unwrap(); @@ -240,13 +240,13 @@ rustc_queries! { /// Get a map with the variance of every item; use `item_variance` /// instead. - query crate_variances(_: CrateNum) -> Lrc { + query crate_variances(_: CrateNum) -> Lrc> { desc { "computing the variances for items in this crate" } } /// Maps from def-id of a type or region parameter to its /// (inferred) variance. - query variances_of(_: DefId) -> Lrc> {} + query variances_of(_: DefId) -> &'tcx [ty::Variance] {} } TypeChecking { @@ -259,7 +259,7 @@ rustc_queries! { Other { /// Maps from an impl/trait def-id to a list of the def-ids of its items - query associated_item_def_ids(_: DefId) -> Lrc> {} + query associated_item_def_ids(_: DefId) -> &'tcx [DefId] {} /// Maps from a trait item to the trait item "descriptor" query associated_item(_: DefId) -> ty::AssociatedItem {} @@ -274,7 +274,7 @@ rustc_queries! { /// Maps a DefId of a type to a list of its inherent impls. /// Contains implementations of methods that are inherent to a type. /// Methods in these implementations don't need to be exported. - query inherent_impls(_: DefId) -> Lrc> { + query inherent_impls(_: DefId) -> &'tcx [DefId] { eval_always } } @@ -356,7 +356,7 @@ rustc_queries! { } Other { - query used_trait_imports(_: DefId) -> Lrc {} + query used_trait_imports(_: DefId) -> &'tcx DefIdSet {} } TypeChecking { @@ -368,7 +368,7 @@ rustc_queries! { } BorrowChecking { - query borrowck(_: DefId) -> Lrc {} + query borrowck(_: DefId) -> &'tcx BorrowCheckResult {} /// Borrow checks the function body. If this is a closure, returns /// additional requirements that the closure's creator must verify. @@ -380,7 +380,7 @@ rustc_queries! { /// Not meant to be used directly outside of coherence. /// (Defined only for `LOCAL_CRATE`.) query crate_inherent_impls(k: CrateNum) - -> Lrc { + -> &'tcx CrateInherentImpls { eval_always desc { "all inherent impls defined in crate `{:?}`", k } } @@ -451,7 +451,7 @@ rustc_queries! { /// Per-body `region::ScopeTree`. The `DefId` should be the owner `DefId` for the body; /// in the case of closures, this will be redirected to the enclosing function. - query region_scope_tree(_: DefId) -> Lrc {} + query region_scope_tree(_: DefId) -> &'tcx region::ScopeTree {} query mir_shims(key: ty::InstanceDef<'tcx>) -> &'tcx mir::Mir<'tcx> { no_force @@ -499,7 +499,7 @@ rustc_queries! { } cache { true } } - query rvalue_promotable_map(key: DefId) -> Lrc { + query rvalue_promotable_map(key: DefId) -> &'tcx ItemLocalSet { desc { |tcx| "checking which parts of `{}` are promotable to static", tcx.def_path_str(key) @@ -535,7 +535,7 @@ rustc_queries! { } TypeChecking { - query trait_impls_of(key: DefId) -> Lrc { + query trait_impls_of(key: DefId) -> &'tcx ty::trait_def::TraitImpls { desc { |tcx| "trait impls of `{}`", tcx.def_path_str(key) } } query specialization_graph_of(_: DefId) -> &'tcx specialization_graph::Graph {} @@ -678,11 +678,11 @@ rustc_queries! { Codegen { query upstream_monomorphizations( k: CrateNum - ) -> Lrc, CrateNum>>>> { + ) -> &'tcx DefIdMap, CrateNum>> { desc { "collecting available upstream monomorphizations `{:?}`", k } } query upstream_monomorphizations_for(_: DefId) - -> Option, CrateNum>>> {} + -> Option<&'tcx FxHashMap, CrateNum>> {} } Other { @@ -721,12 +721,12 @@ rustc_queries! { TypeChecking { query implementations_of_trait(_: (CrateNum, DefId)) - -> Lrc> { + -> &'tcx [DefId] { no_force desc { "looking up implementations of a trait in a crate" } } query all_trait_implementations(_: CrateNum) - -> Lrc> { + -> &'tcx [DefId] { desc { "looking up all (?) trait implementations" } } } @@ -751,19 +751,19 @@ rustc_queries! { BorrowChecking { // Lifetime resolution. See `middle::resolve_lifetimes`. - query resolve_lifetimes(_: CrateNum) -> Lrc { + query resolve_lifetimes(_: CrateNum) -> &'tcx ResolveLifetimes { desc { "resolving lifetimes" } } query named_region_map(_: DefIndex) -> - Option>> { + Option<&'tcx FxHashMap> { desc { "looking up a named region" } } query is_late_bound_map(_: DefIndex) -> - Option>> { + Option<&'tcx FxHashSet> { desc { "testing if a region is late bound" } } query object_lifetime_defaults_map(_: DefIndex) - -> Option>>>> { + -> Option<&'tcx FxHashMap>> { desc { "looking up lifetime defaults for a region" } } } @@ -781,7 +781,7 @@ rustc_queries! { eval_always desc { "fetching what a crate is named" } } - query item_children(_: DefId) -> Lrc> {} + query item_children(_: DefId) -> &'tcx [Export] {} query extern_mod_stmt_cnum(_: DefId) -> Option {} query get_lib_features(_: CrateNum) -> Lrc { @@ -887,7 +887,7 @@ rustc_queries! { query normalize_projection_ty( goal: CanonicalProjectionGoal<'tcx> ) -> Result< - Lrc>>>, + &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>, NoSolution, > { no_force @@ -905,7 +905,7 @@ rustc_queries! { query implied_outlives_bounds( goal: CanonicalTyGoal<'tcx> ) -> Result< - Lrc>>>>, + &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec>>>, NoSolution, > { no_force @@ -916,7 +916,7 @@ rustc_queries! { query dropck_outlives( goal: CanonicalTyGoal<'tcx> ) -> Result< - Lrc>>>, + &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, DropckOutlivesResult<'tcx>>>, NoSolution, > { no_force @@ -935,7 +935,7 @@ rustc_queries! { query evaluate_goal( goal: traits::ChalkCanonicalGoal<'tcx> ) -> Result< - Lrc>>, + &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>, NoSolution > { no_force @@ -946,7 +946,7 @@ rustc_queries! { query type_op_ascribe_user_type( goal: CanonicalTypeOpAscribeUserTypeGoal<'tcx> ) -> Result< - Lrc>>, + &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>, NoSolution, > { no_force @@ -957,7 +957,7 @@ rustc_queries! { query type_op_eq( goal: CanonicalTypeOpEqGoal<'tcx> ) -> Result< - Lrc>>, + &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>, NoSolution, > { no_force @@ -968,7 +968,7 @@ rustc_queries! { query type_op_subtype( goal: CanonicalTypeOpSubtypeGoal<'tcx> ) -> Result< - Lrc>>, + &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>, NoSolution, > { no_force @@ -979,7 +979,7 @@ rustc_queries! { query type_op_prove_predicate( goal: CanonicalTypeOpProvePredicateGoal<'tcx> ) -> Result< - Lrc>>, + &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>, NoSolution, > { no_force @@ -990,7 +990,7 @@ rustc_queries! { query type_op_normalize_ty( goal: CanonicalTypeOpNormalizeGoal<'tcx, Ty<'tcx>> ) -> Result< - Lrc>>>, + &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Ty<'tcx>>>, NoSolution, > { no_force @@ -1001,7 +1001,7 @@ rustc_queries! { query type_op_normalize_predicate( goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::Predicate<'tcx>> ) -> Result< - Lrc>>>, + &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::Predicate<'tcx>>>, NoSolution, > { no_force @@ -1012,7 +1012,7 @@ rustc_queries! { query type_op_normalize_poly_fn_sig( goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::PolyFnSig<'tcx>> ) -> Result< - Lrc>>>, + &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::PolyFnSig<'tcx>>>, NoSolution, > { no_force @@ -1023,7 +1023,7 @@ rustc_queries! { query type_op_normalize_fn_sig( goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::FnSig<'tcx>> ) -> Result< - Lrc>>>, + &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::FnSig<'tcx>>>, NoSolution, > { no_force diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 7dc4dee3fbf91..6f0130b3776f8 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -2975,10 +2975,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn object_lifetime_defaults(self, id: HirId) - -> Option>> + -> Option<&'gcx [ObjectLifetimeDefault]> { self.object_lifetime_defaults_map(id.owner) - .and_then(|map| map.get(&id.local_id).cloned()) + .and_then(|map| map.get(&id.local_id).map(|v| &**v)) } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 7d47867cea125..2ce548b80c1aa 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -330,15 +330,11 @@ pub enum Variance { /// `tcx.variances_of()` to get the variance for a *particular* /// item. #[derive(HashStable)] -pub struct CrateVariancesMap { +pub struct CrateVariancesMap<'tcx> { /// For each item with generics, maps to a vector of the variance /// of its generics. If an item has no generics, it will have no /// entry. - pub variances: FxHashMap>>, - - /// An empty vector, useful for cloning. - #[stable_hasher(ignore)] - pub empty_variance: Lrc>, + pub variances: FxHashMap, } impl Variance { @@ -1110,11 +1106,7 @@ pub struct CratePredicatesMap<'tcx> { /// For each struct with outlive bounds, maps to a vector of the /// predicate of its outlive bounds. If an item has no outlives /// bounds, it will have no entry. - pub predicates: FxHashMap>>>, - - /// An empty vector, useful for cloning. - #[stable_hasher(ignore)] - pub empty_predicate: Lrc>>, + pub predicates: FxHashMap]>, } impl<'tcx> AsRef> for Predicate<'tcx> { @@ -2291,7 +2283,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { } #[inline] - pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Lrc> { + pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> &'tcx GenericPredicates<'gcx> { tcx.predicates_of(self.did) } @@ -3091,7 +3083,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub struct AssociatedItemsIterator<'a, 'gcx: 'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, - def_ids: Lrc>, + def_ids: &'gcx [DefId], next_index: usize, } @@ -3180,26 +3172,27 @@ fn adt_sized_constraint<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn associated_item_def_ids<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) - -> Lrc> { + -> &'tcx [DefId] { let id = tcx.hir().as_local_hir_id(def_id).unwrap(); let item = tcx.hir().expect_item_by_hir_id(id); - let vec: Vec<_> = match item.node { + match item.node { hir::ItemKind::Trait(.., ref trait_item_refs) => { - trait_item_refs.iter() - .map(|trait_item_ref| trait_item_ref.id) - .map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id)) - .collect() + tcx.arena.alloc_from_iter( + trait_item_refs.iter() + .map(|trait_item_ref| trait_item_ref.id) + .map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id)) + ) } hir::ItemKind::Impl(.., ref impl_item_refs) => { - impl_item_refs.iter() - .map(|impl_item_ref| impl_item_ref.id) - .map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id)) - .collect() + tcx.arena.alloc_from_iter( + impl_item_refs.iter() + .map(|impl_item_ref| impl_item_ref.id) + .map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id)) + ) } - hir::ItemKind::TraitAlias(..) => vec![], + hir::ItemKind::TraitAlias(..) => &[], _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait") - }; - Lrc::new(vec) + } } fn def_span<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Span { @@ -3385,7 +3378,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { /// (constructing this map requires touching the entire crate). #[derive(Clone, Debug, Default, HashStable)] pub struct CrateInherentImpls { - pub inherent_impls: DefIdMap>>, + pub inherent_impls: DefIdMap>, } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable)] diff --git a/src/librustc/ty/query/values.rs b/src/librustc/ty/query/values.rs index a4b8d365a12ef..8834bc9f0f70b 100644 --- a/src/librustc/ty/query/values.rs +++ b/src/librustc/ty/query/values.rs @@ -14,12 +14,6 @@ impl<'tcx, T> Value<'tcx> for T { } } -impl<'tcx, T: Default> Value<'tcx> for T { - default fn from_cycle_error<'a>(_: TyCtxt<'a, 'tcx, 'tcx>) -> T { - T::default() - } -} - impl<'tcx> Value<'tcx> for Ty<'tcx> { fn from_cycle_error<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> { tcx.types.err diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 810bd10c8f4f7..601226182ed62 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -60,7 +60,7 @@ pub trait TypeRelation<'a, 'gcx: 'a+'tcx, 'tcx: 'a> : Sized { b_subst); let opt_variances = self.tcx().variances_of(item_def_id); - relate_substs(self, Some(&opt_variances), a_subst, b_subst) + relate_substs(self, Some(opt_variances), a_subst, b_subst) } /// Switch variance for the purpose of relating `a` and `b`. @@ -122,7 +122,7 @@ impl<'tcx> Relate<'tcx> for ty::TypeAndMut<'tcx> { } pub fn relate_substs<'a, 'gcx, 'tcx, R>(relation: &mut R, - variances: Option<&Vec>, + variances: Option<&[ty::Variance]>, a_subst: SubstsRef<'tcx>, b_subst: SubstsRef<'tcx>) -> RelateResult<'tcx, SubstsRef<'tcx>> diff --git a/src/librustc/ty/trait_def.rs b/src/librustc/ty/trait_def.rs index 58f21893de143..a0b409bc4004a 100644 --- a/src/librustc/ty/trait_def.rs +++ b/src/librustc/ty/trait_def.rs @@ -10,7 +10,6 @@ use crate::ty::{Ty, TyCtxt}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; -use rustc_data_structures::sync::Lrc; use rustc_macros::HashStable; /// A trait's definition with type information. @@ -151,7 +150,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // Query provider for `trait_impls_of`. pub(super) fn trait_impls_of_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_id: DefId) - -> Lrc { + -> &'tcx TraitImpls { let mut impls = TraitImpls::default(); { @@ -188,7 +187,7 @@ pub(super) fn trait_impls_of_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } - Lrc::new(impls) + tcx.arena.alloc(impls) } impl<'a> HashStable> for TraitImpls { diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index fe39e3ae0c6cd..8e9a0af2f29ea 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -32,7 +32,6 @@ use std::borrow::Cow; use std::cell::{Cell, RefCell}; use std::fmt; use std::rc::Rc; -use rustc_data_structures::sync::Lrc; use std::hash::{Hash, Hasher}; use syntax::source_map::CompilerDesugaringKind; use syntax_pos::{MultiSpan, Span}; @@ -77,7 +76,7 @@ pub struct AnalysisData<'a, 'tcx: 'a> { } fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) - -> Lrc + -> &'tcx BorrowCheckResult { assert!(tcx.use_ast_borrowck() || tcx.migrate_borrowck()); @@ -91,7 +90,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) // those things (notably the synthesized constructors from // tuple structs/variants) do not have an associated body // and do not need borrowchecking. - return Lrc::new(BorrowCheckResult { + return tcx.arena.alloc(BorrowCheckResult { used_mut_nodes: Default::default(), signalled_any_error: SignalledError::NoErrorsSeen, }) @@ -142,7 +141,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) unused::check(&mut bccx, body); } - Lrc::new(BorrowCheckResult { + tcx.arena.alloc(BorrowCheckResult { used_mut_nodes: bccx.used_mut_nodes.into_inner(), signalled_any_error: bccx.signalled_any_error.into_inner(), }) @@ -234,7 +233,7 @@ pub struct BorrowckCtxt<'a, 'tcx: 'a> { // Some in `borrowck_fn` and cleared later tables: &'a ty::TypeckTables<'tcx>, - region_scope_tree: Lrc, + region_scope_tree: &'tcx region::ScopeTree, owner_def_id: DefId, diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index 336f41b784a81..7347599efa1f7 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -282,7 +282,7 @@ fn exported_symbols_provider_local<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn upstream_monomorphizations_provider<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum) - -> Lrc, CrateNum>>>> + -> &'tcx DefIdMap, CrateNum>> { debug_assert!(cnum == LOCAL_CRATE); @@ -326,20 +326,16 @@ fn upstream_monomorphizations_provider<'a, 'tcx>( } } - Lrc::new(instances.into_iter() - .map(|(key, value)| (key, Lrc::new(value))) - .collect()) + tcx.arena.alloc(instances) } fn upstream_monomorphizations_for_provider<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) - -> Option, CrateNum>>> + -> Option<&'tcx FxHashMap, CrateNum>> { debug_assert!(!def_id.is_local()); - tcx.upstream_monomorphizations(LOCAL_CRATE) - .get(&def_id) - .cloned() + tcx.upstream_monomorphizations(LOCAL_CRATE).get(&def_id) } fn is_unreachable_local_definition_provider(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> bool { diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml index e234f4f880703..76aba33b6a404 100644 --- a/src/librustc_metadata/Cargo.toml +++ b/src/librustc_metadata/Cargo.toml @@ -13,6 +13,7 @@ crate-type = ["dylib"] flate2 = "1.0" log = "0.4" memmap = "0.6" +smallvec = { version = "0.6.7", features = ["union", "may_dangle"] } rustc = { path = "../librustc" } rustc_data_structures = { path = "../librustc_data_structures" } errors = { path = "../librustc_errors", package = "rustc_errors" } diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 995532a00cd6e..b3f4bb03822ea 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -20,6 +20,7 @@ use rustc::hir::map::definitions::DefPathTable; use rustc::util::nodemap::DefIdMap; use rustc_data_structures::svh::Svh; +use smallvec::SmallVec; use std::any::Any; use rustc_data_structures::sync::Lrc; use std::sync::Arc; @@ -94,9 +95,11 @@ provide! { <'tcx> tcx, def_id, other, cdata, generics_of => { tcx.alloc_generics(cdata.get_generics(def_id.index, tcx.sess)) } - predicates_of => { Lrc::new(cdata.get_predicates(def_id.index, tcx)) } - predicates_defined_on => { Lrc::new(cdata.get_predicates_defined_on(def_id.index, tcx)) } - super_predicates_of => { Lrc::new(cdata.get_super_predicates(def_id.index, tcx)) } + predicates_of => { tcx.arena.alloc(cdata.get_predicates(def_id.index, tcx)) } + predicates_defined_on => { + tcx.arena.alloc(cdata.get_predicates_defined_on(def_id.index, tcx)) + } + super_predicates_of => { tcx.arena.alloc(cdata.get_super_predicates(def_id.index, tcx)) } trait_def => { tcx.alloc_trait_def(cdata.get_trait_def(def_id.index, tcx.sess)) } @@ -105,12 +108,12 @@ provide! { <'tcx> tcx, def_id, other, cdata, let _ = cdata; tcx.calculate_dtor(def_id, &mut |_,_| Ok(())) } - variances_of => { Lrc::new(cdata.get_item_variances(def_id.index)) } + variances_of => { tcx.arena.alloc_from_iter(cdata.get_item_variances(def_id.index)) } associated_item_def_ids => { - let mut result = vec![]; + let mut result = SmallVec::<[_; 8]>::new(); cdata.each_child_of_item(def_id.index, |child| result.push(child.def.def_id()), tcx.sess); - Lrc::new(result) + tcx.arena.alloc_from_iter(result) } associated_item => { cdata.get_associated_item(def_id.index) } impl_trait_ref => { cdata.get_impl_trait(def_id.index, tcx) } @@ -130,10 +133,10 @@ provide! { <'tcx> tcx, def_id, other, cdata, mir } mir_const_qualif => { - (cdata.mir_const_qualif(def_id.index), Lrc::new(BitSet::new_empty(0))) + (cdata.mir_const_qualif(def_id.index), tcx.arena.alloc(BitSet::new_empty(0))) } fn_sig => { cdata.fn_sig(def_id.index, tcx) } - inherent_impls => { Lrc::new(cdata.get_inherent_implementations_for_type(def_id.index)) } + inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) } is_const_fn_raw => { cdata.is_const_fn_raw(def_id.index) } is_foreign_item => { cdata.is_foreign_item(def_id.index) } describe_def => { cdata.get_def(def_id.index) } @@ -205,18 +208,12 @@ provide! { <'tcx> tcx, def_id, other, cdata, extra_filename => { cdata.root.extra_filename.clone() } - implementations_of_trait => { - let mut result = vec![]; - let filter = Some(other); - cdata.get_implementations_for_trait(filter, &mut result); - Lrc::new(result) + cdata.get_implementations_for_trait(tcx, Some(other)) } all_trait_implementations => { - let mut result = vec![]; - cdata.get_implementations_for_trait(None, &mut result); - Lrc::new(result) + cdata.get_implementations_for_trait(tcx, None) } visibility => { cdata.get_visibility(def_id.index) } @@ -226,9 +223,9 @@ provide! { <'tcx> tcx, def_id, other, cdata, } crate_name => { cdata.name } item_children => { - let mut result = vec![]; + let mut result = SmallVec::<[_; 8]>::new(); cdata.each_child_of_item(def_id.index, |child| result.push(child), tcx.sess); - Lrc::new(result) + tcx.arena.alloc_from_iter(result) } defined_lib_features => { Lrc::new(cdata.get_lib_features()) } defined_lang_items => { Lrc::new(cdata.get_lang_items()) } diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index f456a5c1619c5..824f509807026 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -998,39 +998,45 @@ impl<'a, 'tcx> CrateMetadata { None } - pub fn get_inherent_implementations_for_type(&self, id: DefIndex) -> Vec { - self.entry(id) - .inherent_impls - .decode(self) - .map(|index| self.local_def_id(index)) - .collect() + pub fn get_inherent_implementations_for_type( + &self, + tcx: TyCtxt<'_, 'tcx, '_>, + id: DefIndex + ) -> &'tcx [DefId] { + tcx.arena.alloc_from_iter(self.entry(id) + .inherent_impls + .decode(self) + .map(|index| self.local_def_id(index))) } - pub fn get_implementations_for_trait(&self, - filter: Option, - result: &mut Vec) { + pub fn get_implementations_for_trait( + &self, + tcx: TyCtxt<'_, 'tcx, '_>, + filter: Option, + ) -> &'tcx [DefId] { if self.proc_macros.is_some() { // proc-macro crates export no trait impls. - return + return &[] } // Do a reverse lookup beforehand to avoid touching the crate_num // hash map in the loop below. let filter = match filter.map(|def_id| self.reverse_translate_def_id(def_id)) { Some(Some(def_id)) => Some((def_id.krate.as_u32(), def_id.index)), - Some(None) => return, + Some(None) => return &[], None => None, }; if let Some(filter) = filter { - if let Some(impls) = self.trait_impls - .get(&filter) { - result.extend(impls.decode(self).map(|idx| self.local_def_id(idx))); + if let Some(impls) = self.trait_impls.get(&filter) { + tcx.arena.alloc_from_iter(impls.decode(self).map(|idx| self.local_def_id(idx))) + } else { + &[] } } else { - for impls in self.trait_impls.values() { - result.extend(impls.decode(self).map(|idx| self.local_def_id(idx))); - } + tcx.arena.alloc_from_iter(self.trait_impls.values().flat_map(|impls| { + impls.decode(self).map(|idx| self.local_def_id(idx)) + })) } } diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 16436a1f2b076..8ae9c67f5e6eb 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -17,7 +17,6 @@ use rustc::ty::layout::VariantIdx; use rustc::ty::print::Print; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::indexed_vec::Idx; -use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, DiagnosticBuilder}; use syntax_pos::Span; use syntax::source_map::CompilerDesugaringKind; @@ -812,7 +811,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { &mut self, context: Context, name: &str, - scope_tree: &Lrc, + scope_tree: &'tcx ScopeTree, borrow: &BorrowData<'tcx>, drop_span: Span, borrow_spans: UseSpans, @@ -1001,7 +1000,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { fn report_temporary_value_does_not_live_long_enough( &mut self, context: Context, - scope_tree: &Lrc, + scope_tree: &'tcx ScopeTree, borrow: &BorrowData<'tcx>, drop_span: Span, borrow_spans: UseSpans, diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index 71c6489d63f0d..7aed0bace8c0b 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -18,7 +18,6 @@ use syntax::ast; use syntax::attr; use syntax::symbol::Symbol; use rustc::hir; -use rustc_data_structures::sync::Lrc; use crate::hair::constant::{lit_to_const, LitToConstError}; #[derive(Clone)] @@ -32,7 +31,7 @@ pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { /// Identity `InternalSubsts` for use with const-evaluation. pub identity_substs: &'gcx InternalSubsts<'gcx>, - pub region_scope_tree: Lrc, + pub region_scope_tree: &'gcx region::ScopeTree, pub tables: &'a ty::TypeckTables<'gcx>, /// This is `Constness::Const` if we are compiling a `static`, diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 1faa9ad0d0da4..5a2180888af3e 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -7,7 +7,6 @@ use rustc_data_structures::bit_set::BitSet; use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::fx::FxHashSet; -use rustc_data_structures::sync::Lrc; use rustc_target::spec::abi::Abi; use rustc::hir; use rustc::hir::def_id::DefId; @@ -831,7 +830,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> { } /// Check a whole const, static initializer or const fn. - fn check_const(&mut self) -> (u8, Lrc>) { + fn check_const(&mut self) -> (u8, &'tcx BitSet) { debug!("const-checking {} {:?}", self.mode, self.def_id); let mir = self.mir; @@ -905,8 +904,6 @@ impl<'a, 'tcx> Checker<'a, 'tcx> { } } - let promoted_temps = Lrc::new(promoted_temps); - let mut qualifs = self.qualifs_in_local(RETURN_PLACE); // Account for errors in consts by using the @@ -915,7 +912,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> { qualifs = self.qualifs_in_any_value_of_ty(mir.return_ty()); } - (qualifs.encode_to_bits(), promoted_temps) + (qualifs.encode_to_bits(), self.tcx.arena.alloc(promoted_temps)) } } @@ -1435,7 +1432,7 @@ pub fn provide(providers: &mut Providers<'_>) { fn mir_const_qualif<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) - -> (u8, Lrc>) { + -> (u8, &'tcx BitSet) { // N.B., this `borrow()` is guaranteed to be valid (i.e., the value // cannot yet be stolen), because `mir_validated()`, which steals // from `mir_const(), forces this query to execute before @@ -1444,7 +1441,7 @@ fn mir_const_qualif<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if mir.return_ty().references_error() { tcx.sess.delay_span_bug(mir.span, "mir_const_qualif: Mir had errors"); - return (1 << IsNotConst::IDX, Lrc::new(BitSet::new_empty(0))); + return (1 << IsNotConst::IDX, tcx.arena.alloc(BitSet::new_empty(0))); } Checker::new(tcx, def_id, mir, Mode::Const).check_const() diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index 7c37c38f2d741..161ea5753cad5 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -25,7 +25,6 @@ use rustc::ty::query::Providers; use rustc::ty::subst::{InternalSubsts, SubstsRef}; use rustc::util::nodemap::{ItemLocalSet, HirIdSet}; use rustc::hir; -use rustc_data_structures::sync::Lrc; use syntax_pos::{Span, DUMMY_SP}; use log::debug; use Promotability::*; @@ -53,7 +52,7 @@ fn const_is_rvalue_promotable_to_static<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn rvalue_promotable_map<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) - -> Lrc + -> &'tcx ItemLocalSet { let outer_def_id = tcx.closure_base_def_id(def_id); if outer_def_id != def_id { @@ -77,7 +76,7 @@ fn rvalue_promotable_map<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let body_id = tcx.hir().body_owned_by(hir_id); let _ = visitor.check_nested_body(body_id); - Lrc::new(visitor.result) + tcx.arena.alloc(visitor.result) } struct CheckCrateVisitor<'a, 'tcx: 'a> { diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 9a8970b2935e0..53daec7fa39c5 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -67,7 +67,7 @@ trait DefIdVisitor<'a, 'tcx: 'a> { fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> bool { self.skeleton().visit_trait(trait_ref) } - fn visit_predicates(&mut self, predicates: Lrc>) -> bool { + fn visit_predicates(&mut self, predicates: &ty::GenericPredicates<'tcx>) -> bool { self.skeleton().visit_predicates(predicates) } } @@ -89,8 +89,8 @@ impl<'a, 'tcx, V> DefIdVisitorSkeleton<'_, 'a, 'tcx, V> (!self.def_id_visitor.shallow() && substs.visit_with(self)) } - fn visit_predicates(&mut self, predicates: Lrc>) -> bool { - let ty::GenericPredicates { parent: _, predicates } = &*predicates; + fn visit_predicates(&mut self, predicates: &ty::GenericPredicates<'tcx>) -> bool { + let ty::GenericPredicates { parent: _, predicates } = predicates; for (predicate, _span) in predicates { match predicate { ty::Predicate::Trait(poly_predicate) => { diff --git a/src/librustc_traits/chalk_context/mod.rs b/src/librustc_traits/chalk_context/mod.rs index 334f510d10dad..04cd632b29793 100644 --- a/src/librustc_traits/chalk_context/mod.rs +++ b/src/librustc_traits/chalk_context/mod.rs @@ -36,7 +36,6 @@ use rustc::ty::{self, TyCtxt, InferConst}; use rustc::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use rustc::ty::query::Providers; use rustc::ty::subst::{Kind, UnpackedKind}; -use rustc_data_structures::sync::Lrc; use rustc::mir::interpret::ConstValue; use syntax_pos::DUMMY_SP; @@ -677,7 +676,7 @@ crate fn evaluate_goal<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, goal: ChalkCanonicalGoal<'tcx> ) -> Result< - Lrc>>, + &'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, traits::query::NoSolution > { use crate::lowering::Lower; @@ -718,6 +717,6 @@ crate fn evaluate_goal<'a, 'tcx>( debug!("evaluate_goal: solution = {:?}", solution); - solution.map(|ok| Ok(Lrc::new(ok))) - .unwrap_or(Err(traits::query::NoSolution)) + solution.map(|ok| Ok(&*tcx.arena.alloc(ok))) + .unwrap_or(Err(traits::query::NoSolution)) } diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs index 49fcb7cd83355..737bf6f9e84d5 100644 --- a/src/librustc_traits/dropck_outlives.rs +++ b/src/librustc_traits/dropck_outlives.rs @@ -7,7 +7,6 @@ use rustc::ty::query::Providers; use rustc::ty::subst::{Subst, InternalSubsts}; use rustc::ty::{self, ParamEnvAnd, Ty, TyCtxt}; use rustc::util::nodemap::FxHashSet; -use rustc_data_structures::sync::Lrc; use syntax::source_map::{Span, DUMMY_SP}; crate fn provide(p: &mut Providers<'_>) { @@ -21,7 +20,7 @@ crate fn provide(p: &mut Providers<'_>) { fn dropck_outlives<'tcx>( tcx: TyCtxt<'_, 'tcx, 'tcx>, canonical_goal: CanonicalTyGoal<'tcx>, -) -> Result>>>, NoSolution> { +) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, DropckOutlivesResult<'tcx>>>, NoSolution> { debug!("dropck_outlives(goal={:#?})", canonical_goal); tcx.infer_ctxt().enter_with_canonical( diff --git a/src/librustc_traits/implied_outlives_bounds.rs b/src/librustc_traits/implied_outlives_bounds.rs index dad45130062a4..b1688a7fbbb72 100644 --- a/src/librustc_traits/implied_outlives_bounds.rs +++ b/src/librustc_traits/implied_outlives_bounds.rs @@ -15,8 +15,6 @@ use smallvec::{SmallVec, smallvec}; use syntax::source_map::DUMMY_SP; use rustc::traits::FulfillmentContext; -use rustc_data_structures::sync::Lrc; - crate fn provide(p: &mut Providers<'_>) { *p = Providers { implied_outlives_bounds, @@ -28,7 +26,7 @@ fn implied_outlives_bounds<'tcx>( tcx: TyCtxt<'_, 'tcx, 'tcx>, goal: CanonicalTyGoal<'tcx>, ) -> Result< - Lrc>>>>, + &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec>>>, NoSolution, > { tcx.infer_ctxt() diff --git a/src/librustc_traits/normalize_projection_ty.rs b/src/librustc_traits/normalize_projection_ty.rs index 38f7a21e66c55..3ff04bc285369 100644 --- a/src/librustc_traits/normalize_projection_ty.rs +++ b/src/librustc_traits/normalize_projection_ty.rs @@ -4,7 +4,6 @@ use rustc::traits::query::{normalize::NormalizationResult, CanonicalProjectionGo use rustc::traits::{self, ObligationCause, SelectionContext, TraitEngineExt}; use rustc::ty::query::Providers; use rustc::ty::{ParamEnvAnd, TyCtxt}; -use rustc_data_structures::sync::Lrc; use std::sync::atomic::Ordering; use syntax_pos::DUMMY_SP; @@ -18,7 +17,7 @@ crate fn provide(p: &mut Providers<'_>) { fn normalize_projection_ty<'tcx>( tcx: TyCtxt<'_, 'tcx, 'tcx>, goal: CanonicalProjectionGoal<'tcx>, -) -> Result>>>, NoSolution> { +) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, NormalizationResult<'tcx>>>, NoSolution> { debug!("normalize_provider(goal={:#?})", goal); tcx.sess diff --git a/src/librustc_traits/type_op.rs b/src/librustc_traits/type_op.rs index 30fbdbdeb4433..ea37024b84f5b 100644 --- a/src/librustc_traits/type_op.rs +++ b/src/librustc_traits/type_op.rs @@ -17,7 +17,6 @@ use rustc::ty::subst::{Kind, Subst, UserSubsts, UserSelfTy}; use rustc::ty::{ FnSig, Lift, ParamEnv, ParamEnvAnd, PolyFnSig, Predicate, Ty, TyCtxt, TypeFoldable, Variance, }; -use rustc_data_structures::sync::Lrc; use std::fmt; use syntax_pos::DUMMY_SP; @@ -38,7 +37,7 @@ crate fn provide(p: &mut Providers<'_>) { fn type_op_ascribe_user_type<'tcx>( tcx: TyCtxt<'_, 'tcx, 'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, AscribeUserType<'tcx>>>, -) -> Result>>, NoSolution> { +) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, NoSolution> { tcx.infer_ctxt() .enter_canonical_trait_query(&canonicalized, |infcx, fulfill_cx, key| { let ( @@ -170,7 +169,7 @@ impl AscribeUserTypeCx<'me, 'gcx, 'tcx> { fn type_op_eq<'tcx>( tcx: TyCtxt<'_, 'tcx, 'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Eq<'tcx>>>, -) -> Result>>, NoSolution> { +) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, NoSolution> { tcx.infer_ctxt() .enter_canonical_trait_query(&canonicalized, |infcx, fulfill_cx, key| { let (param_env, Eq { a, b }) = key.into_parts(); @@ -200,7 +199,7 @@ where fn type_op_normalize_ty( tcx: TyCtxt<'_, 'tcx, 'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize>>>, -) -> Result>>>, NoSolution> { +) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>, NoSolution> { tcx.infer_ctxt() .enter_canonical_trait_query(&canonicalized, type_op_normalize) } @@ -208,7 +207,7 @@ fn type_op_normalize_ty( fn type_op_normalize_predicate( tcx: TyCtxt<'_, 'tcx, 'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize>>>, -) -> Result>>>, NoSolution> { +) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, Predicate<'tcx>>>, NoSolution> { tcx.infer_ctxt() .enter_canonical_trait_query(&canonicalized, type_op_normalize) } @@ -216,7 +215,7 @@ fn type_op_normalize_predicate( fn type_op_normalize_fn_sig( tcx: TyCtxt<'_, 'tcx, 'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize>>>, -) -> Result>>>, NoSolution> { +) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, FnSig<'tcx>>>, NoSolution> { tcx.infer_ctxt() .enter_canonical_trait_query(&canonicalized, type_op_normalize) } @@ -224,7 +223,7 @@ fn type_op_normalize_fn_sig( fn type_op_normalize_poly_fn_sig( tcx: TyCtxt<'_, 'tcx, 'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize>>>, -) -> Result>>>, NoSolution> { +) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, PolyFnSig<'tcx>>>, NoSolution> { tcx.infer_ctxt() .enter_canonical_trait_query(&canonicalized, type_op_normalize) } @@ -232,7 +231,7 @@ fn type_op_normalize_poly_fn_sig( fn type_op_subtype<'tcx>( tcx: TyCtxt<'_, 'tcx, 'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Subtype<'tcx>>>, -) -> Result>>, NoSolution> { +) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, NoSolution> { tcx.infer_ctxt() .enter_canonical_trait_query(&canonicalized, |infcx, fulfill_cx, key| { let (param_env, Subtype { sub, sup }) = key.into_parts(); @@ -246,7 +245,7 @@ fn type_op_subtype<'tcx>( fn type_op_prove_predicate<'tcx>( tcx: TyCtxt<'_, 'tcx, 'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, ProvePredicate<'tcx>>>, -) -> Result>>, NoSolution> { +) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, NoSolution> { tcx.infer_ctxt() .enter_canonical_trait_query(&canonicalized, |infcx, fulfill_cx, key| { let (param_env, ProvePredicate { predicate }) = key.into_parts(); diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 0c206b27f8058..ff0f0923b0550 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -17,7 +17,6 @@ use rustc::ty::{GenericParamDef, GenericParamDefKind}; use rustc::ty::subst::{Kind, Subst, InternalSubsts, SubstsRef}; use rustc::ty::wf::object_region_bounds; use rustc::mir::interpret::ConstValue; -use rustc_data_structures::sync::Lrc; use rustc_target::spec::abi; use crate::require_c_abi_if_c_variadic; use smallvec::SmallVec; @@ -45,7 +44,7 @@ pub trait AstConv<'gcx, 'tcx> { /// Returns the set of bounds in scope for the type parameter with /// the given id. fn get_type_parameter_bounds(&self, span: Span, def_id: DefId) - -> Lrc>; + -> &'tcx ty::GenericPredicates<'tcx>; /// What lifetime should we use when a lifetime is omitted (and not elided)? fn re_infer(&self, span: Span, _def: Option<&ty::GenericParamDef>) diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs index 7f4b0a96a15ab..df3623ea6fbd1 100644 --- a/src/librustc_typeck/check/generator_interior.rs +++ b/src/librustc_typeck/check/generator_interior.rs @@ -8,7 +8,6 @@ use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir::{self, Pat, PatKind, Expr}; use rustc::middle::region; use rustc::ty::{self, Ty}; -use rustc_data_structures::sync::Lrc; use syntax_pos::Span; use super::FnCtxt; use crate::util::nodemap::FxHashMap; @@ -16,7 +15,7 @@ use crate::util::nodemap::FxHashMap; struct InteriorVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { fcx: &'a FnCtxt<'a, 'gcx, 'tcx>, types: FxHashMap, usize>, - region_scope_tree: Lrc, + region_scope_tree: &'gcx region::ScopeTree, expr_count: usize, } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 313ed19b945d1..3ace00139e6e4 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -803,8 +803,8 @@ fn has_typeck_tables<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn used_trait_imports<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) - -> Lrc { - tcx.typeck_tables_of(def_id).used_trait_imports.clone() + -> &'tcx DefIdSet { + &*tcx.typeck_tables_of(def_id).used_trait_imports } fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -1894,7 +1894,7 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx } fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) - -> Lrc> + -> &'tcx ty::GenericPredicates<'tcx> { let tcx = self.tcx; let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); @@ -1902,7 +1902,7 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> { let item_def_id = tcx.hir().local_def_id_from_hir_id(item_id); let generics = tcx.generics_of(item_def_id); let index = generics.param_def_id_to_index[&def_id]; - Lrc::new(ty::GenericPredicates { + tcx.arena.alloc(ty::GenericPredicates { parent: None, predicates: self.param_env.caller_bounds.iter().filter_map(|&predicate| { match predicate { diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index a03d33a3ef5bc..353b9ac6cc30c 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -86,7 +86,6 @@ use rustc::ty::{self, Ty}; use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc::hir::{self, PatKind}; -use rustc_data_structures::sync::Lrc; use std::mem; use std::ops::Deref; use std::rc::Rc; @@ -195,7 +194,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub struct RegionCtxt<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { pub fcx: &'a FnCtxt<'a, 'gcx, 'tcx>, - pub region_scope_tree: Lrc, + pub region_scope_tree: &'gcx region::ScopeTree, outlives_environment: OutlivesEnvironment<'tcx>, diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index d167c7fcafbe4..644d95963e652 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -13,14 +13,13 @@ use rustc::hir; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::ty::{self, CrateInherentImpls, TyCtxt}; -use rustc_data_structures::sync::Lrc; use syntax::ast; use syntax_pos::Span; /// On-demand query: yields a map containing all types mapped to their inherent impls. pub fn crate_inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) - -> Lrc { + -> &'tcx CrateInherentImpls { assert_eq!(crate_num, LOCAL_CRATE); let krate = tcx.hir().krate(); @@ -29,13 +28,13 @@ pub fn crate_inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impls_map: Default::default(), }; krate.visit_all_item_likes(&mut collect); - Lrc::new(collect.impls_map) + tcx.arena.alloc(collect.impls_map) } /// On-demand query: yields a vector of the inherent impls for a specific type. pub fn inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty_def_id: DefId) - -> Lrc> { + -> &'tcx [DefId] { assert!(ty_def_id.is_local()); // NB. Until we adopt the red-green dep-tracking algorithm (see @@ -53,15 +52,11 @@ pub fn inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // // [the plan]: https://github.com/rust-lang/rust-roadmap/issues/4 - thread_local! { - static EMPTY_DEF_ID_VEC: Lrc> = Lrc::new(vec![]) - } - let result = tcx.dep_graph.with_ignore(|| { let crate_map = tcx.crate_inherent_impls(ty_def_id.krate); match crate_map.inherent_impls.get(&ty_def_id) { - Some(v) => v.clone(), - None => EMPTY_DEF_ID_VEC.with(|v| v.clone()) + Some(v) => &v[..], + None => &[], } }); @@ -289,13 +284,8 @@ impl<'a, 'tcx> InherentCollect<'a, 'tcx> { // type def ID, if there is a base type for this implementation and // the implementation does not have any associated traits. let impl_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); - let mut rc_vec = self.impls_map.inherent_impls - .entry(def_id) - .or_default(); - - // At this point, there should not be any clones of the - // `Lrc`, so we can still safely push into it in place: - Lrc::get_mut(&mut rc_vec).unwrap().push(impl_def_id); + let vec = self.impls_map.inherent_impls.entry(def_id).or_default(); + vec.push(impl_def_id); } else { struct_span_err!(self.tcx.sess, item.span, diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 0cd7fe9159493..d1d0fbdc76a4c 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -31,7 +31,6 @@ use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt}; use rustc::ty::{ReprOptions, ToPredicate}; use rustc::util::captures::Captures; use rustc::util::nodemap::FxHashMap; -use rustc_data_structures::sync::Lrc; use rustc_target::spec::abi; use syntax::ast; @@ -177,7 +176,7 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> { } fn get_type_parameter_bounds(&self, span: Span, def_id: DefId) - -> Lrc> { + -> &'tcx ty::GenericPredicates<'tcx> { self.tcx .at(span) .type_param_predicates((self.item_def_id, def_id)) @@ -242,7 +241,7 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> { fn type_param_predicates<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, (item_def_id, def_id): (DefId, DefId), -) -> Lrc> { +) -> &'tcx ty::GenericPredicates<'tcx> { use rustc::hir::*; // In the AST, bounds can derive from two places. Either @@ -263,8 +262,9 @@ fn type_param_predicates<'a, 'tcx>( tcx.generics_of(item_def_id).parent }; - let mut result = parent.map_or_else( - || Lrc::new(ty::GenericPredicates { + let result = parent.map_or_else( + // FIXME: Allocate this empty predicate only once + || &*tcx.arena.alloc(ty::GenericPredicates { parent: None, predicates: vec![], }), @@ -273,6 +273,7 @@ fn type_param_predicates<'a, 'tcx>( icx.get_type_parameter_bounds(DUMMY_SP, def_id) }, ); + let mut extend = None; let item_hir_id = tcx.hir().as_local_hir_id(item_def_id).unwrap(); let ast_generics = match tcx.hir().get_by_hir_id(item_hir_id) { @@ -297,9 +298,7 @@ fn type_param_predicates<'a, 'tcx>( // Implied `Self: Trait` and supertrait bounds. if param_id == item_hir_id { let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id); - Lrc::make_mut(&mut result) - .predicates - .push((identity_trait_ref.to_predicate(), item.span)); + extend = Some((identity_trait_ref.to_predicate(), item.span)); } generics } @@ -316,11 +315,12 @@ fn type_param_predicates<'a, 'tcx>( }; let icx = ItemCtxt::new(tcx, item_def_id); - Lrc::make_mut(&mut result) - .predicates - .extend(icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty, - OnlySelfBounds(true))); - result + let mut result = (*result).clone(); + result.predicates.extend(extend.into_iter()); + result.predicates + .extend(icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty, + OnlySelfBounds(true))); + tcx.arena.alloc(result) } impl<'a, 'tcx> ItemCtxt<'a, 'tcx> { @@ -689,7 +689,7 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Ad fn super_predicates_of<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_def_id: DefId, -) -> Lrc> { +) -> &'tcx ty::GenericPredicates<'tcx> { debug!("super_predicates(trait_def_id={:?})", trait_def_id); let trait_hir_id = tcx.hir().as_local_hir_id(trait_def_id).unwrap(); @@ -733,7 +733,7 @@ fn super_predicates_of<'a, 'tcx>( } } - Lrc::new(ty::GenericPredicates { + tcx.arena.alloc(ty::GenericPredicates { parent: None, predicates: superbounds, }) @@ -1823,7 +1823,7 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx>( fn predicates_defined_on<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, -) -> Lrc> { +) -> &'tcx ty::GenericPredicates<'tcx> { debug!("predicates_defined_on({:?})", def_id); let mut result = tcx.explicit_predicates_of(def_id); debug!( @@ -1839,9 +1839,9 @@ fn predicates_defined_on<'a, 'tcx>( def_id, inferred_outlives, ); - Lrc::make_mut(&mut result) - .predicates - .extend(inferred_outlives.iter().map(|&p| (p, span))); + let mut predicates = (*result).clone(); + predicates.predicates.extend(inferred_outlives.iter().map(|&p| (p, span))); + result = tcx.arena.alloc(predicates); } debug!("predicates_defined_on({:?}) = {:?}", def_id, result); result @@ -1853,7 +1853,7 @@ fn predicates_defined_on<'a, 'tcx>( fn predicates_of<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, -) -> Lrc> { +) -> &'tcx ty::GenericPredicates<'tcx> { let mut result = tcx.predicates_defined_on(def_id); if tcx.is_trait(def_id) { @@ -1870,9 +1870,9 @@ fn predicates_of<'a, 'tcx>( // used, and adding the predicate into this list ensures // that this is done. let span = tcx.def_span(def_id); - Lrc::make_mut(&mut result) - .predicates - .push((ty::TraitRef::identity(tcx, def_id).to_predicate(), span)); + let mut predicates = (*result).clone(); + predicates.predicates.push((ty::TraitRef::identity(tcx, def_id).to_predicate(), span)); + result = tcx.arena.alloc(predicates); } debug!("predicates_of(def_id={:?}) = {:?}", def_id, result); result @@ -1883,7 +1883,7 @@ fn predicates_of<'a, 'tcx>( fn explicit_predicates_of<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, -) -> Lrc> { +) -> &'tcx ty::GenericPredicates<'tcx> { use rustc::hir::*; use rustc_data_structures::fx::FxHashSet; @@ -1998,7 +1998,7 @@ fn explicit_predicates_of<'a, 'tcx>( if impl_trait_fn.is_some() { // impl Trait - return Lrc::new(ty::GenericPredicates { + return tcx.arena.alloc(ty::GenericPredicates { parent: None, predicates: bounds.predicates(tcx, opaque_ty), }); @@ -2209,7 +2209,7 @@ fn explicit_predicates_of<'a, 'tcx>( ); } - let result = Lrc::new(ty::GenericPredicates { + let result = tcx.arena.alloc(ty::GenericPredicates { parent: generics.parent, predicates, }); diff --git a/src/librustc_typeck/outlives/mod.rs b/src/librustc_typeck/outlives/mod.rs index 913990ee87897..e3e2fe7106a08 100644 --- a/src/librustc_typeck/outlives/mod.rs +++ b/src/librustc_typeck/outlives/mod.rs @@ -23,7 +23,7 @@ pub fn provide(providers: &mut Providers<'_>) { fn inferred_outlives_of<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId, -) -> Lrc>> { +) -> &'tcx [ty::Predicate<'tcx>] { let id = tcx .hir() .as_local_hir_id(item_def_id) @@ -37,8 +37,8 @@ fn inferred_outlives_of<'a, 'tcx>( let predicates = crate_map .predicates .get(&item_def_id) - .unwrap_or(&crate_map.empty_predicate) - .clone(); + .map(|p| *p) + .unwrap_or(&[]); if tcx.has_attr(item_def_id, "rustc_outlives") { let mut pred: Vec = predicates @@ -63,10 +63,10 @@ fn inferred_outlives_of<'a, 'tcx>( predicates } - _ => Lrc::new(Vec::new()), + _ => &[], }, - _ => Lrc::new(Vec::new()), + _ => &[], } } @@ -96,7 +96,7 @@ fn inferred_outlives_crate<'tcx>( let predicates = global_inferred_outlives .iter() .map(|(&def_id, set)| { - let vec: Vec> = set + let predicates = tcx.arena.alloc_from_iter(set .iter() .filter_map( |ty::OutlivesPredicate(kind1, region2)| match kind1.unpack() { @@ -115,14 +115,11 @@ fn inferred_outlives_crate<'tcx>( None } }, - ).collect(); - (def_id, Lrc::new(vec)) + )); + (def_id, &*predicates) }).collect(); - let empty_predicate = Lrc::new(Vec::new()); - Lrc::new(ty::CratePredicatesMap { predicates, - empty_predicate, }) } diff --git a/src/librustc_typeck/variance/mod.rs b/src/librustc_typeck/variance/mod.rs index 9b9a6bace96b1..88ee1d79f5435 100644 --- a/src/librustc_typeck/variance/mod.rs +++ b/src/librustc_typeck/variance/mod.rs @@ -36,7 +36,7 @@ pub fn provide(providers: &mut Providers<'_>) { } fn crate_variances<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) - -> Lrc { + -> Lrc> { assert_eq!(crate_num, LOCAL_CRATE); let mut arena = arena::TypedArena::default(); let terms_cx = terms::determine_parameters_to_be_inferred(tcx, &mut arena); @@ -45,7 +45,7 @@ fn crate_variances<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) } fn variances_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId) - -> Lrc> { + -> &'tcx [ty::Variance] { let id = tcx.hir().as_local_hir_id(item_def_id).expect("expected local def-id"); let unsupported = || { // Variance not relevant. @@ -88,6 +88,6 @@ fn variances_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId) let crate_map = tcx.crate_variances(LOCAL_CRATE); crate_map.variances.get(&item_def_id) - .unwrap_or(&crate_map.empty_variance) - .clone() + .map(|p| *p) + .unwrap_or(&[]) } diff --git a/src/librustc_typeck/variance/solve.rs b/src/librustc_typeck/variance/solve.rs index cec33ba87dea4..1727e6917252b 100644 --- a/src/librustc_typeck/variance/solve.rs +++ b/src/librustc_typeck/variance/solve.rs @@ -8,7 +8,6 @@ use rustc::hir::def_id::DefId; use rustc::ty; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::sync::Lrc; use super::constraints::*; use super::terms::*; @@ -23,7 +22,9 @@ struct SolveContext<'a, 'tcx: 'a> { solutions: Vec, } -pub fn solve_constraints(constraints_cx: ConstraintContext<'_, '_>) -> ty::CrateVariancesMap { +pub fn solve_constraints<'tcx>( + constraints_cx: ConstraintContext<'_, 'tcx> +) -> ty::CrateVariancesMap<'tcx> { let ConstraintContext { terms_cx, constraints, .. } = constraints_cx; let mut solutions = vec![ty::Bivariant; terms_cx.inferred_terms.len()]; @@ -41,9 +42,8 @@ pub fn solve_constraints(constraints_cx: ConstraintContext<'_, '_>) -> ty::Crate }; solutions_cx.solve(); let variances = solutions_cx.create_map(); - let empty_variance = Lrc::new(Vec::new()); - ty::CrateVariancesMap { variances, empty_variance } + ty::CrateVariancesMap { variances } } impl<'a, 'tcx> SolveContext<'a, 'tcx> { @@ -78,7 +78,7 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> { } } - fn create_map(&self) -> FxHashMap>> { + fn create_map(&self) -> FxHashMap { let tcx = self.terms_cx.tcx; let solutions = &self.solutions; @@ -86,20 +86,24 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> { let def_id = tcx.hir().local_def_id_from_hir_id(id); let generics = tcx.generics_of(def_id); - let mut variances = solutions[start..start+generics.count()].to_vec(); + let variances = solutions[start..start+generics.count()].iter().cloned(); debug!("id={} variances={:?}", id, variances); - // Functions can have unused type parameters: make those invariant. - if let ty::FnDef(..) = tcx.type_of(def_id).sty { - for variance in &mut variances { - if *variance == ty::Bivariant { - *variance = ty::Invariant; + let variances = if let ty::FnDef(..) = tcx.type_of(def_id).sty { + // Functions can have unused type parameters: make those invariant. + tcx.arena.alloc_from_iter(variances.map(|variance| { + if variance == ty::Bivariant { + ty::Invariant + } else { + variance } - } - } + })) + } else { + tcx.arena.alloc_from_iter(variances) + }; - (def_id, Lrc::new(variances)) + (def_id, &*variances) }).collect() } diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 555cb1bd64f6e..159b09e28d6be 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -140,7 +140,10 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { // Instead, we generate `impl !Send for Foo`, which better // expresses the fact that `Foo` never implements `Send`, // regardless of the choice of `T`. - let real_generics = (&generics, &Default::default()); + let real_generics = ( + &generics, + &&*self.cx.tcx.arena.alloc(Default::default()) + ); // Clean the generics, but ignore the '?Sized' bounds generated // by the `Clean` impl diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e994c661fdceb..f89bca677f06b 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -9,7 +9,6 @@ mod blanket_impl; pub mod def_ctor; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; -use rustc_data_structures::sync::Lrc; use rustc_target::spec::abi::Abi; use rustc_typeck::hir_ty_to_ty; use rustc::infer::region_constraints::{RegionConstraintData, Constraint}; @@ -1682,7 +1681,7 @@ impl Clean for hir::Generics { } impl<'a, 'tcx> Clean for (&'a ty::Generics, - &'a Lrc>) { + &'a &'tcx ty::GenericPredicates<'tcx>) { fn clean(&self, cx: &DocContext<'_>) -> Generics { use self::WherePredicate as WP; @@ -4434,7 +4433,7 @@ pub fn path_to_def(tcx: &TyCtxt<'_, '_, '_>, path: &[&str]) -> Option { loop { let segment = path_it.next()?; - for item in mem::replace(&mut items, Lrc::new(vec![])).iter() { + for item in mem::replace(&mut items, &[]).iter() { if item.ident.name == *segment { if path_it.peek().is_none() { return match item.def { diff --git a/src/test/ui/cycle-projection-based-on-where-clause.rs b/src/test/ui/cycle-projection-based-on-where-clause.rs index 336b67852cd01..d3609acfdff63 100644 --- a/src/test/ui/cycle-projection-based-on-where-clause.rs +++ b/src/test/ui/cycle-projection-based-on-where-clause.rs @@ -16,7 +16,6 @@ struct A where T : Trait, T : Add //~^ ERROR cycle detected - //~| ERROR associated type `Item` not found for `T` { data: T } diff --git a/src/test/ui/cycle-projection-based-on-where-clause.stderr b/src/test/ui/cycle-projection-based-on-where-clause.stderr index b11a8bda9b4f4..59815138e2e36 100644 --- a/src/test/ui/cycle-projection-based-on-where-clause.stderr +++ b/src/test/ui/cycle-projection-based-on-where-clause.stderr @@ -11,13 +11,6 @@ note: cycle used when processing `A` LL | T : Add | ^^^^^^^ -error[E0220]: associated type `Item` not found for `T` - --> $DIR/cycle-projection-based-on-where-clause.rs:17:19 - | -LL | T : Add - | ^^^^^^^ associated type `Item` not found - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors occurred: E0220, E0391. -For more information about an error, try `rustc --explain E0220`. +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/issues/issue-20772.rs b/src/test/ui/issues/issue-20772.rs index 36551e7014f10..1500bc831528a 100644 --- a/src/test/ui/issues/issue-20772.rs +++ b/src/test/ui/issues/issue-20772.rs @@ -1,6 +1,5 @@ trait T : Iterator //~^ ERROR cycle detected -//~| ERROR associated type `Item` not found for `Self` {} fn main() {} diff --git a/src/test/ui/issues/issue-20772.stderr b/src/test/ui/issues/issue-20772.stderr index e67fedc5a9ebc..d64636310a368 100644 --- a/src/test/ui/issues/issue-20772.stderr +++ b/src/test/ui/issues/issue-20772.stderr @@ -3,7 +3,6 @@ error[E0391]: cycle detected when computing the supertraits of `T` | LL | / trait T : Iterator LL | | -LL | | LL | | {} | |__^ | @@ -13,17 +12,9 @@ note: cycle used when collecting item types in top-level module | LL | / trait T : Iterator LL | | -LL | | LL | | {} | |__^ -error[E0220]: associated type `Item` not found for `Self` - --> $DIR/issue-20772.rs:1:25 - | -LL | trait T : Iterator - | ^^^^^^^^^^ associated type `Item` not found - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors occurred: E0220, E0391. -For more information about an error, try `rustc --explain E0220`. +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/issues/issue-21177.rs b/src/test/ui/issues/issue-21177.rs index 9d153696b885e..258e362d1317c 100644 --- a/src/test/ui/issues/issue-21177.rs +++ b/src/test/ui/issues/issue-21177.rs @@ -5,6 +5,5 @@ trait Trait { fn foo>() { } //~^ ERROR cycle detected -//~| ERROR associated type `B` not found for `T` fn main() { } diff --git a/src/test/ui/issues/issue-21177.stderr b/src/test/ui/issues/issue-21177.stderr index c3d2c6f48af6c..00d9a3c46a723 100644 --- a/src/test/ui/issues/issue-21177.stderr +++ b/src/test/ui/issues/issue-21177.stderr @@ -11,13 +11,6 @@ note: cycle used when processing `foo` LL | fn foo>() { } | ^^^^ -error[E0220]: associated type `B` not found for `T` - --> $DIR/issue-21177.rs:6:21 - | -LL | fn foo>() { } - | ^^^^ associated type `B` not found - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors occurred: E0220, E0391. -For more information about an error, try `rustc --explain E0220`. +For more information about this error, try `rustc --explain E0391`.