Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 48a339d

Browse files
committed
Store lowering outputs per owner.
1 parent f9e1de9 commit 48a339d

File tree

13 files changed

+169
-124
lines changed

13 files changed

+169
-124
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4088,6 +4088,7 @@ dependencies = [
40884088
"polonius-engine",
40894089
"rand 0.8.4",
40904090
"rand_xoshiro 0.6.0",
4091+
"rustc-rayon",
40914092
"rustc-rayon-core",
40924093
"rustc_apfloat",
40934094
"rustc_arena",

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,9 +252,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
252252
}
253253
// Merge attributes into the inner expression.
254254
if !e.attrs.is_empty() {
255-
let old_attrs = self.attrs.get(&ex.hir_id).map(|la| *la).unwrap_or(&[]);
255+
let old_attrs =
256+
self.attrs.get(&ex.hir_id.local_id).map(|la| *la).unwrap_or(&[]);
256257
self.attrs.insert(
257-
ex.hir_id,
258+
ex.hir_id.local_id,
258259
&*self.arena.alloc_from_iter(
259260
e.attrs
260261
.iter()

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_errors::struct_span_err;
1010
use rustc_hir as hir;
1111
use rustc_hir::def::{DefKind, Res};
1212
use rustc_hir::def_id::LocalDefId;
13+
use rustc_index::vec::Idx;
1314
use rustc_span::source_map::{respan, DesugaringKind};
1415
use rustc_span::symbol::{kw, sym, Ident};
1516
use rustc_span::Span;
@@ -99,11 +100,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
99100
) -> T {
100101
let old_len = self.in_scope_lifetimes.len();
101102

102-
let parent_generics = match self.owners[parent_hir_id].unwrap().expect_item().kind {
103-
hir::ItemKind::Impl(hir::Impl { ref generics, .. })
104-
| hir::ItemKind::Trait(_, _, ref generics, ..) => generics.params,
105-
_ => &[],
106-
};
103+
let parent_generics =
104+
match self.owners[parent_hir_id].as_ref().unwrap().node.expect_item().kind {
105+
hir::ItemKind::Impl(hir::Impl { ref generics, .. })
106+
| hir::ItemKind::Trait(_, _, ref generics, ..) => generics.params,
107+
_ => &[],
108+
};
107109
let lt_def_names = parent_generics.iter().filter_map(|param| match param.kind {
108110
hir::GenericParamKind::Lifetime { .. } => Some(param.name.normalize_to_macros_2_0()),
109111
_ => None,
@@ -493,7 +495,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
493495
let kind = hir::ItemKind::Use(path, hir::UseKind::Single);
494496
let vis = this.rebuild_vis(&vis);
495497
if let Some(attrs) = attrs {
496-
this.attrs.insert(hir::HirId::make_owner(new_id), attrs);
498+
this.attrs.insert(hir::ItemLocalId::new(0), attrs);
497499
}
498500

499501
let item = hir::Item {
@@ -568,7 +570,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
568570
let kind =
569571
this.lower_use_tree(use_tree, &prefix, id, &mut vis, &mut ident, attrs);
570572
if let Some(attrs) = attrs {
571-
this.attrs.insert(hir::HirId::make_owner(new_hir_id), attrs);
573+
this.attrs.insert(hir::ItemLocalId::new(0), attrs);
572574
}
573575

574576
let item = hir::Item {
@@ -971,7 +973,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
971973
) -> hir::BodyId {
972974
let body = hir::Body { generator_kind: self.generator_kind, params, value };
973975
let id = body.id();
974-
self.bodies.insert(id, body);
976+
debug_assert_eq!(id.hir_id.owner, self.current_hir_id_owner);
977+
self.bodies.insert(id.hir_id.local_id, body);
975978
id
976979
}
977980

@@ -1124,7 +1127,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
11241127
//
11251128
// If this is the simple case, this parameter will end up being the same as the
11261129
// original parameter, but with a different pattern id.
1127-
let stmt_attrs = this.attrs.get(&parameter.hir_id).copied();
1130+
let stmt_attrs = this.attrs.get(&parameter.hir_id.local_id).copied();
11281131
let (new_parameter_pat, new_parameter_id) = this.pat_ident(desugared_span, ident);
11291132
let new_parameter = hir::Param {
11301133
hir_id: parameter.hir_id,

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 57 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,13 @@
3535
#![feature(iter_zip)]
3636
#![recursion_limit = "256"]
3737

38-
use rustc_ast::node_id::NodeMap;
3938
use rustc_ast::token::{self, Token};
4039
use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, TokenStream, TokenTree};
4140
use rustc_ast::visit;
4241
use rustc_ast::{self as ast, *};
4342
use rustc_ast_pretty::pprust;
4443
use rustc_data_structures::captures::Captures;
45-
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
44+
use rustc_data_structures::fx::FxHashSet;
4645
use rustc_data_structures::sync::Lrc;
4746
use rustc_errors::{struct_span_err, Applicability};
4847
use rustc_hir as hir;
@@ -97,13 +96,12 @@ struct LoweringContext<'a, 'hir: 'a> {
9796
arena: &'hir Arena<'hir>,
9897

9998
/// The items being lowered are collected here.
100-
owners: IndexVec<LocalDefId, Option<hir::OwnerNode<'hir>>>,
101-
bodies: BTreeMap<hir::BodyId, hir::Body<'hir>>,
99+
owners: IndexVec<LocalDefId, Option<hir::OwnerInfo<'hir>>>,
100+
bodies: BTreeMap<hir::ItemLocalId, hir::Body<'hir>>,
101+
attrs: BTreeMap<hir::ItemLocalId, &'hir [Attribute]>,
102102

103103
generator_kind: Option<hir::GeneratorKind>,
104104

105-
attrs: BTreeMap<hir::HirId, &'hir [Attribute]>,
106-
107105
/// When inside an `async` context, this is the `HirId` of the
108106
/// `task_context` local bound to the resume argument of the generator.
109107
task_context: Option<hir::HirId>,
@@ -152,6 +150,9 @@ struct LoweringContext<'a, 'hir: 'a> {
152150
item_local_id_counter: hir::ItemLocalId,
153151
node_id_to_hir_id: IndexVec<NodeId, Option<hir::HirId>>,
154152

153+
/// NodeIds that are lowered inside the current HIR owner.
154+
local_node_ids: Vec<NodeId>,
155+
155156
allow_try_trait: Option<Lrc<[Symbol]>>,
156157
allow_gen_future: Option<Lrc<[Symbol]>>,
157158
}
@@ -182,7 +183,7 @@ pub trait ResolverAstLowering {
182183

183184
fn next_node_id(&mut self) -> NodeId;
184185

185-
fn take_trait_map(&mut self) -> NodeMap<Vec<hir::TraitCandidate>>;
186+
fn take_trait_map(&mut self, node: NodeId) -> Option<Vec<hir::TraitCandidate>>;
186187

187188
fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId>;
188189

@@ -314,12 +315,13 @@ pub fn lower_crate<'a, 'hir>(
314315
) -> &'hir hir::Crate<'hir> {
315316
let _prof_timer = sess.prof.verbose_generic_activity("hir_lowering");
316317

318+
let owners = IndexVec::from_fn_n(|_| None, resolver.definitions().def_index_count());
317319
LoweringContext {
318320
sess,
319321
resolver,
320322
nt_to_tokenstream,
321323
arena,
322-
owners: IndexVec::default(),
324+
owners,
323325
bodies: BTreeMap::new(),
324326
attrs: BTreeMap::default(),
325327
catch_scope: None,
@@ -331,6 +333,7 @@ pub fn lower_crate<'a, 'hir>(
331333
current_hir_id_owner: CRATE_DEF_ID,
332334
item_local_id_counter: hir::ItemLocalId::new(0),
333335
node_id_to_hir_id: IndexVec::new(),
336+
local_node_ids: Vec::new(),
334337
generator_kind: None,
335338
task_context: None,
336339
current_item: None,
@@ -420,14 +423,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
420423
hir::OwnerNode::Crate(lctx.arena.alloc(module))
421424
});
422425

423-
let mut trait_map: FxHashMap<_, FxHashMap<_, _>> = FxHashMap::default();
424-
for (k, v) in self.resolver.take_trait_map().into_iter() {
425-
if let Some(Some(hir_id)) = self.node_id_to_hir_id.get(k) {
426-
let map = trait_map.entry(hir_id.owner).or_default();
427-
map.insert(hir_id.local_id, v.into_boxed_slice());
428-
}
429-
}
430-
431426
let mut def_id_to_hir_id = IndexVec::default();
432427

433428
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> {
441436

442437
self.resolver.definitions().init_def_id_to_hir_id_mapping(def_id_to_hir_id);
443438

444-
#[cfg(debug_assertions)]
445-
for (&id, attrs) in self.attrs.iter() {
446-
// Verify that we do not store empty slices in the map.
447-
if attrs.is_empty() {
448-
panic!("Stored empty attributes for {:?}", id);
449-
}
450-
}
451-
452-
let krate =
453-
hir::Crate { owners: self.owners, bodies: self.bodies, trait_map, attrs: self.attrs };
439+
let krate = hir::Crate { owners: self.owners };
454440
self.arena.alloc(krate)
455441
}
456442

@@ -468,25 +454,57 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
468454
) -> LocalDefId {
469455
let def_id = self.resolver.local_def_id(owner);
470456

471-
// Always allocate the first `HirId` for the owner itself.
472-
let _old = self.node_id_to_hir_id.insert(owner, hir::HirId::make_owner(def_id));
473-
debug_assert_eq!(_old, None);
474-
457+
let current_attrs = std::mem::take(&mut self.attrs);
458+
let current_bodies = std::mem::take(&mut self.bodies);
459+
let current_node_ids = std::mem::take(&mut self.local_node_ids);
475460
let current_owner = std::mem::replace(&mut self.current_hir_id_owner, def_id);
476461
let current_local_counter =
477462
std::mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1));
478463

464+
// Always allocate the first `HirId` for the owner itself.
465+
let _old = self.node_id_to_hir_id.insert(owner, hir::HirId::make_owner(def_id));
466+
debug_assert_eq!(_old, None);
467+
self.local_node_ids.push(owner);
468+
479469
let item = f(self);
470+
let info = self.make_owner_info(item);
480471

472+
self.attrs = current_attrs;
473+
self.bodies = current_bodies;
474+
self.local_node_ids = current_node_ids;
481475
self.current_hir_id_owner = current_owner;
482476
self.item_local_id_counter = current_local_counter;
483477

484-
let _old = self.owners.insert(def_id, item);
478+
let _old = self.owners.insert(def_id, info);
485479
debug_assert!(_old.is_none());
486480

487481
def_id
488482
}
489483

484+
fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> hir::OwnerInfo<'hir> {
485+
let attrs = std::mem::take(&mut self.attrs);
486+
let bodies = std::mem::take(&mut self.bodies);
487+
let local_node_ids = std::mem::take(&mut self.local_node_ids);
488+
let trait_map = local_node_ids
489+
.into_iter()
490+
.filter_map(|node_id| {
491+
let hir_id = self.node_id_to_hir_id[node_id]?;
492+
let traits = self.resolver.take_trait_map(node_id)?;
493+
Some((hir_id.local_id, traits.into_boxed_slice()))
494+
})
495+
.collect();
496+
497+
#[cfg(debug_assertions)]
498+
for (&id, attrs) in attrs.iter() {
499+
// Verify that we do not store empty slices in the map.
500+
if attrs.is_empty() {
501+
panic!("Stored empty attributes for {:?}", id);
502+
}
503+
}
504+
505+
hir::OwnerInfo { node, attrs, bodies, trait_map }
506+
}
507+
490508
/// This method allocates a new `HirId` for the given `NodeId` and stores it in
491509
/// the `LoweringContext`'s `NodeId => HirId` map.
492510
/// Take care not to call this method if the resulting `HirId` is then not
@@ -501,6 +519,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
501519
let owner = self.current_hir_id_owner;
502520
let local_id = self.item_local_id_counter;
503521
self.item_local_id_counter.increment_by(1);
522+
self.local_node_ids.push(ast_node_id);
504523
hir::HirId { owner, local_id }
505524
})
506525
}
@@ -791,9 +810,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
791810
if attrs.is_empty() {
792811
None
793812
} else {
813+
debug_assert_eq!(id.owner, self.current_hir_id_owner);
794814
let ret = self.arena.alloc_from_iter(attrs.iter().map(|a| self.lower_attr(a)));
795815
debug_assert!(!ret.is_empty());
796-
self.attrs.insert(id, ret);
816+
self.attrs.insert(id.local_id, ret);
797817
Some(ret)
798818
}
799819
}
@@ -819,9 +839,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
819839
}
820840

