Skip to content

Commit 4838281

Browse files
committed
Unify new expansions with ones loaded from incremental cache.
1 parent 52ef8cd commit 4838281

File tree

1 file changed

+78
-22
lines changed

1 file changed

+78
-22
lines changed

compiler/rustc_span/src/hygiene.rs

Lines changed: 78 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use rustc_data_structures::unhash::UnhashMap;
3939
use rustc_index::vec::IndexVec;
4040
use rustc_macros::HashStable_Generic;
4141
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
42+
use std::collections::hash_map::Entry;
4243
use std::fmt;
4344
use std::hash::Hash;
4445
use tracing::*;
@@ -179,6 +180,9 @@ impl LocalExpnId {
179180
ExpnIndex::from_u32(self.as_u32())
180181
}
181182

183+
/// Creates an empty expansion to be filled later.
184+
/// This method should only be used outside of the incremental compilation engine.
185+
/// Prefer using `fresh` when the expansion data is available.
182186
pub fn fresh_empty() -> LocalExpnId {
183187
HygieneData::with(|data| {
184188
let expn_id = data.local_expn_data.push(None);
@@ -188,17 +192,51 @@ impl LocalExpnId {
188192
})
189193
}
190194

195+
/// Creates an expansion.
191196
pub fn fresh(mut expn_data: ExpnData, ctx: impl HashStableContext) -> LocalExpnId {
197+
debug_assert_eq!(expn_data.parent.krate, LOCAL_CRATE);
198+
#[cfg(debug_assertions)]
199+
let hashing_controls = ctx.hashing_controls();
200+
let expn_hash = update_disambiguator(&mut expn_data, ctx);
201+
HygieneData::with(|data| match data.expn_hash_to_expn_id.entry(expn_hash) {
202+
Entry::Vacant(v) => {
203+
let expn_id = data.local_expn_data.push(Some(expn_data));
204+
let _eid = data.local_expn_hashes.push(expn_hash);
205+
debug_assert_eq!(expn_id, _eid);
206+
debug!(?expn_hash, ?expn_id);
207+
v.insert(expn_id.to_expn_id());
208+
expn_id
209+
}
210+
Entry::Occupied(o) => {
211+
let old_id = *o.get();
212+
// The hash starts with the local crate's hash, so this must be a local id.
213+
let old_id = old_id.expect_local();
214+
#[cfg(debug_assertions)]
215+
{
216+
let old_data = data.local_expn_data[old_id].as_ref().unwrap();
217+
debug!(?old_id, ?old_data, ?expn_data);
218+
expn_data.assert_identical(&old_data, hashing_controls);
219+
}
220+
old_id
221+
}
222+
})
223+
}
224+
225+
/// Fill an empty expansion.
226+
/// This method should only be used outside of the incremental compilation engine.
227+
pub fn set_expn_data(self, mut expn_data: ExpnData, ctx: impl HashStableContext) {
192228
debug_assert_eq!(expn_data.parent.krate, LOCAL_CRATE);
193229
let expn_hash = update_disambiguator(&mut expn_data, ctx);
194230
HygieneData::with(|data| {
195-
let expn_id = data.local_expn_data.push(Some(expn_data));
196-
let _eid = data.local_expn_hashes.push(expn_hash);
197-
debug_assert_eq!(expn_id, _eid);
198-
let _old_id = data.expn_hash_to_expn_id.insert(expn_hash, expn_id.to_expn_id());
231+
let old_expn_data = &mut data.local_expn_data[self];
232+
assert!(old_expn_data.is_none(), "expansion data is reset for an expansion ID");
233+
*old_expn_data = Some(expn_data);
234+
debug_assert_eq!(data.local_expn_hashes[self].0, Fingerprint::ZERO);
235+
data.local_expn_hashes[self] = expn_hash;
236+
debug!(?expn_hash, ?self);
237+
let _old_id = data.expn_hash_to_expn_id.insert(expn_hash, self.to_expn_id());
199238
debug_assert!(_old_id.is_none());
200-
expn_id
201-
})
239+
});
202240
}
203241

