diff options
| -rw-r--r-- | Cargo.lock | 1 | ||||
| -rw-r--r-- | compiler/rustc_ast_lowering/src/expr.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_ast_lowering/src/item.rs | 21 | ||||
| -rw-r--r-- | compiler/rustc_ast_lowering/src/lib.rs | 92 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/hir.rs | 39 | ||||
| -rw-r--r-- | compiler/rustc_middle/Cargo.toml | 1 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/hir/map/collector.rs | 16 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/hir/map/mod.rs | 54 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/hir/mod.rs | 46 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/lib.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/context.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/lib.rs | 8 |
13 files changed, 169 insertions, 124 deletions
diff --git a/Cargo.lock b/Cargo.lock index 197b2c8f3f0..00d470017bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4088,6 +4088,7 @@ dependencies = [ "polonius-engine", "rand 0.8.4", "rand_xoshiro 0.6.0", + "rustc-rayon", "rustc-rayon-core", "rustc_apfloat", "rustc_arena", diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 6027027428e..22f93f50788 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -252,9 +252,10 @@ impl<'hir> LoweringContext<'_, 'hir> { } // Merge attributes into the inner expression. if !e.attrs.is_empty() { - let old_attrs = self.attrs.get(&ex.hir_id).map(|la| *la).unwrap_or(&[]); + let old_attrs = + self.attrs.get(&ex.hir_id.local_id).map(|la| *la).unwrap_or(&[]); self.attrs.insert( - ex.hir_id, + ex.hir_id.local_id, &*self.arena.alloc_from_iter( e.attrs .iter() diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index ea9eb0cf274..c6572b19d1d 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -10,6 +10,7 @@ use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::LocalDefId; +use rustc_index::vec::Idx; use rustc_span::source_map::{respan, DesugaringKind}; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Span; @@ -99,11 +100,12 @@ impl<'hir> LoweringContext<'_, 'hir> { ) -> T { let old_len = self.in_scope_lifetimes.len(); - let parent_generics = match self.owners[parent_hir_id].unwrap().expect_item().kind { - hir::ItemKind::Impl(hir::Impl { ref generics, .. }) - | hir::ItemKind::Trait(_, _, ref generics, ..) => generics.params, - _ => &[], - }; + let parent_generics = + match self.owners[parent_hir_id].as_ref().unwrap().node.expect_item().kind { + hir::ItemKind::Impl(hir::Impl { ref generics, .. }) + | hir::ItemKind::Trait(_, _, ref generics, ..) => generics.params, + _ => &[], + }; let lt_def_names = parent_generics.iter().filter_map(|param| match param.kind { hir::GenericParamKind::Lifetime { .. } => Some(param.name.normalize_to_macros_2_0()), _ => None, @@ -493,7 +495,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let kind = hir::ItemKind::Use(path, hir::UseKind::Single); let vis = this.rebuild_vis(&vis); if let Some(attrs) = attrs { - this.attrs.insert(hir::HirId::make_owner(new_id), attrs); + this.attrs.insert(hir::ItemLocalId::new(0), attrs); } let item = hir::Item { @@ -568,7 +570,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let kind = this.lower_use_tree(use_tree, &prefix, id, &mut vis, &mut ident, attrs); if let Some(attrs) = attrs { - this.attrs.insert(hir::HirId::make_owner(new_hir_id), attrs); + this.attrs.insert(hir::ItemLocalId::new(0), attrs); } let item = hir::Item { @@ -971,7 +973,8 @@ impl<'hir> LoweringContext<'_, 'hir> { ) -> hir::BodyId { let body = hir::Body { generator_kind: self.generator_kind, params, value }; let id = body.id(); - self.bodies.insert(id, body); + debug_assert_eq!(id.hir_id.owner, self.current_hir_id_owner); + self.bodies.insert(id.hir_id.local_id, body); id } @@ -1124,7 +1127,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // // If this is the simple case, this parameter will end up being the same as the // original parameter, but with a different pattern id. - let stmt_attrs = this.attrs.get(¶meter.hir_id).copied(); + let stmt_attrs = this.attrs.get(¶meter.hir_id.local_id).copied(); let (new_parameter_pat, new_parameter_id) = this.pat_ident(desugared_span, ident); let new_parameter = hir::Param { hir_id: parameter.hir_id, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 245199e3751..1b82ac68e15 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -35,14 +35,13 @@ #![feature(iter_zip)] #![recursion_limit = "256"] -use rustc_ast::node_id::NodeMap; use rustc_ast::token::{self, Token}; use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, TokenStream, TokenTree}; use rustc_ast::visit; 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::fx::FxHashSet; use rustc_data_structures::sync::Lrc; use rustc_errors::{struct_span_err, Applicability}; use rustc_hir as hir; @@ -97,13 +96,12 @@ struct LoweringContext<'a, 'hir: 'a> { arena: &'hir Arena<'hir>, /// The items being lowered are collected here. - owners: IndexVec<LocalDefId, Option<hir::OwnerNode<'hir>>>, - bodies: BTreeMap<hir::BodyId, hir::Body<'hir>>, + owners: IndexVec<LocalDefId, Option<hir::OwnerInfo<'hir>>>, + bodies: BTreeMap<hir::ItemLocalId, hir::Body<'hir>>, + attrs: BTreeMap<hir::ItemLocalId, &'hir [Attribute]>, generator_kind: Option<hir::GeneratorKind>, - attrs: BTreeMap<hir::HirId, &'hir [Attribute]>, - /// When inside an `async` context, this is the `HirId` of the /// `task_context` local bound to the resume argument of the generator. task_context: Option<hir::HirId>, @@ -152,6 +150,9 @@ struct LoweringContext<'a, 'hir: 'a> { item_local_id_counter: hir::ItemLocalId, node_id_to_hir_id: IndexVec<NodeId, Option<hir::HirId>>, + /// NodeIds that are lowered inside the current HIR owner. + local_node_ids: Vec<NodeId>, + allow_try_trait: Option<Lrc<[Symbol]>>, allow_gen_future: Option<Lrc<[Symbol]>>, } @@ -182,7 +183,7 @@ pub trait ResolverAstLowering { fn next_node_id(&mut self) -> NodeId; - fn take_trait_map(&mut self) -> NodeMap<Vec<hir::TraitCandidate>>; + fn take_trait_map(&mut self, node: NodeId) -> Option<Vec<hir::TraitCandidate>>; fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId>; @@ -314,12 +315,13 @@ pub fn lower_crate<'a, 'hir>( ) -> &'hir hir::Crate<'hir> { let _prof_timer = sess.prof.verbose_generic_activity("hir_lowering"); + let owners = IndexVec::from_fn_n(|_| None, resolver.definitions().def_index_count()); LoweringContext { sess, resolver, nt_to_tokenstream, arena, - owners: IndexVec::default(), + owners, bodies: BTreeMap::new(), attrs: BTreeMap::default(), catch_scope: None, @@ -331,6 +333,7 @@ pub fn lower_crate<'a, 'hir>( current_hir_id_owner: CRATE_DEF_ID, item_local_id_counter: hir::ItemLocalId::new(0), node_id_to_hir_id: IndexVec::new(), + local_node_ids: Vec::new(), generator_kind: None, task_context: None, current_item: None, @@ -420,14 +423,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::OwnerNode::Crate(lctx.arena.alloc(module)) }); - let mut trait_map: FxHashMap<_, FxHashMap<_, _>> = FxHashMap::default(); - 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()); - } - } - let mut def_id_to_hir_id = IndexVec::default(); for (node_id, hir_id) in self.node_id_to_hir_id.into_iter_enumerated() { @@ -441,16 +436,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.resolver.definitions().init_def_id_to_hir_id_mapping(def_id_to_hir_id); - #[cfg(debug_assertions)] - for (&id, attrs) in self.attrs.iter() { - // Verify that we do not store empty slices in the map. - if attrs.is_empty() { - panic!("Stored empty attributes for {:?}", id); - } - } - - let krate = - hir::Crate { owners: self.owners, bodies: self.bodies, trait_map, attrs: self.attrs }; + let krate = hir::Crate { owners: self.owners }; self.arena.alloc(krate) } @@ -468,25 +454,57 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) -> LocalDefId { let def_id = self.resolver.local_def_id(owner); - // Always allocate the first `HirId` for the owner itself. - let _old = self.node_id_to_hir_id.insert(owner, hir::HirId::make_owner(def_id)); - debug_assert_eq!(_old, None); - + let current_attrs = std::mem::take(&mut self.attrs); + let current_bodies = std::mem::take(&mut self.bodies); + let current_node_ids = std::mem::take(&mut self.local_node_ids); let current_owner = std::mem::replace(&mut self.current_hir_id_owner, def_id); let current_local_counter = std::mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1)); + // Always allocate the first `HirId` for the owner itself. + let _old = self.node_id_to_hir_id.insert(owner, hir::HirId::make_owner(def_id)); + debug_assert_eq!(_old, None); + self.local_node_ids.push(owner); + let item = f(self); + let info = self.make_owner_info(item); + self.attrs = current_attrs; + self.bodies = current_bodies; + self.local_node_ids = current_node_ids; self.current_hir_id_owner = current_owner; self.item_local_id_counter = current_local_counter; - let _old = self.owners.insert(def_id, item); + let _old = self.owners.insert(def_id, info); debug_assert!(_old.is_none()); def_id } + fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> hir::OwnerInfo<'hir> { + let attrs = std::mem::take(&mut self.attrs); + let bodies = std::mem::take(&mut self.bodies); + let local_node_ids = std::mem::take(&mut self.local_node_ids); + let trait_map = local_node_ids + .into_iter() + .filter_map(|node_id| { + let hir_id = self.node_id_to_hir_id[node_id]?; + let traits = self.resolver.take_trait_map(node_id)?; + Some((hir_id.local_id, traits.into_boxed_slice())) + }) + .collect(); + + #[cfg(debug_assertions)] + for (&id, attrs) in attrs.iter() { + // Verify that we do not store empty slices in the map. + if attrs.is_empty() { + panic!("Stored empty attributes for {:?}", id); + } + } + + hir::OwnerInfo { node, attrs, bodies, trait_map } + } + /// This method allocates a new `HirId` for the given `NodeId` and stores it in /// the `LoweringContext`'s `NodeId => HirId` map. /// Take care not to call this method if the resulting `HirId` is then not @@ -501,6 +519,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let owner = self.current_hir_id_owner; let local_id = self.item_local_id_counter; self.item_local_id_counter.increment_by(1); + self.local_node_ids.push(ast_node_id); hir::HirId { owner, local_id } }) } @@ -791,9 +810,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { if attrs.is_empty() { None } else { + debug_assert_eq!(id.owner, self.current_hir_id_owner); let ret = self.arena.alloc_from_iter(attrs.iter().map(|a| self.lower_attr(a))); debug_assert!(!ret.is_empty()); - self.attrs.insert(id, ret); + self.attrs.insert(id.local_id, ret); Some(ret) } } @@ -819,9 +839,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } fn alias_attrs(&mut self, id: hir::HirId, target_id: hir::HirId) { - if let Some(&a) = self.attrs.get(&target_id) { + debug_assert_eq!(id.owner, self.current_hir_id_owner); + debug_assert_eq!(target_id.owner, self.current_hir_id_owner); + if let Some(&a) = self.attrs.get(&target_id.local_id) { debug_assert!(!a.is_empty()); - self.attrs.insert(id, a); + self.attrs.insert(id.local_id, a); } } @@ -2066,7 +2088,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let hir_id = self.next_id(); if let Some(a) = attrs { debug_assert!(!a.is_empty()); - self.attrs.insert(hir_id, a); + self.attrs.insert(hir_id.local_id, a); } let local = hir::Local { hir_id, init, pat, source, span: self.lower_span(span), ty: None }; self.stmt(span, hir::StmtKind::Local(self.arena.alloc(local))) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index fdd52bd7495..a24d92d0c01 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -662,6 +662,16 @@ pub struct WhereEqPredicate<'hir> { pub rhs_ty: &'hir Ty<'hir>, } +#[derive(Debug)] +pub struct OwnerInfo<'hir> { + pub node: OwnerNode<'hir>, + pub attrs: BTreeMap<ItemLocalId, &'hir [Attribute]>, + pub bodies: BTreeMap<ItemLocalId, Body<'hir>>, + /// Map indicating what traits are in scope for places where this + /// is relevant; generated by resolve. + pub trait_map: FxHashMap<ItemLocalId, Box<[TraitCandidate]>>, +} + /// The top-level data structure that stores the entire contents of /// the crate currently being compiled. /// @@ -670,40 +680,39 @@ pub struct WhereEqPredicate<'hir> { /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html #[derive(Debug)] pub struct Crate<'hir> { - pub owners: IndexVec<LocalDefId, Option<OwnerNode<'hir>>>, - pub bodies: BTreeMap<BodyId, Body<'hir>>, - - /// Map indicating what traits are in scope for places where this - /// is relevant; generated by resolve. - pub trait_map: FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Box<[TraitCandidate]>>>, - - /// Collected attributes from HIR nodes. - pub attrs: BTreeMap<HirId, &'hir [Attribute]>, + pub owners: IndexVec<LocalDefId, Option<OwnerInfo<'hir>>>, } impl Crate<'hir> { pub fn module(&self) -> &'hir Mod<'hir> { - if let Some(OwnerNode::Crate(m)) = self.owners[CRATE_DEF_ID] { m } else { panic!() } + let i = self.owners[CRATE_DEF_ID].as_ref().unwrap().node; + if let OwnerNode::Crate(m) = i { m } else { panic!() } } pub fn item(&self, id: ItemId) -> &'hir Item<'hir> { - self.owners[id.def_id].as_ref().unwrap().expect_item() + self.owners[id.def_id].as_ref().unwrap().node.expect_item() } pub fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir> { - self.owners[id.def_id].as_ref().unwrap().expect_trait_item() + self.owners[id.def_id].as_ref().unwrap().node.expect_trait_item() } pub fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir> { - self.owners[id.def_id].as_ref().unwrap().expect_impl_item() + self.owners[id.def_id].as_ref().unwrap().node.expect_impl_item() } pub fn foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir> { - self.owners[id.def_id].as_ref().unwrap().expect_foreign_item() + self.owners[id.def_id].as_ref().unwrap().node.expect_foreign_item() } pub fn body(&self, id: BodyId) -> &Body<'hir> { - &self.bodies[&id] + let HirId { owner, local_id } = id.hir_id; + &self.owners[owner].as_ref().unwrap().bodies[&local_id] + } + + pub fn attrs(&self, id: HirId) -> &'hir [Attribute] { + let HirId { owner, local_id } = id; + &self.owners[owner].as_ref().unwrap().attrs.get(&local_id).map(|la| *la).unwrap_or(&[]) } } diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index d06c593d394..daeccde6024 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -12,6 +12,7 @@ bitflags = "1.2.1" either = "1.5.0" gsgdt = "0.1.2" tracing = "0.1" +rustc-rayon = "0.3.1" rustc-rayon-core = "0.3.1" polonius-engine = "0.13.0" rustc_apfloat = { path = "../rustc_apfloat" } diff --git a/compiler/rustc_middle/src/hir/map/collector.rs b/compiler/rustc_middle/src/hir/map/collector.rs index efebf73224f..1e405d0d7fc 100644 --- a/compiler/rustc_middle/src/hir/map/collector.rs +++ b/compiler/rustc_middle/src/hir/map/collector.rs @@ -86,12 +86,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { collector } - pub(super) fn finalize_and_compute_crate_hash(mut self) -> IndexedHir<'hir> { - // Insert bodies into the map - for (id, body) in self.krate.bodies.iter() { - let bodies = &mut self.map[id.hir_id.owner].as_mut().unwrap().bodies; - assert!(bodies.insert(id.hir_id.local_id, body).is_none()); - } + pub(super) fn finalize_and_compute_crate_hash(self) -> IndexedHir<'hir> { IndexedHir { map: self.map, parenting: self.parenting } } @@ -101,9 +96,14 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { let mut nodes = IndexVec::new(); nodes.push(Some(ParentedNode { parent: ItemLocalId::new(0), node: node.into() })); + let mut bodies = FxHashMap::default(); + for (id, body) in self.krate.owners[owner].as_ref().unwrap().bodies.iter() { + let _old = bodies.insert(*id, body); + debug_assert!(_old.is_none()); + } + debug_assert!(self.map[owner].is_none()); - self.map[owner] = - Some(self.arena.alloc(OwnerNodes { hash, nodes, bodies: FxHashMap::default() })); + self.map[owner] = Some(self.arena.alloc(OwnerNodes { hash, nodes, bodies })); } fn insert(&mut self, span: Span, hir_id: HirId, node: Node<'hir>) { diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index e6f56b0be93..9a1bdba824e 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -1,6 +1,6 @@ use self::collector::NodeCollector; -use crate::hir::{AttributeMap, IndexedHir, ModuleItems, Owner}; +use crate::hir::{IndexedHir, ModuleItems, Owner}; use crate::ty::TyCtxt; use rustc_ast as ast; use rustc_data_structures::fingerprint::Fingerprint; @@ -166,8 +166,8 @@ impl<'hir> Map<'hir> { pub fn items(&self) -> impl Iterator<Item = &'hir Item<'hir>> + 'hir { let krate = self.krate(); - krate.owners.iter().filter_map(|owner| match owner.as_ref()? { - OwnerNode::Item(item) => Some(*item), + krate.owners.iter().filter_map(|owner| match owner.as_ref()?.node { + OwnerNode::Item(item) => Some(item), _ => None, }) } @@ -495,11 +495,35 @@ impl<'hir> Map<'hir> { /// crate. If you would prefer to iterate over the bodies /// themselves, you can do `self.hir().krate().body_ids.iter()`. pub fn body_owners(self) -> impl Iterator<Item = LocalDefId> + 'hir { - self.krate().bodies.keys().map(move |&body_id| self.body_owner_def_id(body_id)) + self.krate() + .owners + .iter_enumerated() + .flat_map(move |(owner, owner_info)| { + let bodies = &owner_info.as_ref()?.bodies; + Some(bodies.keys().map(move |&local_id| { + let hir_id = HirId { owner, local_id }; + let body_id = BodyId { hir_id }; + self.body_owner_def_id(body_id) + })) + }) + .flatten() } pub fn par_body_owners<F: Fn(LocalDefId) + Sync + Send>(self, f: F) { - par_for_each_in(&self.krate().bodies, |(&body_id, _)| f(self.body_owner_def_id(body_id))); + use rustc_data_structures::sync::{par_iter, ParallelIterator}; + #[cfg(parallel_compiler)] + use rustc_rayon::iter::IndexedParallelIterator; + + par_iter(&self.krate().owners.raw).enumerate().for_each(|(owner, owner_info)| { + let owner = LocalDefId::new(owner); + if let Some(owner_info) = owner_info { + par_iter(&owner_info.bodies).for_each(|(&local_id, _)| { + let hir_id = HirId { owner, local_id }; + let body_id = BodyId { hir_id }; + f(self.body_owner_def_id(body_id)) + }) + } + }); } pub fn ty_param_owner(&self, id: HirId) -> HirId { @@ -551,9 +575,14 @@ impl<'hir> Map<'hir> { /// Walks the attributes in a crate. pub fn walk_attributes(self, visitor: &mut impl Visitor<'hir>) { let krate = self.krate(); - for (&id, attrs) in krate.attrs.iter() { - for a in *attrs { - visitor.visit_attribute(id, a) + for (owner, info) in krate.owners.iter_enumerated() { + if let Some(info) = info { + for (&local_id, attrs) in info.attrs.iter() { + let id = HirId { owner, local_id }; + for a in *attrs { + visitor.visit_attribute(id, a) + } + } } } } @@ -572,7 +601,7 @@ impl<'hir> Map<'hir> { { let krate = self.krate(); for owner in krate.owners.iter().filter_map(Option::as_ref) { - match owner { + match owner.node { OwnerNode::Item(item) => visitor.visit_item(item), OwnerNode::ForeignItem(item) => visitor.visit_foreign_item(item), OwnerNode::ImplItem(item) => visitor.visit_impl_item(item), @@ -588,7 +617,7 @@ impl<'hir> Map<'hir> { V: itemlikevisit::ParItemLikeVisitor<'hir> + Sync + Send, { let krate = self.krate(); - par_for_each_in(&krate.owners.raw, |owner| match owner.as_ref() { + par_for_each_in(&krate.owners.raw, |owner| match owner.as_ref().map(|o| o.node) { Some(OwnerNode::Item(item)) => visitor.visit_item(item), Some(OwnerNode::ForeignItem(item)) => visitor.visit_foreign_item(item), Some(OwnerNode::ImplItem(item)) => visitor.visit_impl_item(item), @@ -1091,7 +1120,10 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh { for (def_path_hash, fingerprint, def_id) in hir_body_nodes.iter() { def_path_hash.0.hash_stable(&mut hcx, &mut stable_hasher); fingerprint.hash_stable(&mut hcx, &mut stable_hasher); - AttributeMap { map: &tcx.untracked_crate.attrs, prefix: *def_id } + tcx.untracked_crate.owners[*def_id] + .as_ref() + .unwrap() + .attrs .hash_stable(&mut hcx, &mut stable_hasher); if tcx.sess.opts.debugging_opts.incremental_relative_spans { let span = tcx.untracked_resolutions.definitions.def_span(*def_id); diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index ded724c9bad..9f2ee9f341c 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -77,47 +77,21 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for OwnerNodes<'tcx> { } } -/// Attributes owner by a HIR owner. It is build as a slice inside the attributes map, restricted -/// to the nodes whose `HirId::owner` is `prefix`. -#[derive(Copy, Clone)] +/// Attributes owner by a HIR owner. +#[derive(Copy, Clone, Debug, HashStable)] pub struct AttributeMap<'tcx> { - map: &'tcx BTreeMap<HirId, &'tcx [Attribute]>, - prefix: LocalDefId, -} - -impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for AttributeMap<'tcx> { - fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - let range = self.range(); - - range.clone().count().hash_stable(hcx, hasher); - for (key, value) in range { - key.hash_stable(hcx, hasher); - value.hash_stable(hcx, hasher); - } - } -} - -impl<'tcx> std::fmt::Debug for AttributeMap<'tcx> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("AttributeMap") - .field("prefix", &self.prefix) - .field("range", &&self.range().collect::<Vec<_>>()[..]) - .finish() - } + map: &'tcx BTreeMap<ItemLocalId, &'tcx [Attribute]>, } impl<'tcx> AttributeMap<'tcx> { - fn get(&self, id: ItemLocalId) -> &'tcx [Attribute] { - self.map.get(&HirId { owner: self.prefix, local_id: id }).copied().unwrap_or(&[]) + fn new(owner_info: &'tcx Option<OwnerInfo<'tcx>>) -> AttributeMap<'tcx> { + const FALLBACK: &'static BTreeMap<ItemLocalId, &'static [Attribute]> = &BTreeMap::new(); + let map = owner_info.as_ref().map_or(FALLBACK, |info| &info.attrs); + AttributeMap { map } } - fn range(&self) -> std::collections::btree_map::Range<'_, rustc_hir::HirId, &[Attribute]> { - let local_zero = ItemLocalId::from_u32(0); - let range = HirId { owner: self.prefix, local_id: local_zero }..HirId { - owner: LocalDefId { local_def_index: self.prefix.local_def_index + 1 }, - local_id: local_zero, - }; - self.map.range(range) + fn get(&self, id: ItemLocalId) -> &'tcx [Attribute] { + self.map.get(&id).copied().unwrap_or(&[]) } } @@ -163,7 +137,7 @@ pub fn provide(providers: &mut Providers) { let index = tcx.index_hir(()); index.parenting.get(&id).copied().unwrap_or(CRATE_HIR_ID) }; - providers.hir_attrs = |tcx, id| AttributeMap { map: &tcx.hir_crate(()).attrs, prefix: id }; + providers.hir_attrs = |tcx, id| AttributeMap::new(&tcx.hir_crate(()).owners[id]); providers.source_span = |tcx, def_id| tcx.resolutions(()).definitions.def_span(def_id); providers.def_span = |tcx, def_id| tcx.hir().span_if_local(def_id).unwrap_or(DUMMY_SP); providers.fn_arg_names = |tcx, id| { diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index e41f5add457..e7219cc58a1 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -30,6 +30,7 @@ #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(core_intrinsics)] +#![feature(const_btree_new)] #![feature(discriminant_kind)] #![feature(exhaustive_patterns)] #![feature(if_let_guard)] diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 6a6fb30dce8..cbbd89e9033 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2828,7 +2828,8 @@ fn ptr_eq<T, U>(t: *const T, u: *const U) -> bool { } pub fn provide(providers: &mut ty::query::Providers) { - providers.in_scope_traits_map = |tcx, id| tcx.hir_crate(()).trait_map.get(&id); + providers.in_scope_traits_map = + |tcx, id| tcx.hir_crate(()).owners[id].as_ref().map(|owner_info| &owner_info.trait_map); providers.resolutions = |tcx, ()| &tcx.untracked_resolutions; providers.module_exports = |tcx, id| tcx.resolutions(()).export_map.get(&id).map(|v| &v[..]); providers.crate_name = |tcx, id| { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 95633257965..0a24e00ee4b 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1994,7 +1994,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.as_mut().unwrap().insert(id, traits); + self.r.trait_map.insert(id, traits); } if PrimTy::from_name(path[0].ident.name).is_some() { @@ -2479,12 +2479,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.as_mut().unwrap().insert(expr.id, traits); + self.r.trait_map.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.as_mut().unwrap().insert(expr.id, traits); + self.r.trait_map.insert(expr.id, traits); } _ => { // Nothing to do. diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 3e7783033ef..28fe365fb58 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -930,7 +930,7 @@ pub struct Resolver<'a> { /// `CrateNum` resolutions of `extern crate` items. extern_crate_map: FxHashMap<LocalDefId, CrateNum>, export_map: ExportMap, - trait_map: Option<NodeMap<Vec<TraitCandidate>>>, + trait_map: NodeMap<Vec<TraitCandidate>>, /// A map from nodes to anonymous modules. /// Anonymous modules are pseudo-modules that are implicitly created around items @@ -1185,8 +1185,8 @@ impl ResolverAstLowering for Resolver<'_> { self.next_node_id() } - fn take_trait_map(&mut self) -> NodeMap<Vec<TraitCandidate>> { - std::mem::replace(&mut self.trait_map, None).unwrap() + fn take_trait_map(&mut self, node: NodeId) -> Option<Vec<TraitCandidate>> { + self.trait_map.remove(&node) } fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> { @@ -1363,7 +1363,7 @@ impl<'a> Resolver<'a> { label_res_map: Default::default(), extern_crate_map: Default::default(), export_map: FxHashMap::default(), - trait_map: Some(NodeMap::default()), + trait_map: NodeMap::default(), underscore_disambiguator: 0, empty_module, module_map, |
