diff options
| author | Alex Macleod <alex@macleod.io> | 2022-07-31 15:11:00 +0000 |
|---|---|---|
| committer | Alex Macleod <alex@macleod.io> | 2022-07-31 15:11:33 +0000 |
| commit | 2a0b51d852e3765d257284f91fc3246084c96ee5 (patch) | |
| tree | 07555af30e2578d89e2798dc261691868be2a017 /compiler/rustc_parse_format | |
| parent | 482153bc208df5fc236cc0e1cddb24e93fcc332f (diff) | |
| download | rust-2a0b51d852e3765d257284f91fc3246084c96ee5.tar.gz rust-2a0b51d852e3765d257284f91fc3246084c96ee5.zip | |
Always include a position span in rustc_parse_format::Argument
Diffstat (limited to 'compiler/rustc_parse_format')
| -rw-r--r-- | compiler/rustc_parse_format/src/lib.rs | 40 | ||||
| -rw-r--r-- | compiler/rustc_parse_format/src/tests.rs | 70 |
2 files changed, 81 insertions, 29 deletions
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 5deb17b8651..a7ff9711691 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -70,6 +70,9 @@ pub enum Piece<'a> { pub struct Argument<'a> { /// Where to find this argument pub position: Position<'a>, + /// The span of the position indicator. Includes any whitespace in implicit + /// positions (`{ }`). + pub position_span: InnerSpan, /// How to format the argument pub format: FormatSpec<'a>, } @@ -105,9 +108,9 @@ pub enum Position<'a> { /// The argument is implied to be located at an index ArgumentImplicitlyIs(usize), /// The argument is located at a specific index given in the format, - ArgumentIs(usize, Option<InnerSpan>), + ArgumentIs(usize), /// The argument has a name. - ArgumentNamed(&'a str, InnerSpan), + ArgumentNamed(&'a str), } impl Position<'_> { @@ -216,14 +219,15 @@ impl<'a> Iterator for Parser<'a> { '{' => { let curr_last_brace = self.last_opening_brace; let byte_pos = self.to_span_index(pos); - self.last_opening_brace = Some(byte_pos.to(InnerOffset(byte_pos.0 + 1))); + let lbrace_end = InnerOffset(byte_pos.0 + 1); + self.last_opening_brace = Some(byte_pos.to(lbrace_end)); self.cur.next(); if self.consume('{') { self.last_opening_brace = curr_last_brace; Some(String(self.string(pos + 1))) } else { - let arg = self.argument(); + let arg = self.argument(lbrace_end); if let Some(rbrace_byte_idx) = self.must_consume('}') { let lbrace_inner_offset = self.to_span_index(pos); let rbrace_inner_offset = self.to_span_index(rbrace_byte_idx); @@ -477,8 +481,16 @@ impl<'a> Parser<'a> { } /// Parses an `Argument` structure, or what's contained within braces inside the format string. - fn argument(&mut self) -> Argument<'a> { + fn argument(&mut self, start: InnerOffset) -> Argument<'a> { let pos = self.position(); + + let end = self + .cur + .clone() + .find(|(_, ch)| !ch.is_whitespace()) + .map_or(start, |(end, _)| self.to_span_index(end)); + let position_span = start.to(end); + let format = match self.mode { ParseMode::Format => self.format(), ParseMode::InlineAsm => self.inline_asm(), @@ -494,7 +506,7 @@ impl<'a> Parser<'a> { } }; - Argument { position: pos, format } + Argument { position: pos, position_span, format } } /// Parses a positional argument for a format. This could either be an @@ -502,23 +514,11 @@ impl<'a> Parser<'a> { /// Returns `Some(parsed_position)` if the position is not implicitly /// consuming a macro argument, `None` if it's the case. fn position(&mut self) -> Option<Position<'a>> { - let start_position = self.cur.peek().map(|item| item.0); if let Some(i) = self.integer() { - let inner_span = start_position.and_then(|start| { - self.cur - .peek() - .cloned() - .and_then(|item| Some(self.to_span_index(start).to(self.to_span_index(item.0)))) - }); - Some(ArgumentIs(i, inner_span)) + Some(ArgumentIs(i)) } else { match self.cur.peek() { - Some(&(start, c)) if rustc_lexer::is_id_start(c) => { - let word = self.word(); - let end = start + word.len(); - let span = self.to_span_index(start).to(self.to_span_index(end)); - Some(ArgumentNamed(word, span)) - } + Some(&(_, c)) if rustc_lexer::is_id_start(c) => Some(ArgumentNamed(self.word())), // This is an `ArgumentNext`. // Record the fact and do the resolution after parsing the diff --git a/compiler/rustc_parse_format/src/tests.rs b/compiler/rustc_parse_format/src/tests.rs index a98f816644b..57853069610 100644 --- a/compiler/rustc_parse_format/src/tests.rs +++ b/compiler/rustc_parse_format/src/tests.rs @@ -58,14 +58,22 @@ fn invalid06() { #[test] fn format_nothing() { - same("{}", &[NextArgument(Argument { position: ArgumentImplicitlyIs(0), format: fmtdflt() })]); + same( + "{}", + &[NextArgument(Argument { + position: ArgumentImplicitlyIs(0), + position_span: InnerSpan { start: 2, end: 2 }, + format: fmtdflt(), + })], + ); } #[test] fn format_position() { same( "{3}", &[NextArgument(Argument { - position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })), + position: ArgumentIs(3), + position_span: InnerSpan { start: 2, end: 3 }, format: fmtdflt(), })], ); @@ -75,17 +83,30 @@ fn format_position_nothing_else() { same( "{3:}", &[NextArgument(Argument { - position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })), + position: ArgumentIs(3), + position_span: InnerSpan { start: 2, end: 3 }, format: fmtdflt(), })], ); } #[test] +fn format_named() { + same( + "{name}", + &[NextArgument(Argument { + position: ArgumentNamed("name"), + position_span: InnerSpan { start: 2, end: 6 }, + format: fmtdflt(), + })], + ) +} +#[test] fn format_type() { same( "{3:x}", &[NextArgument(Argument { - position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })), + position: ArgumentIs(3), + position_span: InnerSpan { start: 2, end: 3 }, format: FormatSpec { fill: None, align: AlignUnknown, @@ -105,7 +126,8 @@ fn format_align_fill() { same( "{3:>}", &[NextArgument(Argument { - position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })), + position: ArgumentIs(3), + position_span: InnerSpan { start: 2, end: 3 }, format: FormatSpec { fill: None, align: AlignRight, @@ -122,7 +144,8 @@ fn format_align_fill() { same( "{3:0<}", &[NextArgument(Argument { - position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })), + position: ArgumentIs(3), + position_span: InnerSpan { start: 2, end: 3 }, format: FormatSpec { fill: Some('0'), align: AlignLeft, @@ -139,7 +162,8 @@ fn format_align_fill() { same( "{3:*<abcd}", &[NextArgument(Argument { - position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })), + position: ArgumentIs(3), + position_span: InnerSpan { start: 2, end: 3 }, format: FormatSpec { fill: Some('*'), align: AlignLeft, @@ -160,6 +184,7 @@ fn format_counts() { "{:10x}", &[NextArgument(Argument { position: ArgumentImplicitlyIs(0), + position_span: InnerSpan { start: 2, end: 2 }, format: FormatSpec { fill: None, align: AlignUnknown, @@ -177,6 +202,7 @@ fn format_counts() { "{:10$.10x}", &[NextArgument(Argument { position: ArgumentImplicitlyIs(0), + position_span: InnerSpan { start: 2, end: 2 }, format: FormatSpec { fill: None, align: AlignUnknown, @@ -193,7 +219,8 @@ fn format_counts() { same( "{1:0$.10x}", &[NextArgument(Argument { - position: ArgumentIs(1, Some(InnerSpan { start: 2, end: 3 })), + position: ArgumentIs(1), + position_span: InnerSpan { start: 2, end: 3 }, format: FormatSpec { fill: None, align: AlignUnknown, @@ -211,6 +238,7 @@ fn format_counts() { "{:.*x}", &[NextArgument(Argument { position: ArgumentImplicitlyIs(1), + position_span: InnerSpan { start: 2, end: 2 }, format: FormatSpec { fill: None, align: AlignUnknown, @@ -228,6 +256,7 @@ fn format_counts() { "{:.10$x}", &[NextArgument(Argument { position: ArgumentImplicitlyIs(0), + position_span: InnerSpan { start: 2, end: 2 }, format: FormatSpec { fill: None, align: AlignUnknown, @@ -245,6 +274,7 @@ fn format_counts() { "{:a$.b$?}", &[NextArgument(Argument { position: ArgumentImplicitlyIs(0), + position_span: InnerSpan { start: 2, end: 2 }, format: FormatSpec { fill: None, align: AlignUnknown, @@ -265,6 +295,7 @@ fn format_flags() { "{:-}", &[NextArgument(Argument { position: ArgumentImplicitlyIs(0), + position_span: InnerSpan { start: 2, end: 2 }, format: FormatSpec { fill: None, align: AlignUnknown, @@ -282,6 +313,7 @@ fn format_flags() { "{:+#}", &[NextArgument(Argument { position: ArgumentImplicitlyIs(0), + position_span: InnerSpan { start: 2, end: 2 }, format: FormatSpec { fill: None, align: AlignUnknown, @@ -303,7 +335,8 @@ fn format_mixture() { &[ String("abcd "), NextArgument(Argument { - position: ArgumentIs(3, Some(InnerSpan { start: 7, end: 8 })), + position: ArgumentIs(3), + position_span: InnerSpan { start: 7, end: 8 }, format: FormatSpec { fill: None, align: AlignUnknown, @@ -320,3 +353,22 @@ fn format_mixture() { ], ); } +#[test] +fn format_whitespace() { + same( + "{ }", + &[NextArgument(Argument { + position: ArgumentImplicitlyIs(0), + position_span: InnerSpan { start: 2, end: 3 }, + format: fmtdflt(), + })], + ); + same( + "{ }", + &[NextArgument(Argument { + position: ArgumentImplicitlyIs(0), + position_span: InnerSpan { start: 2, end: 4 }, + format: fmtdflt(), + })], + ); +} |
