about summary refs log tree commit diff
path: root/compiler/rustc_parse_format
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_parse_format')
-rw-r--r--compiler/rustc_parse_format/src/lib.rs48
1 files changed, 41 insertions, 7 deletions
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs
index a7ff9711691..4d8bd20aa36 100644
--- a/compiler/rustc_parse_format/src/lib.rs
+++ b/compiler/rustc_parse_format/src/lib.rs
@@ -175,6 +175,7 @@ pub struct ParseError {
     pub label: string::String,
     pub span: InnerSpan,
     pub secondary_label: Option<(string::String, InnerSpan)>,
+    pub should_be_replaced_with_positional_argument: bool,
 }
 
 /// The parser structure for interpreting the input format string. This is
@@ -228,13 +229,19 @@ impl<'a> Iterator for Parser<'a> {
                         Some(String(self.string(pos + 1)))
                     } else {
                         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);
-                            if self.is_literal {
-                                self.arg_places.push(
-                                    lbrace_inner_offset.to(InnerOffset(rbrace_inner_offset.0 + 1)),
-                                );
+                        match self.must_consume('}') {
+                            Some(rbrace_byte_idx) => {
+                                let lbrace_inner_offset = self.to_span_index(pos);
+                                let rbrace_inner_offset = self.to_span_index(rbrace_byte_idx);
+                                if self.is_literal {
+                                    self.arg_places.push(
+                                        lbrace_inner_offset
+                                            .to(InnerOffset(rbrace_inner_offset.0 + 1)),
+                                    );
+                                }
+                            }
+                            None => {
+                                self.suggest_positional_arg_instead_of_captured_arg(arg);
                             }
                         }
                         Some(NextArgument(arg))
@@ -313,6 +320,7 @@ impl<'a> Parser<'a> {
             label: label.into(),
             span,
             secondary_label: None,
+            should_be_replaced_with_positional_argument: false,
         });
     }
 
@@ -336,6 +344,7 @@ impl<'a> Parser<'a> {
             label: label.into(),
             span,
             secondary_label: None,
+            should_be_replaced_with_positional_argument: false,
         });
     }
 
@@ -407,6 +416,7 @@ impl<'a> Parser<'a> {
                     label,
                     span: pos.to(pos),
                     secondary_label,
+                    should_be_replaced_with_positional_argument: false,
                 });
                 None
             }
@@ -434,6 +444,7 @@ impl<'a> Parser<'a> {
                     label,
                     span: pos.to(pos),
                     secondary_label,
+                    should_be_replaced_with_positional_argument: false,
                 });
             } else {
                 self.err(description, format!("expected `{:?}`", c), pos.to(pos));
@@ -750,6 +761,29 @@ impl<'a> Parser<'a> {
         }
         if found { Some(cur) } else { None }
     }
+
+    fn suggest_positional_arg_instead_of_captured_arg(&mut self, arg: Argument<'a>) {
+        if let Some(end) = self.consume_pos('.') {
+            let byte_pos = self.to_span_index(end);
+            let start = InnerOffset(byte_pos.0 + 1);
+            let field = self.argument(start);
+            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,
+                            should_be_replaced_with_positional_argument: true,
+                        },
+                    );
+                }
+            }
+        }
+    }
 }
 
 /// Finds the indices of all characters that have been processed and differ between the actual