Merge pull request #6657 from roc-lang/issue-6074

Fix parsing lists in tag patterns
This commit is contained in:
Luke Boswell 2024-04-22 12:11:31 +10:00 committed by GitHub
commit e4713ce2c5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 65 additions and 19 deletions

View file

@ -46,7 +46,7 @@ pub fn closure_param<'a>() -> impl Parser<'a, Loc<Pattern<'a>>, EPattern<'a>> {
pub fn loc_pattern_help<'a>() -> impl Parser<'a, Loc<Pattern<'a>>, EPattern<'a>> {
move |arena, state: State<'a>, min_indent| {
let (_, pattern, state) = loc_pattern_help_help().parse(arena, state, min_indent)?;
let (_, pattern, state) = loc_pattern_help_help(true).parse(arena, state, min_indent)?;
let pattern_state = state.clone();
@ -82,11 +82,13 @@ pub fn loc_pattern_help<'a>() -> impl Parser<'a, Loc<Pattern<'a>>, EPattern<'a>>
}
}
fn loc_pattern_help_help<'a>() -> impl Parser<'a, Loc<Pattern<'a>>, EPattern<'a>> {
fn loc_pattern_help_help<'a>(
can_have_arguments: bool,
) -> impl Parser<'a, Loc<Pattern<'a>>, EPattern<'a>> {
one_of!(
specialize_err(EPattern::PInParens, loc_pattern_in_parens_help()),
loc!(underscore_pattern_help()),
loc_ident_pattern_help(true),
loc_ident_pattern_help(can_have_arguments),
loc!(specialize_err(
EPattern::Record,
crate::pattern::record_pattern_help()
@ -143,7 +145,8 @@ fn loc_tag_pattern_arg<'a>(
min_indent,
)?;
let (_, loc_pat, state) = loc_parse_tag_pattern_arg().parse(arena, state, min_indent)?;
// Cannot have arguments here, pass `false` to make sure `Foo Bar 1` is parsed as `Foo (Bar) 1`, and not `Foo (Bar 1)`
let (_, loc_pat, state) = loc_pattern_help_help(false).parse(arena, state, min_indent)?;
let Loc { region, value } = loc_pat;
@ -194,21 +197,6 @@ pub fn loc_implements_parser<'a>() -> impl Parser<'a, Loc<Implements<'a>>, EPatt
)
}
fn loc_parse_tag_pattern_arg<'a>() -> impl Parser<'a, Loc<Pattern<'a>>, EPattern<'a>> {
one_of!(
specialize_err(EPattern::PInParens, loc_pattern_in_parens_help()),
loc!(underscore_pattern_help()),
// Make sure `Foo Bar 1` is parsed as `Foo (Bar) 1`, and not `Foo (Bar 1)`
loc_ident_pattern_help(false),
loc!(specialize_err(
EPattern::Record,
crate::pattern::record_pattern_help()
)),
loc!(string_like_pattern_help()),
loc!(number_pattern_help())
)
}
fn loc_pattern_in_parens_help<'a>() -> impl Parser<'a, Loc<Pattern<'a>>, PInParens<'a>> {
then(
loc!(collection_trailing_sep_e!(

View file

@ -0,0 +1,54 @@
When(
@5-10 Apply(
@5-7 Tag(
"Ok",
),
[
@8-10 List(
[],
),
],
Space,
),
[
WhenBranch {
patterns: [
@18-23 SpaceBefore(
Apply(
@18-20 Tag(
"Ok",
),
[
@21-23 List(
[],
),
],
),
[
Newline,
],
),
],
value: @27-29 Record(
[],
),
guard: None,
},
WhenBranch {
patterns: [
@34-35 SpaceBefore(
Underscore(
"",
),
[
Newline,
],
),
],
value: @39-41 Record(
[],
),
guard: None,
},
],
)

View file

@ -0,0 +1,3 @@
when Ok [] is
Ok [] -> {}
_ -> {}

View file

@ -482,6 +482,7 @@ mod test_snapshots {
pass/when_in_function_python_style_indent.expr,
pass/when_in_parens.expr,
pass/when_in_parens_indented.expr,
pass/when_result_list.expr,
pass/when_with_alternative_patterns.expr,
pass/when_with_function_application.expr,
pass/when_with_negative_numbers.expr,