about summary refs log tree commit diff
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2020-07-15 11:01:26 -0700
committerGitHub <noreply@github.com>2020-07-15 11:01:26 -0700
commitf4bbd0e607d3f302342b835999105d4a2ad4025d (patch)
tree67b9a7de2c75e5ca3140ada8fdec0b04a44a068a
parent64a27880de6dc7362cb5453807859324d9ce34b7 (diff)
parentce3bd29c68a4fa78b95de7b98241726e5ba4f5e3 (diff)
downloadrust-f4bbd0e607d3f302342b835999105d4a2ad4025d.tar.gz
rust-f4bbd0e607d3f302342b835999105d4a2ad4025d.zip
Rollup merge of #74337 - estebank:ty-parse-recovery, r=varkor
Handle case of incomplete local ty more gracefully

When encountering a local binding with a type that isn't completed, the
parser will reach a `=` token. When this happen, consider the type
"complete" as far as the parser is concerned to avoid further errors
being emitted by parse recovery logic.
-rw-r--r--src/librustc_parse/parser/stmt.rs14
-rw-r--r--src/test/ui/issues/issue-34334.rs7
-rw-r--r--src/test/ui/issues/issue-34334.stderr54
3 files changed, 20 insertions, 55 deletions
diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs
index 53f32b7c800..d04920de47f 100644
--- a/src/librustc_parse/parser/stmt.rs
+++ b/src/librustc_parse/parser/stmt.rs
@@ -162,13 +162,19 @@ impl<'a> Parser<'a> {
             match self.parse_ty() {
                 Ok(ty) => (None, Some(ty)),
                 Err(mut err) => {
-                    // Rewind to before attempting to parse the type and continue parsing.
-                    let parser_snapshot_after_type =
-                        mem::replace(self, parser_snapshot_before_type);
                     if let Ok(snip) = self.span_to_snippet(pat.span) {
                         err.span_label(pat.span, format!("while parsing the type for `{}`", snip));
                     }
-                    (Some((parser_snapshot_after_type, colon_sp, err)), None)
+                    let err = if self.check(&token::Eq) {
+                        err.emit();
+                        None
+                    } else {
+                        // Rewind to before attempting to parse the type and continue parsing.
+                        let parser_snapshot_after_type =
+                            mem::replace(self, parser_snapshot_before_type);
+                        Some((parser_snapshot_after_type, colon_sp, err))
+                    };
+                    (err, None)
                 }
             }
         } else {
diff --git a/src/test/ui/issues/issue-34334.rs b/src/test/ui/issues/issue-34334.rs
index afe4d42edd8..97905e2f8fa 100644
--- a/src/test/ui/issues/issue-34334.rs
+++ b/src/test/ui/issues/issue-34334.rs
@@ -1,11 +1,6 @@
 fn main () {
     let sr: Vec<(u32, _, _) = vec![];
     //~^ ERROR expected one of `,` or `>`, found `=`
-    //~| ERROR expected value, found struct `Vec`
-    //~| ERROR mismatched types
-    //~| ERROR invalid left-hand side of assignment
-    //~| ERROR expected expression, found reserved identifier `_`
-    //~| ERROR expected expression, found reserved identifier `_`
     let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect();
-    //~^ ERROR no method named `iter` found
+    //~^ ERROR a value of type `std::vec::Vec<(u32, _, _)>` cannot be built
 }
diff --git a/src/test/ui/issues/issue-34334.stderr b/src/test/ui/issues/issue-34334.stderr
index 5f157f6e3c0..364f8264db4 100644
--- a/src/test/ui/issues/issue-34334.stderr
+++ b/src/test/ui/issues/issue-34334.stderr
@@ -1,55 +1,19 @@
-error: expected expression, found reserved identifier `_`
-  --> $DIR/issue-34334.rs:2:23
-   |
-LL |     let sr: Vec<(u32, _, _) = vec![];
-   |                       ^ expected expression
-
-error: expected expression, found reserved identifier `_`
-  --> $DIR/issue-34334.rs:2:26
-   |
-LL |     let sr: Vec<(u32, _, _) = vec![];
-   |                          ^ expected expression
-
 error: expected one of `,` or `>`, found `=`
   --> $DIR/issue-34334.rs:2:29
    |
 LL |     let sr: Vec<(u32, _, _) = vec![];
-   |         ---                 ^ expected one of `,` or `>`
-   |         | |
-   |         | help: use `=` if you meant to assign
+   |         --                  ^ expected one of `,` or `>`
+   |         |
    |         while parsing the type for `sr`
 
-error[E0423]: expected value, found struct `Vec`
-  --> $DIR/issue-34334.rs:2:13
-   |
-LL |     let sr: Vec<(u32, _, _) = vec![];
-   |             ^^^ help: use struct literal syntax instead: `Vec { buf: val, len: val }`
-
-error[E0308]: mismatched types
-  --> $DIR/issue-34334.rs:2:31
-   |
-LL |     let sr: Vec<(u32, _, _) = vec![];
-   |                               ^^^^^^ expected `bool`, found struct `std::vec::Vec`
-   |
-   = note: expected type `bool`
-            found struct `std::vec::Vec<_>`
-   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error[E0070]: invalid left-hand side of assignment
-  --> $DIR/issue-34334.rs:2:29
-   |
-LL |     let sr: Vec<(u32, _, _) = vec![];
-   |             --------------- ^
-   |             |
-   |             cannot assign to this expression
-
-error[E0599]: no method named `iter` found for unit type `()` in the current scope
-  --> $DIR/issue-34334.rs:9:36
+error[E0277]: a value of type `std::vec::Vec<(u32, _, _)>` cannot be built from an iterator over elements of type `()`
+  --> $DIR/issue-34334.rs:4:87
    |
 LL |     let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect();
-   |                                    ^^^^ method not found in `()`
+   |                                                                                       ^^^^^^^ value of type `std::vec::Vec<(u32, _, _)>` cannot be built from `std::iter::Iterator<Item=()>`
+   |
+   = help: the trait `std::iter::FromIterator<()>` is not implemented for `std::vec::Vec<(u32, _, _)>`
 
-error: aborting due to 7 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0070, E0308, E0423, E0599.
-For more information about an error, try `rustc --explain E0070`.
+For more information about this error, try `rustc --explain E0277`.