@@ -117,6 +117,8 @@ struct Context<'a, 'b: 'a> {
117117 invalid_refs : Vec < ( usize , usize ) > ,
118118 /// Spans of all the formatting arguments, in order.
119119 arg_spans : Vec < Span > ,
120+ /// Wether this formatting string is a literal or it comes from a macro.
121+ is_literal : bool ,
120122}
121123
122124/// Parses the arguments from the given list of tokens, returning None
@@ -276,7 +278,11 @@ impl<'a, 'b> Context<'a, 'b> {
276278 /// format string.
277279 fn report_invalid_references ( & self , numbered_position_args : bool ) {
278280 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+ } ;
280286 let mut refs: Vec < _ > = self
281287 . invalid_refs
282288 . iter ( )
@@ -294,7 +300,7 @@ impl<'a, 'b> Context<'a, 'b> {
294300 ) ,
295301 ) ;
296302 } else {
297- let ( arg_list, sp) = match refs. len ( ) {
303+ let ( arg_list, mut sp) = match refs. len ( ) {
298304 1 => {
299305 let ( reg, pos) = refs. pop ( ) . unwrap ( ) ;
300306 (
@@ -317,11 +323,14 @@ impl<'a, 'b> Context<'a, 'b> {
317323 )
318324 }
319325 } ;
326+ if !self . is_literal {
327+ sp = MultiSpan :: from_span ( self . fmtsp ) ;
328+ }
320329
321330 e = self . ecx . mut_span_err ( sp,
322331 & format ! ( "invalid reference to positional {} ({})" ,
323- arg_list,
324- self . describe_num_args( ) ) ) ;
332+ arg_list,
333+ self . describe_num_args( ) ) ) ;
325334 e. note ( "positional arguments are zero-based" ) ;
326335 } ;
327336
@@ -370,7 +379,11 @@ impl<'a, 'b> Context<'a, 'b> {
370379 Some ( e) => * e,
371380 None => {
372381 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+ } ;
374387 let mut err = self . ecx . struct_span_err ( sp, & msg[ ..] ) ;
375388 err. emit ( ) ;
376389 return ;
@@ -721,7 +734,7 @@ pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt,
721734
722735pub fn expand_format_args_nl < ' cx > (
723736 ecx : & ' cx mut ExtCtxt ,
724- mut sp : Span ,
737+ mut sp : Span ,
725738 tts : & [ tokenstream:: TokenTree ] ,
726739) -> Box < dyn base:: MacResult + ' cx > {
727740 //if !ecx.ecfg.enable_allow_internal_unstable() {
@@ -784,6 +797,10 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
784797 return DummyResult :: raw_expr ( sp) ;
785798 }
786799 } ;
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+ } ;
787804
788805 let mut cx = Context {
789806 ecx,
@@ -806,6 +823,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
806823 fmtsp : fmt. span ,
807824 invalid_refs : Vec :: new ( ) ,
808825 arg_spans : Vec :: new ( ) ,
826+ is_literal,
809827 } ;
810828
811829 let fmt_str = & * fmt. node . 0 . as_str ( ) ;
0 commit comments