Skip to content

Commit 4230659

Browse files
author
Esteban Küber
committed
Point at incorrect named arg in format string
1 parent 38abca8 commit 4230659

File tree

2 files changed

+27
-10
lines changed

2 files changed

+27
-10
lines changed

src/libsyntax_ext/format.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,10 @@ struct Context<'a, 'b: 'a> {
111111
/// still existed in this phase of processing.
112112
/// Used only for `all_pieces_simple` tracking in `build_piece`.
113113
curarg: usize,
114+
curpiece: usize,
114115
/// Keep track of invalid references to positional arguments
115116
invalid_refs: Vec<usize>,
117+
arg_spans: Vec<Span>,
116118
}
117119

118120
/// Parses the arguments from the given list of tokens, returning None
@@ -235,6 +237,7 @@ impl<'a, 'b> Context<'a, 'b> {
235237

236238
let ty = Placeholder(arg.format.ty.to_string());
237239
self.verify_arg_type(pos, ty);
240+
self.curpiece += 1;
238241
}
239242
}
240243
}
@@ -347,7 +350,9 @@ impl<'a, 'b> Context<'a, 'b> {
347350
Some(e) => *e,
348351
None => {
349352
let msg = format!("there is no argument named `{}`", name);
350-
self.ecx.span_err(self.fmtsp, &msg[..]);
353+
let sp = *self.arg_spans.get(self.curpiece).unwrap_or(&self.fmtsp);
354+
let mut err = self.ecx.struct_span_err(sp, &msg[..]);
355+
err.emit();
351356
return;
352357
}
353358
};
@@ -773,6 +778,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
773778
arg_unique_types,
774779
names,
775780
curarg: 0,
781+
curpiece: 0,
776782
arg_index_map: Vec::new(),
777783
count_args: Vec::new(),
778784
count_positions: HashMap::new(),
@@ -785,6 +791,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
785791
macsp,
786792
fmtsp: fmt.span,
787793
invalid_refs: Vec::new(),
794+
arg_spans: Vec::new(),
788795
};
789796

790797
let fmt_str = &*fmt.node.0.as_str();
@@ -793,12 +800,22 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
793800
ast::StrStyle::Raw(raw) => Some(raw as usize),
794801
};
795802
let mut parser = parse::Parser::new(fmt_str, str_style);
803+
let mut unverified_pieces = vec![];
796804
let mut pieces = vec![];
797805

798-
while let Some(mut piece) = parser.next() {
806+
while let Some(piece) = parser.next() {
799807
if !parser.errors.is_empty() {
800808
break;
801809
}
810+
unverified_pieces.push(piece);
811+
}
812+
813+
cx.arg_spans = parser.arg_places.iter()
814+
.map(|&(start, end)| fmt.span.from_inner_byte_pos(start, end))
815+
.collect();
816+
817+
// This needs to happen *after* the Parser has consumed all pieces to create all the spans
818+
for mut piece in unverified_pieces {
802819
cx.verify_piece(&piece);
803820
cx.resolve_name_inplace(&mut piece);
804821
pieces.push(piece);

src/test/ui/ifmt-bad-arg.stderr

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,22 +57,22 @@ LL | format!("{name} {value} {} {} {} {} {} {}", 0, name=1, value=2);
5757
= note: positional arguments are zero-based
5858

5959
error: there is no argument named `foo`
60-
--> $DIR/ifmt-bad-arg.rs:37:13
60+
--> $DIR/ifmt-bad-arg.rs:37:17
6161
|
6262
LL | format!("{} {foo} {} {bar} {}", 1, 2, 3);
63-
| ^^^^^^^^^^^^^^^^^^^^^^
63+
| ^^^^^
6464

6565
error: there is no argument named `bar`
66-
--> $DIR/ifmt-bad-arg.rs:37:13
66+
--> $DIR/ifmt-bad-arg.rs:37:26
6767
|
6868
LL | format!("{} {foo} {} {bar} {}", 1, 2, 3);
69-
| ^^^^^^^^^^^^^^^^^^^^^^
69+
| ^^^^^
7070

7171
error: there is no argument named `foo`
72-
--> $DIR/ifmt-bad-arg.rs:41:13
72+
--> $DIR/ifmt-bad-arg.rs:41:14
7373
|
7474
LL | format!("{foo}"); //~ ERROR: no argument named `foo`
75-
| ^^^^^^^
75+
| ^^^^^
7676

7777
error: multiple unused formatting arguments
7878
--> $DIR/ifmt-bad-arg.rs:42:17
@@ -139,10 +139,10 @@ LL | format!("", foo=1, 2); //~ ERROR: positional arguments cannot
139139
| ^
140140

141141
error: there is no argument named `valueb`
142-
--> $DIR/ifmt-bad-arg.rs:55:13
142+
--> $DIR/ifmt-bad-arg.rs:55:23
143143
|
144144
LL | format!("{valuea} {valueb}", valuea=5, valuec=7);
145-
| ^^^^^^^^^^^^^^^^^^^
145+
| ^^^^^^^^
146146

147147
error: named argument never used
148148
--> $DIR/ifmt-bad-arg.rs:55:51

0 commit comments

Comments
 (0)