@@ -32,18 +32,21 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
3232use rustc_middle:: util:: common:: record_time;
3333use rustc_serialize:: { opaque, Decodable , Decoder , SpecializedDecoder , UseSpecializedDecodable } ;
3434use rustc_session:: Session ;
35+ use rustc_span:: hygiene:: ExpnDataDecodeMode ;
3536use rustc_span:: source_map:: { respan, Spanned } ;
3637use rustc_span:: symbol:: { sym, Ident , Symbol } ;
37- use rustc_span:: { self , hygiene:: MacroKind , BytePos , Pos , Span , DUMMY_SP } ;
38+ use rustc_span:: { self , hygiene:: MacroKind , BytePos , ExpnId , Pos , Span , SyntaxContext , DUMMY_SP } ;
3839
3940use log:: debug;
4041use proc_macro:: bridge:: client:: ProcMacro ;
42+ use std:: cell:: Cell ;
4143use std:: io;
4244use std:: mem;
4345use std:: num:: NonZeroUsize ;
4446use std:: path:: Path ;
4547
4648pub use cstore_impl:: { provide, provide_extern} ;
49+ use rustc_span:: hygiene:: HygieneContext ;
4750
4851mod cstore_impl;
4952
@@ -106,6 +109,13 @@ crate struct CrateMetadata {
106109 /// The hash for the host proc macro. Used to support `-Z dual-proc-macro`.
107110 host_hash : Option < Svh > ,
108111
112+ /// Additional data used for decoding `HygieneData` (e.g. `SyntaxContext`
113+ /// and `ExpnId`).
114+ /// Note that we store a `HygieneContext` for each `CrateMetadat`. This is
115+ /// because `SyntaxContext` ids are not globally unique, so we need
116+ /// to track which ids we've decoded on a per-crate basis.
117+ hygiene_context : HygieneContext ,
118+
109119 // --- Data used only for improving diagnostics ---
110120 /// Information about the `extern crate` item or path that caused this crate to be loaded.
111121 /// If this is `None`, then the crate was injected (e.g., by the allocator).
@@ -411,6 +421,7 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
411421
412422 let lo = BytePos :: decode ( self ) ?;
413423 let len = BytePos :: decode ( self ) ?;
424+ let ctxt = SyntaxContext :: decode ( self ) ?;
414425 let hi = lo + len;
415426
416427 let sess = if let Some ( sess) = self . sess {
@@ -524,7 +535,7 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
524535 let hi =
525536 ( hi + source_file. translated_source_file . start_pos ) - source_file. original_start_pos ;
526537
527- Ok ( Span :: with_root_ctxt ( lo, hi) )
538+ Ok ( Span :: new ( lo, hi, ctxt ) )
528539 }
529540}
530541
@@ -1120,6 +1131,14 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
11201131 !self . is_proc_macro ( id) && self . root . tables . mir . get ( self , id) . is_some ( )
11211132 }
11221133
1134+ fn module_expansion ( & self , id : DefIndex , sess : & Session ) -> ExpnId {
1135+ if let EntryKind :: Mod ( m) = self . kind ( id) {
1136+ m. decode ( ( self , sess) ) . expansion
1137+ } else {
1138+ panic ! ( "Expected module, found {:?}" , self . local_def_id( id) )
1139+ }
1140+ }
1141+
11231142 fn get_optimized_mir ( & self , tcx : TyCtxt < ' tcx > , id : DefIndex ) -> Body < ' tcx > {
11241143 self . root
11251144 . tables
@@ -1652,6 +1671,7 @@ impl CrateMetadata {
16521671 private_dep,
16531672 host_hash,
16541673 extern_crate : Lock :: new ( None ) ,
1674+ hygiene_context : HygieneContext :: new ( ) ,
16551675 }
16561676 }
16571677
@@ -1784,3 +1804,57 @@ fn macro_kind(raw: &ProcMacro) -> MacroKind {
17841804 ProcMacro :: Bang { .. } => MacroKind :: Bang ,
17851805 }
17861806}
1807+
1808+ impl < ' a , ' tcx > SpecializedDecoder < SyntaxContext > for DecodeContext < ' a , ' tcx > {
1809+ fn specialized_decode ( & mut self ) -> Result < SyntaxContext , Self :: Error > {
1810+ let cdata = self . cdata ( ) ;
1811+ let sess = self . sess . unwrap ( ) ;
1812+ let cname = cdata. root . name ;
1813+ rustc_span:: hygiene:: decode_syntax_context ( self , & cdata. hygiene_context , |_, id| {
1814+ debug ! ( "SpecializedDecoder<SyntaxContext>: decoding {}" , id) ;
1815+ Ok ( cdata
1816+ . root
1817+ . syntax_contexts
1818+ . get ( & cdata, id)
1819+ . unwrap_or_else ( || panic ! ( "Missing SyntaxContext {:?} for crate {:?}" , id, cname) )
1820+ . decode ( ( & cdata, sess) ) )
1821+ } )
1822+ }
1823+ }
1824+
1825+ impl < ' a , ' tcx > SpecializedDecoder < ExpnId > for DecodeContext < ' a , ' tcx > {
1826+ fn specialized_decode ( & mut self ) -> Result < ExpnId , Self :: Error > {
1827+ let local_cdata = self . cdata ( ) ;
1828+ let sess = self . sess . unwrap ( ) ;
1829+ let expn_cnum = Cell :: new ( None ) ;
1830+ let get_ctxt = |cnum| {
1831+ expn_cnum. set ( Some ( cnum) ) ;
1832+ if cnum == LOCAL_CRATE {
1833+ & local_cdata. hygiene_context
1834+ } else {
1835+ & local_cdata. cstore . get_crate_data ( cnum) . cdata . hygiene_context
1836+ }
1837+ } ;
1838+
1839+ rustc_span:: hygiene:: decode_expn_id (
1840+ self ,
1841+ ExpnDataDecodeMode :: Metadata ( get_ctxt) ,
1842+ |_this, index| {
1843+ let cnum = expn_cnum. get ( ) . unwrap ( ) ;
1844+ // Lookup local `ExpnData`s in our own crate data. Foreign `ExpnData`s
1845+ // are stored in the owning crate, to avoid duplication.
1846+ let crate_data = if cnum == LOCAL_CRATE {
1847+ local_cdata
1848+ } else {
1849+ local_cdata. cstore . get_crate_data ( cnum)
1850+ } ;
1851+ Ok ( crate_data
1852+ . root
1853+ . expn_data
1854+ . get ( & crate_data, index)
1855+ . unwrap ( )
1856+ . decode ( ( & crate_data, sess) ) )
1857+ } ,
1858+ )
1859+ }
1860+ }
0 commit comments