From e919db3731968ae7a6877530d2cb645b0495d5fd Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 4 Aug 2018 13:17:24 +0300 Subject: [PATCH] refine item parsing --- src/grammar/expressions.rs | 29 +- src/grammar/items/mod.rs | 310 ++++++++---------- src/grammar/items/traits.rs | 2 +- .../parser/err/0001_item_recovery_in_file.txt | 4 +- .../parser/err/0002_duplicate_shebang.txt | 2 +- tests/data/parser/err/0003_C++_semicolon.txt | 6 +- .../parser/err/0004_use_path_bad_segment.txt | 5 +- .../parser/err/0007_stray_curly_in_file.txt | 6 +- .../parser/err/0008_item_block_recovery.txt | 8 +- .../err/0009_broken_struct_type_parameter.txt | 8 +- .../0011_extern_struct.rs} | 0 .../0011_extern_struct.txt} | 9 +- .../inline/0013_unsafe_block_in_mod.txt | 8 +- .../inline/0023_array_type_missing_semi.txt | 7 +- .../0029_fn_pointer_type_missing_fn.txt | 7 +- tests/data/parser/inline/0068_pub_expr.rs | 1 + tests/data/parser/inline/0068_pub_expr.txt | 25 ++ .../data/parser/ok/0025_extern_fn_in_block.rs | 3 + .../parser/ok/0025_extern_fn_in_block.txt | 31 ++ .../data/parser/ok/0026_const_fn_in_block.rs | 3 + .../data/parser/ok/0026_const_fn_in_block.txt | 30 ++ .../data/parser/ok/0027_unsafe_fn_in_block.rs | 4 + .../parser/ok/0027_unsafe_fn_in_block.txt | 40 +++ tests/testutils/src/lib.rs | 1 + 24 files changed, 334 insertions(+), 215 deletions(-) rename tests/data/parser/{inline/0006_extern_struct.rs => err/0011_extern_struct.rs} (100%) rename tests/data/parser/{inline/0006_extern_struct.txt => err/0011_extern_struct.txt} (59%) create mode 100644 tests/data/parser/inline/0068_pub_expr.rs create mode 100644 tests/data/parser/inline/0068_pub_expr.txt create mode 100644 tests/data/parser/ok/0025_extern_fn_in_block.rs create mode 100644 tests/data/parser/ok/0025_extern_fn_in_block.txt create mode 100644 tests/data/parser/ok/0026_const_fn_in_block.rs create mode 100644 tests/data/parser/ok/0026_const_fn_in_block.txt create mode 100644 tests/data/parser/ok/0027_unsafe_fn_in_block.rs create mode 100644 tests/data/parser/ok/0027_unsafe_fn_in_block.txt diff --git a/src/grammar/expressions.rs b/src/grammar/expressions.rs index 423e1a95ac08..c6841992939e 100644 --- a/src/grammar/expressions.rs +++ b/src/grammar/expressions.rs @@ -229,18 +229,27 @@ fn block_expr(p: &mut Parser) -> CompletedMarker { while !p.at(EOF) && !p.at(R_CURLY) { match p.current() { LET_KW => let_stmt(p), - c => { + _ => { // test block_items // fn a() { fn b() {} } - if items::ITEM_FIRST.contains(c) { - items::item(p) - } else { - let expr_stmt = p.start(); - expressions::expr(p); - if p.eat(SEMI) { - expr_stmt.complete(p, EXPR_STMT); - } else { - expr_stmt.abandon(p); + let m = p.start(); + match items::maybe_item(p) { + items::MaybeItem::Item(kind) => { + m.complete(p, kind); + } + items::MaybeItem::Modifiers => { + m.abandon(p); + p.error("expected an item"); + } + // test pub_expr + // fn foo() { pub 92; } //FIXME + items::MaybeItem::None => { + expressions::expr(p); + if p.eat(SEMI) { + m.complete(p, EXPR_STMT); + } else { + m.abandon(p); + } } } } diff --git a/src/grammar/items/mod.rs b/src/grammar/items/mod.rs index a1150e2ac034..1ed0aea07162 100644 --- a/src/grammar/items/mod.rs +++ b/src/grammar/items/mod.rs @@ -8,174 +8,137 @@ mod use_item; pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) { attributes::inner_attributes(p); while !p.at(EOF) && !(stop_on_r_curly && p.at(R_CURLY)) { - item(p); + item(p, stop_on_r_curly) + } +} + +pub(super) fn item(p: &mut Parser, stop_on_r_curly: bool) { + let m = p.start(); + match maybe_item(p) { + MaybeItem::Item(kind) => { + m.complete(p, kind); + } + MaybeItem::None => { + m.abandon(p); + if p.at(L_CURLY) { + error_block(p, "expected an item"); + } else if !p.at(EOF) && !(stop_on_r_curly && p.at(R_CURLY)) { + p.err_and_bump("expected an item"); + } else { + p.error("expected an item"); + } + } + MaybeItem::Modifiers => { + p.error("expected fn, trait or impl"); + m.complete(p, ERROR); + } } } pub(super) const ITEM_FIRST: TokenSet = token_set![EXTERN_KW, MOD_KW, USE_KW, STRUCT_KW, ENUM_KW, FN_KW, PUB_KW, POUND]; -pub(super) fn item(p: &mut Parser) { - let item = p.start(); +pub(super) enum MaybeItem { + None, + Item(SyntaxKind), + Modifiers, +} + +pub(super) fn maybe_item(p: &mut Parser) -> MaybeItem { attributes::outer_attributes(p); visibility(p); - let la = p.nth(1); - let item_kind = match p.current() { - USE_KW => { - use_item::use_item(p); - USE_ITEM + if let Some(kind) = items_without_modifiers(p) { + return MaybeItem::Item(kind); + } + + let mut has_mods = false; + // modifiers + has_mods |= p.eat(CONST_KW); + + // test unsafe_block_in_mod + // fn foo(){} unsafe { } fn bar(){} + if p.at(UNSAFE_KW) && p.nth(1) != L_CURLY { + p.eat(UNSAFE_KW); + has_mods = true; + } + if p.at(EXTERN_KW) { + has_mods = true; + abi(p); + } + if p.at(IDENT) && p.at_contextual_kw("auto") && p.nth(1) == TRAIT_KW { + p.bump_remap(AUTO_KW); + has_mods = true; + } + if p.at(IDENT) && p.at_contextual_kw("default") && p.nth(1) == IMPL_KW { + p.bump_remap(DEFAULT_KW); + has_mods = true; + } + + // items + let kind = match p.current() { + // test extern_fn + // extern fn foo() {} + + // test const_fn + // const fn foo() {} + + // test const_unsafe_fn + // const unsafe fn foo() {} + + // test unsafe_extern_fn + // unsafe extern "C" fn foo() {} + + // test unsafe_fn + // unsafe fn foo() {} + FN_KW => { + fn_item(p); + FN_ITEM } + + // test unsafe_trait + // unsafe trait T {} + + // test auto_trait + // auto trait T {} + + // test unsafe_auto_trait + // unsafe auto trait T {} + TRAIT_KW => { + traits::trait_item(p); + TRAIT_ITEM + } + + // test unsafe_impl + // unsafe impl Foo {} + + // test default_impl + // default impl Foo {} + + // test unsafe_default_impl + // unsafe default impl Foo {} + IMPL_KW => { + traits::impl_item(p); + IMPL_ITEM + } + _ => return if has_mods { + MaybeItem::Modifiers + } else { + MaybeItem::None + } + }; + + MaybeItem::Item(kind) +} + +fn items_without_modifiers(p: &mut Parser) -> Option { + let la = p.nth(1); + let kind = match p.current() { // test extern_crate // extern crate foo; EXTERN_KW if la == CRATE_KW => { extern_crate_item(p); EXTERN_CRATE_ITEM } - EXTERN_KW => { - abi(p); - match p.current() { - // test extern_fn - // extern fn foo() {} - FN_KW => { - fn_item(p); - FN_ITEM - } - // test extern_block - // extern {} - L_CURLY => { - extern_block(p); - EXTERN_BLOCK_EXPR - } - // test extern_struct - // extern struct Foo; - _ => { - item.abandon(p); - p.error("expected `fn` or `{`"); - return; - } - } - } - STATIC_KW => { - consts::static_item(p); - STATIC_ITEM - } - CONST_KW => match p.nth(1) { - // test const_fn - // const fn foo() {} - FN_KW => { - p.bump(); - fn_item(p); - FN_ITEM - } - // test const_unsafe_fn - // const unsafe fn foo() {} - UNSAFE_KW if p.nth(2) == FN_KW => { - p.bump(); - p.bump(); - fn_item(p); - FN_ITEM - } - _ => { - consts::const_item(p); - CONST_ITEM - } - }, - UNSAFE_KW => { - p.bump(); - let la = p.nth(1); - match p.current() { - // test unsafe_trait - // unsafe trait T {} - TRAIT_KW => { - traits::trait_item(p); - TRAIT_ITEM - } - - // test unsafe_auto_trait - // unsafe auto trait T {} - IDENT if p.at_contextual_kw("auto") && la == TRAIT_KW => { - p.bump_remap(AUTO_KW); - traits::trait_item(p); - TRAIT_ITEM - } - - // test unsafe_impl - // unsafe impl Foo {} - IMPL_KW => { - traits::impl_item(p); - IMPL_ITEM - } - - // test unsafe_default_impl - // unsafe default impl Foo {} - IDENT if p.at_contextual_kw("default") && la == IMPL_KW => { - p.bump_remap(DEFAULT_KW); - traits::impl_item(p); - IMPL_ITEM - } - - // test unsafe_extern_fn - // unsafe extern "C" fn foo() {} - EXTERN_KW => { - abi(p); - if !p.at(FN_KW) { - item.abandon(p); - p.error("expected function"); - return; - } - fn_item(p); - FN_ITEM - } - - // test unsafe_fn - // unsafe fn foo() {} - FN_KW => { - fn_item(p); - FN_ITEM - } - - t => { - item.abandon(p); - let message = "expected `trait`, `impl` or `fn`"; - - // test unsafe_block_in_mod - // fn foo(){} unsafe { } fn bar(){} - if t == L_CURLY { - error_block(p, message); - } else { - p.error(message); - } - return; - } - } - } - TRAIT_KW => { - traits::trait_item(p); - TRAIT_ITEM - } - // test auto_trait - // auto trait T {} - IDENT if p.at_contextual_kw("auto") && la == TRAIT_KW => { - p.bump_remap(AUTO_KW); - traits::trait_item(p); - TRAIT_ITEM - } - IMPL_KW => { - traits::impl_item(p); - IMPL_ITEM - } - // test default_impl - // default impl Foo {} - IDENT if p.at_contextual_kw("default") && la == IMPL_KW => { - p.bump_remap(DEFAULT_KW); - traits::impl_item(p); - IMPL_ITEM - } - - FN_KW => { - fn_item(p); - FN_ITEM - } TYPE_KW => { type_item(p); TYPE_ITEM @@ -186,31 +149,40 @@ pub(super) fn item(p: &mut Parser) { } STRUCT_KW => { structs::struct_item(p); + if p.at(SEMI) { + p.err_and_bump( + "expected item, found `;`\n\ + consider removing this semicolon" + ); + } STRUCT_ITEM } ENUM_KW => { structs::enum_item(p); ENUM_ITEM } - L_CURLY => { - item.abandon(p); - error_block(p, "expected item"); - return; + USE_KW => { + use_item::use_item(p); + USE_ITEM } - err_token => { - item.abandon(p); - let message = if err_token == SEMI { - //TODO: if the item is incomplete, this message is misleading - "expected item, found `;`\n\ - consider removing this semicolon" - } else { - "expected item" - }; - p.err_and_bump(message); - return; + CONST_KW if (la == IDENT || la == MUT_KW) => { + consts::const_item(p); + CONST_ITEM } + STATIC_KW => { + consts::static_item(p); + STATIC_ITEM + } + // test extern_block + // extern {} + EXTERN_KW if la == L_CURLY || ((la == STRING || la == RAW_STRING) && p.nth(2) == L_CURLY) => { + abi(p); + extern_block(p); + EXTERN_BLOCK_EXPR + } + _ => return None, }; - item.complete(p, item_kind); + Some(kind) } fn extern_crate_item(p: &mut Parser) { diff --git a/src/grammar/items/traits.rs b/src/grammar/items/traits.rs index bda13e56504a..0614e8ab681e 100644 --- a/src/grammar/items/traits.rs +++ b/src/grammar/items/traits.rs @@ -45,7 +45,7 @@ pub(super) fn impl_item(p: &mut Parser) { // fn bar(&self) {} // } while !p.at(EOF) && !p.at(R_CURLY) { - item(p); + item(p, true); } p.expect(R_CURLY); } diff --git a/tests/data/parser/err/0001_item_recovery_in_file.txt b/tests/data/parser/err/0001_item_recovery_in_file.txt index f35b97b48ad6..49612ac73765 100644 --- a/tests/data/parser/err/0001_item_recovery_in_file.txt +++ b/tests/data/parser/err/0001_item_recovery_in_file.txt @@ -1,9 +1,9 @@ FILE@[0; 21) ERROR@[0; 3) IF_KW@[0; 2) - err: `expected item` + err: `expected an item` WHITESPACE@[2; 3) - err: `expected item` + err: `expected an item` ERROR@[3; 10) MATCH_KW@[3; 8) WHITESPACE@[8; 10) diff --git a/tests/data/parser/err/0002_duplicate_shebang.txt b/tests/data/parser/err/0002_duplicate_shebang.txt index 1a4b37da8407..ef0ddb09a55f 100644 --- a/tests/data/parser/err/0002_duplicate_shebang.txt +++ b/tests/data/parser/err/0002_duplicate_shebang.txt @@ -1,6 +1,6 @@ FILE@[0; 42) SHEBANG@[0; 20) - err: `expected item` + err: `expected an item` ERROR@[20; 42) WHITESPACE@[20; 21) SHEBANG@[21; 41) diff --git a/tests/data/parser/err/0003_C++_semicolon.txt b/tests/data/parser/err/0003_C++_semicolon.txt index dc3cf6c732e1..0a2dad70d18f 100644 --- a/tests/data/parser/err/0003_C++_semicolon.txt +++ b/tests/data/parser/err/0003_C++_semicolon.txt @@ -1,5 +1,5 @@ FILE@[0; 40) - STRUCT_ITEM@[0; 39) + STRUCT_ITEM@[0; 40) STRUCT_KW@[0; 6) NAME@[6; 9) WHITESPACE@[6; 7) @@ -34,5 +34,5 @@ FILE@[0; 40) R_CURLY@[38; 39) err: `expected item, found `;` consider removing this semicolon` - ERROR@[39; 40) - SEMI@[39; 40) + ERROR@[39; 40) + SEMI@[39; 40) diff --git a/tests/data/parser/err/0004_use_path_bad_segment.txt b/tests/data/parser/err/0004_use_path_bad_segment.txt index 6eb6123ecc8f..9b827d862b82 100644 --- a/tests/data/parser/err/0004_use_path_bad_segment.txt +++ b/tests/data/parser/err/0004_use_path_bad_segment.txt @@ -11,11 +11,10 @@ FILE@[0; 12) COLONCOLON@[7; 9) err: `expected identifier` err: `expected SEMI` - err: `expected item` + err: `expected an item` PATH_SEGMENT@[9; 9) ERROR@[9; 11) INT_NUMBER@[9; 11) "92" - err: `expected item, found `;` -consider removing this semicolon` + err: `expected an item` ERROR@[11; 12) SEMI@[11; 12) diff --git a/tests/data/parser/err/0007_stray_curly_in_file.txt b/tests/data/parser/err/0007_stray_curly_in_file.txt index 9758a969f6ad..473fe17cbbfa 100644 --- a/tests/data/parser/err/0007_stray_curly_in_file.txt +++ b/tests/data/parser/err/0007_stray_curly_in_file.txt @@ -1,7 +1,7 @@ FILE@[0; 31) ERROR@[0; 3) R_CURLY@[0; 1) - err: `expected item` + err: `expected an item` WHITESPACE@[1; 3) STRUCT_ITEM@[3; 14) STRUCT_KW@[3; 9) @@ -10,7 +10,7 @@ FILE@[0; 31) IDENT@[10; 11) "S" SEMI@[11; 12) WHITESPACE@[12; 14) - err: `expected item` + err: `expected an item` ERROR@[14; 17) R_CURLY@[14; 15) WHITESPACE@[15; 17) @@ -26,7 +26,7 @@ FILE@[0; 31) L_CURLY@[25; 26) R_CURLY@[26; 27) WHITESPACE@[27; 29) - err: `expected item` + err: `expected an item` ERROR@[29; 31) R_CURLY@[29; 30) WHITESPACE@[30; 31) diff --git a/tests/data/parser/err/0008_item_block_recovery.txt b/tests/data/parser/err/0008_item_block_recovery.txt index 5bc62b6e13c7..80253d8afd68 100644 --- a/tests/data/parser/err/0008_item_block_recovery.txt +++ b/tests/data/parser/err/0008_item_block_recovery.txt @@ -13,17 +13,17 @@ FILE@[0; 95) WHITESPACE@[10; 11) R_CURLY@[11; 12) WHITESPACE@[12; 14) - err: `expected item` + err: `expected an item` ERROR@[14; 17) IDENT@[14; 17) "bar" - err: `expected item` + err: `expected an item` ERROR@[17; 18) L_PAREN@[17; 18) - err: `expected item` + err: `expected an item` ERROR@[18; 20) R_PAREN@[18; 19) WHITESPACE@[19; 20) - err: `expected item` + err: `expected an item` ERROR@[20; 82) L_CURLY@[20; 21) WHITESPACE@[21; 26) diff --git a/tests/data/parser/err/0009_broken_struct_type_parameter.txt b/tests/data/parser/err/0009_broken_struct_type_parameter.txt index 700fc550f869..72e5b36e56b2 100644 --- a/tests/data/parser/err/0009_broken_struct_type_parameter.txt +++ b/tests/data/parser/err/0009_broken_struct_type_parameter.txt @@ -13,18 +13,18 @@ FILE@[0; 43) err: `expected COMMA` err: `expected R_ANGLE` err: `expected `;`, `{`, or `(`` - err: `expected item` + err: `expected an item` ERROR@[12; 14) PLUS@[12; 13) WHITESPACE@[13; 14) - err: `expected item` + err: `expected an item` ERROR@[14; 15) INT_NUMBER@[14; 15) "2" - err: `expected item` + err: `expected an item` ERROR@[15; 17) R_ANGLE@[15; 16) WHITESPACE@[16; 17) - err: `expected item` + err: `expected an item` ERROR@[17; 33) L_CURLY@[17; 18) WHITESPACE@[18; 23) diff --git a/tests/data/parser/inline/0006_extern_struct.rs b/tests/data/parser/err/0011_extern_struct.rs similarity index 100% rename from tests/data/parser/inline/0006_extern_struct.rs rename to tests/data/parser/err/0011_extern_struct.rs diff --git a/tests/data/parser/inline/0006_extern_struct.txt b/tests/data/parser/err/0011_extern_struct.txt similarity index 59% rename from tests/data/parser/inline/0006_extern_struct.txt rename to tests/data/parser/err/0011_extern_struct.txt index f310e1225a52..288f3469b7fb 100644 --- a/tests/data/parser/inline/0006_extern_struct.txt +++ b/tests/data/parser/err/0011_extern_struct.txt @@ -1,8 +1,9 @@ FILE@[0; 19) - ABI@[0; 7) - EXTERN_KW@[0; 6) - WHITESPACE@[6; 7) - err: `expected `fn` or `{`` + ERROR@[0; 7) + ABI@[0; 7) + EXTERN_KW@[0; 6) + WHITESPACE@[6; 7) + err: `expected fn, trait or impl` STRUCT_ITEM@[7; 19) STRUCT_KW@[7; 13) NAME@[13; 17) diff --git a/tests/data/parser/inline/0013_unsafe_block_in_mod.txt b/tests/data/parser/inline/0013_unsafe_block_in_mod.txt index e5581d615fd2..1428386921d5 100644 --- a/tests/data/parser/inline/0013_unsafe_block_in_mod.txt +++ b/tests/data/parser/inline/0013_unsafe_block_in_mod.txt @@ -11,10 +11,12 @@ FILE@[0; 33) L_CURLY@[8; 9) R_CURLY@[9; 10) WHITESPACE@[10; 11) - UNSAFE_KW@[11; 17) - err: `expected `trait`, `impl` or `fn`` - ERROR@[17; 22) + err: `expected an item` + ERROR@[11; 18) + UNSAFE_KW@[11; 17) WHITESPACE@[17; 18) + err: `expected an item` + ERROR@[18; 22) L_CURLY@[18; 19) WHITESPACE@[19; 20) R_CURLY@[20; 21) diff --git a/tests/data/parser/inline/0023_array_type_missing_semi.txt b/tests/data/parser/inline/0023_array_type_missing_semi.txt index f3e9ffe4ab37..aa600eab4486 100644 --- a/tests/data/parser/inline/0023_array_type_missing_semi.txt +++ b/tests/data/parser/inline/0023_array_type_missing_semi.txt @@ -15,14 +15,13 @@ FILE@[0; 18) WHITESPACE@[12; 13) err: `expected `;` or `]`` err: `expected SEMI` - err: `expected item` + err: `expected an item` ERROR@[13; 15) INT_NUMBER@[13; 15) "92" - err: `expected item` + err: `expected an item` ERROR@[15; 16) R_BRACK@[15; 16) - err: `expected item, found `;` -consider removing this semicolon` + err: `expected an item` ERROR@[16; 18) SEMI@[16; 17) WHITESPACE@[17; 18) diff --git a/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.txt b/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.txt index c99714ed4bc3..82632b7bfa38 100644 --- a/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.txt +++ b/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.txt @@ -11,14 +11,13 @@ FILE@[0; 20) err: `expected `fn`` err: `expected SEMI` WHITESPACE@[15; 16) - err: `expected item` + err: `expected an item` ERROR@[16; 17) L_PAREN@[16; 17) - err: `expected item` + err: `expected an item` ERROR@[17; 18) R_PAREN@[17; 18) - err: `expected item, found `;` -consider removing this semicolon` + err: `expected an item` ERROR@[18; 20) SEMI@[18; 19) WHITESPACE@[19; 20) diff --git a/tests/data/parser/inline/0068_pub_expr.rs b/tests/data/parser/inline/0068_pub_expr.rs new file mode 100644 index 000000000000..d9d99d2d3d7f --- /dev/null +++ b/tests/data/parser/inline/0068_pub_expr.rs @@ -0,0 +1 @@ +fn foo() { pub 92; } //FIXME diff --git a/tests/data/parser/inline/0068_pub_expr.txt b/tests/data/parser/inline/0068_pub_expr.txt new file mode 100644 index 000000000000..09cf9b2627c8 --- /dev/null +++ b/tests/data/parser/inline/0068_pub_expr.txt @@ -0,0 +1,25 @@ +FILE@[0; 29) + FN_ITEM@[0; 29) + FN_KW@[0; 2) + NAME@[2; 6) + WHITESPACE@[2; 3) + IDENT@[3; 6) "foo" + PARAM_LIST@[6; 9) + L_PAREN@[6; 7) + R_PAREN@[7; 8) + WHITESPACE@[8; 9) + BLOCK_EXPR@[9; 29) + L_CURLY@[9; 10) + EXPR_STMT@[10; 19) + VISIBILITY@[10; 15) + WHITESPACE@[10; 11) + PUB_KW@[11; 14) + WHITESPACE@[14; 15) + LITERAL@[15; 17) + INT_NUMBER@[15; 17) "92" + SEMI@[17; 18) + WHITESPACE@[18; 19) + R_CURLY@[19; 20) + WHITESPACE@[20; 21) + COMMENT@[21; 28) + WHITESPACE@[28; 29) diff --git a/tests/data/parser/ok/0025_extern_fn_in_block.rs b/tests/data/parser/ok/0025_extern_fn_in_block.rs new file mode 100644 index 000000000000..289809809a6b --- /dev/null +++ b/tests/data/parser/ok/0025_extern_fn_in_block.rs @@ -0,0 +1,3 @@ +fn main() { + extern fn f() {} +} diff --git a/tests/data/parser/ok/0025_extern_fn_in_block.txt b/tests/data/parser/ok/0025_extern_fn_in_block.txt new file mode 100644 index 000000000000..0623740aae71 --- /dev/null +++ b/tests/data/parser/ok/0025_extern_fn_in_block.txt @@ -0,0 +1,31 @@ +FILE@[0; 35) + FN_ITEM@[0; 35) + FN_KW@[0; 2) + NAME@[2; 7) + WHITESPACE@[2; 3) + IDENT@[3; 7) "main" + PARAM_LIST@[7; 10) + L_PAREN@[7; 8) + R_PAREN@[8; 9) + WHITESPACE@[9; 10) + BLOCK_EXPR@[10; 35) + L_CURLY@[10; 11) + FN_ITEM@[11; 33) + ABI@[11; 23) + WHITESPACE@[11; 16) + EXTERN_KW@[16; 22) + WHITESPACE@[22; 23) + FN_KW@[23; 25) + NAME@[25; 27) + WHITESPACE@[25; 26) + IDENT@[26; 27) "f" + PARAM_LIST@[27; 30) + L_PAREN@[27; 28) + R_PAREN@[28; 29) + WHITESPACE@[29; 30) + BLOCK_EXPR@[30; 33) + L_CURLY@[30; 31) + R_CURLY@[31; 32) + WHITESPACE@[32; 33) + R_CURLY@[33; 34) + WHITESPACE@[34; 35) diff --git a/tests/data/parser/ok/0026_const_fn_in_block.rs b/tests/data/parser/ok/0026_const_fn_in_block.rs new file mode 100644 index 000000000000..7641a3d28e66 --- /dev/null +++ b/tests/data/parser/ok/0026_const_fn_in_block.rs @@ -0,0 +1,3 @@ +fn main() { + const fn f() {} +} diff --git a/tests/data/parser/ok/0026_const_fn_in_block.txt b/tests/data/parser/ok/0026_const_fn_in_block.txt new file mode 100644 index 000000000000..329c658463c9 --- /dev/null +++ b/tests/data/parser/ok/0026_const_fn_in_block.txt @@ -0,0 +1,30 @@ +FILE@[0; 34) + FN_ITEM@[0; 34) + FN_KW@[0; 2) + NAME@[2; 7) + WHITESPACE@[2; 3) + IDENT@[3; 7) "main" + PARAM_LIST@[7; 10) + L_PAREN@[7; 8) + R_PAREN@[8; 9) + WHITESPACE@[9; 10) + BLOCK_EXPR@[10; 34) + L_CURLY@[10; 11) + FN_ITEM@[11; 32) + WHITESPACE@[11; 16) + CONST_KW@[16; 21) + WHITESPACE@[21; 22) + FN_KW@[22; 24) + NAME@[24; 26) + WHITESPACE@[24; 25) + IDENT@[25; 26) "f" + PARAM_LIST@[26; 29) + L_PAREN@[26; 27) + R_PAREN@[27; 28) + WHITESPACE@[28; 29) + BLOCK_EXPR@[29; 32) + L_CURLY@[29; 30) + R_CURLY@[30; 31) + WHITESPACE@[31; 32) + R_CURLY@[32; 33) + WHITESPACE@[33; 34) diff --git a/tests/data/parser/ok/0027_unsafe_fn_in_block.rs b/tests/data/parser/ok/0027_unsafe_fn_in_block.rs new file mode 100644 index 000000000000..f3c5ff93863e --- /dev/null +++ b/tests/data/parser/ok/0027_unsafe_fn_in_block.rs @@ -0,0 +1,4 @@ +fn main() { + unsafe fn f() {} + unsafe { 92 } +} diff --git a/tests/data/parser/ok/0027_unsafe_fn_in_block.txt b/tests/data/parser/ok/0027_unsafe_fn_in_block.txt new file mode 100644 index 000000000000..9982d0308483 --- /dev/null +++ b/tests/data/parser/ok/0027_unsafe_fn_in_block.txt @@ -0,0 +1,40 @@ +FILE@[0; 53) + FN_ITEM@[0; 53) + FN_KW@[0; 2) + NAME@[2; 7) + WHITESPACE@[2; 3) + IDENT@[3; 7) "main" + PARAM_LIST@[7; 10) + L_PAREN@[7; 8) + R_PAREN@[8; 9) + WHITESPACE@[9; 10) + BLOCK_EXPR@[10; 53) + L_CURLY@[10; 11) + FN_ITEM@[11; 37) + WHITESPACE@[11; 16) + UNSAFE_KW@[16; 22) + WHITESPACE@[22; 23) + FN_KW@[23; 25) + NAME@[25; 27) + WHITESPACE@[25; 26) + IDENT@[26; 27) "f" + PARAM_LIST@[27; 30) + L_PAREN@[27; 28) + R_PAREN@[28; 29) + WHITESPACE@[29; 30) + BLOCK_EXPR@[30; 37) + L_CURLY@[30; 31) + R_CURLY@[31; 32) + WHITESPACE@[32; 37) + BLOCK_EXPR@[37; 51) + UNSAFE_KW@[37; 43) + WHITESPACE@[43; 44) + L_CURLY@[44; 45) + LITERAL@[45; 49) + WHITESPACE@[45; 46) + INT_NUMBER@[46; 48) "92" + WHITESPACE@[48; 49) + R_CURLY@[49; 50) + WHITESPACE@[50; 51) + R_CURLY@[51; 52) + WHITESPACE@[52; 53) diff --git a/tests/testutils/src/lib.rs b/tests/testutils/src/lib.rs index deeb707d3d8d..39c82166121a 100644 --- a/tests/testutils/src/lib.rs +++ b/tests/testutils/src/lib.rs @@ -90,6 +90,7 @@ fn print_difference(expected: &str, actual: &str, path: &Path) { return; } let changeset = Changeset::new(actual, expected, "\n"); + println!("Expected:\n{}\n\nActual:\n{}\n", expected, actual); print!("{}", changeset); println!("file: {}\n", path.display()); panic!("Comparison failed")