Skip to content

Commit 518c78f

Browse files
committed
Create Map after TyCtxt
1 parent 21386e1 commit 518c78f

File tree

8 files changed

+130
-157
lines changed

8 files changed

+130
-157
lines changed

src/librustc/arena.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,8 @@ macro_rules! arena_types {
163163
[] where_predicate: rustc_hir::WherePredicate<$tcx>,
164164

165165
// HIR query types
166+
[few] hir_map: rustc::hir::map::Map<$tcx>,
167+
[few] hir_definitions: rustc::hir::map::definitions::Definitions,
166168
[] hir_owner: rustc::hir::HirOwner<$tcx>,
167169
[] hir_owner_items: rustc::hir::HirOwnerItems<$tcx>,
168170
], $tcx);

src/librustc/hir/map/collector.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,12 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
209209
FxHashMap<DefIndex, &'hir mut HirOwnerItems<'hir>>,
210210
Svh,
211211
) {
212+
// Insert bodies into the map
213+
for (id, body) in self.krate.bodies.iter() {
214+
let bodies = &mut self.owner_items_map.get_mut(&id.hir_id.owner).unwrap().bodies;
215+
assert!(bodies.insert(id.hir_id.local_id, body).is_none());
216+
}
217+
212218
self.hir_body_nodes.sort_unstable_by_key(|bn| bn.0);
213219

214220
let node_hashes = self.hir_body_nodes.iter().fold(

src/librustc/hir/map/hir_id_validator.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
use crate::hir::map::Map;
2-
use rustc_data_structures::fx::FxHashSet;
1+
use crate::hir::map::EarlyMap;
2+
/*use rustc_data_structures::fx::FxHashSet;
33
use rustc_data_structures::sync::{par_iter, Lock, ParallelIterator};
44
use rustc_hir as hir;
55
use rustc_hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
66
use rustc_hir::intravisit;
77
use rustc_hir::itemlikevisit::ItemLikeVisitor;
8-
use rustc_hir::{HirId, ItemLocalId};
8+
use rustc_hir::{HirId, ItemLocalId};*/
99

10-
pub fn check_crate(hir_map: &Map<'_>, sess: &rustc_session::Session) {
10+
pub fn check_crate(hir_map: &EarlyMap<'_>, sess: &rustc_session::Session) {
1111
hir_map.dep_graph.assert_ignored();
12-
12+
/*
1313
let errors = Lock::new(Vec::new());
1414
1515
par_iter(&hir_map.krate.modules).for_each(|(module_id, _)| {
@@ -25,23 +25,23 @@ pub fn check_crate(hir_map: &Map<'_>, sess: &rustc_session::Session) {
2525
if !errors.is_empty() {
2626
let message = errors.iter().fold(String::new(), |s1, s2| s1 + "\n" + s2);
2727
sess.delay_span_bug(rustc_span::DUMMY_SP, &message);
28-
}
28+
}*/
2929
}
30-
30+
/*
3131
struct HirIdValidator<'a, 'hir> {
32-
hir_map: &'a Map<'hir>,
32+
hir_map: &'a EarlyMap<'hir>,
3333
owner_def_index: Option<DefIndex>,
3434
hir_ids_seen: FxHashSet<ItemLocalId>,
3535
errors: &'a Lock<Vec<String>>,
3636
}
3737
3838
struct OuterVisitor<'a, 'hir> {
39-
hir_map: &'a Map<'hir>,
39+
hir_map: &'a EarlyMap<'hir>,
4040
errors: &'a Lock<Vec<String>>,
4141
}
4242
4343
impl<'a, 'hir> OuterVisitor<'a, 'hir> {
44-
fn new_inner_visitor(&self, hir_map: &'a Map<'hir>) -> HirIdValidator<'a, 'hir> {
44+
fn new_inner_visitor(&self, hir_map: &'a EarlyMap<'hir>) -> HirIdValidator<'a, 'hir> {
4545
HirIdValidator {
4646
hir_map,
4747
owner_def_index: None,
@@ -133,7 +133,7 @@ impl<'a, 'hir> HirIdValidator<'a, 'hir> {
133133
}
134134
135135
impl<'a, 'hir> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> {
136-
type Map = Map<'hir>;
136+
type Map = EarlyMap<'hir>;
137137
138138
fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<'_, Self::Map> {
139139
intravisit::NestedVisitorMap::OnlyBodies(self.hir_map)
@@ -173,3 +173,4 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> {
173173
// different owner.
174174
}
175175
}
176+
*/

src/librustc/hir/map/mod.rs

Lines changed: 35 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::dep_graph::{DepGraph, DepKind, DepNode, DepNodeIndex};
88
use crate::hir::{HirOwner, HirOwnerItems};
99
use crate::middle::cstore::CrateStoreDyn;
1010
use crate::ty::query::Providers;
11+
use crate::ty::TyCtxt;
1112
use rustc_ast::ast::{self, Name, NodeId};
1213
use rustc_data_structures::fx::FxHashMap;
1314
use rustc_data_structures::svh::Svh;
@@ -138,9 +139,30 @@ impl<'hir> Entry<'hir> {
138139
pub(super) type HirEntryMap<'hir> = IndexVec<DefIndex, IndexVec<ItemLocalId, Option<Entry<'hir>>>>;
139140

140141
/// Represents a mapping from `NodeId`s to AST elements and their parent `NodeId`s.
141-
#[derive(Clone)]
142+
pub struct EarlyMap<'hir> {
143+
pub krate: &'hir Crate<'hir>,
144+
145+
pub dep_graph: DepGraph,
146+
147+
/// The SVH of the local crate.
148+
pub crate_hash: Svh,
149+
150+
pub(super) owner_map: FxHashMap<DefIndex, &'hir HirOwner<'hir>>,
151+
pub(super) owner_items_map: FxHashMap<DefIndex, &'hir HirOwnerItems<'hir>>,
152+
153+
pub(super) map: HirEntryMap<'hir>,
154+
155+
pub(crate) definitions: &'hir Definitions,
156+
157+
/// The reverse mapping of `node_to_hir_id`.
158+
pub(super) hir_to_node_id: FxHashMap<HirId, NodeId>,
159+
}
160+
161+
/// Represents a mapping from `NodeId`s to AST elements and their parent `NodeId`s.
142162
pub struct Map<'hir> {
143-
krate: &'hir Crate<'hir>,
163+
pub(super) tcx: TyCtxt<'hir>,
164+
165+
pub(super) krate: &'hir Crate<'hir>,
144166

145167
pub dep_graph: DepGraph,
146168

@@ -150,12 +172,12 @@ pub struct Map<'hir> {
150172
pub(super) owner_map: FxHashMap<DefIndex, &'hir HirOwner<'hir>>,
151173
pub(super) owner_items_map: FxHashMap<DefIndex, &'hir HirOwnerItems<'hir>>,
152174

153-
map: HirEntryMap<'hir>,
175+
pub(super) map: HirEntryMap<'hir>,
154176

155-
definitions: Definitions,
177+
pub(super) definitions: &'hir Definitions,
156178

157179
/// The reverse mapping of `node_to_hir_id`.
158-
hir_to_node_id: FxHashMap<HirId, NodeId>,
180+
pub(super) hir_to_node_id: FxHashMap<HirId, NodeId>,
159181
}
160182

161183
/// An iterator that walks up the ancestor tree of a given `HirId`.
@@ -406,11 +428,11 @@ impl<'hir> Map<'hir> {
406428
}
407429

408430
pub fn body(&self, id: BodyId) -> &'hir Body<'hir> {
409-
self.read(id.hir_id);
410-
411-
// N.B., intentionally bypass `self.krate()` so that we
412-
// do not trigger a read of the whole krate here
413-
self.krate.body(id)
431+
self.tcx
432+
.hir_owner_items(DefId::local(id.hir_id.owner))
433+
.bodies
434+
.get(&id.hir_id.local_id)
435+
.unwrap()
414436
}
415437

416438
pub fn fn_decl_by_hir_id(&self, hir_id: HirId) -> Option<&'hir FnDecl<'hir>> {
@@ -966,45 +988,6 @@ impl<'hir> Map<'hir> {
966988
attrs.unwrap_or(&[])
967989
}
968990

969-
/// Returns an iterator that yields all the hir ids in the map.
970-
fn all_ids<'a>(&'a self) -> impl Iterator<Item = HirId> + 'a {
971-
// This code is a bit awkward because the map is implemented as 2 levels of arrays,
972-
// see the comment on `HirEntryMap`.
973-
// Iterate over all the indices and return a reference to
974-
// local maps and their index given that they exist.
975-
self.map.iter_enumerated().flat_map(move |(owner, local_map)| {
976-
// Iterate over each valid entry in the local map.
977-
local_map.iter_enumerated().filter_map(move |(i, entry)| {
978-
entry.map(move |_| {
979-
// Reconstruct the `HirId` based on the 3 indices we used to find it.
980-
HirId { owner, local_id: i }
981-
})
982-
})
983-
})
984-
}
985-
986-
/// Returns an iterator that yields the node id's with paths that
987-
/// match `parts`. (Requires `parts` is non-empty.)
988-
///
989-
/// For example, if given `parts` equal to `["bar", "quux"]`, then
990-
/// the iterator will produce node id's for items with paths
991-
/// such as `foo::bar::quux`, `bar::quux`, `other::bar::quux`, and
992-
/// any other such items it can find in the map.
993-
pub fn nodes_matching_suffix<'a>(
994-
&'a self,
995-
parts: &'a [String],
996-
) -> impl Iterator<Item = NodeId> + 'a {
997-
let nodes = NodesMatchingSuffix {
998-
map: self,
999-
item_name: parts.last().unwrap(),
1000-
in_which: &parts[..parts.len() - 1],
1001-
};
1002-
1003-
self.all_ids()
1004-
.filter(move |hir| nodes.matches_suffix(*hir))
1005-
.map(move |hir| self.hir_to_node_id(hir))
1006-
}
1007-
1008991
pub fn span(&self, hir_id: HirId) -> Span {
1009992
self.read(hir_id); // reveals span from node
1010993
match self.find_entry(hir_id).map(|entry| entry.node) {
@@ -1087,82 +1070,6 @@ impl<'hir> intravisit::Map<'hir> for Map<'hir> {
10871070
}
10881071
}
10891072

