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

Commit 457de08

Browse files
committed
Forbid hashing HIR outside of indexing.
1 parent cd1ace4 commit 457de08

File tree

11 files changed

+86
-132
lines changed

11 files changed

+86
-132
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3552,6 +3552,7 @@ dependencies = [
35523552
"rustc_errors",
35533553
"rustc_hir",
35543554
"rustc_index",
3555+
"rustc_query_system",
35553556
"rustc_session",
35563557
"rustc_span",
35573558
"rustc_target",
@@ -4333,6 +4334,7 @@ dependencies = [
43334334
"rustc_index",
43344335
"rustc_metadata",
43354336
"rustc_middle",
4337+
"rustc_query_system",
43364338
"rustc_session",
43374339
"rustc_span",
43384340
"smallvec",

compiler/rustc_ast_lowering/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ rustc_hir = { path = "../rustc_hir" }
1414
rustc_target = { path = "../rustc_target" }
1515
rustc_data_structures = { path = "../rustc_data_structures" }
1616
rustc_index = { path = "../rustc_index" }
17+
rustc_query_system = { path = "../rustc_query_system" }
1718
rustc_span = { path = "../rustc_span" }
1819
rustc_errors = { path = "../rustc_errors" }
1920
rustc_session = { path = "../rustc_session" }

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 5 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,14 @@ use rustc_hir::definitions::{DefKey, DefPathData, Definitions};
5151
use rustc_hir::intravisit;
5252
use rustc_hir::{ConstArg, GenericArg, InferKind, ParamName};
5353
use rustc_index::vec::{Idx, IndexVec};
54+
use rustc_query_system::ich::StableHashingContext;
5455
use rustc_session::lint::builtin::BARE_TRAIT_OBJECTS;
5556
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
5657
use rustc_session::utils::{FlattenNonterminals, NtToTokenstream};
5758
use rustc_session::Session;
5859
use rustc_span::edition::Edition;
5960
use rustc_span::hygiene::ExpnId;
60-
use rustc_span::source_map::{respan, CachingSourceMapView, DesugaringKind};
61+
use rustc_span::source_map::{respan, DesugaringKind};
6162
use rustc_span::symbol::{kw, sym, Ident, Symbol};
6263
use rustc_span::{Span, DUMMY_SP};
6364

@@ -179,6 +180,8 @@ pub trait ResolverAstLowering {
179180
/// This should only return `None` during testing.
180181
fn definitions(&mut self) -> &mut Definitions;
181182

183+
fn create_stable_hashing_context(&self) -> StableHashingContext<'_>;
184+
182185
fn lint_buffer(&mut self) -> &mut LintBuffer;
183186

184187
fn next_node_id(&mut self) -> NodeId;
@@ -201,37 +204,6 @@ pub trait ResolverAstLowering {
201204
) -> LocalDefId;
202205
}
203206

204-
struct LoweringHasher<'a> {
205-
source_map: CachingSourceMapView<'a>,
206-
resolver: &'a dyn ResolverAstLowering,
207-
}
208-
209-
impl<'a> rustc_span::HashStableContext for LoweringHasher<'a> {
210-
#[inline]
211-
fn hash_spans(&self) -> bool {
212-
true
213-
}
214-
215-
#[inline]
216-
fn def_span(&self, id: LocalDefId) -> Span {
217-
self.resolver.def_span(id)
218-
}
219-
220-
#[inline]
221-
fn def_path_hash(&self, def_id: DefId) -> DefPathHash {
222-
self.resolver.def_path_hash(def_id)
223-
}
224-
225-
#[inline]
226-
fn span_data_to_lines_and_cols(
227-
&mut self,
228-
span: &rustc_span::SpanData,
229-
) -> Option<(Lrc<rustc_span::SourceFile>, usize, rustc_span::BytePos, usize, rustc_span::BytePos)>
230-
{
231-
self.source_map.span_data_to_lines_and_cols(span)
232-
}
233-
}
234-
235207
/// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,
236208
/// and if so, what meaning it has.
237209
#[derive(Debug)]
@@ -440,13 +412,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
440412
self.arena.alloc(krate)
441413
}
442414

