Skip to content

Commit 38a7d04

Browse files
committed
Create Map after TyCtxt
1 parent 30f3941 commit 38a7d04

File tree

7 files changed

+112
-153
lines changed

7 files changed

+112
-153
lines changed

src/librustc/arena.rs

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

163163
// HIR query types
164+
[few] hir_map: rustc::hir::map::Map<$tcx>,
165+
[few] hir_definitions: rustc::hir::map::definitions::Definitions,
164166
[] hir_owner: rustc::hir::HirOwner<$tcx>,
165167
[] hir_owner_items: rustc::hir::HirOwnerItems<$tcx>,
166168
], $tcx);

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<'_>) {
10+
pub fn check_crate(hir_map: &EarlyMap<'_>) {
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<'_>) {
2525
if !errors.is_empty() {
2626
let message = errors.iter().fold(String::new(), |s1, s2| s1 + "\n" + s2);
2727
bug!("{}", 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<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 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: 30 additions & 123 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_data_structures::fx::FxHashMap;
1213
use rustc_data_structures::svh::Svh;
1314
use rustc_hir::def::{DefKind, Res};
@@ -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
struct ParentHirIterator<'map, 'hir> {
@@ -971,45 +993,6 @@ impl<'hir> Map<'hir> {
971993
attrs.unwrap_or(&[])
972994
}
973995

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

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

12221129
// Build the reverse mapping of `node_to_hir_id`.
@@ -1238,15 +1145,15 @@ pub fn map_crate<'hir>(
12381145
collector.finalize_and_compute_crate_hash(crate_disambiguator, cstore, cmdline_args)
12391146
};
12401147

1241-
let map = Map {
1148+
let map = EarlyMap {
12421149
krate,
12431150
dep_graph,
12441151
crate_hash,
12451152
map,
12461153
owner_map,
12471154
owner_items_map: owner_items_map.into_iter().map(|(k, v)| (k, &*v)).collect(),
12481155
hir_to_node_id,
1249-
definitions,
1156+
definitions: arena.alloc(definitions),
12501157
};
12511158

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

src/librustc/hir/mod.rs

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ pub mod map;
88

99
use crate::ty::query::Providers;
1010
use crate::ty::TyCtxt;
11+
use rustc_data_structures::cold_path;
1112
use rustc_data_structures::fx::FxHashMap;
1213
use rustc_hir::def_id::DefId;
1314
use rustc_hir::def_id::LOCAL_CRATE;
@@ -79,19 +80,50 @@ impl<'hir> print::PpAnn for Hir<'hir> {
7980
impl<'tcx> TyCtxt<'tcx> {
8081
#[inline(always)]
8182
pub fn hir(self) -> Hir<'tcx> {
82-
Hir { tcx: self, map: &self.hir_map }
83+
let map = self.late_hir_map.load();
84+
let map = if unlikely!(map.is_none()) {
85+
cold_path(|| {
86+
let map = self.hir_map(LOCAL_CRATE);
87+
self.late_hir_map.store(Some(map));
88+
map
89+
})
90+
} else {
91+
map.unwrap()
92+
};
93+
Hir { tcx: self, map }
8394
}
8495
}
8596

8697
pub fn provide(providers: &mut Providers<'_>) {
87-
providers.hir_crate = |tcx, _| tcx.hir_map.untracked_krate();
98+
providers.hir_crate = |tcx, _| tcx.hir_map(LOCAL_CRATE).untracked_krate();
99+
providers.hir_map = |tcx, id| {
100+
assert_eq!(id, LOCAL_CRATE);
101+
let early = tcx.hir_map.steal();
102+
tcx.arena.alloc(map::Map {
103+
tcx,
104+
krate: early.krate,
105+
106+
dep_graph: early.dep_graph,
107+
108+
crate_hash: early.crate_hash,
109+
110+
owner_map: early.owner_map,
111+
owner_items_map: early.owner_items_map,
112+
113+
map: early.map,
114+
115+
definitions: early.definitions,
116+
117+
hir_to_node_id: early.hir_to_node_id,
118+
})
119+
};
88120
providers.hir_owner = |tcx, id| {
89121
assert_eq!(id.krate, LOCAL_CRATE);
90-
*tcx.hir_map.owner_map.get(&id.index).unwrap()
122+
*tcx.hir().map.owner_map.get(&id.index).unwrap()
91123
};
92124
providers.hir_owner_items = |tcx, id| {
93125
assert_eq!(id.krate, LOCAL_CRATE);
94-
*tcx.hir_map.owner_items_map.get(&id.index).unwrap()
126+
*tcx.hir().map.owner_items_map.get(&id.index).unwrap()
95127
};
96128
map::provide(providers);
97129
}

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)