@@ -1076,22 +1076,74 @@ pub struct HygieneDecodeContext {
10761076 remapped_expns : Lock < Vec < Option < ExpnId > > > ,
10771077}
10781078
1079- pub fn decode_expn_id < ' a , D : Decoder , G > (
1079+ pub fn decode_expn_id_incrcomp < D : Decoder > (
10801080 d : & mut D ,
1081- mode : ExpnDataDecodeMode < ' a , G > ,
1081+ context : & HygieneDecodeContext ,
10821082 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 > {
10871084 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) ;
10931099 }
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) ;
10951147
10961148 // Do this after decoding, so that we decode a `CrateNum`
10971149 // if necessary
@@ -1274,56 +1326,39 @@ pub fn raw_encode_syntax_context<E: Encoder>(
12741326 ctxt. 0 . encode ( e)
12751327}
12761328
1277- pub fn raw_encode_expn_id < E : Encoder > (
1329+ pub fn raw_encode_expn_id_incrcomp < E : Encoder > (
12781330 expn : ExpnId ,
12791331 context : & HygieneEncodeContext ,
1280- mode : ExpnDataEncodeMode ,
12811332 e : & mut E ,
12821333) -> Result < ( ) , E :: Error > {
12831334 // Record the fact that we need to serialize the corresponding
12841335 // `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) ;
13101338 }
1339+ expn. 0 . encode ( e)
13111340}
13121341
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+ }
13261359 }
1360+ data. orig_id . expect ( "Missing orig_id" ) . encode ( e) ?;
1361+ data. krate . encode ( e)
13271362}
13281363
13291364impl < E : Encoder > Encodable < E > for SyntaxContext {
0 commit comments