mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
Fix parsing of blocks without {
This commit is contained in:
parent
fb8fb65131
commit
359d3be308
11 changed files with 107 additions and 62 deletions
|
@ -54,7 +54,7 @@ pub(crate) mod fragments {
|
|||
use super::*;
|
||||
|
||||
pub(crate) use super::{
|
||||
expressions::block, paths::type_path as path, patterns::pattern, types::type_,
|
||||
expressions::block_expr, paths::type_path as path, patterns::pattern, types::type_,
|
||||
};
|
||||
|
||||
pub(crate) fn expr(p: &mut Parser) {
|
||||
|
@ -143,7 +143,7 @@ pub(crate) fn reparser(
|
|||
parent: Option<SyntaxKind>,
|
||||
) -> Option<fn(&mut Parser)> {
|
||||
let res = match node {
|
||||
BLOCK_EXPR => expressions::block,
|
||||
BLOCK_EXPR => expressions::block_expr,
|
||||
RECORD_FIELD_DEF_LIST => items::record_field_def_list,
|
||||
RECORD_FIELD_LIST => items::record_field_list,
|
||||
ENUM_VARIANT_LIST => items::enum_variant_list,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
mod atom;
|
||||
|
||||
pub(crate) use self::atom::match_arm_list;
|
||||
pub(crate) use self::atom::{block_expr, match_arm_list};
|
||||
pub(super) use self::atom::{literal, LITERAL_FIRST};
|
||||
use super::*;
|
||||
|
||||
|
@ -49,19 +49,6 @@ fn expr_no_struct(p: &mut Parser) {
|
|||
expr_bp(p, r, 1);
|
||||
}
|
||||
|
||||
// test block
|
||||
// fn a() {}
|
||||
// fn b() { let _ = 1; }
|
||||
// fn c() { 1; 2; }
|
||||
// fn d() { 1; 2 }
|
||||
pub(crate) fn block(p: &mut Parser) {
|
||||
if !p.at(T!['{']) {
|
||||
p.error("expected a block");
|
||||
return;
|
||||
}
|
||||
atom::block_expr(p);
|
||||
}
|
||||
|
||||
fn is_expr_stmt_attr_allowed(kind: SyntaxKind) -> bool {
|
||||
match kind {
|
||||
BIN_EXPR | RANGE_EXPR | IF_EXPR => false,
|
||||
|
|
|
@ -132,7 +132,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
|
|||
// break;
|
||||
// }
|
||||
// }
|
||||
block_expr(p)
|
||||
block_expr_unchecked(p)
|
||||
}
|
||||
T![return] => return_expr(p),
|
||||
T![continue] => continue_expr(p),
|
||||
|
@ -240,13 +240,9 @@ fn lambda_expr(p: &mut Parser) -> CompletedMarker {
|
|||
p.eat(T![move]);
|
||||
params::param_list_closure(p);
|
||||
if opt_fn_ret_type(p) {
|
||||
if p.at(T!['{']) {
|
||||
// test lambda_ret_block
|
||||
// fn main() { || -> i32 { 92 }(); }
|
||||
block_expr(p);
|
||||
} else {
|
||||
p.error("expected `{`");
|
||||
}
|
||||
// test lambda_ret_block
|
||||
// fn main() { || -> i32 { 92 }(); }
|
||||
block_expr(p);
|
||||
} else {
|
||||
if p.at_ts(EXPR_FIRST) {
|
||||
expr(p);
|
||||
|
@ -270,13 +266,13 @@ fn if_expr(p: &mut Parser) -> CompletedMarker {
|
|||
let m = p.start();
|
||||
p.bump(T![if]);
|
||||
cond(p);
|
||||
block(p);
|
||||
block_expr(p);
|
||||
if p.at(T![else]) {
|
||||
p.bump(T![else]);
|
||||
if p.at(T![if]) {
|
||||
if_expr(p);
|
||||
} else {
|
||||
block(p);
|
||||
block_expr(p);
|
||||
}
|
||||
}
|
||||
m.complete(p, IF_EXPR)
|
||||
|
@ -304,7 +300,7 @@ fn loop_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
|
|||
assert!(p.at(T![loop]));
|
||||
let m = m.unwrap_or_else(|| p.start());
|
||||
p.bump(T![loop]);
|
||||
block(p);
|
||||
block_expr(p);
|
||||
m.complete(p, LOOP_EXPR)
|
||||
}
|
||||
|
||||
|
@ -319,7 +315,7 @@ fn while_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
|
|||
let m = m.unwrap_or_else(|| p.start());
|
||||
p.bump(T![while]);
|
||||
cond(p);
|
||||
block(p);
|
||||
block_expr(p);
|
||||
m.complete(p, WHILE_EXPR)
|
||||
}
|
||||
|
||||
|
@ -334,7 +330,7 @@ fn for_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
|
|||
patterns::pattern(p);
|
||||
p.expect(T![in]);
|
||||
expr_no_struct(p);
|
||||
block(p);
|
||||
block_expr(p);
|
||||
m.complete(p, FOR_EXPR)
|
||||
}
|
||||
|
||||
|
@ -467,11 +463,20 @@ fn match_guard(p: &mut Parser) -> CompletedMarker {
|
|||
m.complete(p, MATCH_GUARD)
|
||||
}
|
||||
|
||||
// test block_expr
|
||||
// fn foo() {
|
||||
// {};
|
||||
// }
|
||||
pub(super) fn block_expr(p: &mut Parser) -> CompletedMarker {
|
||||
// test block
|
||||
// fn a() {}
|
||||
// fn b() { let _ = 1; }
|
||||
// fn c() { 1; 2; }
|
||||
// fn d() { 1; 2 }
|
||||
pub(crate) fn block_expr(p: &mut Parser) {
|
||||
if !p.at(T!['{']) {
|
||||
p.error("expected a block");
|
||||
return;
|
||||
}
|
||||
block_expr_unchecked(p);
|
||||
}
|
||||
|
||||
fn block_expr_unchecked(p: &mut Parser) -> CompletedMarker {
|
||||
assert!(p.at(T!['{']));
|
||||
let m = p.start();
|
||||
p.bump(T!['{']);
|
||||
|
|
|
@ -329,7 +329,7 @@ fn fn_def(p: &mut Parser) {
|
|||
if p.at(T![;]) {
|
||||
p.bump(T![;]);
|
||||
} else {
|
||||
expressions::block(p)
|
||||
expressions::block_expr(p)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ fn type_arg(p: &mut Parser) {
|
|||
m.complete(p, ASSOC_TYPE_ARG);
|
||||
}
|
||||
T!['{'] => {
|
||||
expressions::block(p);
|
||||
expressions::block_expr(p);
|
||||
m.complete(p, CONST_ARG);
|
||||
}
|
||||
k if k.is_literal() => {
|
||||
|
|
|
@ -112,7 +112,7 @@ pub fn parse_fragment(
|
|||
FragmentKind::Type => grammar::fragments::type_,
|
||||
FragmentKind::Pattern => grammar::fragments::pattern,
|
||||
FragmentKind::Item => grammar::fragments::item,
|
||||
FragmentKind::Block => grammar::fragments::block,
|
||||
FragmentKind::Block => grammar::fragments::block_expr,
|
||||
FragmentKind::Visibility => grammar::fragments::opt_visibility,
|
||||
FragmentKind::MetaItem => grammar::fragments::meta_item,
|
||||
FragmentKind::Statement => grammar::fragments::stmt,
|
||||
|
|
|
@ -40,5 +40,5 @@ SOURCE_FILE@0..42
|
|||
WHITESPACE@39..40 "\n"
|
||||
R_CURLY@40..41 "}"
|
||||
WHITESPACE@41..42 "\n"
|
||||
error 24..24: expected `{`
|
||||
error 24..24: expected a block
|
||||
error 24..24: expected SEMICOLON
|
||||
|
|
71
crates/ra_syntax/test_data/parser/err/0163_weird_blocks.rast
Normal file
71
crates/ra_syntax/test_data/parser/err/0163_weird_blocks.rast
Normal file
|
@ -0,0 +1,71 @@
|
|||
SOURCE_FILE@0..83
|
||||
FN_DEF@0..82
|
||||
FN_KW@0..2 "fn"
|
||||
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_EXPR@10..82
|
||||
L_CURLY@10..11 "{"
|
||||
WHITESPACE@11..16 "\n "
|
||||
EXPR_STMT@16..29
|
||||
BLOCK_EXPR@16..29
|
||||
L_CURLY@16..17 "{"
|
||||
WHITESPACE@17..18 " "
|
||||
ERROR@18..24
|
||||
UNSAFE_KW@18..24 "unsafe"
|
||||
WHITESPACE@24..25 " "
|
||||
LITERAL@25..27
|
||||
INT_NUMBER@25..27 "92"
|
||||
WHITESPACE@27..28 " "
|
||||
R_CURLY@28..29 "}"
|
||||
WHITESPACE@29..34 "\n "
|
||||
EXPR_STMT@34..46
|
||||
BLOCK_EXPR@34..46
|
||||
L_CURLY@34..35 "{"
|
||||
WHITESPACE@35..36 " "
|
||||
ERROR@36..41
|
||||
ASYNC_KW@36..41 "async"
|
||||
WHITESPACE@41..42 " "
|
||||
LITERAL@42..44
|
||||
INT_NUMBER@42..44 "92"
|
||||
WHITESPACE@44..45 " "
|
||||
R_CURLY@45..46 "}"
|
||||
WHITESPACE@46..51 "\n "
|
||||
EXPR_STMT@51..61
|
||||
BLOCK_EXPR@51..61
|
||||
L_CURLY@51..52 "{"
|
||||
WHITESPACE@52..53 " "
|
||||
EXPR_STMT@53..56
|
||||
EFFECT_EXPR@53..56
|
||||
TRY_KW@53..56 "try"
|
||||
WHITESPACE@56..57 " "
|
||||
LITERAL@57..59
|
||||
INT_NUMBER@57..59 "92"
|
||||
WHITESPACE@59..60 " "
|
||||
R_CURLY@60..61 "}"
|
||||
WHITESPACE@61..66 "\n "
|
||||
BLOCK_EXPR@66..80
|
||||
L_CURLY@66..67 "{"
|
||||
WHITESPACE@67..68 " "
|
||||
EXPR_STMT@68..75
|
||||
ERROR@68..75
|
||||
LABEL@68..75
|
||||
LIFETIME@68..74 "\'label"
|
||||
COLON@74..75 ":"
|
||||
WHITESPACE@75..76 " "
|
||||
LITERAL@76..78
|
||||
INT_NUMBER@76..78 "92"
|
||||
WHITESPACE@78..79 " "
|
||||
R_CURLY@79..80 "}"
|
||||
WHITESPACE@80..81 "\n"
|
||||
R_CURLY@81..82 "}"
|
||||
WHITESPACE@82..83 "\n"
|
||||
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
|
|
@ -0,0 +1,6 @@
|
|||
fn main() {
|
||||
{ unsafe 92 }
|
||||
{ async 92 }
|
||||
{ try 92 }
|
||||
{ 'label: 92 }
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
SOURCE_FILE@0..21
|
||||
FN_DEF@0..20
|
||||
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..20
|
||||
L_CURLY@9..10 "{"
|
||||
WHITESPACE@10..15 "\n "
|
||||
EXPR_STMT@15..18
|
||||
BLOCK_EXPR@15..17
|
||||
L_CURLY@15..16 "{"
|
||||
R_CURLY@16..17 "}"
|
||||
SEMICOLON@17..18 ";"
|
||||
WHITESPACE@18..19 "\n"
|
||||
R_CURLY@19..20 "}"
|
||||
WHITESPACE@20..21 "\n"
|
|
@ -1,3 +0,0 @@
|
|||
fn foo() {
|
||||
{};
|
||||
}
|
Loading…
Reference in a new issue