@@ -41,7 +41,7 @@ use syntax::ast::{self, CRATE_NODE_ID};
41
41
use syntax:: codemap:: Spanned ;
42
42
use syntax:: attr;
43
43
use syntax:: symbol:: Symbol ;
44
- use syntax_pos:: { self , FileName } ;
44
+ use syntax_pos:: { self , FileName , FileMap , Span , DUMMY_SP } ;
45
45
46
46
use rustc:: hir:: { self , PatKind } ;
47
47
use rustc:: hir:: itemlikevisit:: ItemLikeVisitor ;
@@ -57,6 +57,9 @@ pub struct EncodeContext<'a, 'tcx: 'a> {
57
57
lazy_state : LazyState ,
58
58
type_shorthands : FxHashMap < Ty < ' tcx > , usize > ,
59
59
predicate_shorthands : FxHashMap < ty:: Predicate < ' tcx > , usize > ,
60
+
61
+ // This is used to speed up Span encoding.
62
+ filemap_cache : Rc < FileMap > ,
60
63
}
61
64
62
65
macro_rules! encoder_methods {
@@ -140,6 +143,40 @@ impl<'a, 'tcx> SpecializedEncoder<DefIndex> for EncodeContext<'a, 'tcx> {
140
143
}
141
144
}
142
145
146
+ impl < ' a , ' tcx > SpecializedEncoder < Span > for EncodeContext < ' a , ' tcx > {
147
+ fn specialized_encode ( & mut self , span : & Span ) -> Result < ( ) , Self :: Error > {
148
+ if * span == DUMMY_SP {
149
+ return TAG_INVALID_SPAN . encode ( self )
150
+ }
151
+
152
+ let span = span. data ( ) ;
153
+
154
+ if span. lo > span. hi {
155
+ return TAG_INVALID_SPAN . encode ( self )
156
+ }
157
+
158
+ if !self . filemap_cache . contains ( span. lo ) {
159
+ let codemap = self . tcx . sess . codemap ( ) ;
160
+ let filemap_index = codemap. lookup_filemap_idx ( span. lo ) ;
161
+ self . filemap_cache = codemap. files ( ) [ filemap_index] . clone ( ) ;
162
+ }
163
+
164
+ if !self . filemap_cache . contains ( span. hi ) {
165
+ return TAG_INVALID_SPAN . encode ( self )
166
+ }
167
+
168
+ TAG_VALID_SPAN . encode ( self ) ?;
169
+ span. lo . encode ( self ) ?;
170
+
171
+ // Encode length which is usually less than span.hi and profits more
172
+ // from the variable-length integer encoding that we use.
173
+ let len = span. hi - span. lo ;
174
+ len. encode ( self )
175
+
176
+ // Don't encode the expansion context.
177
+ }
178
+ }
179
+
143
180
impl < ' a , ' tcx > SpecializedEncoder < Ty < ' tcx > > for EncodeContext < ' a , ' tcx > {
144
181
fn specialized_encode ( & mut self , ty : & Ty < ' tcx > ) -> Result < ( ) , Self :: Error > {
145
182
ty_codec:: encode_with_shorthand ( self , ty, |ecx| & mut ecx. type_shorthands )
@@ -1648,6 +1685,7 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1648
1685
lazy_state : LazyState :: NoNode ,
1649
1686
type_shorthands : Default :: default ( ) ,
1650
1687
predicate_shorthands : Default :: default ( ) ,
1688
+ filemap_cache : tcx. sess . codemap ( ) . files ( ) [ 0 ] . clone ( ) ,
1651
1689
} ;
1652
1690
1653
1691
// Encode the rustc version string in a predictable location.
0 commit comments