From ce3bd29c68a4fa78b95de7b98241726e5ba4f5e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 14 Jul 2020 10:35:59 -0700 Subject: [PATCH] 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. --- src/librustc_parse/parser/stmt.rs | 14 +++++-- src/test/ui/issues/issue-34334.rs | 7 +--- src/test/ui/issues/issue-34334.stderr | 54 +++++---------------------- 3 files changed, 20 insertions(+), 55 deletions(-) diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs index 53f32b7c800bd..d04920de47f09 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 afe4d42edd8c8..97905e2f8fa43 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 5f157f6e3c089..364f8264db463 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` + | + = 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`.