Put leading |
in patterns under OrPat
Previously it was one level above, and that caused problems with macros that expand to it, because macros expect to get only one top-level node.
This commit is contained in:
parent
aaae1d4c55
commit
f50b201c86
@ -1598,6 +1598,10 @@ fn collect_pat(&mut self, pat: ast::Pat, binding_list: &mut BindingList) -> PatI
|
|||||||
for (id, _) in current_is_used.into_iter() {
|
for (id, _) in current_is_used.into_iter() {
|
||||||
binding_list.check_is_used(self, id);
|
binding_list.check_is_used(self, id);
|
||||||
}
|
}
|
||||||
|
if let &[pat] = &*pats {
|
||||||
|
// Leading pipe without real OR pattern. Leaving an one-item OR pattern may confuse later stages.
|
||||||
|
return pat;
|
||||||
|
}
|
||||||
Pat::Or(pats.into())
|
Pat::Or(pats.into())
|
||||||
}
|
}
|
||||||
ast::Pat::ParenPat(p) => return self.collect_pat_opt(p.pat(), binding_list),
|
ast::Pat::ParenPat(p) => return self.collect_pat_opt(p.pat(), binding_list),
|
||||||
|
@ -34,6 +34,9 @@
|
|||||||
pub(crate) fn unmerge_match_arm(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
|
pub(crate) fn unmerge_match_arm(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
|
||||||
let pipe_token = ctx.find_token_syntax_at_offset(T![|])?;
|
let pipe_token = ctx.find_token_syntax_at_offset(T![|])?;
|
||||||
let or_pat = ast::OrPat::cast(pipe_token.parent()?)?.clone_for_update();
|
let or_pat = ast::OrPat::cast(pipe_token.parent()?)?.clone_for_update();
|
||||||
|
if or_pat.leading_pipe().is_some_and(|it| it == pipe_token) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
let match_arm = ast::MatchArm::cast(or_pat.syntax().parent()?)?;
|
let match_arm = ast::MatchArm::cast(or_pat.syntax().parent()?)?;
|
||||||
let match_arm_body = match_arm.expr()?;
|
let match_arm_body = match_arm.expr()?;
|
||||||
|
|
||||||
|
@ -21,7 +21,8 @@
|
|||||||
expressions::LITERAL_FIRST.union(paths::PATH_FIRST).union(TokenSet::new(&[T![-], T![const]]));
|
expressions::LITERAL_FIRST.union(paths::PATH_FIRST).union(TokenSet::new(&[T![-], T![const]]));
|
||||||
|
|
||||||
pub(crate) fn pattern(p: &mut Parser<'_>) {
|
pub(crate) fn pattern(p: &mut Parser<'_>) {
|
||||||
pattern_r(p, PAT_RECOVERY_SET);
|
let m = p.start();
|
||||||
|
pattern_r(p, m, false, PAT_RECOVERY_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a pattern list separated by pipes `|`.
|
/// Parses a pattern list separated by pipes `|`.
|
||||||
@ -36,8 +37,9 @@ pub(crate) fn pattern_single(p: &mut Parser<'_>) {
|
|||||||
/// Parses a pattern list separated by pipes `|`
|
/// Parses a pattern list separated by pipes `|`
|
||||||
/// using the given `recovery_set`.
|
/// using the given `recovery_set`.
|
||||||
pub(super) fn pattern_top_r(p: &mut Parser<'_>, recovery_set: TokenSet) {
|
pub(super) fn pattern_top_r(p: &mut Parser<'_>, recovery_set: TokenSet) {
|
||||||
p.eat(T![|]);
|
let m = p.start();
|
||||||
pattern_r(p, recovery_set);
|
let has_leading_pipe = p.eat(T![|]);
|
||||||
|
pattern_r(p, m, has_leading_pipe, recovery_set);
|
||||||
}
|
}
|
||||||
|
|
||||||
// test or_pattern
|
// test or_pattern
|
||||||
@ -51,11 +53,10 @@ pub(super) fn pattern_top_r(p: &mut Parser<'_>, recovery_set: TokenSet) {
|
|||||||
// }
|
// }
|
||||||
/// Parses a pattern list separated by pipes `|`, with no leading `|`,using the
|
/// Parses a pattern list separated by pipes `|`, with no leading `|`,using the
|
||||||
/// given `recovery_set`.
|
/// given `recovery_set`.
|
||||||
fn pattern_r(p: &mut Parser<'_>, recovery_set: TokenSet) {
|
fn pattern_r(p: &mut Parser<'_>, m: Marker, has_leading_pipe: bool, recovery_set: TokenSet) {
|
||||||
let m = p.start();
|
|
||||||
pattern_single_r(p, recovery_set);
|
pattern_single_r(p, recovery_set);
|
||||||
|
|
||||||
if !p.at(T![|]) {
|
if !p.at(T![|]) && !has_leading_pipe {
|
||||||
m.abandon(p);
|
m.abandon(p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -195,6 +195,38 @@ fn macro_pattern() {
|
|||||||
error 0: expected pattern
|
error 0: expected pattern
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
check(
|
||||||
|
TopEntryPoint::Pattern,
|
||||||
|
"| 42 | 43",
|
||||||
|
expect![[r#"
|
||||||
|
OR_PAT
|
||||||
|
PIPE "|"
|
||||||
|
WHITESPACE " "
|
||||||
|
LITERAL_PAT
|
||||||
|
LITERAL
|
||||||
|
INT_NUMBER "42"
|
||||||
|
WHITESPACE " "
|
||||||
|
PIPE "|"
|
||||||
|
WHITESPACE " "
|
||||||
|
LITERAL_PAT
|
||||||
|
LITERAL
|
||||||
|
INT_NUMBER "43"
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
|
||||||
|
check(
|
||||||
|
TopEntryPoint::Pattern,
|
||||||
|
"| 42",
|
||||||
|
expect![[r#"
|
||||||
|
OR_PAT
|
||||||
|
PIPE "|"
|
||||||
|
WHITESPACE " "
|
||||||
|
LITERAL_PAT
|
||||||
|
LITERAL
|
||||||
|
INT_NUMBER "42"
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -102,9 +102,9 @@ SOURCE_FILE
|
|||||||
COMMA ","
|
COMMA ","
|
||||||
WHITESPACE "\n "
|
WHITESPACE "\n "
|
||||||
MATCH_ARM
|
MATCH_ARM
|
||||||
PIPE "|"
|
|
||||||
WHITESPACE " "
|
|
||||||
OR_PAT
|
OR_PAT
|
||||||
|
PIPE "|"
|
||||||
|
WHITESPACE " "
|
||||||
IDENT_PAT
|
IDENT_PAT
|
||||||
NAME
|
NAME
|
||||||
IDENT "X"
|
IDENT "X"
|
||||||
@ -132,11 +132,12 @@ SOURCE_FILE
|
|||||||
COMMA ","
|
COMMA ","
|
||||||
WHITESPACE "\n "
|
WHITESPACE "\n "
|
||||||
MATCH_ARM
|
MATCH_ARM
|
||||||
PIPE "|"
|
OR_PAT
|
||||||
WHITESPACE " "
|
PIPE "|"
|
||||||
IDENT_PAT
|
WHITESPACE " "
|
||||||
NAME
|
IDENT_PAT
|
||||||
IDENT "X"
|
NAME
|
||||||
|
IDENT "X"
|
||||||
WHITESPACE " "
|
WHITESPACE " "
|
||||||
FAT_ARROW "=>"
|
FAT_ARROW "=>"
|
||||||
WHITESPACE " "
|
WHITESPACE " "
|
||||||
|
@ -43,11 +43,12 @@ SOURCE_FILE
|
|||||||
WHITESPACE " "
|
WHITESPACE " "
|
||||||
SLICE_PAT
|
SLICE_PAT
|
||||||
L_BRACK "["
|
L_BRACK "["
|
||||||
PIPE "|"
|
OR_PAT
|
||||||
WHITESPACE " "
|
PIPE "|"
|
||||||
IDENT_PAT
|
WHITESPACE " "
|
||||||
NAME
|
IDENT_PAT
|
||||||
IDENT "a"
|
NAME
|
||||||
|
IDENT "a"
|
||||||
COMMA ","
|
COMMA ","
|
||||||
WHITESPACE " "
|
WHITESPACE " "
|
||||||
REST_PAT
|
REST_PAT
|
||||||
|
@ -91,9 +91,9 @@ SOURCE_FILE
|
|||||||
WHITESPACE " "
|
WHITESPACE " "
|
||||||
TUPLE_PAT
|
TUPLE_PAT
|
||||||
L_PAREN "("
|
L_PAREN "("
|
||||||
PIPE "|"
|
|
||||||
WHITESPACE " "
|
|
||||||
OR_PAT
|
OR_PAT
|
||||||
|
PIPE "|"
|
||||||
|
WHITESPACE " "
|
||||||
IDENT_PAT
|
IDENT_PAT
|
||||||
NAME
|
NAME
|
||||||
IDENT "a"
|
IDENT "a"
|
||||||
@ -105,11 +105,12 @@ SOURCE_FILE
|
|||||||
IDENT "a"
|
IDENT "a"
|
||||||
COMMA ","
|
COMMA ","
|
||||||
WHITESPACE " "
|
WHITESPACE " "
|
||||||
PIPE "|"
|
OR_PAT
|
||||||
WHITESPACE " "
|
PIPE "|"
|
||||||
IDENT_PAT
|
WHITESPACE " "
|
||||||
NAME
|
IDENT_PAT
|
||||||
IDENT "b"
|
NAME
|
||||||
|
IDENT "b"
|
||||||
R_PAREN ")"
|
R_PAREN ")"
|
||||||
WHITESPACE " "
|
WHITESPACE " "
|
||||||
EQ "="
|
EQ "="
|
||||||
|
@ -110,11 +110,12 @@ SOURCE_FILE
|
|||||||
NAME_REF
|
NAME_REF
|
||||||
IDENT "S"
|
IDENT "S"
|
||||||
L_PAREN "("
|
L_PAREN "("
|
||||||
PIPE "|"
|
OR_PAT
|
||||||
WHITESPACE " "
|
PIPE "|"
|
||||||
IDENT_PAT
|
WHITESPACE " "
|
||||||
NAME
|
IDENT_PAT
|
||||||
IDENT "a"
|
NAME
|
||||||
|
IDENT "a"
|
||||||
R_PAREN ")"
|
R_PAREN ")"
|
||||||
WHITESPACE " "
|
WHITESPACE " "
|
||||||
EQ "="
|
EQ "="
|
||||||
|
@ -736,7 +736,7 @@ PathPat =
|
|||||||
Path
|
Path
|
||||||
|
|
||||||
OrPat =
|
OrPat =
|
||||||
(Pat ('|' Pat)* '|'?)
|
'|'? (Pat ('|' Pat)*)
|
||||||
|
|
||||||
BoxPat =
|
BoxPat =
|
||||||
'box' Pat
|
'box' Pat
|
||||||
|
@ -1283,6 +1283,8 @@ pub struct OrPat {
|
|||||||
impl OrPat {
|
impl OrPat {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn pats(&self) -> AstChildren<Pat> { support::children(&self.syntax) }
|
pub fn pats(&self) -> AstChildren<Pat> { support::children(&self.syntax) }
|
||||||
|
#[inline]
|
||||||
|
pub fn pipe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![|]) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
@ -1140,3 +1140,13 @@ fn from(node: ast::AssocItem) -> Self {
|
|||||||
Self::new(node)
|
Self::new(node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ast::OrPat {
|
||||||
|
pub fn leading_pipe(&self) -> Option<SyntaxToken> {
|
||||||
|
self.syntax
|
||||||
|
.children_with_tokens()
|
||||||
|
.find(|it| !it.kind().is_trivia())
|
||||||
|
.and_then(NodeOrToken::into_token)
|
||||||
|
.filter(|it| it.kind() == T![|])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user