From 60c6ed9664e8d6fa30388290d5fe86eb80bc6fc7 Mon Sep 17 00:00:00 2001 From: David Wood Date: Sat, 20 Apr 2019 11:31:38 +0100 Subject: [PATCH] Fix fn front matter parsing ICE from invalid code. This commit fixes an "unreachable code" ICE that results from parsing invalid code where the compiler is expecting the next trait item declaration in the middle of the previous trait item due to extra closing braces. --- src/libsyntax/parse/parser.rs | 7 ++++++- src/test/ui/issue-60075.rs | 12 +++++++++++ src/test/ui/issue-60075.stderr | 37 ++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/issue-60075.rs create mode 100644 src/test/ui/issue-60075.stderr diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index a5adb37f745..8e6db8a541a 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -6575,7 +6575,12 @@ impl<'a> Parser<'a> { }; (respan(self.prev_span, Constness::NotConst), unsafety, abi) }; - self.expect_keyword(keywords::Fn)?; + if !self.eat_keyword(keywords::Fn) { + // It is possible for `expect_one_of` to recover given the contents of + // `self.expected_tokens`, therefore, do not use `self.unexpected()` which doesn't + // account for this. + if !self.expect_one_of(&[], &[])? { unreachable!() } + } Ok((constness, unsafety, asyncness, abi)) } diff --git a/src/test/ui/issue-60075.rs b/src/test/ui/issue-60075.rs new file mode 100644 index 00000000000..5788716a526 --- /dev/null +++ b/src/test/ui/issue-60075.rs @@ -0,0 +1,12 @@ +fn main() {} + +trait T { + fn qux() -> Option { + let _ = if true { + }); +//~^ ERROR expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found `;` +//~^^ ERROR expected one of `.`, `;`, `?`, `else`, or an operator, found `}` +//~^^^ ERROR 6:11: 6:12: expected identifier, found `;` +//~^^^^ ERROR missing `fn`, `type`, or `const` for trait-item declaration + Some(4) + } diff --git a/src/test/ui/issue-60075.stderr b/src/test/ui/issue-60075.stderr new file mode 100644 index 00000000000..244aef2d1f0 --- /dev/null +++ b/src/test/ui/issue-60075.stderr @@ -0,0 +1,37 @@ +error: expected one of `.`, `;`, `?`, `else`, or an operator, found `}` + --> $DIR/issue-60075.rs:6:10 + | +LL | }); + | ^ expected one of `.`, `;`, `?`, `else`, or an operator here + +error: expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found `;` + --> $DIR/issue-60075.rs:6:11 + | +LL | fn qux() -> Option { + | - unclosed delimiter +LL | let _ = if true { +LL | }); + | ^ + | | + | help: `}` may belong here + +error: expected identifier, found `;` + --> $DIR/issue-60075.rs:6:11 + | +LL | }); + | ^ expected identifier + +error: missing `fn`, `type`, or `const` for trait-item declaration + --> $DIR/issue-60075.rs:6:12 + | +LL | }); + | ____________^ +LL | | +LL | | +LL | | +LL | | +LL | | Some(4) + | |________^ missing `fn`, `type`, or `const` + +error: aborting due to 4 previous errors +