Make sure ext's can't slurp surrounding apply args

This commit is contained in:
Joshua Warner 2024-12-02 19:42:17 -08:00
parent fc74b67d86
commit 1be2075e7f
No known key found for this signature in database
GPG key ID: 89AD497003F93FDD
5 changed files with 101 additions and 8 deletions

View file

@ -97,7 +97,7 @@ fn check_type_alias<'a>(
fn parse_type_alias_after_as<'a>() -> impl Parser<'a, TypeHeader<'a>, EType<'a>> { fn parse_type_alias_after_as<'a>() -> impl Parser<'a, TypeHeader<'a>, EType<'a>> {
then( then(
space0_before_e(term(false), EType::TAsIndentStart), space0_before_e(term_or_apply_with_as(false), EType::TAsIndentStart),
// TODO: introduce a better combinator for this. // TODO: introduce a better combinator for this.
// `check_type_alias` doesn't need to modify the state or progress, but it needs to access `state.pos()` // `check_type_alias` doesn't need to modify the state or progress, but it needs to access `state.pos()`
|arena, state, progress, output| { |arena, state, progress, output| {
@ -112,6 +112,28 @@ fn parse_type_alias_after_as<'a>() -> impl Parser<'a, TypeHeader<'a>, EType<'a>>
} }
fn term<'a>(stop_at_surface_has: bool) -> impl Parser<'a, Loc<TypeAnnotation<'a>>, EType<'a>> { fn term<'a>(stop_at_surface_has: bool) -> impl Parser<'a, Loc<TypeAnnotation<'a>>, EType<'a>> {
one_of!(
loc_wildcard(),
loc_inferred(),
specialize_err(EType::TInParens, loc_type_in_parens(stop_at_surface_has)),
loc(specialize_err(
EType::TRecord,
record_type(stop_at_surface_has)
)),
loc(specialize_err(
EType::TTagUnion,
tag_union_type(stop_at_surface_has)
)),
loc(specialize_err(EType::TApply, concrete_type())),
loc(parse_type_variable(stop_at_surface_has)),
fail(EType::TStart),
)
.trace("type_annotation:term")
}
fn term_or_apply_with_as<'a>(
stop_at_surface_has: bool,
) -> impl Parser<'a, Loc<TypeAnnotation<'a>>, EType<'a>> {
map_with_arena( map_with_arena(
and( and(
one_of!( one_of!(
@ -161,7 +183,7 @@ fn term<'a>(stop_at_surface_has: bool) -> impl Parser<'a, Loc<TypeAnnotation<'a>
} }
}, },
) )
.trace("type_annotation:term") .trace("type_annotation:term_or_apply_with_as")
} }
/// The `*` type variable, e.g. in (List *) Wildcard, /// The `*` type variable, e.g. in (List *) Wildcard,
@ -579,8 +601,11 @@ fn expression<'a>(
stop_at_surface_has: bool, stop_at_surface_has: bool,
) -> impl Parser<'a, Loc<TypeAnnotation<'a>>, EType<'a>> { ) -> impl Parser<'a, Loc<TypeAnnotation<'a>>, EType<'a>> {
(move |arena, state: State<'a>, min_indent: u32| { (move |arena, state: State<'a>, min_indent: u32| {
let (p1, first, state) = space0_before_e(term(stop_at_surface_has), EType::TIndentStart) let (p1, first, state) = space0_before_e(
.parse(arena, state, min_indent)?; term_or_apply_with_as(stop_at_surface_has),
EType::TIndentStart,
)
.parse(arena, state, min_indent)?;
let (p2, rest, rest_state) = zero_or_more(skip_first( let (p2, rest, rest_state) = zero_or_more(skip_first(
backtrackable(byte(b',', EType::TFunctionArgument)), backtrackable(byte(b',', EType::TFunctionArgument)),
@ -588,7 +613,10 @@ fn expression<'a>(
map_with_arena( map_with_arena(
and( and(
backtrackable(space0_e(EType::TIndentStart)), backtrackable(space0_e(EType::TIndentStart)),
and(term(stop_at_surface_has), space0_e(EType::TIndentEnd)), and(
term_or_apply_with_as(stop_at_surface_has),
space0_e(EType::TIndentEnd)
),
), ),
comma_args_help, comma_args_help,
), ),
@ -614,9 +642,11 @@ fn expression<'a>(
let (progress, annot, state) = match result { let (progress, annot, state) = match result {
Ok((p3, (space_before_arrow, arrow), state)) => { Ok((p3, (space_before_arrow, arrow), state)) => {
let (p4, return_type, state) = let (p4, return_type, state) = space0_before_e(
space0_before_e(term(stop_at_surface_has), EType::TIndentStart) term_or_apply_with_as(stop_at_surface_has),
.parse(arena, state, min_indent)?; EType::TIndentStart,
)
.parse(arena, state, min_indent)?;
let region = Region::span_across(&first.region, &return_type.region); let region = Region::span_across(&first.region, &return_type.region);

View file

@ -0,0 +1,58 @@
SpaceAfter(
Defs(
Defs {
tags: [
EitherIndex(2147483648),
],
regions: [
@0-10,
],
space_before: [
Slice<roc_parse::ast::CommentOrNewline> { start: 0, length: 0 },
],
space_after: [
Slice<roc_parse::ast::CommentOrNewline> { start: 0, length: 0 },
],
spaces: [],
type_defs: [],
value_defs: [
Annotation(
@0-1 Identifier {
ident: "i",
},
@2-10 Apply(
"",
"M",
[
@3-8 Tuple {
elems: [],
ext: Some(
@6-7 Apply(
"",
"Y",
[],
),
),
},
@9-10 BoundVariable(
"c",
),
],
),
),
],
},
@11-12 SpaceBefore(
Var {
module_name: "",
ident: "t",
},
[
Newline,
],
),
),
[
Newline,
],
)

View file

@ -306,6 +306,7 @@ mod test_snapshots {
pass/apply_record_ann.expr, pass/apply_record_ann.expr,
pass/apply_tag.expr, pass/apply_tag.expr,
pass/apply_three_args.expr, pass/apply_three_args.expr,
pass/apply_tuple_ext_parens_ty.expr,
pass/apply_two_args.expr, pass/apply_two_args.expr,
pass/apply_unary_negation.expr, pass/apply_unary_negation.expr,
pass/apply_unary_not.expr, pass/apply_unary_not.expr,