From f48b9d9be737339be988042ca88d31330738618c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 8 Sep 2018 10:55:09 +0300 Subject: [PATCH] Fix block structure in enums --- crates/libsyntax2/src/grammar/items/mod.rs | 8 +- .../grammar/items/{structs.rs => nominal.rs} | 13 +- .../data/parser/err/0013_invalid_type.txt | 44 ++-- .../tests/data/parser/err/0025_nope.rs | 31 +++ .../tests/data/parser/err/0025_nope.txt | 203 ++++++++++++++++++ 5 files changed, 274 insertions(+), 25 deletions(-) rename crates/libsyntax2/src/grammar/items/{structs.rs => nominal.rs} (91%) create mode 100644 crates/libsyntax2/tests/data/parser/err/0025_nope.rs create mode 100644 crates/libsyntax2/tests/data/parser/err/0025_nope.txt diff --git a/crates/libsyntax2/src/grammar/items/mod.rs b/crates/libsyntax2/src/grammar/items/mod.rs index 57742ecb92..85d7fe7704 100644 --- a/crates/libsyntax2/src/grammar/items/mod.rs +++ b/crates/libsyntax2/src/grammar/items/mod.rs @@ -1,11 +1,11 @@ mod consts; -mod structs; +mod nominal; mod traits; mod use_item; use super::*; -pub(crate) use self::structs::named_field_def_list; +pub(crate) use self::nominal::named_field_def_list; // test mod_contents // fn foo() {} @@ -176,7 +176,7 @@ fn items_without_modifiers(p: &mut Parser) -> Option { MODULE } STRUCT_KW => { - structs::struct_def(p); + nominal::struct_def(p); if p.at(SEMI) { p.err_and_bump( "expected item, found `;`\n\ @@ -186,7 +186,7 @@ fn items_without_modifiers(p: &mut Parser) -> Option { STRUCT_DEF } ENUM_KW => { - structs::enum_def(p); + nominal::enum_def(p); ENUM_DEF } USE_KW => { diff --git a/crates/libsyntax2/src/grammar/items/structs.rs b/crates/libsyntax2/src/grammar/items/nominal.rs similarity index 91% rename from crates/libsyntax2/src/grammar/items/structs.rs rename to crates/libsyntax2/src/grammar/items/nominal.rs index f1e78865c7..3db5b24afd 100644 --- a/crates/libsyntax2/src/grammar/items/structs.rs +++ b/crates/libsyntax2/src/grammar/items/nominal.rs @@ -91,6 +91,10 @@ pub(crate) fn named_field_def_list(p: &mut Parser) { let m = p.start(); p.bump(); while !p.at(R_CURLY) && !p.at(EOF) { + if p.at(L_CURLY) { + error_block(p, "expected field"); + continue; + } named_field_def(p); if !p.at(R_CURLY) { p.expect(COMMA); @@ -127,10 +131,15 @@ fn pos_field_list(p: &mut Parser) { return; } while !p.at(R_PAREN) && !p.at(EOF) { - let pos_field = p.start(); + let m = p.start(); opt_visibility(p); + if !p.at_ts(types::TYPE_FIRST) { + p.error("expected a type"); + m.complete(p, ERROR); + break; + } types::type_(p); - pos_field.complete(p, POS_FIELD); + m.complete(p, POS_FIELD); if !p.at(R_PAREN) { p.expect(COMMA); diff --git a/crates/libsyntax2/tests/data/parser/err/0013_invalid_type.txt b/crates/libsyntax2/tests/data/parser/err/0013_invalid_type.txt index f7f6c6bce8..e1a6b64326 100644 --- a/crates/libsyntax2/tests/data/parser/err/0013_invalid_type.txt +++ b/crates/libsyntax2/tests/data/parser/err/0013_invalid_type.txt @@ -1,5 +1,5 @@ ROOT@[0; 86) - STRUCT_DEF@[0; 84) + STRUCT_DEF@[0; 72) VISIBILITY@[0; 3) PUB_KW@[0; 3) WHITESPACE@[3; 4) @@ -7,7 +7,7 @@ ROOT@[0; 86) WHITESPACE@[10; 11) NAME@[11; 16) IDENT@[11; 16) "Cache" - POS_FIELD_LIST@[16; 83) + POS_FIELD_LIST@[16; 72) L_PAREN@[16; 17) WHITESPACE@[17; 22) POS_FIELD@[22; 68) @@ -62,22 +62,28 @@ ROOT@[0; 86) NAME_REF@[69; 72) IDENT@[69; 72) "Any" err: `expected COMMA` - err: `expected type` - POS_FIELD@[72; 73) - ERROR@[72; 73) - R_ANGLE@[72; 73) - COMMA@[73; 74) - WHITESPACE@[74; 79) - err: `expected type` - POS_FIELD@[79; 80) - ERROR@[79; 80) - R_ANGLE@[79; 80) - err: `expected COMMA` - err: `expected type` - POS_FIELD@[80; 81) - ERROR@[80; 81) - R_ANGLE@[80; 81) - WHITESPACE@[81; 82) - R_PAREN@[82; 83) + err: `expected a type` + err: `expected R_PAREN` + err: `expected SEMI` + err: `expected an item` + ERROR@[72; 72) + ERROR@[72; 73) + R_ANGLE@[72; 73) + err: `expected an item` + ERROR@[73; 74) + COMMA@[73; 74) + WHITESPACE@[74; 79) + err: `expected an item` + ERROR@[79; 80) + R_ANGLE@[79; 80) + err: `expected an item` + ERROR@[80; 81) + R_ANGLE@[80; 81) + WHITESPACE@[81; 82) + err: `expected an item` + ERROR@[82; 83) + R_PAREN@[82; 83) + err: `expected an item` + ERROR@[83; 84) SEMI@[83; 84) WHITESPACE@[84; 86) diff --git a/crates/libsyntax2/tests/data/parser/err/0025_nope.rs b/crates/libsyntax2/tests/data/parser/err/0025_nope.rs new file mode 100644 index 0000000000..28726ed513 --- /dev/null +++ b/crates/libsyntax2/tests/data/parser/err/0025_nope.rs @@ -0,0 +1,31 @@ +fn main() { + enum Test { + Var1, + Var2(String), + Var3 { + abc: {}, //~ ERROR: expected type, found `{` + }, + } + + // recover... + let a = 1; + enum Test2 { + Fine, + } + + enum Test3 { + StillFine { + def: i32, + }, + } + + { + // fail again + enum Test4 { + Nope(i32 {}) //~ ERROR: found `{` + //~^ ERROR: found `{` + } + } + // still recover later + let bad_syntax = _; //~ ERROR: expected expression, found reserved identifier `_` +} diff --git a/crates/libsyntax2/tests/data/parser/err/0025_nope.txt b/crates/libsyntax2/tests/data/parser/err/0025_nope.txt new file mode 100644 index 0000000000..c30b8585fc --- /dev/null +++ b/crates/libsyntax2/tests/data/parser/err/0025_nope.txt @@ -0,0 +1,203 @@ +ROOT@[0; 575) + FN_DEF@[0; 574) + FN_KW@[0; 2) + WHITESPACE@[2; 3) + NAME@[3; 7) + IDENT@[3; 7) "main" + PARAM_LIST@[7; 9) + L_PAREN@[7; 8) + R_PAREN@[8; 9) + WHITESPACE@[9; 10) + BLOCK@[10; 574) + L_CURLY@[10; 11) + WHITESPACE@[11; 16) + ENUM_DEF@[16; 152) + ENUM_KW@[16; 20) + WHITESPACE@[20; 21) + NAME@[21; 25) + IDENT@[21; 25) "Test" + WHITESPACE@[25; 26) + ENUM_VARIANT_LIST@[26; 152) + L_CURLY@[26; 27) + WHITESPACE@[27; 36) + ENUM_VARIANT@[36; 40) + NAME@[36; 40) + IDENT@[36; 40) "Var1" + COMMA@[40; 41) + WHITESPACE@[41; 50) + ENUM_VARIANT@[50; 62) + NAME@[50; 54) + IDENT@[50; 54) "Var2" + POS_FIELD_LIST@[54; 62) + L_PAREN@[54; 55) + POS_FIELD@[55; 61) + PATH_TYPE@[55; 61) + PATH@[55; 61) + PATH_SEGMENT@[55; 61) + NAME_REF@[55; 61) + IDENT@[55; 61) "String" + R_PAREN@[61; 62) + COMMA@[62; 63) + WHITESPACE@[63; 72) + ENUM_VARIANT@[72; 145) + NAME@[72; 76) + IDENT@[72; 76) "Var3" + WHITESPACE@[76; 77) + NAMED_FIELD_DEF_LIST@[77; 145) + L_CURLY@[77; 78) + WHITESPACE@[78; 91) + NAMED_FIELD_DEF@[91; 95) + NAME@[91; 94) + IDENT@[91; 94) "abc" + COLON@[94; 95) + err: `expected type` + err: `expected COMMA` + WHITESPACE@[95; 96) + err: `expected field` + ERROR@[96; 98) + L_CURLY@[96; 97) + R_CURLY@[97; 98) + err: `expected field declaration` + ERROR@[98; 99) + COMMA@[98; 99) + WHITESPACE@[99; 100) + COMMENT@[100; 135) + WHITESPACE@[135; 144) + R_CURLY@[144; 145) + COMMA@[145; 146) + WHITESPACE@[146; 151) + R_CURLY@[151; 152) + WHITESPACE@[152; 158) + COMMENT@[158; 171) + WHITESPACE@[171; 176) + LET_STMT@[176; 186) + LET_KW@[176; 179) + WHITESPACE@[179; 180) + BIND_PAT@[180; 181) + NAME@[180; 181) + IDENT@[180; 181) "a" + WHITESPACE@[181; 182) + EQ@[182; 183) + WHITESPACE@[183; 184) + LITERAL@[184; 185) + INT_NUMBER@[184; 185) "1" + SEMI@[185; 186) + WHITESPACE@[186; 191) + ENUM_DEF@[191; 223) + ENUM_KW@[191; 195) + WHITESPACE@[195; 196) + NAME@[196; 201) + IDENT@[196; 201) "Test2" + WHITESPACE@[201; 202) + ENUM_VARIANT_LIST@[202; 223) + L_CURLY@[202; 203) + WHITESPACE@[203; 212) + ENUM_VARIANT@[212; 216) + NAME@[212; 216) + IDENT@[212; 216) "Fine" + COMMA@[216; 217) + WHITESPACE@[217; 222) + R_CURLY@[222; 223) + WHITESPACE@[223; 229) + ENUM_DEF@[229; 300) + ENUM_KW@[229; 233) + WHITESPACE@[233; 234) + NAME@[234; 239) + IDENT@[234; 239) "Test3" + WHITESPACE@[239; 240) + ENUM_VARIANT_LIST@[240; 300) + L_CURLY@[240; 241) + WHITESPACE@[241; 250) + ENUM_VARIANT@[250; 293) + NAME@[250; 259) + IDENT@[250; 259) "StillFine" + WHITESPACE@[259; 260) + NAMED_FIELD_DEF_LIST@[260; 293) + L_CURLY@[260; 261) + WHITESPACE@[261; 274) + NAMED_FIELD_DEF@[274; 282) + NAME@[274; 277) + IDENT@[274; 277) "def" + COLON@[277; 278) + WHITESPACE@[278; 279) + PATH_TYPE@[279; 282) + PATH@[279; 282) + PATH_SEGMENT@[279; 282) + NAME_REF@[279; 282) + IDENT@[279; 282) "i32" + COMMA@[282; 283) + WHITESPACE@[283; 292) + R_CURLY@[292; 293) + COMMA@[293; 294) + WHITESPACE@[294; 299) + R_CURLY@[299; 300) + WHITESPACE@[300; 306) + EXPR_STMT@[306; 459) + BLOCK_EXPR@[306; 459) + BLOCK@[306; 459) + L_CURLY@[306; 307) + WHITESPACE@[307; 316) + COMMENT@[316; 329) + WHITESPACE@[329; 338) + ENUM_DEF@[338; 453) + ENUM_KW@[338; 342) + WHITESPACE@[342; 343) + NAME@[343; 348) + IDENT@[343; 348) "Test4" + WHITESPACE@[348; 349) + ENUM_VARIANT_LIST@[349; 453) + L_CURLY@[349; 350) + WHITESPACE@[350; 363) + ENUM_VARIANT@[363; 372) + NAME@[363; 367) + IDENT@[363; 367) "Nope" + POS_FIELD_LIST@[367; 372) + L_PAREN@[367; 368) + POS_FIELD@[368; 371) + PATH_TYPE@[368; 371) + PATH@[368; 371) + PATH_SEGMENT@[368; 371) + NAME_REF@[368; 371) + IDENT@[368; 371) "i32" + err: `expected COMMA` + WHITESPACE@[371; 372) + err: `expected a type` + err: `expected R_PAREN` + err: `expected COMMA` + err: `expected enum variant` + ERROR@[372; 372) + ERROR@[372; 374) + L_CURLY@[372; 373) + R_CURLY@[373; 374) + err: `expected enum variant` + ERROR@[374; 375) + R_PAREN@[374; 375) + WHITESPACE@[375; 376) + COMMENT@[376; 396) + WHITESPACE@[396; 422) + COMMENT@[422; 443) + WHITESPACE@[443; 452) + R_CURLY@[452; 453) + WHITESPACE@[453; 458) + R_CURLY@[458; 459) + WHITESPACE@[459; 464) + COMMENT@[464; 486) + WHITESPACE@[486; 491) + LET_STMT@[491; 510) + LET_KW@[491; 494) + WHITESPACE@[494; 495) + BIND_PAT@[495; 505) + NAME@[495; 505) + IDENT@[495; 505) "bad_syntax" + WHITESPACE@[505; 506) + EQ@[506; 507) + WHITESPACE@[507; 508) + err: `expected expression` + ERROR@[508; 509) + UNDERSCORE@[508; 509) + SEMI@[509; 510) + WHITESPACE@[510; 511) + COMMENT@[511; 572) + WHITESPACE@[572; 573) + R_CURLY@[573; 574) + WHITESPACE@[574; 575)