mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +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::*;
|
use super::*;
|
||||||
|
|
||||||
pub(crate) 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) {
|
pub(crate) fn expr(p: &mut Parser) {
|
||||||
|
@ -143,7 +143,7 @@ pub(crate) fn reparser(
|
||||||
parent: Option<SyntaxKind>,
|
parent: Option<SyntaxKind>,
|
||||||
) -> Option<fn(&mut Parser)> {
|
) -> Option<fn(&mut Parser)> {
|
||||||
let res = match node {
|
let res = match node {
|
||||||
BLOCK_EXPR => expressions::block,
|
BLOCK_EXPR => expressions::block_expr,
|
||||||
RECORD_FIELD_DEF_LIST => items::record_field_def_list,
|
RECORD_FIELD_DEF_LIST => items::record_field_def_list,
|
||||||
RECORD_FIELD_LIST => items::record_field_list,
|
RECORD_FIELD_LIST => items::record_field_list,
|
||||||
ENUM_VARIANT_LIST => items::enum_variant_list,
|
ENUM_VARIANT_LIST => items::enum_variant_list,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
mod atom;
|
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};
|
pub(super) use self::atom::{literal, LITERAL_FIRST};
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
@ -49,19 +49,6 @@ fn expr_no_struct(p: &mut Parser) {
|
||||||
expr_bp(p, r, 1);
|
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 {
|
fn is_expr_stmt_attr_allowed(kind: SyntaxKind) -> bool {
|
||||||
match kind {
|
match kind {
|
||||||
BIN_EXPR | RANGE_EXPR | IF_EXPR => false,
|
BIN_EXPR | RANGE_EXPR | IF_EXPR => false,
|
||||||
|
|
|
@ -132,7 +132,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
|
||||||
// break;
|
// break;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
block_expr(p)
|
block_expr_unchecked(p)
|
||||||
}
|
}
|
||||||
T![return] => return_expr(p),
|
T![return] => return_expr(p),
|
||||||
T![continue] => continue_expr(p),
|
T![continue] => continue_expr(p),
|
||||||
|
@ -240,13 +240,9 @@ fn lambda_expr(p: &mut Parser) -> CompletedMarker {
|
||||||
p.eat(T![move]);
|
p.eat(T![move]);
|
||||||
params::param_list_closure(p);
|
params::param_list_closure(p);
|
||||||
if opt_fn_ret_type(p) {
|
if opt_fn_ret_type(p) {
|
||||||
if p.at(T!['{']) {
|
// test lambda_ret_block
|
||||||
// test lambda_ret_block
|
// fn main() { || -> i32 { 92 }(); }
|
||||||
// fn main() { || -> i32 { 92 }(); }
|
block_expr(p);
|
||||||
block_expr(p);
|
|
||||||
} else {
|
|
||||||
p.error("expected `{`");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if p.at_ts(EXPR_FIRST) {
|
if p.at_ts(EXPR_FIRST) {
|
||||||
expr(p);
|
expr(p);
|
||||||
|
@ -270,13 +266,13 @@ fn if_expr(p: &mut Parser) -> CompletedMarker {
|
||||||
let m = p.start();
|
let m = p.start();
|
||||||
p.bump(T![if]);
|
p.bump(T![if]);
|
||||||
cond(p);
|
cond(p);
|
||||||
block(p);
|
block_expr(p);
|
||||||
if p.at(T![else]) {
|
if p.at(T![else]) {
|
||||||
p.bump(T![else]);
|
p.bump(T![else]);
|
||||||
if p.at(T![if]) {
|
if p.at(T![if]) {
|
||||||
if_expr(p);
|
if_expr(p);
|
||||||
} else {
|
} else {
|
||||||
block(p);
|
block_expr(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m.complete(p, IF_EXPR)
|
m.complete(p, IF_EXPR)
|
||||||
|
@ -304,7 +300,7 @@ fn loop_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
|
||||||
assert!(p.at(T![loop]));
|
assert!(p.at(T![loop]));
|
||||||
let m = m.unwrap_or_else(|| p.start());
|
let m = m.unwrap_or_else(|| p.start());
|
||||||
p.bump(T![loop]);
|
p.bump(T![loop]);
|
||||||
block(p);
|
block_expr(p);
|
||||||
m.complete(p, LOOP_EXPR)
|
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());
|
let m = m.unwrap_or_else(|| p.start());
|
||||||
p.bump(T![while]);
|
p.bump(T![while]);
|
||||||
cond(p);
|
cond(p);
|
||||||
block(p);
|
block_expr(p);
|
||||||
m.complete(p, WHILE_EXPR)
|
m.complete(p, WHILE_EXPR)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,7 +330,7 @@ fn for_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
|
||||||
patterns::pattern(p);
|
patterns::pattern(p);
|
||||||
p.expect(T![in]);
|
p.expect(T![in]);
|
||||||
expr_no_struct(p);
|
expr_no_struct(p);
|
||||||
block(p);
|
block_expr(p);
|
||||||
m.complete(p, FOR_EXPR)
|
m.complete(p, FOR_EXPR)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,11 +463,20 @@ fn match_guard(p: &mut Parser) -> CompletedMarker {
|
||||||
m.complete(p, MATCH_GUARD)
|
m.complete(p, MATCH_GUARD)
|
||||||
}
|
}
|
||||||
|
|
||||||
// test block_expr
|
// test block
|
||||||
// fn foo() {
|
// fn a() {}
|
||||||
// {};
|
// fn b() { let _ = 1; }
|
||||||
// }
|
// fn c() { 1; 2; }
|
||||||
pub(super) fn block_expr(p: &mut Parser) -> CompletedMarker {
|
// 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!['{']));
|
assert!(p.at(T!['{']));
|
||||||
let m = p.start();
|
let m = p.start();
|
||||||
p.bump(T!['{']);
|
p.bump(T!['{']);
|
||||||
|
|
|
@ -329,7 +329,7 @@ fn fn_def(p: &mut Parser) {
|
||||||
if p.at(T![;]) {
|
if p.at(T![;]) {
|
||||||
p.bump(T![;]);
|
p.bump(T![;]);
|
||||||
} else {
|
} else {
|
||||||
expressions::block(p)
|
expressions::block_expr(p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ fn type_arg(p: &mut Parser) {
|
||||||
m.complete(p, ASSOC_TYPE_ARG);
|
m.complete(p, ASSOC_TYPE_ARG);
|
||||||
}
|
}
|
||||||
T!['{'] => {
|
T!['{'] => {
|
||||||
expressions::block(p);
|
expressions::block_expr(p);
|
||||||
m.complete(p, CONST_ARG);
|
m.complete(p, CONST_ARG);
|
||||||
}
|
}
|
||||||
k if k.is_literal() => {
|
k if k.is_literal() => {
|
||||||
|
|
|
@ -112,7 +112,7 @@ pub fn parse_fragment(
|
||||||
FragmentKind::Type => grammar::fragments::type_,
|
FragmentKind::Type => grammar::fragments::type_,
|
||||||
FragmentKind::Pattern => grammar::fragments::pattern,
|
FragmentKind::Pattern => grammar::fragments::pattern,
|
||||||
FragmentKind::Item => grammar::fragments::item,
|
FragmentKind::Item => grammar::fragments::item,
|
||||||
FragmentKind::Block => grammar::fragments::block,
|
FragmentKind::Block => grammar::fragments::block_expr,
|
||||||
FragmentKind::Visibility => grammar::fragments::opt_visibility,
|
FragmentKind::Visibility => grammar::fragments::opt_visibility,
|
||||||
FragmentKind::MetaItem => grammar::fragments::meta_item,
|
FragmentKind::MetaItem => grammar::fragments::meta_item,
|
||||||
FragmentKind::Statement => grammar::fragments::stmt,
|
FragmentKind::Statement => grammar::fragments::stmt,
|
||||||
|
|
|
@ -40,5 +40,5 @@ SOURCE_FILE@0..42
|
||||||
WHITESPACE@39..40 "\n"
|
WHITESPACE@39..40 "\n"
|
||||||
R_CURLY@40..41 "}"
|
R_CURLY@40..41 "}"
|
||||||
WHITESPACE@41..42 "\n"
|
WHITESPACE@41..42 "\n"
|
||||||
error 24..24: expected `{`
|
error 24..24: expected a block
|
||||||
error 24..24: expected SEMICOLON
|
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