diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs index 759f2cc865..a34c18d6d0 100644 --- a/crates/hir_def/src/body/lower.rs +++ b/crates/hir_def/src/body/lower.rs @@ -650,8 +650,10 @@ impl ExprCollector<'_> { self.statements_in_scope.push(Statement::Let { pat, type_ref, initializer }); } ast::Stmt::ExprStmt(stmt) => { - if self.check_cfg(&stmt).is_none() { - return; + if let Some(expr) = stmt.expr() { + if self.check_cfg(&expr).is_none() { + return; + } } let has_semi = stmt.semicolon_token().is_some(); // Note that macro could be expended to multiple statements diff --git a/crates/parser/src/event.rs b/crates/parser/src/event.rs index 9036688921..41b0328027 100644 --- a/crates/parser/src/event.rs +++ b/crates/parser/src/event.rs @@ -93,8 +93,6 @@ pub(super) fn process(sink: &mut dyn TreeSink, mut events: Vec) { for i in 0..events.len() { match mem::replace(&mut events[i], Event::tombstone()) { - Event::Start { kind: TOMBSTONE, .. } => (), - Event::Start { kind, forward_parent } => { // For events[A, B, C], B is A's forward_parent, C is B's forward_parent, // in the normal control flow, the parent-child relation: `A -> B -> C`, @@ -109,9 +107,7 @@ pub(super) fn process(sink: &mut dyn TreeSink, mut events: Vec) { // append `A`'s forward_parent `B` fp = match mem::replace(&mut events[idx], Event::tombstone()) { Event::Start { kind, forward_parent } => { - if kind != TOMBSTONE { - forward_parents.push(kind); - } + forward_parents.push(kind); forward_parent } _ => unreachable!(), @@ -120,7 +116,9 @@ pub(super) fn process(sink: &mut dyn TreeSink, mut events: Vec) { } for kind in forward_parents.drain(..).rev() { - sink.start_node(kind); + if kind != TOMBSTONE { + sink.start_node(kind); + } } } Event::Finish => sink.finish_node(), diff --git a/crates/parser/src/grammar.rs b/crates/parser/src/grammar.rs index d0b07f5931..3d0ad6735e 100644 --- a/crates/parser/src/grammar.rs +++ b/crates/parser/src/grammar.rs @@ -63,7 +63,7 @@ pub(crate) mod entry_points { pub(crate) use types::type_; pub(crate) fn expr(p: &mut Parser) { - let _ = expressions::expr_with_attrs(p); + let _ = expressions::expr(p); } pub(crate) fn stmt(p: &mut Parser) { diff --git a/crates/parser/src/grammar/attributes.rs b/crates/parser/src/grammar/attributes.rs index 80d7b09b3e..574629f31a 100644 --- a/crates/parser/src/grammar/attributes.rs +++ b/crates/parser/src/grammar/attributes.rs @@ -41,7 +41,7 @@ pub(super) fn meta(p: &mut Parser) { match p.current() { T![=] => { p.bump(T![=]); - if expressions::expr(p).0.is_none() { + if !expressions::expr(p) { p.error("expected expression"); } } diff --git a/crates/parser/src/grammar/expressions.rs b/crates/parser/src/grammar/expressions.rs index 30d3d4421a..645101e2f7 100644 --- a/crates/parser/src/grammar/expressions.rs +++ b/crates/parser/src/grammar/expressions.rs @@ -13,35 +13,19 @@ pub(super) enum StmtWithSemi { const EXPR_FIRST: TokenSet = LHS_FIRST; -pub(super) fn expr(p: &mut Parser) -> (Option, BlockLike) { +pub(super) fn expr(p: &mut Parser) -> bool { let r = Restrictions { forbid_structs: false, prefer_stmt: false }; - expr_bp(p, r, 1) + expr_bp(p, None, r, 1).is_some() } -pub(super) fn expr_with_attrs(p: &mut Parser) -> bool { - let m = p.start(); - let has_attrs = p.at(T![#]); - attributes::outer_attrs(p); - - let (cm, _block_like) = expr(p); - let success = cm.is_some(); - - match (has_attrs, cm) { - (true, Some(cm)) => cm.extend_to(p, m), - _ => m.abandon(p), - } - - success -} - -pub(super) fn expr_stmt(p: &mut Parser) -> (Option, BlockLike) { +pub(super) fn expr_stmt(p: &mut Parser, m: Option) -> Option<(CompletedMarker, BlockLike)> { let r = Restrictions { forbid_structs: false, prefer_stmt: true }; - expr_bp(p, r, 1) + expr_bp(p, m, r, 1) } fn expr_no_struct(p: &mut Parser) { let r = Restrictions { forbid_structs: true, prefer_stmt: false }; - expr_bp(p, r, 1); + expr_bp(p, None, r, 1); } pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi, prefer_expr: bool) { @@ -53,7 +37,6 @@ pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi, prefer_expr: bool) { // #[C] #[D] {} // #[D] return (); // } - let has_attrs = p.at(T![#]); attributes::outer_attrs(p); if p.at(T![let]) { @@ -68,61 +51,39 @@ pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi, prefer_expr: bool) { Err(m) => m, }; - let (cm, blocklike) = expr_stmt(p); - let kind = cm.as_ref().map(|cm| cm.kind()).unwrap_or(ERROR); - - if has_attrs { - if matches!(kind, BIN_EXPR | RANGE_EXPR) { - // test_err attr_on_expr_not_allowed + if let Some((cm, blocklike)) = expr_stmt(p, Some(m)) { + if !(p.at(T!['}']) || (prefer_expr && p.at(EOF))) { + // test no_semi_after_block // fn foo() { - // #[A] 1 + 2; - // #[B] if true {}; + // if true {} + // loop {} + // match () {} + // while true {} + // for _ in () {} + // {} + // {} + // macro_rules! test { + // () => {} + // } + // test!{} // } - p.error(format!("attributes are not allowed on {:?}", kind)); - } - } - - if p.at(T!['}']) || (prefer_expr && p.at(EOF)) { - // test attr_on_last_expr_in_block - // fn foo() { - // { #[A] bar!()? } - // #[B] &() - // } - match cm { - Some(cm) => cm.extend_to(p, m), - None => m.abandon(p), - } - } else { - // test no_semi_after_block - // fn foo() { - // if true {} - // loop {} - // match () {} - // while true {} - // for _ in () {} - // {} - // {} - // macro_rules! test { - // () => {} - // } - // test!{} - // } - - match with_semi { - StmtWithSemi::No => (), - StmtWithSemi::Optional => { - p.eat(T![;]); - } - StmtWithSemi::Yes => { - if blocklike.is_block() { + let m = cm.precede(p); + match with_semi { + StmtWithSemi::No => (), + StmtWithSemi::Optional => { p.eat(T![;]); - } else { - p.expect(T![;]); + } + StmtWithSemi::Yes => { + if blocklike.is_block() { + p.eat(T![;]); + } else { + p.expect(T![;]); + } } } - } - m.complete(p, EXPR_STMT); + m.complete(p, EXPR_STMT); + } } // test let_stmt @@ -138,7 +99,7 @@ pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi, prefer_expr: bool) { if p.eat(T![=]) { // test let_stmt_init // fn f() { let x = 92; } - expressions::expr_with_attrs(p); + expressions::expr(p); } match with_semi { @@ -234,20 +195,34 @@ fn current_op(p: &Parser) -> (u8, SyntaxKind) { } // Parses expression with binding power of at least bp. -fn expr_bp(p: &mut Parser, mut r: Restrictions, bp: u8) -> (Option, BlockLike) { +fn expr_bp( + p: &mut Parser, + m: Option, + mut r: Restrictions, + bp: u8, +) -> Option<(CompletedMarker, BlockLike)> { + let m = m.unwrap_or_else(|| { + let m = p.start(); + attributes::outer_attrs(p); + m + }); let mut lhs = match lhs(p, r) { Some((lhs, blocklike)) => { + let lhs = lhs.extend_to(p, m); if r.prefer_stmt && blocklike.is_block() { // test stmt_bin_expr_ambiguity // fn f() { // let _ = {1} & 2; // {1} &2; // } - return (Some(lhs), BlockLike::Block); + return Some((lhs, BlockLike::Block)); } lhs } - None => return (None, BlockLike::NotBlock), + None => { + m.abandon(p); + return None; + } }; loop { @@ -285,10 +260,10 @@ fn expr_bp(p: &mut Parser, mut r: Restrictions, bp: u8) -> (Option Option<(CompletedMarker, BlockLike)> m = p.start(); p.bump(op); if p.at_ts(EXPR_FIRST) && !(r.forbid_structs && p.at(T!['{'])) { - expr_bp(p, r, 2); + expr_bp(p, None, r, 2); } - return Some((m.complete(p, RANGE_EXPR), BlockLike::NotBlock)); + let cm = m.complete(p, RANGE_EXPR); + return Some((cm, BlockLike::NotBlock)); } } @@ -353,12 +329,15 @@ fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)> // {p}.x = 10; // } let (lhs, blocklike) = atom::atom_expr(p, r)?; - return Some(postfix_expr(p, lhs, blocklike, !(r.prefer_stmt && blocklike.is_block()))); + let (cm, block_like) = + postfix_expr(p, lhs, blocklike, !(r.prefer_stmt && blocklike.is_block())); + return Some((cm, block_like)); } }; // parse the interior of the unary expression - expr_bp(p, r, 255); - Some((m.complete(p, kind), BlockLike::NotBlock)) + expr_bp(p, None, r, 255); + let cm = m.complete(p, kind); + Some((cm, BlockLike::NotBlock)) } fn postfix_expr( @@ -536,7 +515,7 @@ fn arg_list(p: &mut Parser) { // fn main() { // foo(#[attr] 92) // } - if !expr_with_attrs(p) { + if !expr(p) { break; } if !p.at(T![')']) && !p.expect(T![,]) { diff --git a/crates/parser/src/grammar/expressions/atom.rs b/crates/parser/src/grammar/expressions/atom.rs index f0048aa301..f6e9a5f1b3 100644 --- a/crates/parser/src/grammar/expressions/atom.rs +++ b/crates/parser/src/grammar/expressions/atom.rs @@ -176,7 +176,7 @@ fn tuple_expr(p: &mut Parser) -> CompletedMarker { // test tuple_attrs // const A: (i64, i64) = (1, #[cfg(test)] 2); - if !expr_with_attrs(p) { + if !expr(p) { break; } @@ -209,7 +209,7 @@ fn array_expr(p: &mut Parser) -> CompletedMarker { // test array_attrs // const A: &[i64] = &[1, #[cfg(test)] 2]; - if !expr_with_attrs(p) { + if !expr(p) { break; } @@ -438,7 +438,10 @@ fn match_arm(p: &mut Parser) { match_guard(p); } p.expect(T![=>]); - let blocklike = expr_stmt(p).1; + let blocklike = match expr_stmt(p, None) { + Some((_, blocklike)) => blocklike, + None => BlockLike::NotBlock, + }; // test match_arms_commas // fn foo() { @@ -619,14 +622,14 @@ fn meta_var_expr(p: &mut Parser) -> CompletedMarker { assert!(p.at(L_DOLLAR)); let m = p.start(); p.bump(L_DOLLAR); - let (completed, _is_block) = - expr_bp(p, Restrictions { forbid_structs: false, prefer_stmt: false }, 1); + let expr = expr_bp(p, None, Restrictions { forbid_structs: false, prefer_stmt: false }, 1); - match (completed, p.current()) { - (Some(it), R_DOLLAR) => { + match (expr, p.current()) { + (Some((cm, _)), R_DOLLAR) => { p.bump(R_DOLLAR); + // FIXME: this leaves the dollar hanging in the air... m.abandon(p); - it + cm } _ => { while !p.at(R_DOLLAR) { diff --git a/crates/parser/src/parser.rs b/crates/parser/src/parser.rs index f6b8308c57..1f9961bb92 100644 --- a/crates/parser/src/parser.rs +++ b/crates/parser/src/parser.rs @@ -339,11 +339,16 @@ impl CompletedMarker { } /// Extends this completed marker *to the left* up to `m`. - pub(crate) fn extend_to(self, p: &mut Parser, mut m: Marker) { - assert!(m.pos <= self.pos); + pub(crate) fn extend_to(self, p: &mut Parser, mut m: Marker) -> CompletedMarker { m.bomb.defuse(); - - p.events.swap(self.pos as usize, m.pos as usize); + let idx = m.pos as usize; + match &mut p.events[idx] { + Event::Start { forward_parent, .. } => { + *forward_parent = Some(self.pos - m.pos); + } + _ => unreachable!(), + } + self } pub(crate) fn kind(&self) -> SyntaxKind { diff --git a/crates/syntax/test_data/parser/err/0009_broken_struct_type_parameter.rast b/crates/syntax/test_data/parser/err/0009_broken_struct_type_parameter.rast index dacf71aa16..2d4c689c7c 100644 --- a/crates/syntax/test_data/parser/err/0009_broken_struct_type_parameter.rast +++ b/crates/syntax/test_data/parser/err/0009_broken_struct_type_parameter.rast @@ -26,9 +26,8 @@ SOURCE_FILE@0..43 PATH_SEGMENT@23..24 NAME_REF@23..24 IDENT@23..24 "f" - EXPR_STMT@24..25 - ERROR@24..25 - COLON@24..25 ":" + ERROR@24..25 + COLON@24..25 ":" WHITESPACE@25..26 " " PATH_EXPR@26..29 PATH@26..29 @@ -55,4 +54,3 @@ error 15..15: expected an item error 17..17: expected an item error 24..24: expected SEMICOLON error 24..24: expected expression -error 25..25: expected SEMICOLON diff --git a/crates/syntax/test_data/parser/err/0022_bad_exprs.rast b/crates/syntax/test_data/parser/err/0022_bad_exprs.rast index 71fb19783a..7e6d82bfb4 100644 --- a/crates/syntax/test_data/parser/err/0022_bad_exprs.rast +++ b/crates/syntax/test_data/parser/err/0022_bad_exprs.rast @@ -24,9 +24,8 @@ SOURCE_FILE@0..112 WHITESPACE@15..16 " " ERROR@16..17 AT@16..17 "@" - EXPR_STMT@17..18 - ERROR@17..18 - COMMA@17..18 "," + ERROR@17..18 + COMMA@17..18 "," WHITESPACE@18..19 " " STRUCT@19..26 STRUCT_KW@19..25 "struct" @@ -71,15 +70,13 @@ SOURCE_FILE@0..112 WHITESPACE@52..53 " " ERROR@53..54 AT@53..54 "@" - EXPR_STMT@54..55 - ERROR@54..55 - COMMA@54..55 "," + ERROR@54..55 + COMMA@54..55 "," WHITESPACE@55..56 " " IMPL@56..60 IMPL_KW@56..60 "impl" - EXPR_STMT@60..61 - ERROR@60..61 - COMMA@60..61 "," + ERROR@60..61 + COMMA@60..61 "," WHITESPACE@61..62 " " LET_STMT@62..65 LET_KW@62..65 "let" @@ -122,16 +119,13 @@ SOURCE_FILE@0..112 WHITESPACE@91..92 " " ERROR@92..93 AT@92..93 "@" - EXPR_STMT@93..94 - ERROR@93..94 - COMMA@93..94 "," + ERROR@93..94 + COMMA@93..94 "," WHITESPACE@94..95 " " - EXPR_STMT@95..96 - ERROR@95..96 - R_BRACK@95..96 "]" - EXPR_STMT@96..97 - ERROR@96..97 - COMMA@96..97 "," + ERROR@95..96 + R_BRACK@95..96 "]" + ERROR@96..97 + COMMA@96..97 "," WHITESPACE@97..98 " " TRAIT@98..104 TRAIT_KW@98..103 "trait" @@ -149,7 +143,6 @@ error 16..16: expected expression error 17..17: expected R_BRACK error 17..17: expected SEMICOLON error 17..17: expected expression -error 18..18: expected SEMICOLON error 25..25: expected a name error 26..26: expected `;`, `{`, or `(` error 30..30: expected pattern @@ -157,22 +150,17 @@ error 31..31: expected SEMICOLON error 53..53: expected expression error 54..54: expected SEMICOLON error 54..54: expected expression -error 55..55: expected SEMICOLON error 60..60: expected type error 60..60: expected `{` error 60..60: expected expression -error 61..61: expected SEMICOLON error 65..65: expected pattern error 65..65: expected SEMICOLON error 65..65: expected expression error 92..92: expected expression error 93..93: expected SEMICOLON error 93..93: expected expression -error 94..94: expected SEMICOLON error 95..95: expected expression -error 96..96: expected SEMICOLON error 96..96: expected expression -error 97..97: expected SEMICOLON error 103..103: expected a name error 104..104: expected `{` error 108..108: expected pattern diff --git a/crates/syntax/test_data/parser/err/0024_many_type_parens.rast b/crates/syntax/test_data/parser/err/0024_many_type_parens.rast index be4a62940b..d29f12c1e5 100644 --- a/crates/syntax/test_data/parser/err/0024_many_type_parens.rast +++ b/crates/syntax/test_data/parser/err/0024_many_type_parens.rast @@ -143,10 +143,9 @@ SOURCE_FILE@0..240 LIFETIME_IDENT@117..119 "'a" R_ANGLE@119..120 ">" R_PAREN@120..121 ")" - EXPR_STMT@121..123 - ERROR@121..122 - R_ANGLE@121..122 ">" - SEMICOLON@122..123 ";" + ERROR@121..122 + R_ANGLE@121..122 ">" + SEMICOLON@122..123 ";" WHITESPACE@123..128 "\n " LET_STMT@128..141 LET_KW@128..131 "let" @@ -173,13 +172,11 @@ SOURCE_FILE@0..240 PATH_SEGMENT@141..146 NAME_REF@141..146 IDENT@141..146 "Sized" - EXPR_STMT@146..147 - ERROR@146..147 - R_PAREN@146..147 ")" + ERROR@146..147 + R_PAREN@146..147 ")" WHITESPACE@147..148 " " - EXPR_STMT@148..149 - ERROR@148..149 - PLUS@148..149 "+" + ERROR@148..149 + PLUS@148..149 "+" WHITESPACE@149..150 " " EXPR_STMT@150..180 TUPLE_EXPR@150..180 @@ -288,10 +285,9 @@ SOURCE_FILE@0..240 NAME_REF@229..234 IDENT@229..234 "Sized" R_PAREN@234..235 ")" - EXPR_STMT@235..237 - ERROR@235..236 - R_ANGLE@235..236 ">" - SEMICOLON@236..237 ";" + ERROR@235..236 + R_ANGLE@235..236 ">" + SEMICOLON@236..237 ";" WHITESPACE@237..238 "\n" R_CURLY@238..239 "}" WHITESPACE@239..240 "\n" @@ -306,9 +302,7 @@ error 141..141: expected R_ANGLE error 141..141: expected SEMICOLON error 146..146: expected SEMICOLON error 146..146: expected expression -error 147..147: expected SEMICOLON error 148..148: expected expression -error 149..149: expected SEMICOLON error 155..155: expected type error 158..158: expected IN_KW error 165..165: expected expression diff --git a/crates/syntax/test_data/parser/err/0043_weird_blocks.rast b/crates/syntax/test_data/parser/err/0043_weird_blocks.rast index e24f01e292..797a089648 100644 --- a/crates/syntax/test_data/parser/err/0043_weird_blocks.rast +++ b/crates/syntax/test_data/parser/err/0043_weird_blocks.rast @@ -51,12 +51,11 @@ SOURCE_FILE@0..83 BLOCK_EXPR@66..80 L_CURLY@66..67 "{" WHITESPACE@67..68 " " - EXPR_STMT@68..75 - ERROR@68..75 - LABEL@68..75 - LIFETIME@68..74 - LIFETIME_IDENT@68..74 "'label" - COLON@74..75 ":" + ERROR@68..75 + LABEL@68..75 + LIFETIME@68..74 + LIFETIME_IDENT@68..74 "'label" + COLON@74..75 ":" WHITESPACE@75..76 " " LITERAL@76..78 INT_NUMBER@76..78 "92" @@ -69,4 +68,3 @@ error 24..24: expected existential, fn, trait or impl error 41..41: expected existential, fn, trait or impl error 56..56: expected a block error 75..75: expected a loop -error 75..75: expected SEMICOLON diff --git a/crates/syntax/test_data/parser/inline/err/0002_misplaced_label_err.rast b/crates/syntax/test_data/parser/inline/err/0002_misplaced_label_err.rast index 97bb5059d7..3774dd0733 100644 --- a/crates/syntax/test_data/parser/inline/err/0002_misplaced_label_err.rast +++ b/crates/syntax/test_data/parser/inline/err/0002_misplaced_label_err.rast @@ -11,12 +11,11 @@ SOURCE_FILE@0..30 BLOCK_EXPR@10..29 L_CURLY@10..11 "{" WHITESPACE@11..16 "\n " - EXPR_STMT@16..22 - ERROR@16..22 - LABEL@16..22 - LIFETIME@16..21 - LIFETIME_IDENT@16..21 "'loop" - COLON@21..22 ":" + ERROR@16..22 + LABEL@16..22 + LIFETIME@16..21 + LIFETIME_IDENT@16..21 "'loop" + COLON@21..22 ":" WHITESPACE@22..23 " " IMPL@23..27 IMPL_KW@23..27 "impl" @@ -24,6 +23,5 @@ SOURCE_FILE@0..30 R_CURLY@28..29 "}" WHITESPACE@29..30 "\n" error 22..22: expected a loop -error 22..22: expected SEMICOLON error 27..27: expected type error 27..27: expected `{` diff --git a/crates/syntax/test_data/parser/inline/err/0009_attr_on_expr_not_allowed.rast b/crates/syntax/test_data/parser/inline/err/0009_attr_on_expr_not_allowed.rast deleted file mode 100644 index 7b8b7284f9..0000000000 --- a/crates/syntax/test_data/parser/inline/err/0009_attr_on_expr_not_allowed.rast +++ /dev/null @@ -1,60 +0,0 @@ -SOURCE_FILE@0..48 - FN@0..47 - FN_KW@0..2 "fn" - 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_EXPR@9..47 - L_CURLY@9..10 "{" - WHITESPACE@10..14 "\n " - EXPR_STMT@14..25 - ATTR@14..18 - POUND@14..15 "#" - L_BRACK@15..16 "[" - META@16..17 - PATH@16..17 - PATH_SEGMENT@16..17 - NAME_REF@16..17 - 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" - SEMICOLON@24..25 ";" - WHITESPACE@25..29 "\n " - EXPR_STMT@29..45 - ATTR@29..33 - POUND@29..30 "#" - L_BRACK@30..31 "[" - META@31..32 - PATH@31..32 - PATH_SEGMENT@31..32 - NAME_REF@31..32 - IDENT@31..32 "B" - R_BRACK@32..33 "]" - WHITESPACE@33..34 " " - IF_EXPR@34..44 - IF_KW@34..36 "if" - WHITESPACE@36..37 " " - CONDITION@37..41 - LITERAL@37..41 - TRUE_KW@37..41 "true" - WHITESPACE@41..42 " " - BLOCK_EXPR@42..44 - L_CURLY@42..43 "{" - R_CURLY@43..44 "}" - SEMICOLON@44..45 ";" - WHITESPACE@45..46 "\n" - R_CURLY@46..47 "}" - WHITESPACE@47..48 "\n" -error 24..24: attributes are not allowed on BIN_EXPR diff --git a/crates/syntax/test_data/parser/inline/err/0009_attr_on_expr_not_allowed.rs b/crates/syntax/test_data/parser/inline/err/0009_attr_on_expr_not_allowed.rs deleted file mode 100644 index d725a07ce9..0000000000 --- a/crates/syntax/test_data/parser/inline/err/0009_attr_on_expr_not_allowed.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn foo() { - #[A] 1 + 2; - #[B] if true {}; -} diff --git a/crates/syntax/test_data/parser/inline/ok/0126_attr_on_expr_stmt.rast b/crates/syntax/test_data/parser/inline/ok/0126_attr_on_expr_stmt.rast index 178204fece..2a4a52eeb5 100644 --- a/crates/syntax/test_data/parser/inline/ok/0126_attr_on_expr_stmt.rast +++ b/crates/syntax/test_data/parser/inline/ok/0126_attr_on_expr_stmt.rast @@ -12,17 +12,17 @@ SOURCE_FILE@0..82 L_CURLY@9..10 "{" WHITESPACE@10..15 "\n " EXPR_STMT@15..26 - ATTR@15..19 - POUND@15..16 "#" - L_BRACK@16..17 "[" - META@17..18 - PATH@17..18 - PATH_SEGMENT@17..18 - NAME_REF@17..18 - IDENT@17..18 "A" - R_BRACK@18..19 "]" - WHITESPACE@19..20 " " - CALL_EXPR@20..25 + CALL_EXPR@15..25 + ATTR@15..19 + POUND@15..16 "#" + L_BRACK@16..17 "[" + META@17..18 + PATH@17..18 + PATH_SEGMENT@17..18 + NAME_REF@17..18 + IDENT@17..18 "A" + R_BRACK@18..19 "]" + WHITESPACE@19..20 " " PATH_EXPR@20..23 PATH@20..23 PATH_SEGMENT@20..23 @@ -34,17 +34,17 @@ SOURCE_FILE@0..82 SEMICOLON@25..26 ";" WHITESPACE@26..31 "\n " EXPR_STMT@31..42 - ATTR@31..35 - POUND@31..32 "#" - L_BRACK@32..33 "[" - META@33..34 - PATH@33..34 - PATH_SEGMENT@33..34 - NAME_REF@33..34 - IDENT@33..34 "B" - R_BRACK@34..35 "]" - WHITESPACE@35..36 " " - MACRO_CALL@36..42 + MACRO_CALL@31..42 + ATTR@31..35 + POUND@31..32 "#" + L_BRACK@32..33 "[" + META@33..34 + PATH@33..34 + PATH_SEGMENT@33..34 + NAME_REF@33..34 + IDENT@33..34 "B" + R_BRACK@34..35 "]" + WHITESPACE@35..36 " " PATH@36..39 PATH_SEGMENT@36..39 NAME_REF@36..39 @@ -55,42 +55,42 @@ SOURCE_FILE@0..82 R_CURLY@41..42 "}" WHITESPACE@42..47 "\n " EXPR_STMT@47..59 - ATTR@47..51 - POUND@47..48 "#" - L_BRACK@48..49 "[" - META@49..50 - PATH@49..50 - PATH_SEGMENT@49..50 - NAME_REF@49..50 - IDENT@49..50 "C" - R_BRACK@50..51 "]" - WHITESPACE@51..52 " " - ATTR@52..56 - POUND@52..53 "#" - L_BRACK@53..54 "[" - META@54..55 - PATH@54..55 - PATH_SEGMENT@54..55 - NAME_REF@54..55 - IDENT@54..55 "D" - R_BRACK@55..56 "]" - WHITESPACE@56..57 " " - BLOCK_EXPR@57..59 + BLOCK_EXPR@47..59 + ATTR@47..51 + POUND@47..48 "#" + L_BRACK@48..49 "[" + META@49..50 + PATH@49..50 + PATH_SEGMENT@49..50 + NAME_REF@49..50 + IDENT@49..50 "C" + R_BRACK@50..51 "]" + WHITESPACE@51..52 " " + ATTR@52..56 + POUND@52..53 "#" + L_BRACK@53..54 "[" + META@54..55 + PATH@54..55 + PATH_SEGMENT@54..55 + NAME_REF@54..55 + IDENT@54..55 "D" + R_BRACK@55..56 "]" + WHITESPACE@56..57 " " L_CURLY@57..58 "{" R_CURLY@58..59 "}" WHITESPACE@59..64 "\n " EXPR_STMT@64..79 - ATTR@64..68 - POUND@64..65 "#" - L_BRACK@65..66 "[" - META@66..67 - PATH@66..67 - PATH_SEGMENT@66..67 - NAME_REF@66..67 - IDENT@66..67 "D" - R_BRACK@67..68 "]" - WHITESPACE@68..69 " " - RETURN_EXPR@69..78 + RETURN_EXPR@64..78 + ATTR@64..68 + POUND@64..65 "#" + L_BRACK@65..66 "[" + META@66..67 + PATH@66..67 + PATH_SEGMENT@66..67 + NAME_REF@66..67 + IDENT@66..67 "D" + R_BRACK@67..68 "]" + WHITESPACE@68..69 " " RETURN_KW@69..75 "return" WHITESPACE@75..76 " " TUPLE_EXPR@76..78 diff --git a/crates/syntax/test_data/parser/inline/ok/0127_attr_on_last_expr_in_block.rast b/crates/syntax/test_data/parser/inline/ok/0127_attr_on_last_expr_in_block.rast deleted file mode 100644 index 9daac234ac..0000000000 --- a/crates/syntax/test_data/parser/inline/ok/0127_attr_on_last_expr_in_block.rast +++ /dev/null @@ -1,59 +0,0 @@ -SOURCE_FILE@0..47 - FN@0..46 - FN_KW@0..2 "fn" - 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_EXPR@9..46 - L_CURLY@9..10 "{" - WHITESPACE@10..15 "\n " - EXPR_STMT@15..31 - BLOCK_EXPR@15..31 - L_CURLY@15..16 "{" - WHITESPACE@16..17 " " - TRY_EXPR@17..29 - ATTR@17..21 - POUND@17..18 "#" - L_BRACK@18..19 "[" - META@19..20 - PATH@19..20 - PATH_SEGMENT@19..20 - NAME_REF@19..20 - IDENT@19..20 "A" - R_BRACK@20..21 "]" - WHITESPACE@21..22 " " - MACRO_CALL@22..28 - PATH@22..25 - PATH_SEGMENT@22..25 - NAME_REF@22..25 - IDENT@22..25 "bar" - BANG@25..26 "!" - TOKEN_TREE@26..28 - L_PAREN@26..27 "(" - R_PAREN@27..28 ")" - QUESTION@28..29 "?" - WHITESPACE@29..30 " " - R_CURLY@30..31 "}" - WHITESPACE@31..36 "\n " - REF_EXPR@36..44 - ATTR@36..40 - POUND@36..37 "#" - L_BRACK@37..38 "[" - META@38..39 - PATH@38..39 - PATH_SEGMENT@38..39 - NAME_REF@38..39 - IDENT@38..39 "B" - R_BRACK@39..40 "]" - WHITESPACE@40..41 " " - AMP@41..42 "&" - TUPLE_EXPR@42..44 - L_PAREN@42..43 "(" - R_PAREN@43..44 ")" - WHITESPACE@44..45 "\n" - R_CURLY@45..46 "}" - WHITESPACE@46..47 "\n" diff --git a/crates/syntax/test_data/parser/inline/ok/0127_attr_on_last_expr_in_block.rs b/crates/syntax/test_data/parser/inline/ok/0127_attr_on_last_expr_in_block.rs deleted file mode 100644 index 9c5c8eb361..0000000000 --- a/crates/syntax/test_data/parser/inline/ok/0127_attr_on_last_expr_in_block.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn foo() { - { #[A] bar!()? } - #[B] &() -} diff --git a/crates/syntax/test_data/parser/ok/0070_expr_attr_placement.rast b/crates/syntax/test_data/parser/ok/0070_expr_attr_placement.rast new file mode 100644 index 0000000000..925fa4cbf6 --- /dev/null +++ b/crates/syntax/test_data/parser/ok/0070_expr_attr_placement.rast @@ -0,0 +1,58 @@ +SOURCE_FILE@0..44 + FN@0..43 + FN_KW@0..2 "fn" + WHITESPACE@2..3 " " + NAME@3..4 + IDENT@3..4 "f" + PARAM_LIST@4..6 + L_PAREN@4..5 "(" + R_PAREN@5..6 ")" + WHITESPACE@6..7 " " + BLOCK_EXPR@7..43 + L_CURLY@7..8 "{" + WHITESPACE@8..13 "\n " + PAREN_EXPR@13..41 + L_PAREN@13..14 "(" + BIN_EXPR@14..40 + TRY_EXPR@14..23 + ATTR@14..18 + POUND@14..15 "#" + L_BRACK@15..16 "[" + META@16..17 + PATH@16..17 + PATH_SEGMENT@16..17 + NAME_REF@16..17 + IDENT@16..17 "a" + R_BRACK@17..18 "]" + WHITESPACE@18..19 " " + PATH_EXPR@19..22 + PATH@19..22 + PATH_SEGMENT@19..22 + NAME_REF@19..22 + IDENT@19..22 "lhs" + QUESTION@22..23 "?" + WHITESPACE@23..24 " " + PLUS@24..25 "+" + WHITESPACE@25..26 " " + AWAIT_EXPR@26..40 + ATTR@26..30 + POUND@26..27 "#" + L_BRACK@27..28 "[" + META@28..29 + PATH@28..29 + PATH_SEGMENT@28..29 + NAME_REF@28..29 + IDENT@28..29 "b" + R_BRACK@29..30 "]" + WHITESPACE@30..31 " " + PATH_EXPR@31..34 + PATH@31..34 + PATH_SEGMENT@31..34 + NAME_REF@31..34 + IDENT@31..34 "rhs" + DOT@34..35 "." + AWAIT_KW@35..40 "await" + R_PAREN@40..41 ")" + WHITESPACE@41..42 "\n" + R_CURLY@42..43 "}" + WHITESPACE@43..44 "\n" diff --git a/crates/syntax/test_data/parser/ok/0070_expr_attr_placement.rs b/crates/syntax/test_data/parser/ok/0070_expr_attr_placement.rs new file mode 100644 index 0000000000..d8b7a3832a --- /dev/null +++ b/crates/syntax/test_data/parser/ok/0070_expr_attr_placement.rs @@ -0,0 +1,3 @@ +fn f() { + (#[a] lhs? + #[b] rhs.await) +} diff --git a/crates/syntax/test_data/parser/ok/0071_stmt_attr_placement.rast b/crates/syntax/test_data/parser/ok/0071_stmt_attr_placement.rast new file mode 100644 index 0000000000..3a00212e80 --- /dev/null +++ b/crates/syntax/test_data/parser/ok/0071_stmt_attr_placement.rast @@ -0,0 +1,69 @@ +SOURCE_FILE@0..52 + FN@0..51 + FN_KW@0..2 "fn" + 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_EXPR@9..51 + L_CURLY@9..10 "{" + WHITESPACE@10..15 "\n " + EXPR_STMT@15..36 + BLOCK_EXPR@15..36 + ATTR@15..19 + POUND@15..16 "#" + L_BRACK@16..17 "[" + META@17..18 + PATH@17..18 + PATH_SEGMENT@17..18 + NAME_REF@17..18 + IDENT@17..18 "A" + R_BRACK@18..19 "]" + WHITESPACE@19..20 " " + L_CURLY@20..21 "{" + WHITESPACE@21..22 " " + TRY_EXPR@22..34 + ATTR@22..26 + POUND@22..23 "#" + L_BRACK@23..24 "[" + META@24..25 + PATH@24..25 + PATH_SEGMENT@24..25 + NAME_REF@24..25 + IDENT@24..25 "B" + R_BRACK@25..26 "]" + WHITESPACE@26..27 " " + MACRO_CALL@27..33 + PATH@27..30 + PATH_SEGMENT@27..30 + NAME_REF@27..30 + IDENT@27..30 "bar" + BANG@30..31 "!" + TOKEN_TREE@31..33 + L_PAREN@31..32 "(" + R_PAREN@32..33 ")" + QUESTION@33..34 "?" + WHITESPACE@34..35 " " + R_CURLY@35..36 "}" + WHITESPACE@36..41 "\n " + REF_EXPR@41..49 + ATTR@41..45 + POUND@41..42 "#" + L_BRACK@42..43 "[" + META@43..44 + PATH@43..44 + PATH_SEGMENT@43..44 + NAME_REF@43..44 + IDENT@43..44 "C" + R_BRACK@44..45 "]" + WHITESPACE@45..46 " " + AMP@46..47 "&" + TUPLE_EXPR@47..49 + L_PAREN@47..48 "(" + R_PAREN@48..49 ")" + WHITESPACE@49..50 "\n" + R_CURLY@50..51 "}" + WHITESPACE@51..52 "\n" diff --git a/crates/syntax/test_data/parser/ok/0071_stmt_attr_placement.rs b/crates/syntax/test_data/parser/ok/0071_stmt_attr_placement.rs new file mode 100644 index 0000000000..b4d5204bc0 --- /dev/null +++ b/crates/syntax/test_data/parser/ok/0071_stmt_attr_placement.rs @@ -0,0 +1,4 @@ +fn foo() { + #[A] { #[B] bar!()? } + #[C] &() +}