1090-
pub struct NodesMatchingSuffix<'a> {
1091-
map: &'a Map<'a>,
1092-
item_name: &'a String,
1093-
in_which: &'a [String],
1094-
}
1095-
1096-
impl<'a> NodesMatchingSuffix<'a> {
1097-
/// Returns `true` only if some suffix of the module path for parent
1098-
/// matches `self.in_which`.
1099-
///
1100-
/// In other words: let `[x_0,x_1,...,x_k]` be `self.in_which`;
1101-
/// returns true if parent's path ends with the suffix
1102-
/// `x_0::x_1::...::x_k`.
1103-
fn suffix_matches(&self, parent: HirId) -> bool {
1104-
let mut cursor = parent;
1105-
for part in self.in_which.iter().rev() {
1106-
let (mod_id, mod_name) = match find_first_mod_parent(self.map, cursor) {
1107-
None => return false,
1108-
Some((node_id, name)) => (node_id, name),
1109-
};
1110-
if mod_name.as_str() != *part {
1111-
return false;
1112-
}
1113-
cursor = self.map.get_parent_item(mod_id);
1114-
}
1115-
return true;
1116-
1117-
// Finds the first mod in parent chain for `id`, along with
1118-
// that mod's name.
1119-
//
1120-
// If `id` itself is a mod named `m` with parent `p`, then
1121-
// returns `Some(id, m, p)`. If `id` has no mod in its parent
1122-
// chain, then returns `None`.
1123-
fn find_first_mod_parent(map: &Map<'_>, mut id: HirId) -> Option<(HirId, Name)> {
1124-
loop {
1125-
if let Node::Item(item) = map.find(id)? {
1126-
if item_is_mod(&item) {
1127-
return Some((id, item.ident.name));
1128-
}
1129-
}
1130-
let parent = map.get_parent_item(id);
1131-
if parent == id {
1132-
return None;
1133-
}
1134-
id = parent;
1135-
}
1136-
1137-
fn item_is_mod(item: &Item<'_>) -> bool {
1138-
match item.kind {
1139-
ItemKind::Mod(_) => true,
1140-
_ => false,
1141-
}
1142-
}
1143-
}
1144-
}
1145-
1146-
// We are looking at some node `n` with a given name and parent
1147-
// id; do their names match what I am seeking?
1148-
fn matches_names(&self, parent_of_n: HirId, name: Name) -> bool {
1149-
name.as_str() == *self.item_name && self.suffix_matches(parent_of_n)
1150-
}
1151-
1152-
fn matches_suffix(&self, hir: HirId) -> bool {
1153-
let name = match self.map.find_entry(hir).map(|entry| entry.node) {
1154-
Some(Node::Item(n)) => n.name(),
1155-
Some(Node::ForeignItem(n)) => n.name(),
1156-
Some(Node::TraitItem(n)) => n.name(),
1157-
Some(Node::ImplItem(n)) => n.name(),
1158-
Some(Node::Variant(n)) => n.name(),
1159-
Some(Node::Field(n)) => n.name(),
1160-
_ => return false,
1161-
};
1162-
self.matches_names(self.map.get_parent_item(hir), name)
1163-
}
1164-
}
1165-
11661073
trait Named {
11671074
fn name(&self) -> Name;
11681075
}
@@ -1211,7 +1118,7 @@ pub fn map_crate<'hir>(
12111118
krate: &'hir Crate<'hir>,
12121119
dep_graph: DepGraph,
12131120
definitions: Definitions,
1214-
) -> Map<'hir> {
1121+
) -> EarlyMap<'hir> {
12151122
let _prof_timer = sess.prof.generic_activity("build_hir_map");
12161123

