Skip to content

Commit 582a4ea

Browse files
committed
Auto merge of #66279 - cjgillot:hashstable, r=Zoxc
Use proc-macro to derive HashStable everywhere Hello, A second proc-macro is added to derive HashStable for crates librustc depends on. This proc-macro `HashStable_Generic` (to bikeshed) allows to decouple code and strip much of librustc's boilerplate. Still, two implementations `Span` and `TokenKind` require to be placed in librustc. The latter only depends on the `bug` macro. Advise welcome on how to sever that link. A trait `StableHasingContextLike` has been introduced at each crate root, in order to handle those implementations which require librustc's very `StableHashingContext`. This overall effort allowed to remove the `impl_stable_hash_for` macro. Each commit passes the `x.py check`. I still have to double check there was no change in the implementation.
2 parents 4eee955 + 782cc9f commit 582a4ea

File tree

18 files changed

+199
-427
lines changed

18 files changed

+199
-427
lines changed

src/librustc/ich/hcx.rs

+10-91
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,23 @@ use crate::hir;
22
use crate::hir::def_id::{DefId, DefIndex};
33
use crate::hir::map::DefPathHash;
44
use crate::hir::map::definitions::Definitions;
5-
use crate::ich::{self, CachingSourceMapView, Fingerprint};
5+
use crate::ich::{self, CachingSourceMapView};
66
use crate::middle::cstore::CrateStore;
77
use crate::ty::{TyCtxt, fast_reject};
88
use crate::session::Session;
99

1010
use std::cmp::Ord;
11-
use std::hash as std_hash;
12-
use std::cell::RefCell;
1311

1412
use syntax::ast;
1513
use syntax::source_map::SourceMap;
1614
use syntax::symbol::Symbol;
17-
use syntax::tokenstream::DelimSpan;
18-
use syntax_pos::{Span, DUMMY_SP};
19-
use syntax_pos::hygiene::{self, SyntaxContext};
15+
use syntax_pos::{SourceFile, BytePos};
2016

2117
use rustc_data_structures::stable_hasher::{
2218
HashStable, StableHasher, ToStableHashKey,
2319
};
2420
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
21+
use rustc_data_structures::sync::Lrc;
2522
use smallvec::SmallVec;
2623

2724
fn compute_ignored_attr_names() -> FxHashSet<Symbol> {
@@ -281,93 +278,15 @@ impl<'a> ToStableHashKey<StableHashingContext<'a>> for ast::NodeId {
281278
}
282279
}
283280

284-
impl<'a> HashStable<StableHashingContext<'a>> for Span {
285-
/// Hashes a span in a stable way. We can't directly hash the span's `BytePos`
286-
/// fields (that would be similar to hashing pointers, since those are just
287-
/// offsets into the `SourceMap`). Instead, we hash the (file name, line, column)
288-
/// triple, which stays the same even if the containing `SourceFile` has moved
289-
/// within the `SourceMap`.
290-
/// Also note that we are hashing byte offsets for the column, not unicode
291-
/// codepoint offsets. For the purpose of the hash that's sufficient.
292-
/// Also, hashing filenames is expensive so we avoid doing it twice when the
293-
/// span starts and ends in the same file, which is almost always the case.
294-
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
295-
const TAG_VALID_SPAN: u8 = 0;
296-
const TAG_INVALID_SPAN: u8 = 1;
297-
const TAG_EXPANSION: u8 = 0;
298-
const TAG_NO_EXPANSION: u8 = 1;
299-
300-
if !hcx.hash_spans {
301-
return
302-
}
303-
304-
if *self == DUMMY_SP {
305-
return std_hash::Hash::hash(&TAG_INVALID_SPAN, hasher);
306-
}
307-
308-
// If this is not an empty or invalid span, we want to hash the last
309-
// position that belongs to it, as opposed to hashing the first
310-
// position past it.
311-
let span = self.data();
312-
let (file_lo, line_lo, col_lo) = match hcx.source_map()
313-
.byte_pos_to_line_and_col(span.lo) {
314-
Some(pos) => pos,
315-
None => {
316-
return std_hash::Hash::hash(&TAG_INVALID_SPAN, hasher);
317-
}
318-
};
319-
320-
if !file_lo.contains(span.hi) {
321-
return std_hash::Hash::hash(&TAG_INVALID_SPAN, hasher);
322-
}
323-
324-
std_hash::Hash::hash(&TAG_VALID_SPAN, hasher);
325-
// We truncate the stable ID hash and line and column numbers. The chances
326-
// of causing a collision this way should be minimal.
327-
std_hash::Hash::hash(&(file_lo.name_hash as u64), hasher);
328-
329-
let col = (col_lo.0 as u64) & 0xFF;
330-
let line = ((line_lo as u64) & 0xFF_FF_FF) << 8;
331-
let len = ((span.hi - span.lo).0 as u64) << 32;
332-
let line_col_len = col | line | len;
333-
std_hash::Hash::hash(&line_col_len, hasher);
334-
335-
if span.ctxt == SyntaxContext::root() {
336-
TAG_NO_EXPANSION.hash_stable(hcx, hasher);
337-
} else {
338-
TAG_EXPANSION.hash_stable(hcx, hasher);
339-
340-
// Since the same expansion context is usually referenced many
341-
// times, we cache a stable hash of it and hash that instead of
342-
// recursing every time.
343-
thread_local! {
344-
static CACHE: RefCell<FxHashMap<hygiene::ExpnId, u64>> = Default::default();
345-
}
346-
347-
let sub_hash: u64 = CACHE.with(|cache| {
348-
let expn_id = span.ctxt.outer_expn();
349-
350-
if let Some(&sub_hash) = cache.borrow().get(&expn_id) {
351-
return sub_hash;
352-
}
353-
354-
let mut hasher = StableHasher::new();
355-
expn_id.expn_data().hash_stable(hcx, &mut hasher);
356-
let sub_hash: Fingerprint = hasher.finish();
357-
let sub_hash = sub_hash.to_smaller_hash();
358-
cache.borrow_mut().insert(expn_id, sub_hash);
359-
sub_hash
360-
});
361-
362-
sub_hash.hash_stable(hcx, hasher);
363-
}
281+
impl<'a> syntax_pos::HashStableContext for StableHashingContext<'a> {
282+
fn hash_spans(&self) -> bool {
283+
self.hash_spans
364284
}
365-
}
366285

367-
impl<'a> HashStable<StableHashingContext<'a>> for DelimSpan {
368-
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
369-
self.open.hash_stable(hcx, hasher);
370-
self.close.hash_stable(hcx, hasher);
286+
fn byte_pos_to_line_and_col(&mut self, byte: BytePos)
287+
-> Option<(Lrc<SourceFile>, usize, BytePos)>
288+
{
289+
self.source_map().byte_pos_to_line_and_col(byte)
371290
}
372291
}
373292

src/librustc/ich/impls_hir.rs

-21
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use crate::ich::{StableHashingContext, NodeIdHashingMode, Fingerprint};
99
use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, StableHasher};
1010
use smallvec::SmallVec;
1111
use std::mem;
12-
use syntax::ast;
1312
use syntax::attr;
1413

