about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_parse_format/src/lib.rs52
-rw-r--r--tests/ui/fmt/format-args-non-identifier-diagnostics.fixed10
-rw-r--r--tests/ui/fmt/format-args-non-identifier-diagnostics.rs10
-rw-r--r--tests/ui/fmt/format-args-non-identifier-diagnostics.stderr13
4 files changed, 70 insertions, 15 deletions
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs
index 79aab47fbe7..2bb4b09e337 100644
--- a/compiler/rustc_parse_format/src/lib.rs
+++ b/compiler/rustc_parse_format/src/lib.rs
@@ -907,25 +907,47 @@ impl<'a> Parser<'a> {
             let byte_pos = self.to_span_index(end);
             let start = InnerOffset(byte_pos.0 + 1);
             let field = self.argument(start);
-            // We can only parse `foo.bar` field access, any deeper nesting,
-            // or another type of expression, like method calls, are not supported
+            // We can only parse simple `foo.bar` field access or `foo.0` tuple index access, any
+            // deeper nesting, or another type of expression, like method calls, are not supported
             if !self.consume('}') {
                 return;
             }
             if let ArgumentNamed(_) = arg.position {
-                if let ArgumentNamed(_) = field.position {
-                    self.errors.insert(
-                        0,
-                        ParseError {
-                            description: "field access isn't supported".to_string(),
-                            note: None,
-                            label: "not supported".to_string(),
-                            span: InnerSpan::new(arg.position_span.start, field.position_span.end),
-                            secondary_label: None,
-                            suggestion: Suggestion::UsePositional,
-                        },
-                    );
-                }
+                match field.position {
+                    ArgumentNamed(_) => {
+                        self.errors.insert(
+                            0,
+                            ParseError {
+                                description: "field access isn't supported".to_string(),
+                                note: None,
+                                label: "not supported".to_string(),
+                                span: InnerSpan::new(
+                                    arg.position_span.start,
+                                    field.position_span.end,
+                                ),
+                                secondary_label: None,
+                                suggestion: Suggestion::UsePositional,
+                            },
+                        );
+                    }
+                    ArgumentIs(_) => {
+                        self.errors.insert(
+                            0,
+                            ParseError {
+                                description: "tuple index access isn't supported".to_string(),
+                                note: None,
+                                label: "not supported".to_string(),
+                                span: InnerSpan::new(
+                                    arg.position_span.start,
+                                    field.position_span.end,
+                                ),
+                                secondary_label: None,
+                                suggestion: Suggestion::UsePositional,
+                            },
+                        );
+                    }
+                    _ => {}
+                };
             }
         }
     }
diff --git a/tests/ui/fmt/format-args-non-identifier-diagnostics.fixed b/tests/ui/fmt/format-args-non-identifier-diagnostics.fixed
new file mode 100644
index 00000000000..bd4db948067
--- /dev/null
+++ b/tests/ui/fmt/format-args-non-identifier-diagnostics.fixed
@@ -0,0 +1,10 @@
+// Checks that there is a suggestion for simple tuple index access expression (used where an
+// identifier is expected in a format arg) to use positional arg instead.
+// Issue: <https://github.com/rust-lang/rust/issues/122535>.
+//@ run-rustfix
+
+fn main() {
+    let x = (1,);
+    println!("{0}", x.0);
+    //~^ ERROR invalid format string
+}
diff --git a/tests/ui/fmt/format-args-non-identifier-diagnostics.rs b/tests/ui/fmt/format-args-non-identifier-diagnostics.rs
new file mode 100644
index 00000000000..aab705341f7
--- /dev/null
+++ b/tests/ui/fmt/format-args-non-identifier-diagnostics.rs
@@ -0,0 +1,10 @@
+// Checks that there is a suggestion for simple tuple index access expression (used where an
+// identifier is expected in a format arg) to use positional arg instead.
+// Issue: <https://github.com/rust-lang/rust/issues/122535>.
+//@ run-rustfix
+
+fn main() {
+    let x = (1,);
+    println!("{x.0}");
+    //~^ ERROR invalid format string
+}
diff --git a/tests/ui/fmt/format-args-non-identifier-diagnostics.stderr b/tests/ui/fmt/format-args-non-identifier-diagnostics.stderr
new file mode 100644
index 00000000000..08abba2854e
--- /dev/null
+++ b/tests/ui/fmt/format-args-non-identifier-diagnostics.stderr
@@ -0,0 +1,13 @@
+error: invalid format string: tuple index access isn't supported
+  --> $DIR/format-args-non-identifier-diagnostics.rs:8:16
+   |
+LL |     println!("{x.0}");
+   |                ^^^ not supported in format string
+   |
+help: consider using a positional formatting argument instead
+   |
+LL |     println!("{0}", x.0);
+   |                ~  +++++
+
+error: aborting due to 1 previous error
+