Skip to content

Commit c55a698

Browse files
committed
Only point at inside of string literals if they're actually string literals
1 parent 6bcf877 commit c55a698

File tree

2 files changed

+26
-8
lines changed

2 files changed

+26
-8
lines changed

src/libsyntax_ext/format.rs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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

722735
pub 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();

src/test/ui/macros/macro-backtrace-println.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error: 1 positional argument in format string, but no arguments were given
2-
--> $DIR/macro-backtrace-println.rs:24:31
2+
--> $DIR/macro-backtrace-println.rs:24:30
33
|
44
LL | ($fmt:expr) => (myprint!(concat!($fmt, "/n"))); //~ ERROR no arguments were given
5-
| ^^
5+
| ^^^^^^^^^^^^^^^^^^^
66
...
77
LL | myprintln!("{}");
88
| ----------------- in this macro invocation

0 commit comments

Comments
 (0)