Skip to content

Commit 32a3871

Browse files
authoredFeb 7, 2020
Rollup merge of rust-lang#68889 - Zoxc:hir-krate, r=eddyb
Move the `hir().krate()` method to a query and remove the `Krate` dep node r? @eddyb cc @michaelwoerister
2 parents b1aae7f + a575495 commit 32a3871

File tree

26 files changed

+146
-156
lines changed

26 files changed

+146
-156
lines changed
 

‎src/librustc/arena.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ macro_rules! arena_types {
127127
[] tys: rustc::ty::TyS<$tcx>,
128128

129129
// HIR types
130-
[few] hir_forest: rustc::hir::map::Forest<$tcx>,
130+
[few] hir_krate: rustc_hir::Crate<$tcx>,
131131
[] arm: rustc_hir::Arm<$tcx>,
132132
[] attribute: syntax::ast::Attribute,
133133
[] block: rustc_hir::Block<$tcx>,

‎src/librustc/dep_graph/dep_node.rs

+1-14
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
//! "infer" some properties for each kind of `DepNode`:
3636
//!
3737
//! * Whether a `DepNode` of a given kind has any parameters at all. Some
38-
//! `DepNode`s, like `Krate`, represent global concepts with only one value.
38+
//! `DepNode`s, like `AllLocalTraitImpls`, represent global concepts with only one value.
3939
//! * Whether it is possible, in principle, to reconstruct a query key from a
4040
//! given `DepNode`. Many `DepKind`s only require a single `DefId` parameter,
4141
//! in which case it is possible to map the node's fingerprint back to the
@@ -400,19 +400,6 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
400400
// We use this for most things when incr. comp. is turned off.
401401
[] Null,
402402

403-
// Represents the `Krate` as a whole (the `hir::Krate` value) (as
404-
// distinct from the krate module). This is basically a hash of
405-
// the entire krate, so if you read from `Krate` (e.g., by calling
406-
// `tcx.hir().krate()`), we will have to assume that any change
407-
// means that you need to be recompiled. This is because the
408-
// `Krate` value gives you access to all other items. To avoid
409-
// this fate, do not call `tcx.hir().krate()`; instead, prefer
410-
// wrappers like `tcx.visit_all_items_in_krate()`. If there is no
411-
// suitable wrapper, you can use `tcx.dep_graph.ignore()` to gain
412-
// access to the krate, but you must remember to add suitable
413-
// edges yourself for the individual items that you read.
414-
[eval_always] Krate,
415-
416403
// Represents the body of a function or method. The def-id is that of the
417404
// function/method.
418405
[eval_always] HirBody(DefId),

‎src/librustc/hir/map/collector.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -223,12 +223,9 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
223223
(commandline_args_hash, crate_disambiguator.to_fingerprint()),
224224
);
225225

226-
let (_, crate_hash) = input_dep_node_and_hash(
227-
self.dep_graph,
228-
&mut self.hcx,
229-
DepNode::new_no_params(DepKind::Krate),
230-
crate_hash_input,
231-
);
226+
let mut stable_hasher = StableHasher::new();
227+
crate_hash_input.hash_stable(&mut self.hcx, &mut stable_hasher);
228+
let crate_hash: Fingerprint = stable_hasher.finish();
232229

233230
let svh = Svh::new(crate_hash.to_smaller_hash());
234231
(self.map, svh)

