@@ -1076,22 +1076,74 @@ pub struct HygieneDecodeContext {
1076
1076
remapped_expns : Lock < Vec < Option < ExpnId > > > ,
1077
1077
}
1078
1078
1079
- pub fn decode_expn_id < ' a , D : Decoder , G > (
1079
+ pub fn decode_expn_id_incrcomp < D : Decoder > (
1080
1080
d : & mut D ,
1081
- mode : ExpnDataDecodeMode < ' a , G > ,
1081
+ context : & HygieneDecodeContext ,
1082
1082
decode_data : impl FnOnce ( & mut D , u32 ) -> Result < ( ExpnData , ExpnHash ) , D :: Error > ,
1083
- ) -> Result < ExpnId , D :: Error >
1084
- where
1085
- G : FnOnce ( CrateNum ) -> & ' a HygieneDecodeContext ,
1086
- {
1083
+ ) -> Result < ExpnId , D :: Error > {
1087
1084
let index = u32:: decode ( d) ?;
1088
- let context = match mode {
1089
- ExpnDataDecodeMode :: IncrComp ( context) => context,
1090
- ExpnDataDecodeMode :: Metadata ( get_context) => {
1091
- let krate = CrateNum :: decode ( d) ?;
1092
- get_context ( krate)
1085
+
1086
+ // Do this after decoding, so that we decode a `CrateNum`
1087
+ // if necessary
1088
+ if index == ExpnId :: root ( ) . as_u32 ( ) {
1089
+ debug ! ( "decode_expn_id: deserialized root" ) ;
1090
+ return Ok ( ExpnId :: root ( ) ) ;
1091
+ }
1092
+
1093
+ let outer_expns = & context. remapped_expns ;
1094
+
1095
+ // Ensure that the lock() temporary is dropped early
1096
+ {
1097
+ if let Some ( expn_id) = outer_expns. lock ( ) . get ( index as usize ) . copied ( ) . flatten ( ) {
1098
+ return Ok ( expn_id) ;
1093
1099
}
1094
- } ;
1100
+ }
1101
+
1102
+ // Don't decode the data inside `HygieneData::with`, since we need to recursively decode
1103
+ // other ExpnIds
1104
+ let ( mut expn_data, hash) = decode_data ( d, index) ?;
1105
+
1106
+ let expn_id = HygieneData :: with ( |hygiene_data| {
1107
+ if let Some ( & expn_id) = hygiene_data. expn_hash_to_expn_id . get ( & hash) {
1108
+ return expn_id;
1109
+ }
1110
+
1111
+ let expn_id = ExpnId ( hygiene_data. expn_data . len ( ) as u32 ) ;
1112
+
1113
+ // If we just deserialized an `ExpnData` owned by
1114
+ // the local crate, its `orig_id` will be stale,
1115
+ // so we need to update it to its own value.
1116
+ // This only happens when we deserialize the incremental cache,
1117
+ // since a crate will never decode its own metadata.
1118
+ if expn_data. krate == LOCAL_CRATE {
1119
+ expn_data. orig_id = Some ( expn_id. 0 ) ;
1120
+ }
1121
+
1122
+ hygiene_data. expn_data . push ( Some ( expn_data) ) ;
1123
+ hygiene_data. expn_hashes . push ( hash) ;
1124
+ let _old_id = hygiene_data. expn_hash_to_expn_id . insert ( hash, expn_id) ;
1125
+ debug_assert ! ( _old_id. is_none( ) ) ;
1126
+
1127
+ let mut expns = outer_expns. lock ( ) ;
1128
+ let new_len = index as usize + 1 ;
1129
+ if expns. len ( ) < new_len {
1130
+ expns. resize ( new_len, None ) ;
1131
+ }
1132
+ expns[ index as usize ] = Some ( expn_id) ;
1133
+ drop ( expns) ;
1134
+ expn_id
1135
+ } ) ;
1136
+ Ok ( expn_id)
1137
+ }
1138
+
1139
+ pub fn decode_expn_id < ' a , D : Decoder > (
1140
+ d : & mut D ,
1141
+ get_context : impl FnOnce ( CrateNum ) -> & ' a HygieneDecodeContext ,
1142
+ decode_data : impl FnOnce ( & mut D , u32 ) -> Result < ( ExpnData , ExpnHash ) , D :: Error > ,
1143
+ ) -> Result < ExpnId , D :: Error > {
1144
+ let index = u32:: decode ( d) ?;
1145
+ let krate = CrateNum :: decode ( d) ?;
1146
+ let context = get_context ( krate) ;
1095
1147
1096
1148
// Do this after decoding, so that we decode a `CrateNum`
1097
1149
// if necessary
@@ -1274,56 +1326,39 @@ pub fn raw_encode_syntax_context<E: Encoder>(
1274
1326
ctxt. 0 . encode ( e)
1275
1327
}
1276
1328
1277
- pub fn raw_encode_expn_id < E : Encoder > (
1329
+ pub fn raw_encode_expn_id_incrcomp < E : Encoder > (
1278
1330
expn : ExpnId ,
1279
1331
context : & HygieneEncodeContext ,
1280
- mode : ExpnDataEncodeMode ,
1281
1332
e : & mut E ,
1282
1333
) -> Result < ( ) , E :: Error > {
1283
1334
// Record the fact that we need to serialize the corresponding
1284
1335
// `ExpnData`
1285
- let needs_data = || {
1286
- if !context. serialized_expns . lock ( ) . contains ( & expn) {
1287
- context. latest_expns . lock ( ) . insert ( expn) ;
1288
- }
1289
- } ;
1290
-
1291
- match mode {
1292
- ExpnDataEncodeMode :: IncrComp => {
1293
- // Always serialize the `ExpnData` in incr comp mode
1294
- needs_data ( ) ;
1295
- expn. 0 . encode ( e)
1296
- }
1297
- ExpnDataEncodeMode :: Metadata => {
1298
- let data = expn. expn_data ( ) ;
1299
- // We only need to serialize the ExpnData
1300
- // if it comes from this crate.
1301
- // We currently don't serialize any hygiene information data for
1302
- // proc-macro crates: see the `SpecializedEncoder<Span>` impl
1303
- // for crate metadata.
1304
- if data. krate == LOCAL_CRATE {
1305
- needs_data ( ) ;
1306
- }
1307
- data. orig_id . expect ( "Missing orig_id" ) . encode ( e) ?;
1308
- data. krate . encode ( e)
1309
- }
1336
+ if !context. serialized_expns . lock ( ) . contains ( & expn) {
1337
+ context. latest_expns . lock ( ) . insert ( expn) ;
1310
1338
}
1339
+ expn. 0 . encode ( e)
1311
1340
}
1312
1341
1313
- pub enum ExpnDataEncodeMode {
1314
- IncrComp ,
1315
- Metadata ,
1316
- }
1317
-
1318
- pub enum ExpnDataDecodeMode < ' a , F : FnOnce ( CrateNum ) -> & ' a HygieneDecodeContext > {
1319
- IncrComp ( & ' a HygieneDecodeContext ) ,
1320
- Metadata ( F ) ,
1321
- }
1322
-
1323
- impl < ' a > ExpnDataDecodeMode < ' a , Box < dyn FnOnce ( CrateNum ) -> & ' a HygieneDecodeContext > > {
1324
- pub fn incr_comp ( ctxt : & ' a HygieneDecodeContext ) -> Self {
1325
- ExpnDataDecodeMode :: IncrComp ( ctxt)
1342
+ pub fn raw_encode_expn_id < E : Encoder > (
1343
+ expn : ExpnId ,
1344
+ context : & HygieneEncodeContext ,
1345
+ e : & mut E ,
1346
+ ) -> Result < ( ) , E :: Error > {
1347
+ let data = expn. expn_data ( ) ;
1348
+ // We only need to serialize the ExpnData
1349
+ // if it comes from this crate.
1350
+ // We currently don't serialize any hygiene information data for
1351
+ // proc-macro crates: see the `SpecializedEncoder<Span>` impl
1352
+ // for crate metadata.
1353
+ if data. krate == LOCAL_CRATE {
1354
+ // Record the fact that we need to serialize the corresponding
1355
+ // `ExpnData`
1356
+ if !context. serialized_expns . lock ( ) . contains ( & expn) {
1357
+ context. latest_expns . lock ( ) . insert ( expn) ;
1358
+ }
1326
1359
}
1360
+ data. orig_id . expect ( "Missing orig_id" ) . encode ( e) ?;
1361
+ data. krate . encode ( e)
1327
1362
}
1328
1363
1329
1364
impl < E : Encoder > Encodable < E > for SyntaxContext {
0 commit comments