@@ -22,6 +22,14 @@ use comment::rewrite_comment;
22
22
use macros:: rewrite_macro;
23
23
use items:: { rewrite_static, rewrite_associated_type, rewrite_type_alias, format_impl, format_trait} ;
24
24
25
+ // For format_missing and last_pos, need to use the source callsite (if applicable).
26
+ // Required as generated code spans aren't guaranteed to follow on from the last span.
27
+ macro_rules! source {
28
+ ( $this: ident, $sp: expr) => {
29
+ $this. codemap. source_callsite( $sp)
30
+ }
31
+ }
32
+
25
33
pub struct FmtVisitor < ' a > {
26
34
pub parse_session : & ' a ParseSess ,
27
35
pub codemap : & ' a CodeMap ,
@@ -55,7 +63,7 @@ impl<'a> FmtVisitor<'a> {
55
63
self . push_rewrite ( stmt. span , rewrite) ;
56
64
}
57
65
ast:: StmtKind :: Mac ( ref mac, _macro_style, _) => {
58
- self . format_missing_with_indent ( stmt. span . lo ) ;
66
+ self . format_missing_with_indent ( source ! ( self , stmt. span) . lo ) ;
59
67
self . visit_mac ( mac, None ) ;
60
68
}
61
69
}
@@ -84,24 +92,24 @@ impl<'a> FmtVisitor<'a> {
84
92
}
85
93
86
94
if let Some ( ref e) = b. expr {
87
- self . format_missing_with_indent ( e. span . lo ) ;
95
+ self . format_missing_with_indent ( source ! ( self , e. span) . lo ) ;
88
96
let rewrite = e. rewrite ( & self . get_context ( ) ,
89
97
self . config . max_width - self . block_indent . width ( ) ,
90
98
self . block_indent )
91
99
. unwrap_or_else ( || self . snippet ( e. span ) ) ;
92
100
93
101
self . buffer . push_str ( & rewrite) ;
94
- self . last_pos = e. span . hi ;
102
+ self . last_pos = source ! ( self , e. span) . hi ;
95
103
96
104
if utils:: semicolon_for_expr ( e) {
97
105
self . buffer . push_str ( ";" ) ;
98
106
}
99
107
}
100
108
101
109
// FIXME: we should compress any newlines here to just one
102
- self . format_missing_with_indent ( b. span . hi - brace_compensation) ;
110
+ self . format_missing_with_indent ( source ! ( self , b. span) . hi - brace_compensation) ;
103
111
self . close_block ( ) ;
104
- self . last_pos = b. span . hi ;
112
+ self . last_pos = source ! ( self , b. span) . hi ;
105
113
}
106
114
107
115
// FIXME: this is a terrible hack to indent the comments between the last
@@ -160,19 +168,19 @@ impl<'a> FmtVisitor<'a> {
160
168
} ;
161
169
162
170
if let Some ( fn_str) = rewrite {
163
- self . format_missing_with_indent ( s . lo ) ;
171
+ self . format_missing_with_indent ( source ! ( self , s ) . lo ) ;
164
172
self . buffer . push_str ( & fn_str) ;
165
173
if let Some ( c) = fn_str. chars ( ) . last ( ) {
166
174
if c == '}' {
167
- self . last_pos = b. span . hi ;
175
+ self . last_pos = source ! ( self , b. span) . hi ;
168
176
return ;
169
177
}
170
178
}
171
179
} else {
172
- self . format_missing ( b. span . lo ) ;
180
+ self . format_missing ( source ! ( self , b. span) . lo ) ;
173
181
}
174
182
175
- self . last_pos = b. span . lo ;
183
+ self . last_pos = source ! ( self , b. span) . lo ;
176
184
self . visit_block ( b)
177
185
}
178
186
@@ -206,10 +214,10 @@ impl<'a> FmtVisitor<'a> {
206
214
self . format_import ( & item. vis , vp, item. span ) ;
207
215
}
208
216
ast:: ItemKind :: Impl ( ..) => {
209
- self . format_missing_with_indent ( item. span . lo ) ;
217
+ self . format_missing_with_indent ( source ! ( self , item. span) . lo ) ;
210
218
if let Some ( impl_str) = format_impl ( & self . get_context ( ) , item, self . block_indent ) {
211
219
self . buffer . push_str ( & impl_str) ;
212
- self . last_pos = item. span . hi ;
220
+ self . last_pos = source ! ( self , item. span) . hi ;
213
221
}
214
222
}
215
223
ast:: ItemKind :: Trait ( ..) => {
@@ -218,14 +226,14 @@ impl<'a> FmtVisitor<'a> {
218
226
item,
219
227
self . block_indent ) {
220
228
self . buffer . push_str ( & trait_str) ;
221
- self . last_pos = item. span . hi ;
229
+ self . last_pos = source ! ( self , item. span) . hi ;
222
230
}
223
231
}
224
232
ast:: ItemKind :: ExternCrate ( _) => {
225
- self . format_missing_with_indent ( item. span . lo ) ;
233
+ self . format_missing_with_indent ( source ! ( self , item. span) . lo ) ;
226
234
let new_str = self . snippet ( item. span ) ;
227
235
self . buffer . push_str ( & new_str) ;
228
- self . last_pos = item. span . hi ;
236
+ self . last_pos = source ! ( self , item. span) . hi ;
229
237
}
230
238
ast:: ItemKind :: Struct ( ref def, ref generics) => {
231
239
let rewrite = {
@@ -249,20 +257,20 @@ impl<'a> FmtVisitor<'a> {
249
257
self . push_rewrite ( item. span , rewrite) ;
250
258
}
251
259
ast:: ItemKind :: Enum ( ref def, ref generics) => {
252
- self . format_missing_with_indent ( item. span . lo ) ;
260
+ self . format_missing_with_indent ( source ! ( self , item. span) . lo ) ;
253
261
self . visit_enum ( item. ident , & item. vis , def, generics, item. span ) ;
254
- self . last_pos = item. span . hi ;
262
+ self . last_pos = source ! ( self , item. span) . hi ;
255
263
}
256
264
ast:: ItemKind :: Mod ( ref module) => {
257
- self . format_missing_with_indent ( item. span . lo ) ;
265
+ self . format_missing_with_indent ( source ! ( self , item. span) . lo ) ;
258
266
self . format_mod ( module, & item. vis , item. span , item. ident ) ;
259
267
}
260
268
ast:: ItemKind :: Mac ( ref mac) => {
261
- self . format_missing_with_indent ( item. span . lo ) ;
269
+ self . format_missing_with_indent ( source ! ( self , item. span) . lo ) ;
262
270
self . visit_mac ( mac, Some ( item. ident ) ) ;
263
271
}
264
272
ast:: ItemKind :: ForeignMod ( ref foreign_mod) => {
265
- self . format_missing_with_indent ( item. span . lo ) ;
273
+ self . format_missing_with_indent ( source ! ( self , item. span) . lo ) ;
266
274
self . format_foreign_mod ( foreign_mod, item. span ) ;
267
275
}
268
276
ast:: ItemKind :: Static ( ref ty, mutability, ref expr) => {
@@ -384,7 +392,7 @@ impl<'a> FmtVisitor<'a> {
384
392
self . push_rewrite ( ii. span , rewrite) ;
385
393
}
386
394
ast:: ImplItemKind :: Macro ( ref mac) => {
387
- self . format_missing_with_indent ( ii. span . lo ) ;
395
+ self . format_missing_with_indent ( source ! ( self , ii. span) . lo ) ;
388
396
self . visit_mac ( mac, Some ( ii. ident ) ) ;
389
397
}
390
398
}
@@ -397,15 +405,15 @@ impl<'a> FmtVisitor<'a> {
397
405
398
406
if let Some ( res) = rewrite {
399
407
self . buffer . push_str ( & res) ;
400
- self . last_pos = mac. span . hi ;
408
+ self . last_pos = source ! ( self , mac. span) . hi ;
401
409
}
402
410
}
403
411
404
412
fn push_rewrite ( & mut self , span : Span , rewrite : Option < String > ) {
405
- self . format_missing_with_indent ( span. lo ) ;
413
+ self . format_missing_with_indent ( source ! ( self , span) . lo ) ;
406
414
let result = rewrite. unwrap_or_else ( || self . snippet ( span) ) ;
407
415
self . buffer . push_str ( & result) ;
408
- self . last_pos = span. hi ;
416
+ self . last_pos = source ! ( self , span) . hi ;
409
417
}
410
418
411
419
pub fn from_codemap ( parse_session : & ' a ParseSess , config : & ' a Config ) -> FmtVisitor < ' a > {
@@ -449,15 +457,15 @@ impl<'a> FmtVisitor<'a> {
449
457
}
450
458
451
459
let first = & outers[ 0 ] ;
452
- self . format_missing_with_indent ( first. span . lo ) ;
460
+ self . format_missing_with_indent ( source ! ( self , first. span) . lo ) ;
453
461
454
462
let rewrite = outers. rewrite ( & self . get_context ( ) ,
455
463
self . config . max_width - self . block_indent . width ( ) ,
456
464
self . block_indent )
457
465
. unwrap ( ) ;
458
466
self . buffer . push_str ( & rewrite) ;
459
467
let last = outers. last ( ) . unwrap ( ) ;
460
- self . last_pos = last. span . hi ;
468
+ self . last_pos = source ! ( self , last. span) . hi ;
461
469
false
462
470
}
463
471
@@ -470,7 +478,7 @@ impl<'a> FmtVisitor<'a> {
470
478
fn format_mod ( & mut self , m : & ast:: Mod , vis : & ast:: Visibility , s : Span , ident : ast:: Ident ) {
471
479
// Decide whether this is an inline mod or an external mod.
472
480
let local_file_name = self . codemap . span_to_filename ( s) ;
473
- let is_internal = local_file_name == self . codemap . span_to_filename ( m. inner ) ;
481
+ let is_internal = local_file_name == self . codemap . span_to_filename ( source ! ( self , m. inner) ) ;
474
482
475
483
if let Some ( vis) = utils:: format_visibility ( vis) {
476
484
self . buffer . push_str ( vis) ;
@@ -481,27 +489,28 @@ impl<'a> FmtVisitor<'a> {
481
489
if is_internal {
482
490
self . buffer . push_str ( " {" ) ;
483
491
// Hackery to account for the closing }.
484
- let mod_lo = self . codemap . span_after ( s, "{" ) ;
485
- let body_snippet = self . snippet ( codemap:: mk_sp ( mod_lo, m. inner . hi - BytePos ( 1 ) ) ) ;
492
+ let mod_lo = self . codemap . span_after ( source ! ( self , s) , "{" ) ;
493
+ let body_snippet =
494
+ self . snippet ( codemap:: mk_sp ( mod_lo, source ! ( self , m. inner) . hi - BytePos ( 1 ) ) ) ;
486
495
let body_snippet = body_snippet. trim ( ) ;
487
496
if body_snippet. is_empty ( ) {
488
497
self . buffer . push_str ( "}" ) ;
489
498
} else {
490
499
self . last_pos = mod_lo;
491
500
self . block_indent = self . block_indent . block_indent ( self . config ) ;
492
501
self . walk_mod_items ( m) ;
493
- self . format_missing_with_indent ( m. inner . hi - BytePos ( 1 ) ) ;
502
+ self . format_missing_with_indent ( source ! ( self , m. inner) . hi - BytePos ( 1 ) ) ;
494
503
self . close_block ( ) ;
495
504
}
496
- self . last_pos = m. inner . hi ;
505
+ self . last_pos = source ! ( self , m. inner) . hi ;
497
506
} else {
498
507
self . buffer . push_str ( ";" ) ;
499
- self . last_pos = s . hi ;
508
+ self . last_pos = source ! ( self , s ) . hi ;
500
509
}
501
510
}
502
511
503
512
pub fn format_separate_mod ( & mut self , m : & ast:: Mod ) {
504
- let filemap = self . codemap . lookup_char_pos ( m. inner . lo ) . file ;
513
+ let filemap = self . codemap . lookup_char_pos ( source ! ( self , m. inner) . lo ) . file ;
505
514
self . last_pos = filemap. start_pos ;
506
515
self . block_indent = Indent :: empty ( ) ;
507
516
self . walk_mod_items ( m) ;
@@ -521,23 +530,23 @@ impl<'a> FmtVisitor<'a> {
521
530
offset) {
522
531
Some ( ref s) if s. is_empty ( ) => {
523
532
// Format up to last newline
524
- let prev_span = codemap:: mk_sp ( self . last_pos , span. lo ) ;
533
+ let prev_span = codemap:: mk_sp ( self . last_pos , source ! ( self , span) . lo ) ;
525
534
let span_end = match self . snippet ( prev_span) . rfind ( '\n' ) {
526
535
Some ( offset) => self . last_pos + BytePos ( offset as u32 ) ,
527
- None => span. lo ,
536
+ None => source ! ( self , span) . lo ,
528
537
} ;
529
538
self . format_missing ( span_end) ;
530
- self . last_pos = span. hi ;
539
+ self . last_pos = source ! ( self , span) . hi ;
531
540
}
532
541
Some ( ref s) => {
533
542
let s = format ! ( "{}use {};" , vis, s) ;
534
- self . format_missing_with_indent ( span. lo ) ;
543
+ self . format_missing_with_indent ( source ! ( self , span) . lo ) ;
535
544
self . buffer . push_str ( & s) ;
536
- self . last_pos = span. hi ;
545
+ self . last_pos = source ! ( self , span) . hi ;
537
546
}
538
547
None => {
539
- self . format_missing_with_indent ( span. lo ) ;
540
- self . format_missing ( span. hi ) ;
548
+ self . format_missing_with_indent ( source ! ( self , span) . lo ) ;
549
+ self . format_missing ( source ! ( self , span) . hi ) ;
541
550
}
542
551
}
543
552
}
0 commit comments