From e291be3649c3088735936a6258317e69d3ad88f0 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 4 Apr 2021 14:24:27 +0200 Subject: [PATCH 1/5] Only compute the trait_map once. --- compiler/rustc_ast_lowering/src/lib.rs | 20 ++++++++++---------- compiler/rustc_hir/src/hir.rs | 8 ++++++-- compiler/rustc_middle/src/query/mod.rs | 1 - compiler/rustc_middle/src/ty/context.rs | 13 +------------ compiler/rustc_resolve/src/lib.rs | 4 ++-- 5 files changed, 19 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 6f1772ff8188d..7202774292f53 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -43,7 +43,8 @@ use rustc_ast::walk_list; use rustc_ast::{self as ast, *}; use rustc_ast_pretty::pprust; use rustc_data_structures::captures::Captures; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::stable_hasher::StableVec; use rustc_data_structures::sync::Lrc; use rustc_errors::{struct_span_err, Applicability}; use rustc_hir as hir; @@ -198,7 +199,7 @@ pub trait ResolverAstLowering { fn next_node_id(&mut self) -> NodeId; - fn trait_map(&self) -> &NodeMap>; + fn trait_map(&mut self) -> NodeMap>; fn opt_local_def_id(&self, node: NodeId) -> Option; @@ -501,14 +502,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let proc_macros = c.proc_macros.iter().map(|id| self.node_id_to_hir_id[*id].unwrap()).collect(); - let trait_map = self - .resolver - .trait_map() - .iter() - .filter_map(|(&k, v)| { - self.node_id_to_hir_id.get(k).and_then(|id| id.as_ref()).map(|id| (*id, v.clone())) - }) - .collect(); + let mut trait_map: FxHashMap<_, FxHashMap<_, _>> = FxHashMap::default(); + for (k, v) in self.resolver.trait_map().into_iter() { + if let Some(Some(hir_id)) = self.node_id_to_hir_id.get(k) { + let map = trait_map.entry(hir_id.owner).or_default(); + map.insert(hir_id.local_id, StableVec::new(v.to_vec())); + } + } let mut def_id_to_hir_id = IndexVec::default(); diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 91fd97a0d4020..8600276f05d2f 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1,7 +1,7 @@ // ignore-tidy-filelength use crate::def::{CtorKind, DefKind, Res}; use crate::def_id::DefId; -crate use crate::hir_id::HirId; +crate use crate::hir_id::{HirId, ItemLocalId}; use crate::{itemlikevisit, LangItem}; use rustc_ast::util::parser::ExprPrecedence; @@ -10,6 +10,8 @@ use rustc_ast::{Attribute, FloatTy, IntTy, Label, LitKind, StrStyle, TraitObject pub use rustc_ast::{BorrowKind, ImplPolarity, IsAuto}; pub use rustc_ast::{CaptureBy, Movability, Mutability}; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; +use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::stable_hasher::StableVec; use rustc_data_structures::sync::{par_for_each_in, Send, Sync}; use rustc_macros::HashStable_Generic; use rustc_span::source_map::Spanned; @@ -658,7 +660,9 @@ pub struct Crate<'hir> { /// they are declared in the static array generated by proc_macro_harness. pub proc_macros: Vec, - pub trait_map: BTreeMap>, + /// Map indicating what traits are in scope for places where this + /// is relevant; generated by resolve. + pub trait_map: FxHashMap>>, /// Collected attributes from HIR nodes. pub attrs: BTreeMap, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 9974f2bb8cac3..90be88e19367a 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1128,7 +1128,6 @@ rustc_queries! { } query in_scope_traits_map(_: LocalDefId) -> Option<&'tcx FxHashMap>> { - eval_always desc { "traits in scope at a block" } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index a2b17e97c29d9..19a768689b888 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -966,10 +966,6 @@ pub struct GlobalCtxt<'tcx> { /// Resolutions of `extern crate` items produced by resolver. extern_crate_map: FxHashMap, - /// Map indicating what traits are in scope for places where this - /// is relevant; generated by resolve. - trait_map: FxHashMap>>, - /// Export map produced by name resolution. export_map: ExportMap, @@ -1150,12 +1146,6 @@ impl<'tcx> TyCtxt<'tcx> { let common_consts = CommonConsts::new(&interners, &common_types); let cstore = resolutions.cstore; - let mut trait_map: FxHashMap<_, FxHashMap<_, _>> = FxHashMap::default(); - for (hir_id, v) in krate.trait_map.iter() { - let map = trait_map.entry(hir_id.owner).or_default(); - map.insert(hir_id.local_id, StableVec::new(v.to_vec())); - } - GlobalCtxt { sess: s, lint_store, @@ -1169,7 +1159,6 @@ impl<'tcx> TyCtxt<'tcx> { consts: common_consts, visibilities: resolutions.visibilities, extern_crate_map: resolutions.extern_crate_map, - trait_map, export_map: resolutions.export_map, maybe_unused_trait_imports: resolutions.maybe_unused_trait_imports, maybe_unused_extern_crates: resolutions.maybe_unused_extern_crates, @@ -2793,7 +2782,7 @@ fn ptr_eq(t: *const T, u: *const U) -> bool { } pub fn provide(providers: &mut ty::query::Providers) { - providers.in_scope_traits_map = |tcx, id| tcx.gcx.trait_map.get(&id); + providers.in_scope_traits_map = |tcx, id| tcx.hir_crate(()).trait_map.get(&id); providers.module_exports = |tcx, id| tcx.gcx.export_map.get(&id).map(|v| &v[..]); providers.crate_name = |tcx, id| { assert_eq!(id, LOCAL_CRATE); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 29d4271c475dd..7f97be9434ce0 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1138,8 +1138,8 @@ impl ResolverAstLowering for Resolver<'_> { self.next_node_id() } - fn trait_map(&self) -> &NodeMap> { - &self.trait_map + fn trait_map(&mut self) -> NodeMap> { + std::mem::take(&mut self.trait_map) } fn opt_local_def_id(&self, node: NodeId) -> Option { From 273778086c08dff938af758ae4a1b00974480c5d Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 11 May 2021 10:38:54 +0200 Subject: [PATCH 2/5] Remove StableVec. --- compiler/rustc_ast_lowering/src/lib.rs | 3 +- .../src/stable_hasher.rs | 32 ------------------- compiler/rustc_hir/src/hir.rs | 3 +- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 8 +++-- compiler/rustc_middle/src/ty/query/mod.rs | 1 - 6 files changed, 8 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 7202774292f53..a9950b82928bc 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -44,7 +44,6 @@ use rustc_ast::{self as ast, *}; use rustc_ast_pretty::pprust; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::stable_hasher::StableVec; use rustc_data_structures::sync::Lrc; use rustc_errors::{struct_span_err, Applicability}; use rustc_hir as hir; @@ -506,7 +505,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { for (k, v) in self.resolver.trait_map().into_iter() { if let Some(Some(hir_id)) = self.node_id_to_hir_id.get(k) { let map = trait_map.entry(hir_id.owner).or_default(); - map.insert(hir_id.local_id, StableVec::new(v.to_vec())); + map.insert(hir_id.local_id, v.into_boxed_slice()); } } diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index ff28784a1dc42..18b352cf3b0b9 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -550,35 +550,3 @@ pub fn hash_stable_hashmap( entries.sort_unstable_by(|&(ref sk1, _), &(ref sk2, _)| sk1.cmp(sk2)); entries.hash_stable(hcx, hasher); } - -/// A vector container that makes sure that its items are hashed in a stable -/// order. -#[derive(Debug)] -pub struct StableVec(Vec); - -impl StableVec { - pub fn new(v: Vec) -> Self { - StableVec(v) - } -} - -impl ::std::ops::Deref for StableVec { - type Target = Vec; - - fn deref(&self) -> &Vec { - &self.0 - } -} - -impl HashStable for StableVec -where - T: HashStable + ToStableHashKey, -{ - fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { - let StableVec(ref v) = *self; - - let mut sorted: Vec<_> = v.iter().map(|x| x.to_stable_hash_key(hcx)).collect(); - sorted.sort_unstable(); - sorted.hash_stable(hcx, hasher); - } -} diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 8600276f05d2f..e9055c9541086 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -11,7 +11,6 @@ pub use rustc_ast::{BorrowKind, ImplPolarity, IsAuto}; pub use rustc_ast::{CaptureBy, Movability, Mutability}; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::stable_hasher::StableVec; use rustc_data_structures::sync::{par_for_each_in, Send, Sync}; use rustc_macros::HashStable_Generic; use rustc_span::source_map::Spanned; @@ -662,7 +661,7 @@ pub struct Crate<'hir> { /// Map indicating what traits are in scope for places where this /// is relevant; generated by resolve. - pub trait_map: FxHashMap>>, + pub trait_map: FxHashMap>>, /// Collected attributes from HIR nodes. pub attrs: BTreeMap, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 90be88e19367a..3cc8fc3fe3189 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1127,7 +1127,7 @@ rustc_queries! { desc { "computing whether impls specialize one another" } } query in_scope_traits_map(_: LocalDefId) - -> Option<&'tcx FxHashMap>> { + -> Option<&'tcx FxHashMap>> { desc { "traits in scope at a block" } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 19a768689b888..ef93f4f64d8bc 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -31,7 +31,7 @@ use rustc_attr as attr; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap}; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableVec}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{self, Lock, Lrc, WorkerLocal}; use rustc_errors::ErrorReported; @@ -2651,8 +2651,10 @@ impl<'tcx> TyCtxt<'tcx> { struct_lint_level(self.sess, lint, level, src, None, decorate); } - pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx StableVec> { - self.in_scope_traits_map(id.owner).and_then(|map| map.get(&id.local_id)) + pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> { + let map = self.in_scope_traits_map(id.owner)?; + let candidates = map.get(&id.local_id)?; + Some(&*candidates) } pub fn named_region(self, id: HirId) -> Option { diff --git a/compiler/rustc_middle/src/ty/query/mod.rs b/compiler/rustc_middle/src/ty/query/mod.rs index bec13da017ea6..a5b540dcb70cd 100644 --- a/compiler/rustc_middle/src/ty/query/mod.rs +++ b/compiler/rustc_middle/src/ty/query/mod.rs @@ -34,7 +34,6 @@ use crate::ty::subst::{GenericArg, SubstsRef}; use crate::ty::util::AlwaysRequiresDrop; use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; -use rustc_data_structures::stable_hasher::StableVec; use rustc_data_structures::steal::Steal; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::Lrc; From c11691b46041fa08b76d556277d17f3e531a4025 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 29 May 2021 22:56:23 +0200 Subject: [PATCH 3/5] Check that trait_map is not moved twice. --- compiler/rustc_resolve/src/lib.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 7f97be9434ce0..e181b30f0e3d4 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -910,6 +910,8 @@ pub struct Resolver<'a> { extern_crate_map: FxHashMap, export_map: ExportMap, trait_map: NodeMap>, + #[cfg(debug_assertions)] + took_trait_map: bool, /// A map from nodes to anonymous modules. /// Anonymous modules are pseudo-modules that are implicitly created around items @@ -1139,6 +1141,11 @@ impl ResolverAstLowering for Resolver<'_> { } fn trait_map(&mut self) -> NodeMap> { + #[cfg(debug_assertions)] + { + debug_assert!(!self.took_trait_map); + self.took_trait_map = true; + } std::mem::take(&mut self.trait_map) } @@ -1287,6 +1294,8 @@ impl<'a> Resolver<'a> { extern_crate_map: Default::default(), export_map: FxHashMap::default(), trait_map: Default::default(), + #[cfg(debug_assertions)] + took_trait_map: false, underscore_disambiguator: 0, empty_module, module_map, From 0839cd5e9ae41acf3694c01fd2a831c9019206ea Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 29 May 2021 23:10:04 +0200 Subject: [PATCH 4/5] Rename take_trait_map. --- compiler/rustc_ast_lowering/src/lib.rs | 4 ++-- compiler/rustc_resolve/src/lib.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index a9950b82928bc..0ff1efd8165ea 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -198,7 +198,7 @@ pub trait ResolverAstLowering { fn next_node_id(&mut self) -> NodeId; - fn trait_map(&mut self) -> NodeMap>; + fn take_trait_map(&mut self) -> NodeMap>; fn opt_local_def_id(&self, node: NodeId) -> Option; @@ -502,7 +502,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { c.proc_macros.iter().map(|id| self.node_id_to_hir_id[*id].unwrap()).collect(); let mut trait_map: FxHashMap<_, FxHashMap<_, _>> = FxHashMap::default(); - for (k, v) in self.resolver.trait_map().into_iter() { + for (k, v) in self.resolver.take_trait_map().into_iter() { if let Some(Some(hir_id)) = self.node_id_to_hir_id.get(k) { let map = trait_map.entry(hir_id.owner).or_default(); map.insert(hir_id.local_id, v.into_boxed_slice()); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index e181b30f0e3d4..5e009d148322c 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1140,7 +1140,7 @@ impl ResolverAstLowering for Resolver<'_> { self.next_node_id() } - fn trait_map(&mut self) -> NodeMap> { + fn take_trait_map(&mut self) -> NodeMap> { #[cfg(debug_assertions)] { debug_assert!(!self.took_trait_map); From 93b25bd2936a92406a10c9aa7d57e764c431fd97 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 1 Jun 2021 21:50:06 +0200 Subject: [PATCH 5/5] Make trait_map an Option. --- compiler/rustc_resolve/src/late.rs | 6 +++--- compiler/rustc_resolve/src/lib.rs | 15 +++------------ 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 662d39f6ef39c..408d9b2392165 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1959,7 +1959,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { if ns == ValueNS { let item_name = path.last().unwrap().ident; let traits = self.traits_in_scope(item_name, ns); - self.r.trait_map.insert(id, traits); + self.r.trait_map.as_mut().unwrap().insert(id, traits); } if PrimTy::from_name(path[0].ident.name).is_some() { @@ -2435,12 +2435,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // the field name so that we can do some nice error reporting // later on in typeck. let traits = self.traits_in_scope(ident, ValueNS); - self.r.trait_map.insert(expr.id, traits); + self.r.trait_map.as_mut().unwrap().insert(expr.id, traits); } ExprKind::MethodCall(ref segment, ..) => { debug!("(recording candidate traits for expr) recording traits for {}", expr.id); let traits = self.traits_in_scope(segment.ident, ValueNS); - self.r.trait_map.insert(expr.id, traits); + self.r.trait_map.as_mut().unwrap().insert(expr.id, traits); } _ => { // Nothing to do. diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 5e009d148322c..86431b44fd680 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -909,9 +909,7 @@ pub struct Resolver<'a> { /// `CrateNum` resolutions of `extern crate` items. extern_crate_map: FxHashMap, export_map: ExportMap, - trait_map: NodeMap>, - #[cfg(debug_assertions)] - took_trait_map: bool, + trait_map: Option>>, /// A map from nodes to anonymous modules. /// Anonymous modules are pseudo-modules that are implicitly created around items @@ -1141,12 +1139,7 @@ impl ResolverAstLowering for Resolver<'_> { } fn take_trait_map(&mut self) -> NodeMap> { - #[cfg(debug_assertions)] - { - debug_assert!(!self.took_trait_map); - self.took_trait_map = true; - } - std::mem::take(&mut self.trait_map) + std::mem::replace(&mut self.trait_map, None).unwrap() } fn opt_local_def_id(&self, node: NodeId) -> Option { @@ -1293,9 +1286,7 @@ impl<'a> Resolver<'a> { label_res_map: Default::default(), extern_crate_map: Default::default(), export_map: FxHashMap::default(), - trait_map: Default::default(), - #[cfg(debug_assertions)] - took_trait_map: false, + trait_map: Some(NodeMap::default()), underscore_disambiguator: 0, empty_module, module_map,