Skip to content

Commit 0743694

Browse files
authored
Auto merge of #37245 - goffrie:recovery, r=nrc
Recover out of an enum or struct's braced block. If we encounter a syntax error inside of a braced block, then we should fail by consuming the rest of the block if possible. This implements such recovery for enums and structs. Fixes #37113.
2 parents a0e31a5 + c9036cc commit 0743694

File tree

5 files changed

+112
-2
lines changed

5 files changed

+112
-2
lines changed

src/libsyntax/parse/parser.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -5145,7 +5145,11 @@ impl<'a> Parser<'a> {
51455145
let mut fields = Vec::new();
51465146
if self.eat(&token::OpenDelim(token::Brace)) {
51475147
while self.token != token::CloseDelim(token::Brace) {
5148-
fields.push(self.parse_struct_decl_field()?);
5148+
fields.push(self.parse_struct_decl_field().map_err(|e| {
5149+
self.recover_stmt();
5150+
self.eat(&token::CloseDelim(token::Brace));
5151+
e
5152+
})?);
51495153
}
51505154

51515155
self.bump();
@@ -5673,7 +5677,11 @@ impl<'a> Parser<'a> {
56735677
generics.where_clause = self.parse_where_clause()?;
56745678
self.expect(&token::OpenDelim(token::Brace))?;
56755679

5676-
let enum_definition = self.parse_enum_def(&generics)?;
5680+
let enum_definition = self.parse_enum_def(&generics).map_err(|e| {
5681+
self.recover_stmt();
5682+
self.eat(&token::CloseDelim(token::Brace));
5683+
e
5684+
})?;
56775685
Ok((id, ItemKind::Enum(enum_definition, generics), None))
56785686
}
56795687

src/test/parse-fail/issue-37113.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
macro_rules! test_macro {
12+
( $( $t:ty ),* $(),*) => {
13+
enum SomeEnum {
14+
$( $t, )* //~ ERROR expected identifier, found `String`
15+
};
16+
};
17+
}
18+
19+
fn main() {
20+
test_macro!(String,);
21+
}

src/test/parse-fail/recover-enum.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-flags: -Z parse-only -Z continue-parse-after-error
12+
13+
fn main() {
14+
enum Test {
15+
Very
16+
Bad //~ ERROR found `Bad`
17+
Stuff
18+
}
19+
}

src/test/parse-fail/recover-enum2.rs

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-flags: -Z parse-only -Z continue-parse-after-error
12+
13+
fn main() {
14+
enum Test {
15+
Var1,
16+
Var2(String),
17+
Var3 {
18+
abc: {}, //~ ERROR: expected type, found `{`
19+
},
20+
}
21+
22+
// recover...
23+
let a = 1;
24+
enum Test2 {
25+
Fine,
26+
}
27+
28+
enum Test3 {
29+
StillFine {
30+
def: i32,
31+
},
32+
}
33+
34+
{
35+
// fail again
36+
enum Test4 {
37+
Nope(i32 {}) //~ ERROR: found `{`
38+
//~^ ERROR: found `{`
39+
}
40+
}
41+
// still recover later
42+
let bad_syntax = _; //~ ERROR: found `_`
43+
}

src/test/parse-fail/recover-struct.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-flags: -Z parse-only -Z continue-parse-after-error
12+
13+
fn main() {
14+
struct Test {
15+
Very
16+
Bad //~ ERROR found `Bad`
17+
Stuff
18+
}
19+
}

0 commit comments

Comments
 (0)