mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Semi statements
This commit is contained in:
parent
bcd6754f12
commit
a04473e2bb
@ -142,6 +142,7 @@ Grammar(
|
|||||||
"STRUCT_PAT",
|
"STRUCT_PAT",
|
||||||
"TUPLE_STRUCT_PAT",
|
"TUPLE_STRUCT_PAT",
|
||||||
"TUPLE_PAT",
|
"TUPLE_PAT",
|
||||||
|
"SLICE_PAT",
|
||||||
|
|
||||||
// atoms
|
// atoms
|
||||||
"TUPLE_EXPR",
|
"TUPLE_EXPR",
|
||||||
|
@ -262,7 +262,7 @@ fn match_arm(p: &mut Parser) -> BlockLike {
|
|||||||
expr_no_struct(p);
|
expr_no_struct(p);
|
||||||
}
|
}
|
||||||
p.expect(FAT_ARROW);
|
p.expect(FAT_ARROW);
|
||||||
let ret = expr(p);
|
let ret = expr_stmt(p);
|
||||||
m.complete(p, MATCH_ARM);
|
m.complete(p, MATCH_ARM);
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
@ -295,7 +295,7 @@ pub(super) fn block_expr(p: &mut Parser) -> CompletedMarker {
|
|||||||
// test pub_expr
|
// test pub_expr
|
||||||
// fn foo() { pub 92; } //FIXME
|
// fn foo() { pub 92; } //FIXME
|
||||||
items::MaybeItem::None => {
|
items::MaybeItem::None => {
|
||||||
let is_blocklike = expressions::expr(p) == BlockLike::Block;
|
let is_blocklike = expressions::expr_stmt(p) == BlockLike::Block;
|
||||||
if p.eat(SEMI) || (is_blocklike && !p.at(R_CURLY)) {
|
if p.eat(SEMI) || (is_blocklike && !p.at(R_CURLY)) {
|
||||||
m.complete(p, EXPR_STMT);
|
m.complete(p, EXPR_STMT);
|
||||||
} else {
|
} else {
|
||||||
|
@ -6,12 +6,17 @@ pub(super) use self::atom::literal;
|
|||||||
const EXPR_FIRST: TokenSet = LHS_FIRST;
|
const EXPR_FIRST: TokenSet = LHS_FIRST;
|
||||||
|
|
||||||
pub(super) fn expr(p: &mut Parser) -> BlockLike {
|
pub(super) fn expr(p: &mut Parser) -> BlockLike {
|
||||||
let r = Restrictions { forbid_structs: false };
|
let r = Restrictions { forbid_structs: false, prefer_stmt: false };
|
||||||
|
expr_bp(p, r, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn expr_stmt(p: &mut Parser) -> BlockLike {
|
||||||
|
let r = Restrictions { forbid_structs: false, prefer_stmt: true };
|
||||||
expr_bp(p, r, 1)
|
expr_bp(p, r, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expr_no_struct(p: &mut Parser) {
|
fn expr_no_struct(p: &mut Parser) {
|
||||||
let r = Restrictions { forbid_structs: true };
|
let r = Restrictions { forbid_structs: true, prefer_stmt: false };
|
||||||
expr_bp(p, r, 1);
|
expr_bp(p, r, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,7 +35,8 @@ pub(super) fn block(p: &mut Parser) {
|
|||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
struct Restrictions {
|
struct Restrictions {
|
||||||
forbid_structs: bool
|
forbid_structs: bool,
|
||||||
|
prefer_stmt: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Op {
|
enum Op {
|
||||||
@ -86,12 +92,18 @@ fn current_op(p: &Parser) -> (u8, Op) {
|
|||||||
|
|
||||||
// Parses expression with binding power of at least bp.
|
// Parses expression with binding power of at least bp.
|
||||||
fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) -> BlockLike {
|
fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) -> BlockLike {
|
||||||
let mut block: bool;
|
|
||||||
let mut lhs = match lhs(p, r) {
|
let mut lhs = match lhs(p, r) {
|
||||||
Some(lhs) => {
|
Some(lhs) => {
|
||||||
block = is_block(lhs.kind());
|
// test stmt_bin_expr_ambiguity
|
||||||
|
// fn foo() {
|
||||||
|
// let _ = {1} & 2;
|
||||||
|
// {1} &2;
|
||||||
|
// }
|
||||||
|
if r.prefer_stmt && is_block(lhs.kind()) {
|
||||||
|
return BlockLike::Block;
|
||||||
|
}
|
||||||
lhs
|
lhs
|
||||||
},
|
}
|
||||||
None => return BlockLike::NotBlock,
|
None => return BlockLike::NotBlock,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -101,7 +113,6 @@ fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) -> BlockLike {
|
|||||||
if op_bp < bp {
|
if op_bp < bp {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
block = false;
|
|
||||||
let m = lhs.precede(p);
|
let m = lhs.precede(p);
|
||||||
match op {
|
match op {
|
||||||
Op::Simple => p.bump(),
|
Op::Simple => p.bump(),
|
||||||
@ -112,7 +123,7 @@ fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) -> BlockLike {
|
|||||||
expr_bp(p, r, op_bp + 1);
|
expr_bp(p, r, op_bp + 1);
|
||||||
lhs = m.complete(p, if is_range { RANGE_EXPR } else { BIN_EXPR });
|
lhs = m.complete(p, if is_range { RANGE_EXPR } else { BIN_EXPR });
|
||||||
}
|
}
|
||||||
if block { BlockLike::Block } else { BlockLike::NotBlock }
|
BlockLike::NotBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
// test no_semi_after_block
|
// test no_semi_after_block
|
||||||
@ -171,18 +182,27 @@ fn lhs(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> {
|
|||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let lhs = atom::atom_expr(p, r)?;
|
let lhs = atom::atom_expr(p, r)?;
|
||||||
return Some(postfix_expr(p, lhs));
|
return Some(postfix_expr(p, r, lhs));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
expr_bp(p, r, 255);
|
expr_bp(p, r, 255);
|
||||||
Some(m.complete(p, kind))
|
Some(m.complete(p, kind))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn postfix_expr(p: &mut Parser, mut lhs: CompletedMarker) -> CompletedMarker {
|
fn postfix_expr(p: &mut Parser, r: Restrictions, mut lhs: CompletedMarker) -> CompletedMarker {
|
||||||
|
let mut allow_calls = !r.prefer_stmt || !is_block(lhs.kind());
|
||||||
loop {
|
loop {
|
||||||
lhs = match p.current() {
|
lhs = match p.current() {
|
||||||
L_PAREN => call_expr(p, lhs),
|
// test stmt_postfix_expr_ambiguity
|
||||||
L_BRACK => index_expr(p, lhs),
|
// fn foo() {
|
||||||
|
// match () {
|
||||||
|
// _ => {}
|
||||||
|
// () => {}
|
||||||
|
// [] => {}
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
L_PAREN if allow_calls => call_expr(p, lhs),
|
||||||
|
L_BRACK if allow_calls => index_expr(p, lhs),
|
||||||
DOT if p.nth(1) == IDENT => if p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON {
|
DOT if p.nth(1) == IDENT => if p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON {
|
||||||
method_call_expr(p, lhs)
|
method_call_expr(p, lhs)
|
||||||
} else {
|
} else {
|
||||||
@ -199,7 +219,8 @@ fn postfix_expr(p: &mut Parser, mut lhs: CompletedMarker) -> CompletedMarker {
|
|||||||
QUESTION => try_expr(p, lhs),
|
QUESTION => try_expr(p, lhs),
|
||||||
AS_KW => cast_expr(p, lhs),
|
AS_KW => cast_expr(p, lhs),
|
||||||
_ => break,
|
_ => break,
|
||||||
}
|
};
|
||||||
|
allow_calls = true
|
||||||
}
|
}
|
||||||
lhs
|
lhs
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ pub(super) fn pattern(p: &mut Parser) {
|
|||||||
UNDERSCORE => placeholder_pat(p),
|
UNDERSCORE => placeholder_pat(p),
|
||||||
AMP => ref_pat(p),
|
AMP => ref_pat(p),
|
||||||
L_PAREN => tuple_pat(p),
|
L_PAREN => tuple_pat(p),
|
||||||
|
L_BRACK => slice_pat(p),
|
||||||
_ => p.err_and_bump("expected pattern"),
|
_ => p.err_and_bump("expected pattern"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,6 +129,28 @@ fn tuple_pat(p: &mut Parser) {
|
|||||||
m.complete(p, TUPLE_PAT);
|
m.complete(p, TUPLE_PAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test slice_pat
|
||||||
|
// fn main() {
|
||||||
|
// let [a, b, ..] = [];
|
||||||
|
// }
|
||||||
|
fn slice_pat(p: &mut Parser) {
|
||||||
|
assert!(p.at(L_BRACK));
|
||||||
|
let m = p.start();
|
||||||
|
p.bump();
|
||||||
|
while !p.at(EOF) && !p.at(R_BRACK) {
|
||||||
|
match p.current() {
|
||||||
|
DOTDOT => p.bump(),
|
||||||
|
_ => pattern(p),
|
||||||
|
}
|
||||||
|
if !p.at(R_BRACK) {
|
||||||
|
p.expect(COMMA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.expect(R_BRACK);
|
||||||
|
|
||||||
|
m.complete(p, SLICE_PAT);
|
||||||
|
}
|
||||||
|
|
||||||
// test bind_pat
|
// test bind_pat
|
||||||
// fn main() {
|
// fn main() {
|
||||||
// let a = ();
|
// let a = ();
|
||||||
|
@ -134,6 +134,7 @@ pub enum SyntaxKind {
|
|||||||
STRUCT_PAT,
|
STRUCT_PAT,
|
||||||
TUPLE_STRUCT_PAT,
|
TUPLE_STRUCT_PAT,
|
||||||
TUPLE_PAT,
|
TUPLE_PAT,
|
||||||
|
SLICE_PAT,
|
||||||
TUPLE_EXPR,
|
TUPLE_EXPR,
|
||||||
ARRAY_EXPR,
|
ARRAY_EXPR,
|
||||||
PAREN_EXPR,
|
PAREN_EXPR,
|
||||||
@ -372,6 +373,7 @@ impl SyntaxKind {
|
|||||||
STRUCT_PAT => &SyntaxInfo { name: "STRUCT_PAT" },
|
STRUCT_PAT => &SyntaxInfo { name: "STRUCT_PAT" },
|
||||||
TUPLE_STRUCT_PAT => &SyntaxInfo { name: "TUPLE_STRUCT_PAT" },
|
TUPLE_STRUCT_PAT => &SyntaxInfo { name: "TUPLE_STRUCT_PAT" },
|
||||||
TUPLE_PAT => &SyntaxInfo { name: "TUPLE_PAT" },
|
TUPLE_PAT => &SyntaxInfo { name: "TUPLE_PAT" },
|
||||||
|
SLICE_PAT => &SyntaxInfo { name: "SLICE_PAT" },
|
||||||
TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" },
|
TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" },
|
||||||
ARRAY_EXPR => &SyntaxInfo { name: "ARRAY_EXPR" },
|
ARRAY_EXPR => &SyntaxInfo { name: "ARRAY_EXPR" },
|
||||||
PAREN_EXPR => &SyntaxInfo { name: "PAREN_EXPR" },
|
PAREN_EXPR => &SyntaxInfo { name: "PAREN_EXPR" },
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
fn foo() {
|
||||||
|
match () {
|
||||||
|
_ => {}
|
||||||
|
() => {}
|
||||||
|
[] => {}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
FILE@[0; 84)
|
||||||
|
FN_ITEM@[0; 83)
|
||||||
|
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_EXPR@[9; 83)
|
||||||
|
L_CURLY@[9; 10)
|
||||||
|
WHITESPACE@[10; 15)
|
||||||
|
MATCH_EXPR@[15; 81)
|
||||||
|
MATCH_KW@[15; 20)
|
||||||
|
WHITESPACE@[20; 21)
|
||||||
|
TUPLE_EXPR@[21; 23)
|
||||||
|
L_PAREN@[21; 22)
|
||||||
|
R_PAREN@[22; 23)
|
||||||
|
WHITESPACE@[23; 24)
|
||||||
|
L_CURLY@[24; 25)
|
||||||
|
WHITESPACE@[25; 34)
|
||||||
|
MATCH_ARM@[34; 41)
|
||||||
|
PLACEHOLDER_PAT@[34; 35)
|
||||||
|
UNDERSCORE@[34; 35)
|
||||||
|
WHITESPACE@[35; 36)
|
||||||
|
FAT_ARROW@[36; 38)
|
||||||
|
WHITESPACE@[38; 39)
|
||||||
|
BLOCK_EXPR@[39; 41)
|
||||||
|
L_CURLY@[39; 40)
|
||||||
|
R_CURLY@[40; 41)
|
||||||
|
WHITESPACE@[41; 50)
|
||||||
|
MATCH_ARM@[50; 58)
|
||||||
|
TUPLE_PAT@[50; 52)
|
||||||
|
L_PAREN@[50; 51)
|
||||||
|
R_PAREN@[51; 52)
|
||||||
|
WHITESPACE@[52; 53)
|
||||||
|
FAT_ARROW@[53; 55)
|
||||||
|
WHITESPACE@[55; 56)
|
||||||
|
BLOCK_EXPR@[56; 58)
|
||||||
|
L_CURLY@[56; 57)
|
||||||
|
R_CURLY@[57; 58)
|
||||||
|
WHITESPACE@[58; 67)
|
||||||
|
MATCH_ARM@[67; 75)
|
||||||
|
SLICE_PAT@[67; 69)
|
||||||
|
L_BRACK@[67; 68)
|
||||||
|
R_BRACK@[68; 69)
|
||||||
|
WHITESPACE@[69; 70)
|
||||||
|
FAT_ARROW@[70; 72)
|
||||||
|
WHITESPACE@[72; 73)
|
||||||
|
BLOCK_EXPR@[73; 75)
|
||||||
|
L_CURLY@[73; 74)
|
||||||
|
R_CURLY@[74; 75)
|
||||||
|
WHITESPACE@[75; 80)
|
||||||
|
R_CURLY@[80; 81)
|
||||||
|
WHITESPACE@[81; 82)
|
||||||
|
R_CURLY@[82; 83)
|
||||||
|
WHITESPACE@[83; 84)
|
4
tests/data/parser/inline/0088_stmt_bin_expr_ambiguity.rs
Normal file
4
tests/data/parser/inline/0088_stmt_bin_expr_ambiguity.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
fn foo() {
|
||||||
|
let _ = {1} & 2;
|
||||||
|
{1} &2;
|
||||||
|
}
|
50
tests/data/parser/inline/0088_stmt_bin_expr_ambiguity.txt
Normal file
50
tests/data/parser/inline/0088_stmt_bin_expr_ambiguity.txt
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
FILE@[0; 46)
|
||||||
|
FN_ITEM@[0; 45)
|
||||||
|
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_EXPR@[9; 45)
|
||||||
|
L_CURLY@[9; 10)
|
||||||
|
WHITESPACE@[10; 15)
|
||||||
|
LET_STMT@[15; 31)
|
||||||
|
LET_KW@[15; 18)
|
||||||
|
WHITESPACE@[18; 19)
|
||||||
|
PLACEHOLDER_PAT@[19; 20)
|
||||||
|
UNDERSCORE@[19; 20)
|
||||||
|
WHITESPACE@[20; 21)
|
||||||
|
EQ@[21; 22)
|
||||||
|
WHITESPACE@[22; 23)
|
||||||
|
BIN_EXPR@[23; 30)
|
||||||
|
BLOCK_EXPR@[23; 26)
|
||||||
|
L_CURLY@[23; 24)
|
||||||
|
LITERAL@[24; 25)
|
||||||
|
INT_NUMBER@[24; 25) "1"
|
||||||
|
R_CURLY@[25; 26)
|
||||||
|
WHITESPACE@[26; 27)
|
||||||
|
AMP@[27; 28)
|
||||||
|
WHITESPACE@[28; 29)
|
||||||
|
LITERAL@[29; 30)
|
||||||
|
INT_NUMBER@[29; 30) "2"
|
||||||
|
SEMI@[30; 31)
|
||||||
|
WHITESPACE@[31; 36)
|
||||||
|
EXPR_STMT@[36; 39)
|
||||||
|
BLOCK_EXPR@[36; 39)
|
||||||
|
L_CURLY@[36; 37)
|
||||||
|
LITERAL@[37; 38)
|
||||||
|
INT_NUMBER@[37; 38) "1"
|
||||||
|
R_CURLY@[38; 39)
|
||||||
|
WHITESPACE@[39; 40)
|
||||||
|
EXPR_STMT@[40; 43)
|
||||||
|
REF_EXPR@[40; 42)
|
||||||
|
AMP@[40; 41)
|
||||||
|
LITERAL@[41; 42)
|
||||||
|
INT_NUMBER@[41; 42) "2"
|
||||||
|
SEMI@[42; 43)
|
||||||
|
WHITESPACE@[43; 44)
|
||||||
|
R_CURLY@[44; 45)
|
||||||
|
WHITESPACE@[45; 46)
|
3
tests/data/parser/inline/0089_slice_pat.rs
Normal file
3
tests/data/parser/inline/0089_slice_pat.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fn main() {
|
||||||
|
let [a, b, ..] = [];
|
||||||
|
}
|
40
tests/data/parser/inline/0089_slice_pat.txt
Normal file
40
tests/data/parser/inline/0089_slice_pat.txt
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
FILE@[0; 39)
|
||||||
|
FN_ITEM@[0; 38)
|
||||||
|
FN_KW@[0; 2)
|
||||||
|
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; 38)
|
||||||
|
L_CURLY@[10; 11)
|
||||||
|
WHITESPACE@[11; 16)
|
||||||
|
LET_STMT@[16; 36)
|
||||||
|
LET_KW@[16; 19)
|
||||||
|
WHITESPACE@[19; 20)
|
||||||
|
SLICE_PAT@[20; 30)
|
||||||
|
L_BRACK@[20; 21)
|
||||||
|
BIND_PAT@[21; 22)
|
||||||
|
NAME@[21; 22)
|
||||||
|
IDENT@[21; 22) "a"
|
||||||
|
COMMA@[22; 23)
|
||||||
|
WHITESPACE@[23; 24)
|
||||||
|
BIND_PAT@[24; 25)
|
||||||
|
NAME@[24; 25)
|
||||||
|
IDENT@[24; 25) "b"
|
||||||
|
COMMA@[25; 26)
|
||||||
|
WHITESPACE@[26; 27)
|
||||||
|
DOTDOT@[27; 29)
|
||||||
|
R_BRACK@[29; 30)
|
||||||
|
WHITESPACE@[30; 31)
|
||||||
|
EQ@[31; 32)
|
||||||
|
WHITESPACE@[32; 33)
|
||||||
|
ARRAY_EXPR@[33; 35)
|
||||||
|
L_BRACK@[33; 34)
|
||||||
|
R_BRACK@[34; 35)
|
||||||
|
SEMI@[35; 36)
|
||||||
|
WHITESPACE@[36; 37)
|
||||||
|
R_CURLY@[37; 38)
|
||||||
|
WHITESPACE@[38; 39)
|
Loading…
x
Reference in New Issue
Block a user