Auto merge of #13096 - jonas-schievink:parse-more-or-pats, r=jonas-schievink
fix: Allow leading `|` in more pattern positions fixes https://github.com/rust-lang/rust-analyzer/issues/12894, fixes https://github.com/rust-lang/rust-analyzer/issues/13094 Oddly, the leading `|` token does not end up inside the `OR_PAT` node, since `pattern_top_r` consumes it first. This is a preexisting issue in match arms though, so I didn't fix it here.
This commit is contained in:
commit
e73b7a9ec7
@ -13,6 +13,8 @@ pub(super) const PATTERN_FIRST: TokenSet =
|
|||||||
T![.],
|
T![.],
|
||||||
]));
|
]));
|
||||||
|
|
||||||
|
const PAT_TOP_FIRST: TokenSet = PATTERN_FIRST.union(TokenSet::new(&[T![|]]));
|
||||||
|
|
||||||
pub(crate) fn pattern(p: &mut Parser<'_>) {
|
pub(crate) fn pattern(p: &mut Parser<'_>) {
|
||||||
pattern_r(p, PAT_RECOVERY_SET);
|
pattern_r(p, PAT_RECOVERY_SET);
|
||||||
}
|
}
|
||||||
@ -228,6 +230,7 @@ fn path_or_macro_pat(p: &mut Parser<'_>) -> CompletedMarker {
|
|||||||
// let S(_) = ();
|
// let S(_) = ();
|
||||||
// let S(_,) = ();
|
// let S(_,) = ();
|
||||||
// let S(_, .. , x) = ();
|
// let S(_, .. , x) = ();
|
||||||
|
// let S(| a) = ();
|
||||||
// }
|
// }
|
||||||
fn tuple_pat_fields(p: &mut Parser<'_>) {
|
fn tuple_pat_fields(p: &mut Parser<'_>) {
|
||||||
assert!(p.at(T!['(']));
|
assert!(p.at(T!['(']));
|
||||||
@ -363,6 +366,7 @@ fn ref_pat(p: &mut Parser<'_>) -> CompletedMarker {
|
|||||||
// let (a,) = ();
|
// let (a,) = ();
|
||||||
// let (..) = ();
|
// let (..) = ();
|
||||||
// let () = ();
|
// let () = ();
|
||||||
|
// let (| a | a, | b) = ((),());
|
||||||
// }
|
// }
|
||||||
fn tuple_pat(p: &mut Parser<'_>) -> CompletedMarker {
|
fn tuple_pat(p: &mut Parser<'_>) -> CompletedMarker {
|
||||||
assert!(p.at(T!['(']));
|
assert!(p.at(T!['(']));
|
||||||
@ -373,13 +377,13 @@ fn tuple_pat(p: &mut Parser<'_>) -> CompletedMarker {
|
|||||||
let mut has_rest = false;
|
let mut has_rest = false;
|
||||||
while !p.at(EOF) && !p.at(T![')']) {
|
while !p.at(EOF) && !p.at(T![')']) {
|
||||||
has_pat = true;
|
has_pat = true;
|
||||||
if !p.at_ts(PATTERN_FIRST) {
|
if !p.at_ts(PAT_TOP_FIRST) {
|
||||||
p.error("expected a pattern");
|
p.error("expected a pattern");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
has_rest |= p.at(T![..]);
|
has_rest |= p.at(T![..]);
|
||||||
|
|
||||||
pattern(p);
|
pattern_top(p);
|
||||||
if !p.at(T![')']) {
|
if !p.at(T![')']) {
|
||||||
has_comma = true;
|
has_comma = true;
|
||||||
p.expect(T![,]);
|
p.expect(T![,]);
|
||||||
@ -393,6 +397,7 @@ fn tuple_pat(p: &mut Parser<'_>) -> CompletedMarker {
|
|||||||
// test slice_pat
|
// test slice_pat
|
||||||
// fn main() {
|
// fn main() {
|
||||||
// let [a, b, ..] = [];
|
// let [a, b, ..] = [];
|
||||||
|
// let [| a, ..] = [];
|
||||||
// }
|
// }
|
||||||
fn slice_pat(p: &mut Parser<'_>) -> CompletedMarker {
|
fn slice_pat(p: &mut Parser<'_>) -> CompletedMarker {
|
||||||
assert!(p.at(T!['[']));
|
assert!(p.at(T!['[']));
|
||||||
@ -405,12 +410,12 @@ fn slice_pat(p: &mut Parser<'_>) -> CompletedMarker {
|
|||||||
|
|
||||||
fn pat_list(p: &mut Parser<'_>, ket: SyntaxKind) {
|
fn pat_list(p: &mut Parser<'_>, ket: SyntaxKind) {
|
||||||
while !p.at(EOF) && !p.at(ket) {
|
while !p.at(EOF) && !p.at(ket) {
|
||||||
if !p.at_ts(PATTERN_FIRST) {
|
if !p.at_ts(PAT_TOP_FIRST) {
|
||||||
p.error("expected a pattern");
|
p.error("expected a pattern");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pattern(p);
|
pattern_top(p);
|
||||||
if !p.at(ket) {
|
if !p.at(ket) {
|
||||||
p.expect(T![,]);
|
p.expect(T![,]);
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,29 @@ SOURCE_FILE
|
|||||||
L_BRACK "["
|
L_BRACK "["
|
||||||
R_BRACK "]"
|
R_BRACK "]"
|
||||||
SEMICOLON ";"
|
SEMICOLON ";"
|
||||||
|
WHITESPACE "\n "
|
||||||
|
LET_STMT
|
||||||
|
LET_KW "let"
|
||||||
|
WHITESPACE " "
|
||||||
|
SLICE_PAT
|
||||||
|
L_BRACK "["
|
||||||
|
PIPE "|"
|
||||||
|
WHITESPACE " "
|
||||||
|
IDENT_PAT
|
||||||
|
NAME
|
||||||
|
IDENT "a"
|
||||||
|
COMMA ","
|
||||||
|
WHITESPACE " "
|
||||||
|
REST_PAT
|
||||||
|
DOT2 ".."
|
||||||
|
R_BRACK "]"
|
||||||
|
WHITESPACE " "
|
||||||
|
EQ "="
|
||||||
|
WHITESPACE " "
|
||||||
|
ARRAY_EXPR
|
||||||
|
L_BRACK "["
|
||||||
|
R_BRACK "]"
|
||||||
|
SEMICOLON ";"
|
||||||
WHITESPACE "\n"
|
WHITESPACE "\n"
|
||||||
R_CURLY "}"
|
R_CURLY "}"
|
||||||
WHITESPACE "\n"
|
WHITESPACE "\n"
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
fn main() {
|
fn main() {
|
||||||
let [a, b, ..] = [];
|
let [a, b, ..] = [];
|
||||||
|
let [| a, ..] = [];
|
||||||
}
|
}
|
||||||
|
@ -100,6 +100,29 @@ SOURCE_FILE
|
|||||||
L_PAREN "("
|
L_PAREN "("
|
||||||
R_PAREN ")"
|
R_PAREN ")"
|
||||||
SEMICOLON ";"
|
SEMICOLON ";"
|
||||||
|
WHITESPACE "\n "
|
||||||
|
LET_STMT
|
||||||
|
LET_KW "let"
|
||||||
|
WHITESPACE " "
|
||||||
|
TUPLE_STRUCT_PAT
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "S"
|
||||||
|
L_PAREN "("
|
||||||
|
PIPE "|"
|
||||||
|
WHITESPACE " "
|
||||||
|
IDENT_PAT
|
||||||
|
NAME
|
||||||
|
IDENT "a"
|
||||||
|
R_PAREN ")"
|
||||||
|
WHITESPACE " "
|
||||||
|
EQ "="
|
||||||
|
WHITESPACE " "
|
||||||
|
TUPLE_EXPR
|
||||||
|
L_PAREN "("
|
||||||
|
R_PAREN ")"
|
||||||
|
SEMICOLON ";"
|
||||||
WHITESPACE "\n"
|
WHITESPACE "\n"
|
||||||
R_CURLY "}"
|
R_CURLY "}"
|
||||||
WHITESPACE "\n"
|
WHITESPACE "\n"
|
||||||
|
@ -3,4 +3,5 @@ fn foo() {
|
|||||||
let S(_) = ();
|
let S(_) = ();
|
||||||
let S(_,) = ();
|
let S(_,) = ();
|
||||||
let S(_, .. , x) = ();
|
let S(_, .. , x) = ();
|
||||||
|
let S(| a) = ();
|
||||||
}
|
}
|
||||||
|
@ -85,6 +85,46 @@ SOURCE_FILE
|
|||||||
L_PAREN "("
|
L_PAREN "("
|
||||||
R_PAREN ")"
|
R_PAREN ")"
|
||||||
SEMICOLON ";"
|
SEMICOLON ";"
|
||||||
|
WHITESPACE "\n "
|
||||||
|
LET_STMT
|
||||||
|
LET_KW "let"
|
||||||
|
WHITESPACE " "
|
||||||
|
TUPLE_PAT
|
||||||
|
L_PAREN "("
|
||||||
|
PIPE "|"
|
||||||
|
WHITESPACE " "
|
||||||
|
OR_PAT
|
||||||
|
IDENT_PAT
|
||||||
|
NAME
|
||||||
|
IDENT "a"
|
||||||
|
WHITESPACE " "
|
||||||
|
PIPE "|"
|
||||||
|
WHITESPACE " "
|
||||||
|
IDENT_PAT
|
||||||
|
NAME
|
||||||
|
IDENT "a"
|
||||||
|
COMMA ","
|
||||||
|
WHITESPACE " "
|
||||||
|
PIPE "|"
|
||||||
|
WHITESPACE " "
|
||||||
|
IDENT_PAT
|
||||||
|
NAME
|
||||||
|
IDENT "b"
|
||||||
|
R_PAREN ")"
|
||||||
|
WHITESPACE " "
|
||||||
|
EQ "="
|
||||||
|
WHITESPACE " "
|
||||||
|
TUPLE_EXPR
|
||||||
|
L_PAREN "("
|
||||||
|
TUPLE_EXPR
|
||||||
|
L_PAREN "("
|
||||||
|
R_PAREN ")"
|
||||||
|
COMMA ","
|
||||||
|
TUPLE_EXPR
|
||||||
|
L_PAREN "("
|
||||||
|
R_PAREN ")"
|
||||||
|
R_PAREN ")"
|
||||||
|
SEMICOLON ";"
|
||||||
WHITESPACE "\n"
|
WHITESPACE "\n"
|
||||||
R_CURLY "}"
|
R_CURLY "}"
|
||||||
WHITESPACE "\n"
|
WHITESPACE "\n"
|
||||||
|
@ -3,4 +3,5 @@ fn main() {
|
|||||||
let (a,) = ();
|
let (a,) = ();
|
||||||
let (..) = ();
|
let (..) = ();
|
||||||
let () = ();
|
let () = ();
|
||||||
|
let (| a | a, | b) = ((),());
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user