Point at correct span for arguments in format strings

When a format string has escaped whitespace characters format
arguments were shifted by one per each escaped character. Account
for these escaped characters when synthesizing the spans.

Fix #55155.
This commit is contained in:
Esteban Küber 2018-12-26 20:05:56 -08:00
parent a1bad57fa5
commit 5e75001c59
4 changed files with 15 additions and 6 deletions

View File

@ -144,7 +144,7 @@ pub struct Parser<'a> {
/// `Some(raw count)` when the string is "raw", used to position spans correctly
style: Option<usize>,
/// Start and end byte offset of every successfully parsed argument
pub arg_places: Vec<(usize, usize)>,
pub arg_places: Vec<(SpanIndex, SpanIndex)>,
/// Characters that need to be shifted
skips: Vec<usize>,
/// Span offset of the last opening brace seen, used for error reporting
@ -154,7 +154,7 @@ pub struct Parser<'a> {
}
#[derive(Clone, Copy, Debug)]
pub struct SpanIndex(usize);
pub struct SpanIndex(pub usize);
impl SpanIndex {
pub fn unwrap(self) -> usize {
@ -166,7 +166,6 @@ impl<'a> Iterator for Parser<'a> {
type Item = Piece<'a>;
fn next(&mut self) -> Option<Piece<'a>> {
let raw = self.raw();
if let Some(&(pos, c)) = self.cur.peek() {
match c {
'{' => {
@ -180,7 +179,7 @@ fn next(&mut self) -> Option<Piece<'a>> {
} else {
let arg = self.argument();
if let Some(arg_pos) = self.must_consume('}').map(|end| {
(pos + raw + 1, end + raw + 2)
(self.to_span_index(pos), self.to_span_index(end + 1))
}) {
self.arg_places.push(arg_pos);
}

View File

@ -861,7 +861,9 @@ fn find_skips(snippet: &str, is_raw: bool) -> Vec<usize> {
}
let arg_spans = parser.arg_places.iter()
.map(|&(start, end)| fmt.span.from_inner_byte_pos(start, end))
.map(|&(parse::SpanIndex(start), parse::SpanIndex(end))| {
fmt.span.from_inner_byte_pos(start, end)
})
.collect();
let mut cx = Context {

View File

@ -67,4 +67,6 @@ fn main() {
asdf}
", asdf=1);
//~^^ ERROR invalid format string
println!("\t{}");
//~^ ERROR 1 positional argument in format string
}

View File

@ -133,5 +133,11 @@ LL | asdf}
|
= note: if you intended to print `{`, you can escape it using `{{`
error: aborting due to 13 previous errors
error: 1 positional argument in format string, but no arguments were given
--> $DIR/format-string-error-2.rs:70:17
|
LL | println!("/t{}");
| ^^
error: aborting due to 14 previous errors