204242
#[inline]
@@ -216,21 +254,6 @@ impl LocalExpnId {
216254
ExpnId { krate: LOCAL_CRATE, local_id: self.as_raw() }
217255
}
218256

219-
#[inline]
220-
pub fn set_expn_data(self, mut expn_data: ExpnData, ctx: impl HashStableContext) {
221-
debug_assert_eq!(expn_data.parent.krate, LOCAL_CRATE);
222-
let expn_hash = update_disambiguator(&mut expn_data, ctx);
223-
HygieneData::with(|data| {
224-
let old_expn_data = &mut data.local_expn_data[self];
225-
assert!(old_expn_data.is_none(), "expansion data is reset for an expansion ID");
226-
*old_expn_data = Some(expn_data);
227-
debug_assert_eq!(data.local_expn_hashes[self].0, Fingerprint::ZERO);
228-
data.local_expn_hashes[self] = expn_hash;
229-
let _old_id = data.expn_hash_to_expn_id.insert(expn_hash, self.to_expn_id());
230-
debug_assert!(_old_id.is_none());
231-
});
232-
}
233-
234257
#[inline]
235258
pub fn is_descendant_of(self, ancestor: LocalExpnId) -> bool {
236259
self.to_expn_id().is_descendant_of(ancestor.to_expn_id())
@@ -1039,6 +1062,36 @@ impl ExpnData {
10391062
self.hash_stable(ctx, &mut hasher);
10401063
hasher.finish()
10411064
}
1065+
1066+
#[inline]
1067+
#[cfg(debug_assertions)]
1068+
fn assert_identical(&self, other: &ExpnData, ctx: HashingControls) {
1069+
let ExpnData {
1070+
kind,
1071+
parent,
1072+
call_site,
1073+
def_site,
1074+
allow_internal_unstable,
1075+
allow_internal_unsafe,
1076+
local_inner_macros,
1077+
edition,
1078+
macro_def_id,
1079+
parent_module,
1080+
disambiguator: _,
1081+
} = self;
1082+
debug_assert_eq!(*kind, other.kind);
1083+
debug_assert_eq!(*parent, other.parent);
1084+
if ctx.hash_spans {
1085+
debug_assert_eq!(*call_site, other.call_site);
1086+
debug_assert_eq!(*def_site, other.def_site);
1087+
}
1088+
debug_assert_eq!(*allow_internal_unstable, other.allow_internal_unstable);
1089+
debug_assert_eq!(*allow_internal_unsafe, other.allow_internal_unsafe);
1090+
debug_assert_eq!(*local_inner_macros, other.local_inner_macros);
1091+
debug_assert_eq!(*edition, other.edition);
1092+
debug_assert_eq!(*macro_def_id, other.macro_def_id);
1093+
debug_assert_eq!(*parent_module, other.parent_module);
1094+
}
10421095
}
10431096

10441097
/// Expansion kind.
@@ -1253,8 +1306,10 @@ pub fn register_local_expn_id(data: ExpnData, hash: ExpnHash) -> ExpnId {
12531306

12541307
let expn_id = expn_id.to_expn_id();
12551308

1309+
debug!(?hash, ?expn_id);
12561310
let _old_id = hygiene_data.expn_hash_to_expn_id.insert(hash, expn_id);
1257-
debug_assert!(_old_id.is_none());
1311+
debug_assert_eq!(_old_id, None);
1312+
12581313
expn_id
12591314
})
12601315
}
@@ -1273,6 +1328,7 @@ pub fn register_expn_id(
12731328
debug_assert!(_old_data.is_none());
12741329
let _old_hash = hygiene_data.foreign_expn_hashes.insert(expn_id, hash);
12751330
debug_assert!(_old_hash.is_none());
1331+
debug!(?hash, ?expn_id);
12761332
let _old_id = hygiene_data.expn_hash_to_expn_id.insert(hash, expn_id);
12771333
debug_assert!(_old_id.is_none());
12781334
});

0 commit comments

Comments
 (0)