443-
fn create_stable_hashing_context(&self) -> LoweringHasher<'_> {
444-
LoweringHasher {
445-
source_map: CachingSourceMapView::new(self.sess.source_map()),
446-
resolver: self.resolver,
447-
}
448-
}
449-
450415
fn with_hir_id_owner(
451416
&mut self,
452417
owner: NodeId,
@@ -566,7 +531,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
566531
allow_internal_unstable,
567532
reason,
568533
self.sess.edition(),
569-
self.create_stable_hashing_context(),
534+
self.resolver.create_stable_hashing_context(),
570535
)
571536
}
572537

compiler/rustc_middle/src/hir/map/collector.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,21 @@ fn insert_vec_map<K: Idx, V: Clone>(map: &mut IndexVec<K, Option<V>>, k: K, v: V
5151
map[k] = Some(v);
5252
}
5353

54-
fn hash_body(
55-
hcx: &mut StableHashingContext<'_>,
54+
fn hash_body<'s, 'hir: 's>(
55+
hcx: &mut StableHashingContext<'s>,
5656
item_like: impl for<'a> HashStable<StableHashingContext<'a>>,
57+
hash_bodies: bool,
58+
owner: LocalDefId,
59+
bodies: &'hir IndexVec<ItemLocalId, Option<&'hir Body<'hir>>>,
5760
) -> Fingerprint {
5861
let mut stable_hasher = StableHasher::new();
59-
hcx.while_hashing_hir_bodies(true, |hcx| {
60-
item_like.hash_stable(hcx, &mut stable_hasher);
62+
hcx.with_hir_bodies(hash_bodies, owner, bodies, |hcx| {
63+
item_like.hash_stable(hcx, &mut stable_hasher)
6164
});
6265
stable_hasher.finish()
6366
}
6467

65-
impl<'a, 'hir> NodeCollector<'a, 'hir> {
68+
impl<'a, 'hir: 'a> NodeCollector<'a, 'hir> {
6669
pub(super) fn root(
6770
sess: &'a Session,
6871
arena: &'hir Arena<'hir>,
@@ -91,15 +94,16 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
9194
}
9295

9396
fn insert_owner(&mut self, owner: LocalDefId, node: OwnerNode<'hir>) {
94-
let hash = hash_body(&mut self.hcx, node);
95-
9697
let mut nodes = IndexVec::new();
9798
nodes.push(Some(ParentedNode { parent: ItemLocalId::new(0), node: node.into() }));
9899

99100
let bodies = &self.krate.owners[owner].as_ref().unwrap().bodies;
100101

102+
let hash = hash_body(&mut self.hcx, node, true, owner, bodies);
103+
let node_hash = hash_body(&mut self.hcx, node, false, owner, bodies);
104+
101105
debug_assert!(self.map[owner].is_none());
102-
self.map[owner] = Some(self.arena.alloc(OwnerNodes { hash, nodes, bodies }));
106+
self.map[owner] = Some(self.arena.alloc(OwnerNodes { hash, node_hash, nodes, bodies }));
103107
}
104108

105109
fn insert(&mut self, span: Span, hir_id: HirId, node: Node<'hir>) {
@@ -176,7 +180,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
176180
}
177181
}
178182

179-
impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
183+
impl<'a, 'hir: 'a> Visitor<'hir> for NodeCollector<'a, 'hir> {
180184
type Map = Map<'hir>;
181185

182186
/// Because we want to track parent items and so forth, enable

compiler/rustc_middle/src/hir/map/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -874,21 +874,21 @@ impl<'hir> Map<'hir> {
874874

875875
pub fn expect_item(&self, id: HirId) -> &'hir Item<'hir> {
876876
match self.tcx.hir_owner(id.expect_owner()) {
877-
Some(Owner { node: OwnerNode::Item(item) }) => item,
877+
Some(Owner { node: OwnerNode::Item(item), .. }) => item,
878878
_ => bug!("expected item, found {}", self.node_to_string(id)),
879879
}
880880
}
881881

882882
pub fn expect_impl_item(&self, id: HirId) -> &'hir ImplItem<'hir> {
883883
match self.tcx.hir_owner(id.expect_owner()) {
884-
Some(Owner { node: OwnerNode::ImplItem(item) }) => item,
884+
Some(Owner { node: OwnerNode::ImplItem(item), .. }) => item,
885885
_ => bug!("expected impl item, found {}", self.node_to_string(id)),
886886
}
887887
}
888888

889889
pub fn expect_trait_item(&self, id: HirId) -> &'hir TraitItem<'hir> {
890890
match self.tcx.hir_owner(id.expect_owner()) {
891-
Some(Owner { node: OwnerNode::TraitItem(item) }) => item,
891+
Some(Owner { node: OwnerNode::TraitItem(item), .. }) => item,
892892
_ => bug!("expected trait item, found {}", self.node_to_string(id)),
893893
}
894894
}
@@ -902,7 +902,7 @@ impl<'hir> Map<'hir> {
902902

903903
pub fn expect_foreign_item(&self, id: HirId) -> &'hir ForeignItem<'hir> {
904904
match self.tcx.hir_owner(id.expect_owner()) {
905-
Some(Owner { node: OwnerNode::ForeignItem(item) }) => item,
905+
Some(Owner { node: OwnerNode::ForeignItem(item), .. }) => item,
906906
_ => bug!("expected foreign item, found {}", self.node_to_string(id)),
907907
}
908908
}

compiler/rustc_middle/src/hir/mod.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,14 @@ pub struct IndexedHir<'hir> {
3939
#[derive(Copy, Clone, Debug)]
4040
pub struct Owner<'tcx> {
4141
node: OwnerNode<'tcx>,
42+
node_hash: Fingerprint,
4243
}
4344

4445
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Owner<'tcx> {
46+
#[inline]
4547
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
46-
let Owner { node } = self;
47-
hcx.while_hashing_hir_bodies(false, |hcx| node.hash_stable(hcx, hasher));
48+
let Owner { node: _, node_hash } = self;
49+
node_hash.hash_stable(hcx, hasher)
4850
}
4951
}
5052

@@ -61,6 +63,8 @@ pub struct ParentedNode<'tcx> {
6163
pub struct OwnerNodes<'tcx> {
6264
/// Pre-computed hash of the full HIR.
6365
hash: Fingerprint,
66+
/// Pre-computed hash of the top node.
67+
node_hash: Fingerprint,
6468
/// Full HIR for the current owner.
6569
// The zeroth node's parent is trash, but is never accessed.
6670
nodes: IndexVec<ItemLocalId, Option<ParentedNode<'tcx>>>,
@@ -69,10 +73,11 @@ pub struct OwnerNodes<'tcx> {
6973
}
7074

7175
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for OwnerNodes<'tcx> {
76+
#[inline]
7277
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
7378
// We ignore the `nodes` and `bodies` fields since these refer to information included in
7479
// `hash` which is hashed in the collector and used for the crate hash.
75-
let OwnerNodes { hash, nodes: _, bodies: _ } = *self;
80+
let OwnerNodes { hash, node_hash: _, nodes: _, bodies: _ } = *self;
7681
hash.hash_stable(hcx, hasher);
7782
}
7883
}
@@ -130,7 +135,7 @@ pub fn provide(providers: &mut Providers) {
130135
let owner = tcx.index_hir(()).map[id].as_ref()?;
131136
let node = owner.nodes[ItemLocalId::new(0)].as_ref().unwrap().node;
132137
let node = node.as_owner().unwrap(); // Indexing must ensure it is an OwnerNode.
133-
Some(Owner { node })
138+
Some(Owner { node, node_hash: owner.node_hash })
134139
};
135140
providers.hir_owner_nodes = |tcx, id| tcx.index_hir(()).map[id].as_deref();
136141
providers.hir_owner_parent = |tcx, id| {

compiler/rustc_middle/src/ty/context.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,20 +1342,15 @@ impl<'tcx> TyCtxt<'tcx> {
13421342

13431343
#[inline(always)]
13441344
pub fn create_stable_hashing_context(self) -> StableHashingContext<'tcx> {
1345-
let krate = self.gcx.untracked_crate;
13461345
let resolutions = &self.gcx.untracked_resolutions;
1347-
1348-
StableHashingContext::new(self.sess, krate, &resolutions.definitions, &*resolutions.cstore)
1346+
StableHashingContext::new(self.sess, &resolutions.definitions, &*resolutions.cstore)
13491347
}
13501348

13511349
#[inline(always)]
13521350
pub fn create_no_span_stable_hashing_context(self) -> StableHashingContext<'tcx> {
1353-
let krate = self.gcx.untracked_crate;
13541351
let resolutions = &self.gcx.untracked_resolutions;
1355-
13561352
StableHashingContext::ignore_spans(
13571353
self.sess,
1358-
krate,
13591354
&resolutions.definitions,
13601355
&*resolutions.cstore,
13611356
)

0 commit comments

Comments
 (0)