From 2fb110e1faa1daabd96a9c961da38a838c906553 Mon Sep 17 00:00:00 2001 From: pcpthm Date: Tue, 19 Mar 2019 17:37:08 +0900 Subject: Error about attributes on unallowed types of expression statement --- crates/ra_parser/src/grammar/expressions.rs | 35 +++++++++----- .../inline/err/0009_attr_on_expr_not_allowed.rs | 4 ++ .../inline/err/0009_attr_on_expr_not_allowed.txt | 55 ++++++++++++++++++++++ 3 files changed, 82 insertions(+), 12 deletions(-) create mode 100644 crates/ra_syntax/tests/data/parser/inline/err/0009_attr_on_expr_not_allowed.rs create mode 100644 crates/ra_syntax/tests/data/parser/inline/err/0009_attr_on_expr_not_allowed.txt diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs index e35c46a5e..c8ce07179 100644 --- a/crates/ra_parser/src/grammar/expressions.rs +++ b/crates/ra_parser/src/grammar/expressions.rs @@ -38,6 +38,13 @@ pub(crate) fn block(p: &mut Parser) { m.complete(p, BLOCK); } +fn is_expr_stmt_attr_allowed(kind: SyntaxKind) -> bool { + match kind { + BIN_EXPR | RANGE_EXPR | IF_EXPR => false, + _ => true, + } +} + pub(crate) fn expr_block_contents(p: &mut Parser) { // This is checked by a validator attributes::inner_attributes(p); @@ -62,6 +69,7 @@ pub(crate) fn expr_block_contents(p: &mut Parser) { // #[C] #[D] {} // #[D] return (); // } + let has_attrs = p.at(POUND); attributes::outer_attributes(p); if p.at(LET_KW) { let_stmt(p, m); @@ -74,18 +82,17 @@ pub(crate) fn expr_block_contents(p: &mut Parser) { }; let (cm, blocklike) = expr_stmt(p); - let cm = match cm { - None => { - if p.at(R_CURLY) { - m.abandon(p); - } else { - p.expect(SEMI); - m.complete(p, EXPR_STMT); - } - continue; + + if let Some(cm) = &cm { + if has_attrs && !is_expr_stmt_attr_allowed(cm.kind()) { + // test_err attr_on_expr_not_allowed + // fn foo() { + // #[A] 1 + 2; + // #[B] if true {}; + // } + p.error(format!("attributes are not allowed on {:?}", cm.kind())); } - Some(cm) => cm, - }; + } if p.at(R_CURLY) { // test attr_on_last_expr_in_block @@ -93,7 +100,11 @@ pub(crate) fn expr_block_contents(p: &mut Parser) { // { #[A] bar!()? } // #[B] &() // } - m.contract_child(p, cm); + if let Some(cm) = cm { + m.contract_child(p, cm); + } else { + m.abandon(p); + } } else { // test no_semi_after_block // fn foo() { diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0009_attr_on_expr_not_allowed.rs b/crates/ra_syntax/tests/data/parser/inline/err/0009_attr_on_expr_not_allowed.rs new file mode 100644 index 000000000..d725a07ce --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/err/0009_attr_on_expr_not_allowed.rs @@ -0,0 +1,4 @@ +fn foo() { + #[A] 1 + 2; + #[B] if true {}; +} diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0009_attr_on_expr_not_allowed.txt b/crates/ra_syntax/tests/data/parser/inline/err/0009_attr_on_expr_not_allowed.txt new file mode 100644 index 000000000..fdea1ec1e --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/err/0009_attr_on_expr_not_allowed.txt @@ -0,0 +1,55 @@ +SOURCE_FILE@[0; 48) + FN_DEF@[0; 47) + FN_KW@[0; 2) + WHITESPACE@[2; 3) + NAME@[3; 6) + IDENT@[3; 6) "foo" + PARAM_LIST@[6; 8) + L_PAREN@[6; 7) + R_PAREN@[7; 8) + WHITESPACE@[8; 9) + BLOCK@[9; 47) + L_CURLY@[9; 10) + WHITESPACE@[10; 14) + EXPR_STMT@[14; 25) + ATTR@[14; 18) + POUND@[14; 15) + TOKEN_TREE@[15; 18) + L_BRACK@[15; 16) + IDENT@[16; 17) "A" + R_BRACK@[17; 18) + WHITESPACE@[18; 19) + BIN_EXPR@[19; 24) + LITERAL@[19; 20) + INT_NUMBER@[19; 20) "1" + WHITESPACE@[20; 21) + PLUS@[21; 22) + WHITESPACE@[22; 23) + LITERAL@[23; 24) + INT_NUMBER@[23; 24) "2" + err: `attributes are not allowed on BIN_EXPR` + SEMI@[24; 25) + WHITESPACE@[25; 29) + EXPR_STMT@[29; 45) + ATTR@[29; 33) + POUND@[29; 30) + TOKEN_TREE@[30; 33) + L_BRACK@[30; 31) + IDENT@[31; 32) "B" + R_BRACK@[32; 33) + WHITESPACE@[33; 34) + IF_EXPR@[34; 44) + IF_KW@[34; 36) + WHITESPACE@[36; 37) + CONDITION@[37; 41) + LITERAL@[37; 41) + TRUE_KW@[37; 41) + WHITESPACE@[41; 42) + BLOCK@[42; 44) + L_CURLY@[42; 43) + R_CURLY@[43; 44) + err: `attributes are not allowed on IF_EXPR` + SEMI@[44; 45) + WHITESPACE@[45; 46) + R_CURLY@[46; 47) + WHITESPACE@[47; 48) -- cgit v1.2.3