821841
fn alias_attrs(&mut self, id: hir::HirId, target_id: hir::HirId) {
822-
if let Some(&a) = self.attrs.get(&target_id) {
842+
debug_assert_eq!(id.owner, self.current_hir_id_owner);
843+
debug_assert_eq!(target_id.owner, self.current_hir_id_owner);
844+
if let Some(&a) = self.attrs.get(&target_id.local_id) {
823845
debug_assert!(!a.is_empty());
824-
self.attrs.insert(id, a);
846+
self.attrs.insert(id.local_id, a);
825847
}
826848
}
827849

@@ -2066,7 +2088,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
20662088
let hir_id = self.next_id();
20672089
if let Some(a) = attrs {
20682090
debug_assert!(!a.is_empty());
2069-
self.attrs.insert(hir_id, a);
2091+
self.attrs.insert(hir_id.local_id, a);
20702092
}
20712093
let local = hir::Local { hir_id, init, pat, source, span: self.lower_span(span), ty: None };
20722094
self.stmt(span, hir::StmtKind::Local(self.arena.alloc(local)))

compiler/rustc_hir/src/hir.rs

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,16 @@ pub struct WhereEqPredicate<'hir> {
662662
pub rhs_ty: &'hir Ty<'hir>,
663663
}
664664

665+
#[derive(Debug)]
666+
pub struct OwnerInfo<'hir> {
667+
pub node: OwnerNode<'hir>,
668+
pub attrs: BTreeMap<ItemLocalId, &'hir [Attribute]>,
669+
pub bodies: BTreeMap<ItemLocalId, Body<'hir>>,
670+
/// Map indicating what traits are in scope for places where this
671+
/// is relevant; generated by resolve.
672+
pub trait_map: FxHashMap<ItemLocalId, Box<[TraitCandidate]>>,
673+
}
674+
665675
/// The top-level data structure that stores the entire contents of
666676
/// the crate currently being compiled.
667677
///
@@ -670,40 +680,39 @@ pub struct WhereEqPredicate<'hir> {
670680
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html
671681
#[derive(Debug)]
672682
pub struct Crate<'hir> {
673-
pub owners: IndexVec<LocalDefId, Option<OwnerNode<'hir>>>,
674-
pub bodies: BTreeMap<BodyId, Body<'hir>>,
675-
676-
/// Map indicating what traits are in scope for places where this
677-
/// is relevant; generated by resolve.
678-
pub trait_map: FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Box<[TraitCandidate]>>>,
679-
680-
/// Collected attributes from HIR nodes.
681-
pub attrs: BTreeMap<HirId, &'hir [Attribute]>,
683+
pub owners: IndexVec<LocalDefId, Option<OwnerInfo<'hir>>>,
682684
}
683685

