@@ -39,6 +39,7 @@ use rustc_data_structures::unhash::UnhashMap;
39
39
use rustc_index:: vec:: IndexVec ;
40
40
use rustc_macros:: HashStable_Generic ;
41
41
use rustc_serialize:: { Decodable , Decoder , Encodable , Encoder } ;
42
+ use std:: collections:: hash_map:: Entry ;
42
43
use std:: fmt;
43
44
use std:: hash:: Hash ;
44
45
use tracing:: * ;
@@ -179,6 +180,9 @@ impl LocalExpnId {
179
180
ExpnIndex :: from_u32 ( self . as_u32 ( ) )
180
181
}
181
182
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.
182
186
pub fn fresh_empty ( ) -> LocalExpnId {
183
187
HygieneData :: with ( |data| {
184
188
let expn_id = data. local_expn_data . push ( None ) ;
@@ -188,17 +192,51 @@ impl LocalExpnId {
188
192
} )
189
193
}
190
194
195
+ /// Creates an expansion.
191
196
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 ) {
192
228
debug_assert_eq ! ( expn_data. parent. krate, LOCAL_CRATE ) ;
193
229
let expn_hash = update_disambiguator ( & mut expn_data, ctx) ;
194
230
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 ( ) ) ;
199
238
debug_assert ! ( _old_id. is_none( ) ) ;
200
- expn_id
201
- } )
239
+ } ) ;
202
240
}
203
241
204
242
#[ inline]
@@ -216,21 +254,6 @@ impl LocalExpnId {
216
254
ExpnId { krate : LOCAL_CRATE , local_id : self . as_raw ( ) }
217
255
}
218
256
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
-
234
257
#[ inline]
235
258
pub fn is_descendant_of ( self , ancestor : LocalExpnId ) -> bool {
236
259
self . to_expn_id ( ) . is_descendant_of ( ancestor. to_expn_id ( ) )
@@ -1039,6 +1062,36 @@ impl ExpnData {
1039
1062
self . hash_stable ( ctx, & mut hasher) ;
1040
1063
hasher. finish ( )
1041
1064
}
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
+ }
1042
1095
}
1043
1096
1044
1097
/// Expansion kind.
@@ -1253,8 +1306,10 @@ pub fn register_local_expn_id(data: ExpnData, hash: ExpnHash) -> ExpnId {
1253
1306
1254
1307
let expn_id = expn_id. to_expn_id ( ) ;
1255
1308
1309
+ debug ! ( ?hash, ?expn_id) ;
1256
1310
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
+
1258
1313
expn_id
1259
1314
} )
1260
1315
}
@@ -1273,6 +1328,7 @@ pub fn register_expn_id(
1273
1328
debug_assert ! ( _old_data. is_none( ) ) ;
1274
1329
let _old_hash = hygiene_data. foreign_expn_hashes . insert ( expn_id, hash) ;
1275
1330
debug_assert ! ( _old_hash. is_none( ) ) ;
1331
+ debug ! ( ?hash, ?expn_id) ;
1276
1332
let _old_id = hygiene_data. expn_hash_to_expn_id . insert ( hash, expn_id) ;
1277
1333
debug_assert ! ( _old_id. is_none( ) ) ;
1278
1334
} ) ;
0 commit comments