about summary refs log tree commit diff
path: root/compiler/rustc_parse_format/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_parse_format/src')
-rw-r--r--compiler/rustc_parse_format/src/lib.rs20
-rw-r--r--compiler/rustc_parse_format/src/tests.rs28
2 files changed, 36 insertions, 12 deletions
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs
index 6e7553f5e49..5deb17b8651 100644
--- a/compiler/rustc_parse_format/src/lib.rs
+++ b/compiler/rustc_parse_format/src/lib.rs
@@ -104,8 +104,8 @@ pub struct FormatSpec<'a> {
 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),
+    /// The argument is located at a specific index given in the format,
+    ArgumentIs(usize, Option<InnerSpan>),
     /// The argument has a name.
     ArgumentNamed(&'a str, InnerSpan),
 }
@@ -113,7 +113,7 @@ pub enum Position<'a> {
 impl Position<'_> {
     pub fn index(&self) -> Option<usize> {
         match self {
-            ArgumentIs(i) | ArgumentImplicitlyIs(i) => Some(*i),
+            ArgumentIs(i, ..) | ArgumentImplicitlyIs(i) => Some(*i),
             _ => None,
         }
     }
@@ -502,8 +502,15 @@ 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() {
-            Some(ArgumentIs(i))
+            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))
         } else {
             match self.cur.peek() {
                 Some(&(start, c)) if rustc_lexer::is_id_start(c) => {
@@ -574,6 +581,10 @@ impl<'a> Parser<'a> {
             // no '0' flag and '0$' as the width instead.
             if let Some(end) = self.consume_pos('$') {
                 spec.width = CountIsParam(0);
+
+                if let Some((pos, _)) = self.cur.peek().cloned() {
+                    spec.width_span = Some(self.to_span_index(pos - 2).to(self.to_span_index(pos)));
+                }
                 havewidth = true;
                 spec.width_span = Some(self.to_span_index(end - 1).to(self.to_span_index(end + 1)));
             } else {
@@ -586,6 +597,7 @@ impl<'a> Parser<'a> {
             spec.width = w;
             spec.width_span = sp;
         }
+
         if let Some(start) = self.consume_pos('.') {
             if let Some(end) = self.consume_pos('*') {
                 // Resolve `CountIsNextParam`.
diff --git a/compiler/rustc_parse_format/src/tests.rs b/compiler/rustc_parse_format/src/tests.rs
index 9c305b4996a..a98f816644b 100644
--- a/compiler/rustc_parse_format/src/tests.rs
+++ b/compiler/rustc_parse_format/src/tests.rs
@@ -62,18 +62,30 @@ fn format_nothing() {
 }
 #[test]
 fn format_position() {
-    same("{3}", &[NextArgument(Argument { position: ArgumentIs(3), format: fmtdflt() })]);
+    same(
+        "{3}",
+        &[NextArgument(Argument {
+            position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })),
+            format: fmtdflt(),
+        })],
+    );
 }
 #[test]
 fn format_position_nothing_else() {
-    same("{3:}", &[NextArgument(Argument { position: ArgumentIs(3), format: fmtdflt() })]);
+    same(
+        "{3:}",
+        &[NextArgument(Argument {
+            position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })),
+            format: fmtdflt(),
+        })],
+    );
 }
 #[test]
 fn format_type() {
     same(
         "{3:x}",
         &[NextArgument(Argument {
-            position: ArgumentIs(3),
+            position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })),
             format: FormatSpec {
                 fill: None,
                 align: AlignUnknown,
@@ -93,7 +105,7 @@ fn format_align_fill() {
     same(
         "{3:>}",
         &[NextArgument(Argument {
-            position: ArgumentIs(3),
+            position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })),
             format: FormatSpec {
                 fill: None,
                 align: AlignRight,
@@ -110,7 +122,7 @@ fn format_align_fill() {
     same(
         "{3:0<}",
         &[NextArgument(Argument {
-            position: ArgumentIs(3),
+            position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })),
             format: FormatSpec {
                 fill: Some('0'),
                 align: AlignLeft,
@@ -127,7 +139,7 @@ fn format_align_fill() {
     same(
         "{3:*<abcd}",
         &[NextArgument(Argument {
-            position: ArgumentIs(3),
+            position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })),
             format: FormatSpec {
                 fill: Some('*'),
                 align: AlignLeft,
@@ -181,7 +193,7 @@ fn format_counts() {
     same(
         "{1:0$.10x}",
         &[NextArgument(Argument {
-            position: ArgumentIs(1),
+            position: ArgumentIs(1, Some(InnerSpan { start: 2, end: 3 })),
             format: FormatSpec {
                 fill: None,
                 align: AlignUnknown,
@@ -291,7 +303,7 @@ fn format_mixture() {
         &[
             String("abcd "),
             NextArgument(Argument {
-                position: ArgumentIs(3),
+                position: ArgumentIs(3, Some(InnerSpan { start: 7, end: 8 })),
                 format: FormatSpec {
                     fill: None,
                     align: AlignUnknown,