684686
impl Crate<'hir> {
685687
pub fn module(&self) -> &'hir Mod<'hir> {
686-
if let Some(OwnerNode::Crate(m)) = self.owners[CRATE_DEF_ID] { m } else { panic!() }
688+
let i = self.owners[CRATE_DEF_ID].as_ref().unwrap().node;
689+
if let OwnerNode::Crate(m) = i { m } else { panic!() }
687690
}
688691

689692
pub fn item(&self, id: ItemId) -> &'hir Item<'hir> {
690-
self.owners[id.def_id].as_ref().unwrap().expect_item()
693+
self.owners[id.def_id].as_ref().unwrap().node.expect_item()
691694
}
692695

693696
pub fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir> {
694-
self.owners[id.def_id].as_ref().unwrap().expect_trait_item()
697+
self.owners[id.def_id].as_ref().unwrap().node.expect_trait_item()
695698
}
696699

697700
pub fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir> {
698-
self.owners[id.def_id].as_ref().unwrap().expect_impl_item()
701+
self.owners[id.def_id].as_ref().unwrap().node.expect_impl_item()
699702
}
700703

701704
pub fn foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir> {
702-
self.owners[id.def_id].as_ref().unwrap().expect_foreign_item()
705+
self.owners[id.def_id].as_ref().unwrap().node.expect_foreign_item()
703706
}
704707

705708
pub fn body(&self, id: BodyId) -> &Body<'hir> {
706-
&self.bodies[&id]
709+
let HirId { owner, local_id } = id.hir_id;
710+
&self.owners[owner].as_ref().unwrap().bodies[&local_id]
711+
}
712+
713+
pub fn attrs(&self, id: HirId) -> &'hir [Attribute] {
714+
let HirId { owner, local_id } = id;
715+
&self.owners[owner].as_ref().unwrap().attrs.get(&local_id).map(|la| *la).unwrap_or(&[])
707716
}
708717
}
709718

compiler/rustc_middle/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ bitflags = "1.2.1"
1212
either = "1.5.0"
1313
gsgdt = "0.1.2"
1414
tracing = "0.1"
15+
rustc-rayon = "0.3.1"
1516
rustc-rayon-core = "0.3.1"
1617
polonius-engine = "0.13.0"
1718
rustc_apfloat = { path = "../rustc_apfloat" }

0 commit comments

Comments
 (0)