‎src/librustc/hir/map/hir_id_validator.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub fn check_crate(hir_map: &Map<'_>) {
1212

1313
let errors = Lock::new(Vec::new());
1414

15-
par_iter(&hir_map.krate().modules).for_each(|(module_id, _)| {
15+
par_iter(&hir_map.krate.modules).for_each(|(module_id, _)| {
1616
let local_def_id = hir_map.local_def_id(*module_id);
1717
hir_map.visit_item_likes_in_module(
1818
local_def_id,

‎src/librustc/hir/map/mod.rs

+31-67
Original file line numberDiff line numberDiff line change
@@ -129,30 +129,6 @@ impl<'hir> Entry<'hir> {
129129
}
130130
}
131131

132-
/// Stores a crate and any number of inlined items from other crates.
133-
pub struct Forest<'hir> {
134-
krate: Crate<'hir>,
135-
pub dep_graph: DepGraph,
136-
}
137-
138-
impl Forest<'hir> {
139-
pub fn new(krate: Crate<'hir>, dep_graph: &DepGraph) -> Forest<'hir> {
140-
Forest { krate, dep_graph: dep_graph.clone() }
141-
}
142-
143-
pub fn krate(&self) -> &Crate<'hir> {
144-
self.dep_graph.read(DepNode::new_no_params(DepKind::Krate));
145-
&self.krate
146-
}
147-
148-
/// This is used internally in the dependency tracking system.
149-
/// Use the `krate` method to ensure your dependency on the
150-
/// crate is tracked.
151-
pub fn untracked_krate(&self) -> &Crate<'hir> {
152-
&self.krate
153-
}
154-
}
155-
156132
/// This type is effectively a `HashMap<HirId, Entry<'hir>>`,
157133
/// but it is implemented as 2 layers of arrays.
158134
/// - first we have `A = IndexVec<DefIndex, B>` mapping `DefIndex`s to an inner value
@@ -162,11 +138,8 @@ pub(super) type HirEntryMap<'hir> = IndexVec<DefIndex, IndexVec<ItemLocalId, Opt
162138
/// Represents a mapping from `NodeId`s to AST elements and their parent `NodeId`s.
163139
#[derive(Clone)]
164140
pub struct Map<'hir> {
165-
/// The backing storage for all the AST nodes.
166-
pub forest: &'hir Forest<'hir>,
141+
krate: &'hir Crate<'hir>,
167142

168-
/// Same as the dep_graph in forest, just available with one fewer
169-
/// deref. This is a gratuitous micro-optimization.
170143
pub dep_graph: DepGraph,
171144

172145
/// The SVH of the local crate.
@@ -217,6 +190,13 @@ impl<'hir> Iterator for ParentHirIterator<'_, 'hir> {
217190
}
218191

219192
impl<'hir> Map<'hir> {
193+
/// This is used internally in the dependency tracking system.
194+
/// Use the `krate` method to ensure your dependency on the
195+
/// crate is tracked.
196+
pub fn untracked_krate(&self) -> &Crate<'hir> {
197+
&self.krate
198+
}
199+
220200
#[inline]
221201
fn lookup(&self, id: HirId) -> Option<&Entry<'hir>> {
222202
let local_map = self.map.get(id.owner)?;
@@ -401,40 +381,36 @@ impl<'hir> Map<'hir> {
401381
self.lookup(id).cloned()
402382
}
403383

404-
pub fn krate(&self) -> &'hir Crate<'hir> {
405-
self.forest.krate()
406-
}
407-
408384
pub fn item(&self, id: HirId) -> &'hir Item<'hir> {
409385
self.read(id);
410386

411-
// N.B., intentionally bypass `self.forest.krate()` so that we
387+
// N.B., intentionally bypass `self.krate()` so that we
412388
// do not trigger a read of the whole krate here
413-
self.forest.krate.item(id)
389+
self.krate.item(id)
414390
}
415391

416392
pub fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir> {
417393
self.read(id.hir_id);
418394

419-
// N.B., intentionally bypass `self.forest.krate()` so that we
395+
// N.B., intentionally bypass `self.krate()` so that we
420396
// do not trigger a read of the whole krate here
421-
self.forest.krate.trait_item(id)
397+
self.krate.trait_item(id)
422398
}
423399

424400
pub fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir> {
425401
self.read(id.hir_id);
426402

427-
// N.B., intentionally bypass `self.forest.krate()` so that we
403+
// N.B., intentionally bypass `self.krate()` so that we
428404
// do not trigger a read of the whole krate here
429-
self.forest.krate.impl_item(id)
405+
self.krate.impl_item(id)
430406
}
431407

432408
pub fn body(&self, id: BodyId) -> &'hir Body<'hir> {
433409
self.read(id.hir_id);
434410

435-
// N.B., intentionally bypass `self.forest.krate()` so that we
411+
// N.B., intentionally bypass `self.krate()` so that we
436412
// do not trigger a read of the whole krate here
437-
self.forest.krate.body(id)
413+
self.krate.body(id)
438414
}
439415

440416
pub fn fn_decl_by_hir_id(&self, hir_id: HirId) -> Option<&'hir FnDecl<'hir>> {
@@ -530,9 +506,9 @@ impl<'hir> Map<'hir> {
530506
pub fn trait_impls(&self, trait_did: DefId) -> &'hir [HirId] {
531507
self.dep_graph.read(DepNode::new_no_params(DepKind::AllLocalTraitImpls));
532508

533-
// N.B., intentionally bypass `self.forest.krate()` so that we
509+
// N.B., intentionally bypass `self.krate()` so that we
534510
// do not trigger a read of the whole krate here
535-
self.forest.krate.trait_impls.get(&trait_did).map_or(&[], |xs| &xs[..])
511+
self.krate.trait_impls.get(&trait_did).map_or(&[], |xs| &xs[..])
536512
}
537513

538514
/// Gets the attributes on the crate. This is preferable to
@@ -542,15 +518,15 @@ impl<'hir> Map<'hir> {
542518
let def_path_hash = self.definitions.def_path_hash(CRATE_DEF_INDEX);
543519

544520
self.dep_graph.read(def_path_hash.to_dep_node(DepKind::Hir));
545-
&self.forest.krate.attrs
521+
&self.krate.attrs
546522
}
547523

548524
pub fn get_module(&self, module: DefId) -> (&'hir Mod<'hir>, Span, HirId) {
549525
let hir_id = self.as_local_hir_id(module).unwrap();
550526
self.read(hir_id);
551527
match self.find_entry(hir_id).unwrap().node {
552528
Node::Item(&Item { span, kind: ItemKind::Mod(ref m), .. }) => (m, span, hir_id),
553-
Node::Crate => (&self.forest.krate.module, self.forest.krate.span, hir_id),
529+
Node::Crate => (&self.krate.module, self.krate.span, hir_id),
554530
node => panic!("not a module: {:?}", node),
555531
}
556532
}
@@ -567,7 +543,7 @@ impl<'hir> Map<'hir> {
567543
// in the expect_* calls the loops below
568544
self.read(hir_id);
569545

570-
let module = &self.forest.krate.modules[&hir_id];
546+
let module = &self.krate.modules[&hir_id];
571547

572548
for id in &module.items {
573549
visitor.visit_item(self.expect_item(*id));
@@ -984,7 +960,7 @@ impl<'hir> Map<'hir> {
984960
// Unit/tuple structs/variants take the attributes straight from
985961
// the struct/variant definition.
986962
Some(Node::Ctor(..)) => return self.attrs(self.get_parent_item(id)),
987-
Some(Node::Crate) => Some(&self.forest.krate.attrs[..]),
963+
Some(Node::Crate) => Some(&self.krate.attrs[..]),
988964
_ => None,
989965
};
990966
attrs.unwrap_or(&[])
@@ -1063,7 +1039,7 @@ impl<'hir> Map<'hir> {
10631039
Some(Node::Visibility(v)) => bug!("unexpected Visibility {:?}", v),
10641040
Some(Node::Local(local)) => local.span,
10651041
Some(Node::MacroDef(macro_def)) => macro_def.span,
1066-
Some(Node::Crate) => self.forest.krate.span,
1042+
Some(Node::Crate) => self.krate.span,
10671043
None => bug!("hir::map::Map::span: id not in map: {:?}", hir_id),
10681044
}
10691045
}
@@ -1231,7 +1207,8 @@ impl Named for ImplItem<'_> {
12311207
pub fn map_crate<'hir>(
12321208
sess: &rustc_session::Session,
12331209
cstore: &CrateStoreDyn,
1234-
forest: &'hir Forest<'hir>,
1210+
krate: &'hir Crate<'hir>,
1211+
dep_graph: DepGraph,
12351212
definitions: Definitions,
12361213
) -> Map<'hir> {
12371214
let _prof_timer = sess.prof.generic_activity("build_hir_map");
@@ -1244,31 +1221,18 @@ pub fn map_crate<'hir>(
12441221
.collect();
12451222

12461223
let (map, crate_hash) = {
1247-
let hcx = crate::ich::StableHashingContext::new(sess, &forest.krate, &definitions, cstore);
1248-
1249-
let mut collector = NodeCollector::root(
1250-
sess,
1251-
&forest.krate,
1252-
&forest.dep_graph,
1253-
&definitions,
1254-
&hir_to_node_id,
1255-
hcx,
1256-
);
1257-
intravisit::walk_crate(&mut collector, &forest.krate);
1224+
let hcx = crate::ich::StableHashingContext::new(sess, krate, &definitions, cstore);
1225+
1226+
let mut collector =
1227+
NodeCollector::root(sess, krate, &dep_graph, &definitions, &hir_to_node_id, hcx);
1228+
intravisit::walk_crate(&mut collector, krate);
12581229

12591230
let crate_disambiguator = sess.local_crate_disambiguator();
12601231
let cmdline_args = sess.opts.dep_tracking_hash();
12611232
collector.finalize_and_compute_crate_hash(crate_disambiguator, cstore, cmdline_args)
12621233
};
12631234

1264-
let map = Map {
1265-
forest,
1266-
dep_graph: forest.dep_graph.clone(),
1267-
crate_hash,
1268-
map,
1269-
hir_to_node_id,
1270-
definitions,
1271-
};
1235+
let map = Map { krate, dep_graph, crate_hash, map, hir_to_node_id, definitions };
12721236

12731237
sess.time("validate_HIR_map", || {
12741238
hir_id_validator::check_crate(&map);

‎src/librustc/hir/mod.rs

+41
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,48 @@ pub mod exports;
77
pub mod map;
88

99
use crate::ty::query::Providers;
10+
use crate::ty::TyCtxt;
11+
use rustc_hir::def_id::LOCAL_CRATE;
12+
use rustc_hir::print;
13+
use rustc_hir::Crate;
14+
use std::ops::Deref;
15+
16+
/// A wrapper type which allows you to access HIR.
17+
#[derive(Clone)]
18+
pub struct Hir<'tcx> {
19+
tcx: TyCtxt<'tcx>,
20+
map: &'tcx map::Map<'tcx>,
21+
}
22+
23+
impl<'tcx> Hir<'tcx> {
24+
pub fn krate(&self) -> &'tcx Crate<'tcx> {
25+
self.tcx.hir_crate(LOCAL_CRATE)
26+
}
27+
}
28+
29+
impl<'tcx> Deref for Hir<'tcx> {
30+
type Target = &'tcx map::Map<'tcx>;
31+
32+
#[inline(always)]
33+
fn deref(&self) -> &Self::Target {
34+
&self.map
35+
}
36+
}
37+
38+
impl<'hir> print::PpAnn for Hir<'hir> {
39+
fn nested(&self, state: &mut print::State<'_>, nested: print::Nested) {
40+
self.map.nested(state, nested)
41+
}
42+
}
43+
44+
impl<'tcx> TyCtxt<'tcx> {
45+
#[inline(always)]
46+
pub fn hir(self) -> Hir<'tcx> {
47+
Hir { tcx: self, map: &self.hir_map }
48+
}
49+
}
1050

1151
pub fn provide(providers: &mut Providers<'_>) {
52+
providers.hir_crate = |tcx, _| tcx.hir_map.untracked_krate();
1253
map::provide(providers);
1354
}

‎src/librustc/query/mod.rs

+12
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@ rustc_queries! {
4343
}
4444

4545
Other {
46+
// Represents crate as a whole (as distinct from the top-level crate module).
47+
// If you call `hir_crate` (e.g., indirectly by calling `tcx.hir().krate()`),
48+
// we will have to assume that any change means that you need to be recompiled.
49+
// This is because the `hir_crate` query gives you access to all other items.
50+
// To avoid this fate, do not call `tcx.hir().krate()`; instead,
51+
// prefer wrappers like `tcx.visit_all_items_in_krate()`.
52+
query hir_crate(key: CrateNum) -> &'tcx Crate<'tcx> {
53+
eval_always
54+
no_hash
55+
desc { "get the crate HIR" }
56+
}
57+
4658
/// Records the type of every item.
4759
query type_of(key: DefId) -> Ty<'tcx> {
4860
cache_on_disk_if { key.is_local() }

‎src/librustc/ty/context.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -966,7 +966,8 @@ pub struct GlobalCtxt<'tcx> {
966966
/// Export map produced by name resolution.
967967
export_map: FxHashMap<DefId, Vec<Export<hir::HirId>>>,
968968

969-
hir_map: hir_map::Map<'tcx>,
969+
/// This should usually be accessed with the `tcx.hir()` method.
970+
pub(crate) hir_map: hir_map::Map<'tcx>,
970971

971972
/// A map from `DefPathHash` -> `DefId`. Includes `DefId`s from the local crate
972973
/// as well as all upstream crates. Only populated in incremental mode.
@@ -1019,11 +1020,6 @@ pub struct GlobalCtxt<'tcx> {
10191020
}
10201021

10211022
impl<'tcx> TyCtxt<'tcx> {
1022-
#[inline(always)]
1023-
pub fn hir(self) -> &'tcx hir_map::Map<'tcx> {
1024-
&self.hir_map
1025-
}
1026-
10271023
pub fn alloc_steal_mir(self, mir: BodyAndCache<'tcx>) -> &'tcx Steal<BodyAndCache<'tcx>> {
10281024
self.arena.alloc(Steal::new(mir))
10291025
}
@@ -1328,7 +1324,7 @@ impl<'tcx> TyCtxt<'tcx> {
13281324

13291325
#[inline(always)]
13301326
pub fn create_stable_hashing_context(self) -> StableHashingContext<'tcx> {
1331-
let krate = self.gcx.hir_map.forest.untracked_krate();
1327+
let krate = self.gcx.hir_map.untracked_krate();
13321328

13331329
StableHashingContext::new(self.sess, krate, self.hir().definitions(), &*self.cstore)
13341330
}

‎src/librustc/ty/query/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use rustc_data_structures::sync::Lrc;
4545
use rustc_hir as hir;
4646
use rustc_hir::def::DefKind;
4747
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, DefIndex};
48-
use rustc_hir::{HirIdSet, ItemLocalId, TraitCandidate};
48+
use rustc_hir::{Crate, HirIdSet, ItemLocalId, TraitCandidate};
4949
use rustc_index::vec::IndexVec;
5050
use rustc_target::spec::PanicStrategy;
5151

‎src/librustc/ty/query/plumbing.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1177,7 +1177,6 @@ pub fn force_from_dep_node(tcx: TyCtxt<'_>, dep_node: &DepNode) -> bool {
11771177
// These are inputs that are expected to be pre-allocated and that
11781178
// should therefore always be red or green already.
11791179
DepKind::AllLocalTraitImpls |
1180-
DepKind::Krate |
11811180
DepKind::CrateMetadata |
11821181
DepKind::HirBody |
11831182
DepKind::Hir |

0 commit comments

Comments
 (0)
Please sign in to comment.