Merge #1950
1950: Fix parsing of block expressions in "forbid_structs" contexts. r=kjeremy a=goffrie Forbidding block expressions entirely is too strict; instead, we should only forbid them in contexts where we are parsing an optional RHS (i.e. the RHS of a range expression). Fixes #1773. Co-authored-by: Geoffry Song <goffrie@gmail.com>
This commit is contained in:
commit
7d1bb35fb1
@ -335,7 +335,13 @@ fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)>
|
||||
// }
|
||||
//
|
||||
let (lhs, blocklike) = atom::atom_expr(p, r)?;
|
||||
return Some(postfix_expr(p, lhs, blocklike, !(r.prefer_stmt && blocklike.is_block())));
|
||||
return Some(postfix_expr(
|
||||
p,
|
||||
lhs,
|
||||
blocklike,
|
||||
!(r.prefer_stmt && blocklike.is_block()),
|
||||
r.forbid_structs,
|
||||
));
|
||||
}
|
||||
};
|
||||
expr_bp(p, r, 255);
|
||||
@ -350,6 +356,7 @@ fn postfix_expr(
|
||||
// `while true {break}; ();`
|
||||
mut block_like: BlockLike,
|
||||
mut allow_calls: bool,
|
||||
forbid_structs: bool,
|
||||
) -> (CompletedMarker, BlockLike) {
|
||||
loop {
|
||||
lhs = match p.current() {
|
||||
@ -363,7 +370,7 @@ fn postfix_expr(
|
||||
// }
|
||||
T!['('] if allow_calls => call_expr(p, lhs),
|
||||
T!['['] if allow_calls => index_expr(p, lhs),
|
||||
T![.] => match postfix_dot_expr(p, lhs) {
|
||||
T![.] => match postfix_dot_expr(p, lhs, forbid_structs) {
|
||||
Ok(it) => it,
|
||||
Err(it) => {
|
||||
lhs = it;
|
||||
@ -382,6 +389,7 @@ fn postfix_expr(
|
||||
fn postfix_dot_expr(
|
||||
p: &mut Parser,
|
||||
lhs: CompletedMarker,
|
||||
forbid_structs: bool,
|
||||
) -> Result<CompletedMarker, CompletedMarker> {
|
||||
assert!(p.at(T![.]));
|
||||
if p.nth(1) == IDENT && (p.nth(2) == T!['('] || p.nth_at(2, T![::])) {
|
||||
@ -402,10 +410,17 @@ fn postfix_dot_expr(
|
||||
}
|
||||
|
||||
// test postfix_range
|
||||
// fn foo() { let x = 1..; }
|
||||
for &(op, la) in [(T![..=], 3), (T![..], 2)].iter() {
|
||||
// fn foo() {
|
||||
// let x = 1..;
|
||||
// match 1.. { _ => () };
|
||||
// match a.b()..S { _ => () };
|
||||
// }
|
||||
for &(op, la) in &[(T![..=], 3), (T![..], 2)] {
|
||||
if p.at(op) {
|
||||
return if EXPR_FIRST.contains(p.nth(la)) {
|
||||
let next_token = p.nth(la);
|
||||
let has_trailing_expression =
|
||||
!(forbid_structs && next_token == T!['{']) && EXPR_FIRST.contains(next_token);
|
||||
return if has_trailing_expression {
|
||||
Err(lhs)
|
||||
} else {
|
||||
let m = lhs.precede(p);
|
||||
|
@ -121,11 +121,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
if r.forbid_structs {
|
||||
return None;
|
||||
} else {
|
||||
block_expr(p, None)
|
||||
}
|
||||
block_expr(p, None)
|
||||
}
|
||||
T![return] => return_expr(p),
|
||||
T![continue] => continue_expr(p),
|
||||
@ -261,6 +257,7 @@ fn lambda_expr(p: &mut Parser) -> CompletedMarker {
|
||||
// if true {} else {};
|
||||
// if true {} else if false {} else {};
|
||||
// if S {};
|
||||
// if { true } { } else { };
|
||||
// }
|
||||
fn if_expr(p: &mut Parser) -> CompletedMarker {
|
||||
assert!(p.at(T![if]));
|
||||
@ -309,6 +306,7 @@ fn loop_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
|
||||
// fn foo() {
|
||||
// while true {};
|
||||
// while let Some(x) = it.next() {};
|
||||
// while { true } {};
|
||||
// }
|
||||
fn while_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
|
||||
assert!(p.at(T![while]));
|
||||
@ -356,6 +354,8 @@ fn cond(p: &mut Parser) {
|
||||
// fn foo() {
|
||||
// match () { };
|
||||
// match S {};
|
||||
// match { } { _ => () };
|
||||
// match { S {} } {};
|
||||
// }
|
||||
fn match_expr(p: &mut Parser) -> CompletedMarker {
|
||||
assert!(p.at(T![match]));
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Stores definitions which must be used in multiple places
|
||||
// See `cargo gen-syntax` (defined in crates/tools/src/main.rs)
|
||||
// See `cargo gen-syntax` (defined in crates/ra_tools/src/main.rs)
|
||||
Grammar(
|
||||
punct: [
|
||||
(";", "SEMI"),
|
||||
|
@ -1,4 +1,5 @@
|
||||
fn foo() {
|
||||
while true {};
|
||||
while let Some(x) = it.next() {};
|
||||
while { true } {};
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
SOURCE_FILE@[0; 70)
|
||||
FN_DEF@[0; 69)
|
||||
SOURCE_FILE@[0; 93)
|
||||
FN_DEF@[0; 92)
|
||||
FN_KW@[0; 2) "fn"
|
||||
WHITESPACE@[2; 3) " "
|
||||
NAME@[3; 6)
|
||||
@ -8,8 +8,8 @@ SOURCE_FILE@[0; 70)
|
||||
L_PAREN@[6; 7) "("
|
||||
R_PAREN@[7; 8) ")"
|
||||
WHITESPACE@[8; 9) " "
|
||||
BLOCK_EXPR@[9; 69)
|
||||
BLOCK@[9; 69)
|
||||
BLOCK_EXPR@[9; 92)
|
||||
BLOCK@[9; 92)
|
||||
L_CURLY@[9; 10) "{"
|
||||
WHITESPACE@[10; 15) "\n "
|
||||
EXPR_STMT@[15; 29)
|
||||
@ -64,6 +64,26 @@ SOURCE_FILE@[0; 70)
|
||||
L_CURLY@[64; 65) "{"
|
||||
R_CURLY@[65; 66) "}"
|
||||
SEMI@[66; 67) ";"
|
||||
WHITESPACE@[67; 68) "\n"
|
||||
R_CURLY@[68; 69) "}"
|
||||
WHITESPACE@[69; 70) "\n"
|
||||
WHITESPACE@[67; 72) "\n "
|
||||
EXPR_STMT@[72; 90)
|
||||
WHILE_EXPR@[72; 89)
|
||||
WHILE_KW@[72; 77) "while"
|
||||
WHITESPACE@[77; 78) " "
|
||||
CONDITION@[78; 86)
|
||||
BLOCK_EXPR@[78; 86)
|
||||
BLOCK@[78; 86)
|
||||
L_CURLY@[78; 79) "{"
|
||||
WHITESPACE@[79; 80) " "
|
||||
LITERAL@[80; 84)
|
||||
TRUE_KW@[80; 84) "true"
|
||||
WHITESPACE@[84; 85) " "
|
||||
R_CURLY@[85; 86) "}"
|
||||
WHITESPACE@[86; 87) " "
|
||||
BLOCK_EXPR@[87; 89)
|
||||
BLOCK@[87; 89)
|
||||
L_CURLY@[87; 88) "{"
|
||||
R_CURLY@[88; 89) "}"
|
||||
SEMI@[89; 90) ";"
|
||||
WHITESPACE@[90; 91) "\n"
|
||||
R_CURLY@[91; 92) "}"
|
||||
WHITESPACE@[92; 93) "\n"
|
||||
|
@ -3,4 +3,5 @@ fn foo() {
|
||||
if true {} else {};
|
||||
if true {} else if false {} else {};
|
||||
if S {};
|
||||
if { true } { } else { };
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
SOURCE_FILE@[0; 107)
|
||||
FN_DEF@[0; 106)
|
||||
SOURCE_FILE@[0; 137)
|
||||
FN_DEF@[0; 136)
|
||||
FN_KW@[0; 2) "fn"
|
||||
WHITESPACE@[2; 3) " "
|
||||
NAME@[3; 6)
|
||||
@ -8,8 +8,8 @@ SOURCE_FILE@[0; 107)
|
||||
L_PAREN@[6; 7) "("
|
||||
R_PAREN@[7; 8) ")"
|
||||
WHITESPACE@[8; 9) " "
|
||||
BLOCK_EXPR@[9; 106)
|
||||
BLOCK@[9; 106)
|
||||
BLOCK_EXPR@[9; 136)
|
||||
BLOCK@[9; 136)
|
||||
L_CURLY@[9; 10) "{"
|
||||
WHITESPACE@[10; 15) "\n "
|
||||
EXPR_STMT@[15; 26)
|
||||
@ -98,6 +98,35 @@ SOURCE_FILE@[0; 107)
|
||||
L_CURLY@[101; 102) "{"
|
||||
R_CURLY@[102; 103) "}"
|
||||
SEMI@[103; 104) ";"
|
||||
WHITESPACE@[104; 105) "\n"
|
||||
R_CURLY@[105; 106) "}"
|
||||
WHITESPACE@[106; 107) "\n"
|
||||
WHITESPACE@[104; 109) "\n "
|
||||
EXPR_STMT@[109; 134)
|
||||
IF_EXPR@[109; 133)
|
||||
IF_KW@[109; 111) "if"
|
||||
WHITESPACE@[111; 112) " "
|
||||
CONDITION@[112; 120)
|
||||
BLOCK_EXPR@[112; 120)
|
||||
BLOCK@[112; 120)
|
||||
L_CURLY@[112; 113) "{"
|
||||
WHITESPACE@[113; 114) " "
|
||||
LITERAL@[114; 118)
|
||||
TRUE_KW@[114; 118) "true"
|
||||
WHITESPACE@[118; 119) " "
|
||||
R_CURLY@[119; 120) "}"
|
||||
WHITESPACE@[120; 121) " "
|
||||
BLOCK_EXPR@[121; 124)
|
||||
BLOCK@[121; 124)
|
||||
L_CURLY@[121; 122) "{"
|
||||
WHITESPACE@[122; 123) " "
|
||||
R_CURLY@[123; 124) "}"
|
||||
WHITESPACE@[124; 125) " "
|
||||
ELSE_KW@[125; 129) "else"
|
||||
WHITESPACE@[129; 130) " "
|
||||
BLOCK_EXPR@[130; 133)
|
||||
BLOCK@[130; 133)
|
||||
L_CURLY@[130; 131) "{"
|
||||
WHITESPACE@[131; 132) " "
|
||||
R_CURLY@[132; 133) "}"
|
||||
SEMI@[133; 134) ";"
|
||||
WHITESPACE@[134; 135) "\n"
|
||||
R_CURLY@[135; 136) "}"
|
||||
WHITESPACE@[136; 137) "\n"
|
||||
|
@ -1,4 +1,6 @@
|
||||
fn foo() {
|
||||
match () { };
|
||||
match S {};
|
||||
match { } { _ => () };
|
||||
match { S {} } {};
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
SOURCE_FILE@[0; 47)
|
||||
FN_DEF@[0; 46)
|
||||
SOURCE_FILE@[0; 97)
|
||||
FN_DEF@[0; 96)
|
||||
FN_KW@[0; 2) "fn"
|
||||
WHITESPACE@[2; 3) " "
|
||||
NAME@[3; 6)
|
||||
@ -8,8 +8,8 @@ SOURCE_FILE@[0; 47)
|
||||
L_PAREN@[6; 7) "("
|
||||
R_PAREN@[7; 8) ")"
|
||||
WHITESPACE@[8; 9) " "
|
||||
BLOCK_EXPR@[9; 46)
|
||||
BLOCK@[9; 46)
|
||||
BLOCK_EXPR@[9; 96)
|
||||
BLOCK@[9; 96)
|
||||
L_CURLY@[9; 10) "{"
|
||||
WHITESPACE@[10; 15) "\n "
|
||||
EXPR_STMT@[15; 28)
|
||||
@ -40,6 +40,57 @@ SOURCE_FILE@[0; 47)
|
||||
L_CURLY@[41; 42) "{"
|
||||
R_CURLY@[42; 43) "}"
|
||||
SEMI@[43; 44) ";"
|
||||
WHITESPACE@[44; 45) "\n"
|
||||
R_CURLY@[45; 46) "}"
|
||||
WHITESPACE@[46; 47) "\n"
|
||||
WHITESPACE@[44; 49) "\n "
|
||||
EXPR_STMT@[49; 71)
|
||||
MATCH_EXPR@[49; 70)
|
||||
MATCH_KW@[49; 54) "match"
|
||||
WHITESPACE@[54; 55) " "
|
||||
BLOCK_EXPR@[55; 58)
|
||||
BLOCK@[55; 58)
|
||||
L_CURLY@[55; 56) "{"
|
||||
WHITESPACE@[56; 57) " "
|
||||
R_CURLY@[57; 58) "}"
|
||||
WHITESPACE@[58; 59) " "
|
||||
MATCH_ARM_LIST@[59; 70)
|
||||
L_CURLY@[59; 60) "{"
|
||||
WHITESPACE@[60; 61) " "
|
||||
MATCH_ARM@[61; 68)
|
||||
PLACEHOLDER_PAT@[61; 62)
|
||||
UNDERSCORE@[61; 62) "_"
|
||||
WHITESPACE@[62; 63) " "
|
||||
FAT_ARROW@[63; 65) "=>"
|
||||
WHITESPACE@[65; 66) " "
|
||||
TUPLE_EXPR@[66; 68)
|
||||
L_PAREN@[66; 67) "("
|
||||
R_PAREN@[67; 68) ")"
|
||||
WHITESPACE@[68; 69) " "
|
||||
R_CURLY@[69; 70) "}"
|
||||
SEMI@[70; 71) ";"
|
||||
WHITESPACE@[71; 76) "\n "
|
||||
EXPR_STMT@[76; 94)
|
||||
MATCH_EXPR@[76; 93)
|
||||
MATCH_KW@[76; 81) "match"
|
||||
WHITESPACE@[81; 82) " "
|
||||
BLOCK_EXPR@[82; 90)
|
||||
BLOCK@[82; 90)
|
||||
L_CURLY@[82; 83) "{"
|
||||
WHITESPACE@[83; 84) " "
|
||||
RECORD_LIT@[84; 88)
|
||||
PATH@[84; 85)
|
||||
PATH_SEGMENT@[84; 85)
|
||||
NAME_REF@[84; 85)
|
||||
IDENT@[84; 85) "S"
|
||||
WHITESPACE@[85; 86) " "
|
||||
RECORD_FIELD_LIST@[86; 88)
|
||||
L_CURLY@[86; 87) "{"
|
||||
R_CURLY@[87; 88) "}"
|
||||
WHITESPACE@[88; 89) " "
|
||||
R_CURLY@[89; 90) "}"
|
||||
WHITESPACE@[90; 91) " "
|
||||
MATCH_ARM_LIST@[91; 93)
|
||||
L_CURLY@[91; 92) "{"
|
||||
R_CURLY@[92; 93) "}"
|
||||
SEMI@[93; 94) ";"
|
||||
WHITESPACE@[94; 95) "\n"
|
||||
R_CURLY@[95; 96) "}"
|
||||
WHITESPACE@[96; 97) "\n"
|
||||
|
@ -1 +1,5 @@
|
||||
fn foo() { let x = 1..; }
|
||||
fn foo() {
|
||||
let x = 1..;
|
||||
match 1.. { _ => () };
|
||||
match a.b()..S { _ => () };
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
SOURCE_FILE@[0; 26)
|
||||
FN_DEF@[0; 25)
|
||||
SOURCE_FILE@[0; 89)
|
||||
FN_DEF@[0; 88)
|
||||
FN_KW@[0; 2) "fn"
|
||||
WHITESPACE@[2; 3) " "
|
||||
NAME@[3; 6)
|
||||
@ -8,24 +8,89 @@ SOURCE_FILE@[0; 26)
|
||||
L_PAREN@[6; 7) "("
|
||||
R_PAREN@[7; 8) ")"
|
||||
WHITESPACE@[8; 9) " "
|
||||
BLOCK_EXPR@[9; 25)
|
||||
BLOCK@[9; 25)
|
||||
BLOCK_EXPR@[9; 88)
|
||||
BLOCK@[9; 88)
|
||||
L_CURLY@[9; 10) "{"
|
||||
WHITESPACE@[10; 11) " "
|
||||
LET_STMT@[11; 23)
|
||||
LET_KW@[11; 14) "let"
|
||||
WHITESPACE@[14; 15) " "
|
||||
BIND_PAT@[15; 16)
|
||||
NAME@[15; 16)
|
||||
IDENT@[15; 16) "x"
|
||||
WHITESPACE@[16; 17) " "
|
||||
EQ@[17; 18) "="
|
||||
WHITESPACE@[10; 15) "\n "
|
||||
LET_STMT@[15; 27)
|
||||
LET_KW@[15; 18) "let"
|
||||
WHITESPACE@[18; 19) " "
|
||||
RANGE_EXPR@[19; 22)
|
||||
LITERAL@[19; 20)
|
||||
INT_NUMBER@[19; 20) "1"
|
||||
DOTDOT@[20; 22) ".."
|
||||
SEMI@[22; 23) ";"
|
||||
WHITESPACE@[23; 24) " "
|
||||
R_CURLY@[24; 25) "}"
|
||||
WHITESPACE@[25; 26) "\n"
|
||||
BIND_PAT@[19; 20)
|
||||
NAME@[19; 20)
|
||||
IDENT@[19; 20) "x"
|
||||
WHITESPACE@[20; 21) " "
|
||||
EQ@[21; 22) "="
|
||||
WHITESPACE@[22; 23) " "
|
||||
RANGE_EXPR@[23; 26)
|
||||
LITERAL@[23; 24)
|
||||
INT_NUMBER@[23; 24) "1"
|
||||
DOTDOT@[24; 26) ".."
|
||||
SEMI@[26; 27) ";"
|
||||
WHITESPACE@[27; 32) "\n "
|
||||
EXPR_STMT@[32; 54)
|
||||
MATCH_EXPR@[32; 53)
|
||||
MATCH_KW@[32; 37) "match"
|
||||
WHITESPACE@[37; 38) " "
|
||||
RANGE_EXPR@[38; 41)
|
||||
LITERAL@[38; 39)
|
||||
INT_NUMBER@[38; 39) "1"
|
||||
DOTDOT@[39; 41) ".."
|
||||
WHITESPACE@[41; 42) " "
|
||||
MATCH_ARM_LIST@[42; 53)
|
||||
L_CURLY@[42; 43) "{"
|
||||
WHITESPACE@[43; 44) " "
|
||||
MATCH_ARM@[44; 51)
|
||||
PLACEHOLDER_PAT@[44; 45)
|
||||
UNDERSCORE@[44; 45) "_"
|
||||
WHITESPACE@[45; 46) " "
|
||||
FAT_ARROW@[46; 48) "=>"
|
||||
WHITESPACE@[48; 49) " "
|
||||
TUPLE_EXPR@[49; 51)
|
||||
L_PAREN@[49; 50) "("
|
||||
R_PAREN@[50; 51) ")"
|
||||
WHITESPACE@[51; 52) " "
|
||||
R_CURLY@[52; 53) "}"
|
||||
SEMI@[53; 54) ";"
|
||||
WHITESPACE@[54; 59) "\n "
|
||||
EXPR_STMT@[59; 86)
|
||||
MATCH_EXPR@[59; 85)
|
||||
MATCH_KW@[59; 64) "match"
|
||||
WHITESPACE@[64; 65) " "
|
||||
RANGE_EXPR@[65; 73)
|
||||
METHOD_CALL_EXPR@[65; 70)
|
||||
PATH_EXPR@[65; 66)
|
||||
PATH@[65; 66)
|
||||
PATH_SEGMENT@[65; 66)
|
||||
NAME_REF@[65; 66)
|
||||
IDENT@[65; 66) "a"
|
||||
DOT@[66; 67) "."
|
||||
NAME_REF@[67; 68)
|
||||
IDENT@[67; 68) "b"
|
||||
ARG_LIST@[68; 70)
|
||||
L_PAREN@[68; 69) "("
|
||||
R_PAREN@[69; 70) ")"
|
||||
DOTDOT@[70; 72) ".."
|
||||
PATH_EXPR@[72; 73)
|
||||
PATH@[72; 73)
|
||||
PATH_SEGMENT@[72; 73)
|
||||
NAME_REF@[72; 73)
|
||||
IDENT@[72; 73) "S"
|
||||
WHITESPACE@[73; 74) " "
|
||||
MATCH_ARM_LIST@[74; 85)
|
||||
L_CURLY@[74; 75) "{"
|
||||
WHITESPACE@[75; 76) " "
|
||||
MATCH_ARM@[76; 83)
|
||||
PLACEHOLDER_PAT@[76; 77)
|
||||
UNDERSCORE@[76; 77) "_"
|
||||
WHITESPACE@[77; 78) " "
|
||||
FAT_ARROW@[78; 80) "=>"
|
||||
WHITESPACE@[80; 81) " "
|
||||
TUPLE_EXPR@[81; 83)
|
||||
L_PAREN@[81; 82) "("
|
||||
R_PAREN@[82; 83) ")"
|
||||
WHITESPACE@[83; 84) " "
|
||||
R_CURLY@[84; 85) "}"
|
||||
SEMI@[85; 86) ";"
|
||||
WHITESPACE@[86; 87) "\n"
|
||||
R_CURLY@[87; 88) "}"
|
||||
WHITESPACE@[88; 89) "\n"
|
||||
|
Loading…
Reference in New Issue
Block a user