mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 08:34:33 +00:00
don't use a tuple to ensure non-emptiness
This commit is contained in:
parent
64a562ebc6
commit
a98113c88d
6 changed files with 46 additions and 67 deletions
|
@ -462,17 +462,17 @@ pub fn canonicalize_expr(
|
|||
|
||||
let mut can_branches = Vec::with_capacity(branches.len());
|
||||
|
||||
for ((loc_pattern, _), loc_expr) in branches {
|
||||
for (loc_pattern, loc_expr) in branches {
|
||||
let mut shadowable_idents = scope.idents.clone();
|
||||
|
||||
remove_idents(&loc_pattern.value, &mut shadowable_idents);
|
||||
remove_idents(&loc_pattern.first().unwrap().value, &mut shadowable_idents);
|
||||
|
||||
let (can_pattern, loc_can_expr, branch_references) = canonicalize_when_branch(
|
||||
env,
|
||||
var_store,
|
||||
scope,
|
||||
region,
|
||||
loc_pattern,
|
||||
loc_pattern.first().unwrap(),
|
||||
loc_expr,
|
||||
&mut output,
|
||||
);
|
||||
|
|
|
@ -166,17 +166,14 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
|
|||
let loc_desugared_cond = &*arena.alloc(desugar_expr(arena, &loc_cond_expr));
|
||||
let mut desugared_branches = Vec::with_capacity_in(branches.len(), arena);
|
||||
|
||||
for ((loc_pattern, _), loc_branch_expr) in branches.into_iter() {
|
||||
for (loc_pattern, loc_branch_expr) in branches.into_iter() {
|
||||
let desugared = desugar_expr(arena, &loc_branch_expr);
|
||||
|
||||
desugared_branches.push(&*arena.alloc((
|
||||
(
|
||||
Located {
|
||||
region: loc_pattern.region,
|
||||
value: Pattern::Nested(&loc_pattern.value),
|
||||
},
|
||||
Vec::with_capacity_in(0, arena),
|
||||
),
|
||||
bumpalo::vec![in arena; Located {
|
||||
region: loc_pattern.first().unwrap().region,
|
||||
value: Pattern::Nested(&loc_pattern.first().unwrap().value),
|
||||
}],
|
||||
Located {
|
||||
region: desugared.region,
|
||||
value: Nested(&desugared.value),
|
||||
|
@ -254,13 +251,10 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
|
|||
let pattern_region = condition.region;
|
||||
|
||||
branches.push(&*arena.alloc((
|
||||
(
|
||||
Located {
|
||||
bumpalo::vec![in arena; Located {
|
||||
value: Pattern::GlobalTag("False"),
|
||||
region: pattern_region,
|
||||
},
|
||||
Vec::new_in(arena),
|
||||
),
|
||||
}],
|
||||
Located {
|
||||
value: Nested(&else_branch.value),
|
||||
region: else_branch.region,
|
||||
|
@ -268,13 +262,10 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
|
|||
)));
|
||||
|
||||
branches.push(&*arena.alloc((
|
||||
(
|
||||
Located {
|
||||
bumpalo::vec![in arena; Located {
|
||||
value: Pattern::Underscore,
|
||||
region: pattern_region,
|
||||
},
|
||||
Vec::new_in(arena),
|
||||
),
|
||||
}],
|
||||
Located {
|
||||
value: Nested(&then_branch.value),
|
||||
region: then_branch.region,
|
||||
|
|
|
@ -141,16 +141,21 @@ pub fn fmt_expr<'a>(
|
|||
buf.push_str(" is\n");
|
||||
|
||||
let mut it = branches.iter().peekable();
|
||||
while let Some(((pattern, _), expr)) = it.next() {
|
||||
while let Some((patterns, expr)) = it.next() {
|
||||
add_spaces(buf, indent + INDENT);
|
||||
|
||||
match pattern.value {
|
||||
match patterns.first().unwrap().value {
|
||||
Pattern::SpaceBefore(nested, spaces) => {
|
||||
fmt_comments_only(buf, spaces.iter(), indent + INDENT);
|
||||
fmt_pattern(buf, nested, indent + INDENT, false);
|
||||
}
|
||||
_ => {
|
||||
fmt_pattern(buf, &pattern.value, indent + INDENT, false);
|
||||
fmt_pattern(
|
||||
buf,
|
||||
&patterns.first().unwrap().value,
|
||||
indent + INDENT,
|
||||
false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ pub enum Expr<'a> {
|
|||
If(&'a (Loc<Expr<'a>>, Loc<Expr<'a>>, Loc<Expr<'a>>)),
|
||||
When(
|
||||
&'a Loc<Expr<'a>>,
|
||||
Vec<'a, &'a ((Loc<Pattern<'a>>, Vec<'a, Loc<Pattern<'a>>>), Loc<Expr<'a>>)>,
|
||||
Vec<'a, &'a (Vec<'a, Loc<Pattern<'a>>>, Loc<Expr<'a>>)>,
|
||||
),
|
||||
|
||||
// Blank Space (e.g. comments, spaces, newlines) before or after an expression.
|
||||
|
|
|
@ -863,46 +863,29 @@ pub fn when_expr<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>> {
|
|||
|
||||
pub fn case_branches<'a>(
|
||||
min_indent: u16,
|
||||
) -> impl Parser<
|
||||
'a,
|
||||
Vec<
|
||||
'a,
|
||||
&'a (
|
||||
(Located<Pattern<'a>>, Vec<'a, Located<Pattern<'a>>>),
|
||||
Located<Expr<'a>>,
|
||||
),
|
||||
>,
|
||||
> {
|
||||
) -> impl Parser<'a, Vec<'a, &'a (Vec<'a, Located<Pattern<'a>>>, Located<Expr<'a>>)>> {
|
||||
move |arena, state| {
|
||||
let mut branches: Vec<
|
||||
'a,
|
||||
&'a (
|
||||
(Located<Pattern<'a>>, Vec<'a, Located<Pattern<'a>>>),
|
||||
Located<Expr<'a>>,
|
||||
),
|
||||
> = Vec::with_capacity_in(2, arena);
|
||||
let mut branches: Vec<'a, &'a (Vec<'a, Located<Pattern<'a>>>, Located<Expr<'a>>)> =
|
||||
Vec::with_capacity_in(2, arena);
|
||||
|
||||
// 1. Parse the first branch and get its indentation level. (It must be >= min_indent.)
|
||||
// 2. Parse the other branches. Their indentation levels must be == the first branch's.
|
||||
|
||||
let (mut loc_first_pattern, state) =
|
||||
space1_before(loc!(pattern(min_indent)), min_indent).parse(arena, state)?;
|
||||
let (mut loc_first_pattern, state) = sep_by1(
|
||||
map!(and!(space1(min_indent), char('|')), |_| ()),
|
||||
space1_before(loc!(pattern(min_indent)), min_indent),
|
||||
)
|
||||
.parse(arena, state)?;
|
||||
let original_indent = state.indent_col;
|
||||
let indented_more = original_indent + 1;
|
||||
let (loc_first_pattern_alt, state) = zero_or_more!(skip_first!(
|
||||
and!(space0(min_indent), char('|')),
|
||||
space0_before(loc!(pattern(min_indent)), min_indent)
|
||||
))
|
||||
.parse(arena, state)?;
|
||||
let (spaces_before_arrow, state) = space0(min_indent).parse(arena, state)?;
|
||||
|
||||
// Record the spaces before the first "->", if any.
|
||||
if !spaces_before_arrow.is_empty() {
|
||||
let region = loc_first_pattern.region;
|
||||
let value =
|
||||
Pattern::SpaceAfter(arena.alloc(loc_first_pattern.value), spaces_before_arrow);
|
||||
|
||||
loc_first_pattern = Located { region, value };
|
||||
let last = loc_first_pattern.pop().unwrap();
|
||||
let region = last.region;
|
||||
let value = Pattern::SpaceAfter(arena.alloc(last.value), spaces_before_arrow);
|
||||
loc_first_pattern.push(Located { region, value });
|
||||
};
|
||||
|
||||
// Parse the first "->" and the expression after it.
|
||||
|
@ -917,14 +900,14 @@ pub fn case_branches<'a>(
|
|||
.parse(arena, state)?;
|
||||
|
||||
// Record this as the first branch, then optionally parse additional branches.
|
||||
branches.push(arena.alloc(((loc_first_pattern, loc_first_pattern_alt), loc_first_expr)));
|
||||
branches.push(arena.alloc((loc_first_pattern, loc_first_expr)));
|
||||
|
||||
let branch_parser = and!(
|
||||
then(
|
||||
space1_around(loc!(pattern(min_indent)), min_indent),
|
||||
move |_arena, state, loc_pattern| {
|
||||
if state.indent_col == original_indent {
|
||||
Ok(((loc_pattern, Vec::with_capacity_in(0, arena)), state))
|
||||
Ok((bumpalo::vec![in arena; loc_pattern ], state))
|
||||
} else {
|
||||
panic!(
|
||||
"TODO additional branch didn't have same indentation as first branch"
|
||||
|
|
|
@ -1364,14 +1364,14 @@ mod test_parse {
|
|||
let loc_pattern1 = Located::new(1, 1, 1, 7, pattern1);
|
||||
let expr1 = Int("1");
|
||||
let loc_expr1 = Located::new(1, 1, 11, 12, expr1);
|
||||
let branch1 = &*arena.alloc(((loc_pattern1, bumpalo::vec![in &arena;]), loc_expr1));
|
||||
let branch1 = &*arena.alloc((bumpalo::vec![in &arena;loc_pattern1], loc_expr1));
|
||||
let newlines = bumpalo::vec![in &arena; Newline];
|
||||
let pattern2 =
|
||||
Pattern::SpaceBefore(arena.alloc(StrLiteral("mise")), newlines.into_bump_slice());
|
||||
let loc_pattern2 = Located::new(2, 2, 1, 7, pattern2);
|
||||
let expr2 = Int("2");
|
||||
let loc_expr2 = Located::new(2, 2, 11, 12, expr2);
|
||||
let branch2 = &*arena.alloc(((loc_pattern2, bumpalo::vec![in &arena;]), loc_expr2));
|
||||
let branch2 = &*arena.alloc((bumpalo::vec![in &arena;loc_pattern2 ], loc_expr2));
|
||||
let branches = bumpalo::vec![in &arena; branch1, branch2];
|
||||
let loc_cond = Located::new(0, 0, 5, 6, Var(&[], "x"));
|
||||
let expected = Expr::When(arena.alloc(loc_cond), branches);
|
||||
|
@ -1398,14 +1398,14 @@ mod test_parse {
|
|||
let loc_pattern1 = Located::new(1, 1, 1, 2, pattern1);
|
||||
let expr1 = Int("2");
|
||||
let loc_expr1 = Located::new(1, 1, 6, 7, expr1);
|
||||
let branch1 = &*arena.alloc(((loc_pattern1, bumpalo::vec![in &arena;]), loc_expr1));
|
||||
let branch1 = &*arena.alloc((bumpalo::vec![in &arena;loc_pattern1], loc_expr1));
|
||||
let newlines = bumpalo::vec![in &arena; Newline];
|
||||
let pattern2 =
|
||||
Pattern::SpaceBefore(arena.alloc(IntLiteral("3")), newlines.into_bump_slice());
|
||||
let loc_pattern2 = Located::new(2, 2, 1, 2, pattern2);
|
||||
let expr2 = Int("4");
|
||||
let loc_expr2 = Located::new(2, 2, 6, 7, expr2);
|
||||
let branch2 = &*arena.alloc(((loc_pattern2, bumpalo::vec![in &arena;]), loc_expr2));
|
||||
let branch2 = &*arena.alloc((bumpalo::vec![in &arena;loc_pattern2], loc_expr2));
|
||||
let branches = bumpalo::vec![in &arena; branch1, branch2];
|
||||
let loc_cond = Located::new(0, 0, 5, 6, Var(&[], "x"));
|
||||
let expected = Expr::When(arena.alloc(loc_cond), branches);
|
||||
|
@ -1435,7 +1435,7 @@ mod test_parse {
|
|||
let loc_pattern1 = Located::new(1, 1, 1, 6, pattern1);
|
||||
let expr1 = Int("2");
|
||||
let loc_expr1 = Located::new(1, 1, 10, 11, expr1);
|
||||
let branch1 = &*arena.alloc(((loc_pattern1, bumpalo::vec![in &arena;]), loc_expr1));
|
||||
let branch1 = &*arena.alloc((bumpalo::vec![in &arena;loc_pattern1 ], loc_expr1));
|
||||
let newlines = bumpalo::vec![in &arena; Newline];
|
||||
let identifiers2 = bumpalo::vec![in &arena; Located::new(2, 2, 3, 4, Identifier("z")), Located::new(2, 2, 6, 7, Identifier("w")) ];
|
||||
let pattern2 = Pattern::SpaceBefore(
|
||||
|
@ -1445,7 +1445,7 @@ mod test_parse {
|
|||
let loc_pattern2 = Located::new(2, 2, 1, 9, pattern2);
|
||||
let expr2 = Int("4");
|
||||
let loc_expr2 = Located::new(2, 2, 13, 14, expr2);
|
||||
let branch2 = &*arena.alloc(((loc_pattern2, bumpalo::vec![in &arena;]), loc_expr2));
|
||||
let branch2 = &*arena.alloc((bumpalo::vec![in &arena;loc_pattern2 ], loc_expr2));
|
||||
let branches = bumpalo::vec![in &arena; branch1, branch2];
|
||||
let loc_cond = Located::new(0, 0, 5, 6, Var(&[], "x"));
|
||||
let expected = Expr::When(arena.alloc(loc_cond), branches);
|
||||
|
@ -1475,7 +1475,7 @@ mod test_parse {
|
|||
let expr1 = Int("1");
|
||||
let loc_expr1 = Located::new(1, 1, 20, 21, expr1);
|
||||
let branch1 = &*arena.alloc((
|
||||
(loc_pattern1, bumpalo::vec![in &arena;loc_pattern1_alt]),
|
||||
bumpalo::vec![in &arena;loc_pattern1, loc_pattern1_alt],
|
||||
loc_expr1,
|
||||
));
|
||||
let branches = bumpalo::vec![in &arena; branch1];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue