From 5b3b6b8d00df27c46d6254c737b40e79bebcced2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 22 Jul 2019 18:29:49 -0700 Subject: [PATCH 1/3] Make the parser TokenStream more resilient after mismatched delimiter recovery --- src/libsyntax/parse/parser.rs | 3 +++ src/test/ui/issues/issue-62881.rs | 6 ++++++ src/test/ui/issues/issue-62881.stderr | 29 +++++++++++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 src/test/ui/issues/issue-62881.rs create mode 100644 src/test/ui/issues/issue-62881.stderr diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 1d4d02c732582..197a9078b1888 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -7670,6 +7670,9 @@ impl<'a> Parser<'a> { let ret = f(self); let last_token = if self.token_cursor.stack.len() == prev { &mut self.token_cursor.frame.last_token + } else if self.token_cursor.stack.is_empty() {//&& !self.unclosed_delims.is_empty() { + // This can happen with mismatched delimiters (#62881) + return Ok((ret?, TokenStream::new(vec![]))); } else { &mut self.token_cursor.stack[prev].last_token }; diff --git a/src/test/ui/issues/issue-62881.rs b/src/test/ui/issues/issue-62881.rs new file mode 100644 index 0000000000000..1782c2e375df5 --- /dev/null +++ b/src/test/ui/issues/issue-62881.rs @@ -0,0 +1,6 @@ +fn main() {} + +fn f() -> isize { fn f() -> isize {} pub f< +//~^ ERROR missing `fn` or `struct` for function or struct definition +//~| ERROR mismatched types +//~ ERROR this file contains an un-closed delimiter diff --git a/src/test/ui/issues/issue-62881.stderr b/src/test/ui/issues/issue-62881.stderr new file mode 100644 index 0000000000000..85c3575fd9288 --- /dev/null +++ b/src/test/ui/issues/issue-62881.stderr @@ -0,0 +1,29 @@ +error: this file contains an un-closed delimiter + --> $DIR/issue-62881.rs:6:53 + | +LL | fn f() -> isize { fn f() -> isize {} pub f< + | - un-closed delimiter +... +LL | + | ^ + +error: missing `fn` or `struct` for function or struct definition + --> $DIR/issue-62881.rs:3:41 + | +LL | fn f() -> isize { fn f() -> isize {} pub f< + | ^ + +error[E0308]: mismatched types + --> $DIR/issue-62881.rs:3:29 + | +LL | fn f() -> isize { fn f() -> isize {} pub f< + | - ^^^^^ expected isize, found () + | | + | this function's body doesn't return + | + = note: expected type `isize` + found type `()` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. From f56c8f6ea426ac24d221b982ff9ee43b77fc9400 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 23 Jul 2019 11:19:13 -0700 Subject: [PATCH 2/3] Fix another case --- src/libsyntax/parse/parser.rs | 15 ++++++-- src/test/ui/issues/issue-62895.rs | 11 ++++++ src/test/ui/issues/issue-62895.stderr | 49 +++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/issues/issue-62895.rs create mode 100644 src/test/ui/issues/issue-62895.stderr diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 197a9078b1888..e494cb472a825 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -7670,8 +7670,9 @@ impl<'a> Parser<'a> { let ret = f(self); let last_token = if self.token_cursor.stack.len() == prev { &mut self.token_cursor.frame.last_token - } else if self.token_cursor.stack.is_empty() {//&& !self.unclosed_delims.is_empty() { - // This can happen with mismatched delimiters (#62881) + } else if self.token_cursor.stack.get(prev).is_none() { + // This can happen due to a bad interaction of two unrelated recovery mechanisms with + // mismatched delimiters *and* recovery lookahead on `pub ident(` likely typo (#62881) return Ok((ret?, TokenStream::new(vec![]))); } else { &mut self.token_cursor.stack[prev].last_token @@ -7680,7 +7681,15 @@ impl<'a> Parser<'a> { // Pull out the tokens that we've collected from the call to `f` above. let mut collected_tokens = match *last_token { LastToken::Collecting(ref mut v) => mem::take(v), - LastToken::Was(_) => panic!("our vector went away?"), + LastToken::Was(ref was) => { + let msg = format!("our vector went away? - found Was({:?})", was); + debug!("collect_tokens: {}", msg); + self.sess.span_diagnostic.delay_span_bug(self.token.span, &msg); + // This can happen due to a bad interaction of two unrelated recovery mechanisms + // with mismatched delimiters *and* recovery lookahead on `pub ident(` likely typo + // (#62895, different but similar to the case above) + return Ok((ret?, TokenStream::new(vec![]))); + } }; // If we're not at EOF our current token wasn't actually consumed by diff --git a/src/test/ui/issues/issue-62895.rs b/src/test/ui/issues/issue-62895.rs new file mode 100644 index 0000000000000..53f17405d79f4 --- /dev/null +++ b/src/test/ui/issues/issue-62895.rs @@ -0,0 +1,11 @@ +fn main() {} + +fn v() -> isize { //~ ERROR mismatched types +mod _ { //~ ERROR expected identifier +pub fn g() -> isizee { //~ ERROR cannot find type `isizee` in this scope +mod _ { //~ ERROR expected identifier +pub g() -> is //~ ERROR missing `fn` for function definition +(), w20); +} +(), w20); //~ ERROR expected item, found `;` +} diff --git a/src/test/ui/issues/issue-62895.stderr b/src/test/ui/issues/issue-62895.stderr new file mode 100644 index 0000000000000..7def7b562ca59 --- /dev/null +++ b/src/test/ui/issues/issue-62895.stderr @@ -0,0 +1,49 @@ +error: expected identifier, found reserved identifier `_` + --> $DIR/issue-62895.rs:4:5 + | +LL | mod _ { + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/issue-62895.rs:6:5 + | +LL | mod _ { + | ^ expected identifier, found reserved identifier + +error: missing `fn` for function definition + --> $DIR/issue-62895.rs:7:4 + | +LL | pub g() -> is + | ^^^^ +help: add `fn` here to parse `g` as a public function + | +LL | pub fn g() -> is + | ^^ + +error: expected item, found `;` + --> $DIR/issue-62895.rs:10:9 + | +LL | (), w20); + | ^ help: remove this semicolon + +error[E0412]: cannot find type `isizee` in this scope + --> $DIR/issue-62895.rs:5:15 + | +LL | pub fn g() -> isizee { + | ^^^^^^ help: a builtin type with a similar name exists: `isize` + +error[E0308]: mismatched types + --> $DIR/issue-62895.rs:3:11 + | +LL | fn v() -> isize { + | - ^^^^^ expected isize, found () + | | + | this function's body doesn't return + | + = note: expected type `isize` + found type `()` + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0308, E0412. +For more information about an error, try `rustc --explain E0308`. From fe2b5bbe6d151ae4713b3bddb4b386f94757435c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 23 Jul 2019 12:51:34 -0700 Subject: [PATCH 3/3] review comments --- src/libsyntax/parse/parser.rs | 7 ++++--- src/test/ui/{issues => parser}/issue-62881.rs | 0 src/test/ui/{issues => parser}/issue-62881.stderr | 0 src/test/ui/{issues => parser}/issue-62895.rs | 0 src/test/ui/{issues => parser}/issue-62895.stderr | 0 5 files changed, 4 insertions(+), 3 deletions(-) rename src/test/ui/{issues => parser}/issue-62881.rs (100%) rename src/test/ui/{issues => parser}/issue-62881.stderr (100%) rename src/test/ui/{issues => parser}/issue-62895.rs (100%) rename src/test/ui/{issues => parser}/issue-62895.stderr (100%) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index e494cb472a825..5c26c2bf9b500 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -7672,7 +7672,8 @@ impl<'a> Parser<'a> { &mut self.token_cursor.frame.last_token } else if self.token_cursor.stack.get(prev).is_none() { // This can happen due to a bad interaction of two unrelated recovery mechanisms with - // mismatched delimiters *and* recovery lookahead on `pub ident(` likely typo (#62881) + // mismatched delimiters *and* recovery lookahead on the likely typo `pub ident(` + // (#62881). return Ok((ret?, TokenStream::new(vec![]))); } else { &mut self.token_cursor.stack[prev].last_token @@ -7686,8 +7687,8 @@ impl<'a> Parser<'a> { debug!("collect_tokens: {}", msg); self.sess.span_diagnostic.delay_span_bug(self.token.span, &msg); // This can happen due to a bad interaction of two unrelated recovery mechanisms - // with mismatched delimiters *and* recovery lookahead on `pub ident(` likely typo - // (#62895, different but similar to the case above) + // with mismatched delimiters *and* recovery lookahead on the likely typo + // `pub ident(` (#62895, different but similar to the case above). return Ok((ret?, TokenStream::new(vec![]))); } }; diff --git a/src/test/ui/issues/issue-62881.rs b/src/test/ui/parser/issue-62881.rs similarity index 100% rename from src/test/ui/issues/issue-62881.rs rename to src/test/ui/parser/issue-62881.rs diff --git a/src/test/ui/issues/issue-62881.stderr b/src/test/ui/parser/issue-62881.stderr similarity index 100% rename from src/test/ui/issues/issue-62881.stderr rename to src/test/ui/parser/issue-62881.stderr diff --git a/src/test/ui/issues/issue-62895.rs b/src/test/ui/parser/issue-62895.rs similarity index 100% rename from src/test/ui/issues/issue-62895.rs rename to src/test/ui/parser/issue-62895.rs diff --git a/src/test/ui/issues/issue-62895.stderr b/src/test/ui/parser/issue-62895.stderr similarity index 100% rename from src/test/ui/issues/issue-62895.stderr rename to src/test/ui/parser/issue-62895.stderr