12171124
// Build the reverse mapping of `node_to_hir_id`.
@@ -1233,15 +1140,15 @@ pub fn map_crate<'hir>(
12331140
collector.finalize_and_compute_crate_hash(crate_disambiguator, cstore, cmdline_args)
12341141
};
12351142

1236-
let map = Map {
1143+
let map = EarlyMap {
12371144
krate,
12381145
dep_graph,
12391146
crate_hash,
12401147
map,
12411148
owner_map,
12421149
owner_items_map: owner_items_map.into_iter().map(|(k, v)| (k, &*v)).collect(),
12431150
hir_to_node_id,
1244-
definitions,
1151+
definitions: arena.alloc(definitions),
12451152
};
12461153

12471154
sess.time("validate_HIR_map", || {

src/librustc/hir/mod.rs

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub mod map;
77

88
use crate::ty::query::Providers;
99
use crate::ty::TyCtxt;
10+
use rustc_data_structures::cold_path;
1011
use rustc_data_structures::fx::FxHashMap;
1112
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
1213
use rustc_hir::print;
@@ -68,7 +69,17 @@ impl<'hir> print::PpAnn for Hir<'hir> {
6869
impl<'tcx> TyCtxt<'tcx> {
6970
#[inline(always)]
7071
pub fn hir(self) -> Hir<'tcx> {
71-
Hir { tcx: self, map: &self.hir_map }
72+
let map = self.late_hir_map.load();
73+
let map = if unlikely!(map.is_none()) {
74+
cold_path(|| {
75+
let map = self.hir_map(LOCAL_CRATE);
76+
self.late_hir_map.store(Some(map));
77+
map
78+
})
79+
} else {
80+
map.unwrap()
81+
};
82+
Hir { tcx: self, map }
7283
}
7384

7485
pub fn parent_module(self, id: HirId) -> DefId {
@@ -81,6 +92,35 @@ pub fn provide(providers: &mut Providers<'_>) {
8192
let hir = tcx.hir();
8293
hir.local_def_id(hir.get_module_parent_node(hir.as_local_hir_id(id).unwrap()))
8394
};
84-
providers.hir_crate = |tcx, _| tcx.hir_map.untracked_krate();
95+
providers.hir_crate = |tcx, _| tcx.hir_map(LOCAL_CRATE).untracked_krate();
96+
providers.hir_map = |tcx, id| {
97+
assert_eq!(id, LOCAL_CRATE);
98+
let early = tcx.hir_map.steal();
99+
tcx.arena.alloc(map::Map {
100+
tcx,
101+
krate: early.krate,
102+
103+
dep_graph: early.dep_graph,
104+
105+
crate_hash: early.crate_hash,
106+
107+
owner_map: early.owner_map,
108+
owner_items_map: early.owner_items_map,
109+
110+
map: early.map,
111+
112+
definitions: early.definitions,
113+
114+
hir_to_node_id: early.hir_to_node_id,
115+
})
116+
};
117+
providers.hir_owner = |tcx, id| {
118+
assert_eq!(id.krate, LOCAL_CRATE);
119+
*tcx.hir().map.owner_map.get(&id.index).unwrap()
120+
};
121+
providers.hir_owner_items = |tcx, id| {
122+
assert_eq!(id.krate, LOCAL_CRATE);
123+
*tcx.hir().map.owner_items_map.get(&id.index).unwrap()
124+
};
85125
map::provide(providers);
86126
}

src/librustc/query/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ rustc_queries! {
5555
desc { "get the crate HIR" }
5656
}
5757

58+
query hir_map(_: CrateNum) -> &'tcx map::Map<'tcx> {
59+
eval_always
60+
no_hash
61+
desc { "index HIR" }
62+
}
63+
5864
query hir_owner(key: DefId) -> &'tcx HirOwner<'tcx> {
5965
eval_always
6066
}

0 commit comments

Comments
 (0)