Only point at inside of string literals if they're actually string literals
This commit is contained in:
@@ -117,6 +117,8 @@ struct Context<'a, 'b: 'a> {
|
|||||||
invalid_refs: Vec<(usize, usize)>,
|
invalid_refs: Vec<(usize, usize)>,
|
||||||
/// Spans of all the formatting arguments, in order.
|
/// Spans of all the formatting arguments, in order.
|
||||||
arg_spans: Vec<Span>,
|
arg_spans: Vec<Span>,
|
||||||
|
/// Wether this formatting string is a literal or it comes from a macro.
|
||||||
|
is_literal: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses the arguments from the given list of tokens, returning None
|
/// Parses the arguments from the given list of tokens, returning None
|
||||||
@@ -276,7 +278,11 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||||||
/// format string.
|
/// format string.
|
||||||
fn report_invalid_references(&self, numbered_position_args: bool) {
|
fn report_invalid_references(&self, numbered_position_args: bool) {
|
||||||
let mut e;
|
let mut e;
|
||||||
let sp = MultiSpan::from_spans(self.arg_spans.clone());
|
let sp = if self.is_literal {
|
||||||
|
MultiSpan::from_spans(self.arg_spans.clone())
|
||||||
|
} else {
|
||||||
|
MultiSpan::from_span(self.fmtsp)
|
||||||
|
};
|
||||||
let mut refs: Vec<_> = self
|
let mut refs: Vec<_> = self
|
||||||
.invalid_refs
|
.invalid_refs
|
||||||
.iter()
|
.iter()
|
||||||
@@ -294,7 +300,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
let (arg_list, sp) = match refs.len() {
|
let (arg_list, mut sp) = match refs.len() {
|
||||||
1 => {
|
1 => {
|
||||||
let (reg, pos) = refs.pop().unwrap();
|
let (reg, pos) = refs.pop().unwrap();
|
||||||
(
|
(
|
||||||
@@ -317,11 +323,14 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
if !self.is_literal {
|
||||||
|
sp = MultiSpan::from_span(self.fmtsp);
|
||||||
|
}
|
||||||
|
|
||||||
e = self.ecx.mut_span_err(sp,
|
e = self.ecx.mut_span_err(sp,
|
||||||
&format!("invalid reference to positional {} ({})",
|
&format!("invalid reference to positional {} ({})",
|
||||||
arg_list,
|
arg_list,
|
||||||
self.describe_num_args()));
|
self.describe_num_args()));
|
||||||
e.note("positional arguments are zero-based");
|
e.note("positional arguments are zero-based");
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -370,7 +379,11 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||||||
Some(e) => *e,
|
Some(e) => *e,
|
||||||
None => {
|
None => {
|
||||||
let msg = format!("there is no argument named `{}`", name);
|
let msg = format!("there is no argument named `{}`", name);
|
||||||
let sp = *self.arg_spans.get(self.curpiece).unwrap_or(&self.fmtsp);
|
let sp = if self.is_literal {
|
||||||
|
*self.arg_spans.get(self.curpiece).unwrap_or(&self.fmtsp)
|
||||||
|
} else {
|
||||||
|
self.fmtsp
|
||||||
|
};
|
||||||
let mut err = self.ecx.struct_span_err(sp, &msg[..]);
|
let mut err = self.ecx.struct_span_err(sp, &msg[..]);
|
||||||
err.emit();
|
err.emit();
|
||||||
return;
|
return;
|
||||||
@@ -721,7 +734,7 @@ pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt,
|
|||||||
|
|
||||||
pub fn expand_format_args_nl<'cx>(
|
pub fn expand_format_args_nl<'cx>(
|
||||||
ecx: &'cx mut ExtCtxt,
|
ecx: &'cx mut ExtCtxt,
|
||||||
mut sp: Span,
|
mut sp: Span,
|
||||||
tts: &[tokenstream::TokenTree],
|
tts: &[tokenstream::TokenTree],
|
||||||
) -> Box<dyn base::MacResult + 'cx> {
|
) -> Box<dyn base::MacResult + 'cx> {
|
||||||
//if !ecx.ecfg.enable_allow_internal_unstable() {
|
//if !ecx.ecfg.enable_allow_internal_unstable() {
|
||||||
@@ -784,6 +797,10 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
|
|||||||
return DummyResult::raw_expr(sp);
|
return DummyResult::raw_expr(sp);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let is_literal = match ecx.codemap().span_to_snippet(fmt_sp) {
|
||||||
|
Ok(ref s) if s.starts_with("\"") || s.starts_with("r#") => true,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
let mut cx = Context {
|
let mut cx = Context {
|
||||||
ecx,
|
ecx,
|
||||||
@@ -806,6 +823,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
|
|||||||
fmtsp: fmt.span,
|
fmtsp: fmt.span,
|
||||||
invalid_refs: Vec::new(),
|
invalid_refs: Vec::new(),
|
||||||
arg_spans: Vec::new(),
|
arg_spans: Vec::new(),
|
||||||
|
is_literal,
|
||||||
};
|
};
|
||||||
|
|
||||||
let fmt_str = &*fmt.node.0.as_str();
|
let fmt_str = &*fmt.node.0.as_str();
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
error: 1 positional argument in format string, but no arguments were given
|
error: 1 positional argument in format string, but no arguments were given
|
||||||
--> $DIR/macro-backtrace-println.rs:24:31
|
--> $DIR/macro-backtrace-println.rs:24:30
|
||||||
|
|
|
|
||||||
LL | ($fmt:expr) => (myprint!(concat!($fmt, "/n"))); //~ ERROR no arguments were given
|
LL | ($fmt:expr) => (myprint!(concat!($fmt, "/n"))); //~ ERROR no arguments were given
|
||||||
| ^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
...
|
...
|
||||||
LL | myprintln!("{}");
|
LL | myprintln!("{}");
|
||||||
| ----------------- in this macro invocation
|
| ----------------- in this macro invocation
|
||||||
|
|||||||
Reference in New Issue
Block a user