Skip to content

Commit

Permalink
Merge pull request #7060 from snobee/early-return-if-else
Browse files Browse the repository at this point in the history
Support "early return" version of if-else statements
  • Loading branch information
smores56 authored Sep 7, 2024
2 parents 527d1dd + 6edee52 commit 9a4d556
Show file tree
Hide file tree
Showing 19 changed files with 262 additions and 88 deletions.
15 changes: 11 additions & 4 deletions crates/compiler/can/src/desugar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -993,10 +993,13 @@ pub fn desugar_expr<'a>(
region: loc_expr.region,
})
}
If(if_thens, final_else_branch) => {
If {
if_thens,
final_else,
indented_else,
} => {
// If does not get desugared into `when` so we can give more targeted error messages during type checking.
let desugared_final_else =
&*env.arena.alloc(desugar_expr(env, scope, final_else_branch));
let desugared_final_else = &*env.arena.alloc(desugar_expr(env, scope, final_else));

let mut desugared_if_thens = Vec::with_capacity_in(if_thens.len(), env.arena);

Expand All @@ -1008,7 +1011,11 @@ pub fn desugar_expr<'a>(
}

env.arena.alloc(Loc {
value: If(desugared_if_thens.into_bump_slice(), desugared_final_else),
value: If {
if_thens: desugared_if_thens.into_bump_slice(),
final_else: desugared_final_else,
indented_else: *indented_else,
},
region: loc_expr.region,
})
}
Expand Down
12 changes: 10 additions & 2 deletions crates/compiler/can/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1261,7 +1261,11 @@ pub fn canonicalize_expr<'a>(
output,
)
}
ast::Expr::If(if_thens, final_else_branch) => {
ast::Expr::If {
if_thens,
final_else: final_else_branch,
..
} => {
let mut branches = Vec::with_capacity(if_thens.len());
let mut output = Output::default();

Expand Down Expand Up @@ -2572,7 +2576,11 @@ pub fn is_valid_interpolation(expr: &ast::Expr<'_>) -> bool {
.iter()
.all(|(loc_expr, _binop)| is_valid_interpolation(&loc_expr.value))
}
ast::Expr::If(branches, final_branch) => {
ast::Expr::If {
if_thens: branches,
final_else: final_branch,
..
} => {
is_valid_interpolation(&final_branch.value)
&& branches.iter().all(|(loc_before, loc_after)| {
is_valid_interpolation(&loc_before.value)
Expand Down
71 changes: 46 additions & 25 deletions crates/compiler/can/src/suffixed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ pub fn unwrap_suffixed_expression<'a>(

Expr::When(..) => unwrap_suffixed_expression_when_help(arena, loc_expr, maybe_def_pat),

Expr::If(..) => {
Expr::If { .. } => {
unwrap_suffixed_expression_if_then_else_help(arena, loc_expr, maybe_def_pat)
}

Expand Down Expand Up @@ -357,7 +357,11 @@ pub fn unwrap_suffixed_expression_if_then_else_help<'a>(
maybe_def_pat: Option<&'a Loc<Pattern<'a>>>,
) -> Result<&'a Loc<Expr<'a>>, EUnwrapped<'a>> {
match loc_expr.value {
Expr::If(if_thens, final_else_branch) => {
Expr::If {
if_thens,
final_else: final_else_branch,
indented_else,
} => {
for (index, if_then) in if_thens.iter().enumerate() {
let (current_if_then_statement, current_if_then_expression) = if_then;

Expand All @@ -376,10 +380,11 @@ pub fn unwrap_suffixed_expression_if_then_else_help<'a>(

let new_if = arena.alloc(Loc::at(
loc_expr.region,
Expr::If(
arena.alloc_slice_copy(new_if_thens.as_slice()),
final_else_branch,
),
Expr::If {
if_thens: arena.alloc_slice_copy(new_if_thens.as_slice()),
final_else: final_else_branch,
indented_else,
},
));

return unwrap_suffixed_expression(arena, new_if, maybe_def_pat);
Expand Down Expand Up @@ -411,10 +416,11 @@ pub fn unwrap_suffixed_expression_if_then_else_help<'a>(

let new_if = arena.alloc(Loc::at(
loc_expr.region,
Expr::If(
arena.alloc_slice_copy(new_if_thens.as_slice()),
final_else_branch,
),
Expr::If {
if_thens: arena.alloc_slice_copy(new_if_thens.as_slice()),
final_else: final_else_branch,
indented_else,
},
));

return unwrap_suffixed_expression(arena, new_if, maybe_def_pat);
Expand All @@ -439,10 +445,11 @@ pub fn unwrap_suffixed_expression_if_then_else_help<'a>(

let new_if = arena.alloc(Loc::at(
loc_expr.region,
Expr::If(
arena.alloc_slice_copy(new_if_thens.as_slice()),
final_else_branch,
),
Expr::If {
if_thens: arena.alloc_slice_copy(new_if_thens.as_slice()),
final_else: final_else_branch,
indented_else,
},
));

return unwrap_suffixed_expression(arena, new_if, maybe_def_pat);
Expand All @@ -465,10 +472,11 @@ pub fn unwrap_suffixed_expression_if_then_else_help<'a>(

let new_if = arena.alloc(Loc::at(
loc_expr.region,
Expr::If(
arena.alloc_slice_copy(new_if_thens.as_slice()),
final_else_branch,
),
Expr::If {
if_thens: arena.alloc_slice_copy(new_if_thens.as_slice()),
final_else: final_else_branch,
indented_else,
},
));

let unwrapped_if_then = apply_try_function(
Expand All @@ -494,10 +502,11 @@ pub fn unwrap_suffixed_expression_if_then_else_help<'a>(

let after_if = arena.alloc(Loc::at(
loc_expr.region,
Expr::If(
arena.alloc_slice_copy(after_if_thens.as_slice()),
final_else_branch,
),
Expr::If {
if_thens: arena.alloc_slice_copy(after_if_thens.as_slice()),
final_else: final_else_branch,
indented_else,
},
));

let after_if_then = apply_try_function(
Expand All @@ -512,7 +521,11 @@ pub fn unwrap_suffixed_expression_if_then_else_help<'a>(

let before_if_then = arena.alloc(Loc::at(
loc_expr.region,
Expr::If(before, after_if_then),
Expr::If {
if_thens: before,
final_else: after_if_then,
indented_else: false,
},
));

return unwrap_suffixed_expression(
Expand All @@ -532,7 +545,11 @@ pub fn unwrap_suffixed_expression_if_then_else_help<'a>(
Ok(unwrapped_final_else) => {
return Ok(arena.alloc(Loc::at(
loc_expr.region,
Expr::If(if_thens, unwrapped_final_else),
Expr::If {
if_thens,
final_else: unwrapped_final_else,
indented_else,
},
)));
}
Err(EUnwrapped::UnwrappedDefExpr { .. }) => {
Expand All @@ -556,7 +573,11 @@ pub fn unwrap_suffixed_expression_if_then_else_help<'a>(

let new_if = arena.alloc(Loc::at(
loc_expr.region,
Expr::If(if_thens, unwrapped_final_else),
Expr::If {
if_thens,
final_else: unwrapped_final_else,
indented_else,
},
));

return unwrap_suffixed_expression(arena, new_if, maybe_def_pat);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ Defs {
),
],
},
@66-130 If(
[
@66-130 If {
if_thens: [
(
@69-70 Var {
module_name: "",
Expand All @@ -76,11 +76,12 @@ Defs {
},
),
],
@128-130 Var {
final_else: @128-130 Var {
module_name: "",
ident: "c",
},
),
indented_else: false,
},
),
guard: None,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ Defs {
ident: "#!1_arg",
},
],
@109-298 If(
[
@109-298 If {
if_thens: [
(
@112-122 Apply(
@112-113 Var {
Expand Down Expand Up @@ -244,7 +244,7 @@ Defs {
),
),
],
Apply(
final_else: Apply(
Var {
module_name: "Task",
ident: "await",
Expand All @@ -269,8 +269,8 @@ Defs {
ident: "#!3_arg",
},
],
@109-298 If(
[
@109-298 If {
if_thens: [
(
@187-209 ParensAround(
Var {
Expand Down Expand Up @@ -366,7 +366,7 @@ Defs {
),
),
],
@283-298 Apply(
final_else: @283-298 Apply(
@283-298 Var {
module_name: "",
ident: "line",
Expand All @@ -380,12 +380,14 @@ Defs {
],
Space,
),
),
indented_else: false,
},
),
],
BangSuffix,
),
),
indented_else: false,
},
),
],
BangSuffix,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ Defs {
ident: "#!0_arg",
},
],
@76-189 If(
[
@76-189 If {
if_thens: [
(
@79-87 Var {
module_name: "",
Expand All @@ -124,7 +124,7 @@ Defs {
),
),
],
@125-132 Apply(
final_else: @125-132 Apply(
@125-132 Var {
module_name: "Task",
ident: "await",
Expand All @@ -140,8 +140,8 @@ Defs {
ident: "#!1_arg",
},
],
@76-189 If(
[
@76-189 If {
if_thens: [
(
@125-132 Var {
module_name: "",
Expand All @@ -163,7 +163,7 @@ Defs {
),
),
],
@178-189 Apply(
final_else: @178-189 Apply(
@178-182 Var {
module_name: "",
ident: "line",
Expand All @@ -177,12 +177,14 @@ Defs {
],
Space,
),
),
indented_else: false,
},
),
],
BangSuffix,
),
),
indented_else: false,
},
),
],
BangSuffix,
Expand Down
Loading

0 comments on commit 9a4d556

Please sign in to comment.