1
Fork 0

Point at incorrect named arg in format string

This commit is contained in:
Esteban Küber 2018-07-23 00:01:17 -07:00
parent 38abca8c2d
commit 42306591b9
2 changed files with 27 additions and 10 deletions

View file

@ -111,8 +111,10 @@ struct Context<'a, 'b: 'a> {
/// still existed in this phase of processing.
/// Used only for `all_pieces_simple` tracking in `build_piece`.
curarg: usize,
curpiece: usize,
/// Keep track of invalid references to positional arguments
invalid_refs: Vec<usize>,
arg_spans: Vec<Span>,
}
/// Parses the arguments from the given list of tokens, returning None
@ -235,6 +237,7 @@ impl<'a, 'b> Context<'a, 'b> {
let ty = Placeholder(arg.format.ty.to_string());
self.verify_arg_type(pos, ty);
self.curpiece += 1;
}
}
}
@ -347,7 +350,9 @@ impl<'a, 'b> Context<'a, 'b> {
Some(e) => *e,
None => {
let msg = format!("there is no argument named `{}`", name);
self.ecx.span_err(self.fmtsp, &msg[..]);
let sp = *self.arg_spans.get(self.curpiece).unwrap_or(&self.fmtsp);
let mut err = self.ecx.struct_span_err(sp, &msg[..]);
err.emit();
return;
}
};
@ -773,6 +778,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
arg_unique_types,
names,
curarg: 0,
curpiece: 0,
arg_index_map: Vec::new(),
count_args: Vec::new(),
count_positions: HashMap::new(),
@ -785,6 +791,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
macsp,
fmtsp: fmt.span,
invalid_refs: Vec::new(),
arg_spans: Vec::new(),
};
let fmt_str = &*fmt.node.0.as_str();
@ -793,12 +800,22 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
ast::StrStyle::Raw(raw) => Some(raw as usize),
};
let mut parser = parse::Parser::new(fmt_str, str_style);
let mut unverified_pieces = vec![];
let mut pieces = vec![];
while let Some(mut piece) = parser.next() {
while let Some(piece) = parser.next() {
if !parser.errors.is_empty() {
break;
}
unverified_pieces.push(piece);
}
cx.arg_spans = parser.arg_places.iter()
.map(|&(start, end)| fmt.span.from_inner_byte_pos(start, end))
.collect();
// This needs to happen *after* the Parser has consumed all pieces to create all the spans
for mut piece in unverified_pieces {
cx.verify_piece(&piece);
cx.resolve_name_inplace(&mut piece);
pieces.push(piece);

View file

@ -57,22 +57,22 @@ LL | format!("{name} {value} {} {} {} {} {} {}", 0, name=1, value=2);
= note: positional arguments are zero-based
error: there is no argument named `foo`
--> $DIR/ifmt-bad-arg.rs:37:13
--> $DIR/ifmt-bad-arg.rs:37:17
|
LL | format!("{} {foo} {} {bar} {}", 1, 2, 3);
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^
error: there is no argument named `bar`
--> $DIR/ifmt-bad-arg.rs:37:13
--> $DIR/ifmt-bad-arg.rs:37:26
|
LL | format!("{} {foo} {} {bar} {}", 1, 2, 3);
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^
error: there is no argument named `foo`
--> $DIR/ifmt-bad-arg.rs:41:13
--> $DIR/ifmt-bad-arg.rs:41:14
|
LL | format!("{foo}"); //~ ERROR: no argument named `foo`
| ^^^^^^^
| ^^^^^
error: multiple unused formatting arguments
--> $DIR/ifmt-bad-arg.rs:42:17
@ -139,10 +139,10 @@ LL | format!("", foo=1, 2); //~ ERROR: positional arguments cannot
| ^
error: there is no argument named `valueb`
--> $DIR/ifmt-bad-arg.rs:55:13
--> $DIR/ifmt-bad-arg.rs:55:23
|
LL | format!("{valuea} {valueb}", valuea=5, valuec=7);
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^
error: named argument never used
--> $DIR/ifmt-bad-arg.rs:55:51