@@ -117,6 +117,8 @@ struct Context<'a, 'b: 'a> {
117
117
invalid_refs : Vec < ( usize , usize ) > ,
118
118
/// Spans of all the formatting arguments, in order.
119
119
arg_spans : Vec < Span > ,
120
+ /// Wether this formatting string is a literal or it comes from a macro.
121
+ is_literal : bool ,
120
122
}
121
123
122
124
/// Parses the arguments from the given list of tokens, returning None
@@ -276,7 +278,11 @@ impl<'a, 'b> Context<'a, 'b> {
276
278
/// format string.
277
279
fn report_invalid_references ( & self , numbered_position_args : bool ) {
278
280
let mut e;
279
- let sp = MultiSpan :: from_spans ( self . arg_spans . clone ( ) ) ;
281
+ let sp = if self . is_literal {
282
+ MultiSpan :: from_spans ( self . arg_spans . clone ( ) )
283
+ } else {
284
+ MultiSpan :: from_span ( self . fmtsp )
285
+ } ;
280
286
let mut refs: Vec < _ > = self
281
287
. invalid_refs
282
288
. iter ( )
@@ -294,7 +300,7 @@ impl<'a, 'b> Context<'a, 'b> {
294
300
) ,
295
301
) ;
296
302
} else {
297
- let ( arg_list, sp) = match refs. len ( ) {
303
+ let ( arg_list, mut sp) = match refs. len ( ) {
298
304
1 => {
299
305
let ( reg, pos) = refs. pop ( ) . unwrap ( ) ;
300
306
(
@@ -317,11 +323,14 @@ impl<'a, 'b> Context<'a, 'b> {
317
323
)
318
324
}
319
325
} ;
326
+ if !self . is_literal {
327
+ sp = MultiSpan :: from_span ( self . fmtsp ) ;
328
+ }
320
329
321
330
e = self . ecx . mut_span_err ( sp,
322
331
& format ! ( "invalid reference to positional {} ({})" ,
323
- arg_list,
324
- self . describe_num_args( ) ) ) ;
332
+ arg_list,
333
+ self . describe_num_args( ) ) ) ;
325
334
e. note ( "positional arguments are zero-based" ) ;
326
335
} ;
327
336
@@ -370,7 +379,11 @@ impl<'a, 'b> Context<'a, 'b> {
370
379
Some ( e) => * e,
371
380
None => {
372
381
let msg = format ! ( "there is no argument named `{}`" , name) ;
373
- let sp = * self . arg_spans . get ( self . curpiece ) . unwrap_or ( & self . fmtsp ) ;
382
+ let sp = if self . is_literal {
383
+ * self . arg_spans . get ( self . curpiece ) . unwrap_or ( & self . fmtsp )
384
+ } else {
385
+ self . fmtsp
386
+ } ;
374
387
let mut err = self . ecx . struct_span_err ( sp, & msg[ ..] ) ;
375
388
err. emit ( ) ;
376
389
return ;
@@ -721,7 +734,7 @@ pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt,
721
734
722
735
pub fn expand_format_args_nl < ' cx > (
723
736
ecx : & ' cx mut ExtCtxt ,
724
- mut sp : Span ,
737
+ mut sp : Span ,
725
738
tts : & [ tokenstream:: TokenTree ] ,
726
739
) -> Box < dyn base:: MacResult + ' cx > {
727
740
//if !ecx.ecfg.enable_allow_internal_unstable() {
@@ -784,6 +797,10 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
784
797
return DummyResult :: raw_expr ( sp) ;
785
798
}
786
799
} ;
800
+ let is_literal = match ecx. codemap ( ) . span_to_snippet ( fmt_sp) {
801
+ Ok ( ref s) if s. starts_with ( "\" " ) || s. starts_with ( "r#" ) => true ,
802
+ _ => false ,
803
+ } ;
787
804
788
805
let mut cx = Context {
789
806
ecx,
@@ -806,6 +823,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
806
823
fmtsp : fmt. span ,
807
824
invalid_refs : Vec :: new ( ) ,
808
825
arg_spans : Vec :: new ( ) ,
826
+ is_literal,
809
827
} ;
810
828
811
829
let fmt_str = & * fmt. node . 0 . as_str ( ) ;
0 commit comments