1514
impl<'a> HashStable<StableHashingContext<'a>> for DefId {
@@ -119,10 +118,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItemId {
119118
}
120119
}
121120

122-
impl_stable_hash_for!(struct ast::Label {
123-
ident
124-
});
125-
126121
impl<'a> HashStable<StableHashingContext<'a>> for hir::Ty {
127122
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
128123
hcx.while_hashing_hir_bodies(true, |hcx| {
@@ -138,10 +133,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::Ty {
138133
}
139134
}
140135

141-
impl_stable_hash_for_spanned!(hir::BinOpKind);
142-
143-
impl_stable_hash_for_spanned!(ast::Name);
144-
145136
impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr {
146137
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
147138
hcx.while_hashing_hir_bodies(true, |hcx| {
@@ -159,13 +150,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr {
159150
}
160151
}
161152

162-
impl_stable_hash_for_spanned!(usize);
163-
164-
impl_stable_hash_for!(struct ast::Ident {
165-
name,
166-
span,
167-
});
168-
169153
impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItem {
170154
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
171155
let hir::TraitItem {
@@ -234,8 +218,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::VisibilityKind {
234218
}
235219
}
236220

237-
impl_stable_hash_for_spanned!(hir::VisibilityKind);
238-
239221
impl<'a> HashStable<StableHashingContext<'a>> for hir::Mod {
240222
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
241223
let hir::Mod {
@@ -263,9 +245,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::Mod {
263245
}
264246
}
265247

266-
impl_stable_hash_for_spanned!(hir::Variant);
267-
268-
269248
impl<'a> HashStable<StableHashingContext<'a>> for hir::Item {
270249
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
271250
let hir::Item {

src/librustc/ich/impls_syntax.rs

+8-150
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,23 @@
33
44
use crate::ich::StableHashingContext;
55

6-
use std::hash as std_hash;
7-
use std::mem;
8-
96
use syntax::ast;
107
use syntax::feature_gate;
11-
use syntax::token;
12-
use syntax::tokenstream;
138
use syntax_pos::SourceFile;
149

1510
use crate::hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX};
1611

1712
use smallvec::SmallVec;
1813
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
1914

20-
impl_stable_hash_for!(struct ::syntax::ast::Lit {
21-
kind,
22-
token,
23-
span
24-
});
25-
26-
impl_stable_hash_for_spanned!(::syntax::ast::LitKind);
15+
impl<'ctx> rustc_target::HashStableContext for StableHashingContext<'ctx> {}
2716

28-
impl_stable_hash_for!(struct ::syntax::ast::Lifetime { id, ident });
17+
impl<'a> HashStable<StableHashingContext<'a>> for ast::Lifetime {
18+
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
19+
self.id.hash_stable(hcx, hasher);
20+
self.ident.hash_stable(hcx, hasher);
21+
}
22+
}
2923

3024
impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
3125
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
@@ -50,20 +44,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
5044
}
5145
}
5246

53-
impl<'a> HashStable<StableHashingContext<'a>> for ast::Path {
54-
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
55-
self.segments.len().hash_stable(hcx, hasher);
56-
for segment in &self.segments {
57-
segment.ident.name.hash_stable(hcx, hasher);
58-
}
59-
}
60-
}
61-
62-
impl_stable_hash_for!(struct ::syntax::ast::AttrItem {
63-
path,
64-
tokens,
65-
});
66-
6747
impl<'a> HashStable<StableHashingContext<'a>> for ast::Attribute {
6848
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
6949
// Make sure that these have been filtered out.
@@ -81,129 +61,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for ast::Attribute {
8161
}
8262
}
8363

84-
impl<'a> HashStable<StableHashingContext<'a>>
85-
for tokenstream::TokenTree {
86-
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
87-
mem::discriminant(self).hash_stable(hcx, hasher);
88-
match *self {
89-
tokenstream::TokenTree::Token(ref token) => {
90-
token.hash_stable(hcx, hasher);
91-
}
92-
tokenstream::TokenTree::Delimited(span, delim, ref tts) => {
93-
span.hash_stable(hcx, hasher);
94-
std_hash::Hash::hash(&delim, hasher);
95-
for sub_tt in tts.trees() {
96-
sub_tt.hash_stable(hcx, hasher);
97-
}
98-
}
99-
}
100-
}
101-
}
102-
103-
impl<'a> HashStable<StableHashingContext<'a>>
104-
for tokenstream::TokenStream {
105-
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
106-
for sub_tt in self.trees() {
107-
sub_tt.hash_stable(hcx, hasher);
108-
}
109-
}
110-
}
111-
112-
impl<'a> HashStable<StableHashingContext<'a>> for token::TokenKind {
113-
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
114-
mem::discriminant(self).hash_stable(hcx, hasher);
115-
match *self {
116-
token::Eq |
117-
token::Lt |
118-
token::Le |
119-
token::EqEq |
120-
token::Ne |
121-
token::Ge |
122-
token::Gt |
123-
token::AndAnd |
124-
token::OrOr |
125-
token::Not |
126-
token::Tilde |
127-
token::At |
128-
token::Dot |
129-
token::DotDot |
130-
token::DotDotDot |
131-
token::DotDotEq |
132-
token::Comma |
133-
token::Semi |
134-
token::Colon |
135-
token::ModSep |
136-
token::RArrow |
137-
token::LArrow |
138-
token::FatArrow |
139-
token::Pound |
140-
token::Dollar |
141-
token::Question |
142-
token::SingleQuote |
143-
token::Whitespace |
144-
token::Comment |
145-
token::Eof => {}
146-
147-
token::BinOp(bin_op_token) |
148-
token::BinOpEq(bin_op_token) => {
149-
std_hash::Hash::hash(&bin_op_token, hasher);
150-
}
151-
152-
token::OpenDelim(delim_token) |
153-
token::CloseDelim(delim_token) => {
154-
std_hash::Hash::hash(&delim_token, hasher);
155-
}
156-
token::Literal(lit) => lit.hash_stable(hcx, hasher),
157-
158-
token::Ident(name, is_raw) => {
159-
name.hash_stable(hcx, hasher);
160-
is_raw.hash_stable(hcx, hasher);
161-
}
162-
token::Lifetime(name) => name.hash_stable(hcx, hasher),
163-
164-
token::Interpolated(_) => {
165-
bug!("interpolated tokens should not be present in the HIR")
166-
}
167-
168-
token::DocComment(val) |
169-
token::Shebang(val) |
170-
token::Unknown(val) => val.hash_stable(hcx, hasher),
171-
}
172-
}
173-
}
174-
175-
impl_stable_hash_for!(struct token::Token {
176-
kind,
177-
span
178-
});
179-
180-
impl_stable_hash_for!(enum ::syntax::ast::NestedMetaItem {
181-
MetaItem(meta_item),
182-
Literal(lit)
183-
});
184-
185-
impl_stable_hash_for!(struct ::syntax::ast::MetaItem {
186-
path,
187-
kind,
188-
span
189-
});
190-
191-
impl_stable_hash_for!(enum ::syntax::ast::MetaItemKind {
192-
Word,
193-
List(nested_items),
194-
NameValue(lit)
195-
});
196-
197-
impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnData {
198-
kind,
199-
parent -> _,
200-
call_site,
201-
def_site,
202-
allow_internal_unstable,
203-
allow_internal_unsafe,
204-
local_inner_macros,
205-
edition
206-
});
64+
impl<'ctx> syntax::HashStableContext for StableHashingContext<'ctx> {}
20765

20866
impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
20967
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {

src/librustc/ich/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
//! ICH - Incremental Compilation Hash
22
33
crate use rustc_data_structures::fingerprint::Fingerprint;
4-
pub use self::caching_source_map_view::CachingSourceMapView;
4+
pub use syntax_pos::CachingSourceMapView;
55
pub use self::hcx::{StableHashingContextProvider, StableHashingContext, NodeIdHashingMode,
66
hash_stable_trait_impls};
77
use syntax::symbol::{Symbol, sym};
88

9-
mod caching_source_map_view;
109
mod hcx;
1110

1211
mod impls_hir;

0 commit comments

Comments
 (0)