mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 06:44:46 +00:00
feat(mono): return Stmt::RuntimeError on bad layouts for If
This commit is contained in:
parent
16542f0e1e
commit
39d39c218f
1 changed files with 109 additions and 104 deletions
|
@ -3150,118 +3150,123 @@ pub fn with_hole<'a>(
|
||||||
branches,
|
branches,
|
||||||
final_else,
|
final_else,
|
||||||
} => {
|
} => {
|
||||||
let ret_layout = layout_cache
|
match (
|
||||||
.from_var(env.arena, branch_var, env.subs)
|
layout_cache.from_var(env.arena, branch_var, env.subs),
|
||||||
.expect("invalid ret_layout");
|
layout_cache.from_var(env.arena, cond_var, env.subs),
|
||||||
let cond_layout = layout_cache
|
) {
|
||||||
.from_var(env.arena, cond_var, env.subs)
|
(Ok(ret_layout), Ok(cond_layout)) => {
|
||||||
.expect("invalid cond_layout");
|
// if the hole is a return, then we don't need to merge the two
|
||||||
|
// branches together again, we can just immediately return
|
||||||
|
let is_terminated = matches!(hole, Stmt::Ret(_));
|
||||||
|
|
||||||
// if the hole is a return, then we don't need to merge the two
|
if is_terminated {
|
||||||
// branches together again, we can just immediately return
|
let terminator = hole;
|
||||||
let is_terminated = matches!(hole, Stmt::Ret(_));
|
|
||||||
|
|
||||||
if is_terminated {
|
let mut stmt = with_hole(
|
||||||
let terminator = hole;
|
env,
|
||||||
|
final_else.value,
|
||||||
|
branch_var,
|
||||||
|
procs,
|
||||||
|
layout_cache,
|
||||||
|
assigned,
|
||||||
|
terminator,
|
||||||
|
);
|
||||||
|
|
||||||
let mut stmt = with_hole(
|
for (loc_cond, loc_then) in branches.into_iter().rev() {
|
||||||
env,
|
let branching_symbol = env.unique_symbol();
|
||||||
final_else.value,
|
|
||||||
branch_var,
|
|
||||||
procs,
|
|
||||||
layout_cache,
|
|
||||||
assigned,
|
|
||||||
terminator,
|
|
||||||
);
|
|
||||||
|
|
||||||
for (loc_cond, loc_then) in branches.into_iter().rev() {
|
let then = with_hole(
|
||||||
let branching_symbol = env.unique_symbol();
|
env,
|
||||||
|
loc_then.value,
|
||||||
|
branch_var,
|
||||||
|
procs,
|
||||||
|
layout_cache,
|
||||||
|
assigned,
|
||||||
|
terminator,
|
||||||
|
);
|
||||||
|
|
||||||
let then = with_hole(
|
stmt = cond(env, branching_symbol, cond_layout, then, stmt, ret_layout);
|
||||||
env,
|
|
||||||
loc_then.value,
|
|
||||||
branch_var,
|
|
||||||
procs,
|
|
||||||
layout_cache,
|
|
||||||
assigned,
|
|
||||||
terminator,
|
|
||||||
);
|
|
||||||
|
|
||||||
stmt = cond(env, branching_symbol, cond_layout, then, stmt, ret_layout);
|
// add condition
|
||||||
|
stmt = with_hole(
|
||||||
|
env,
|
||||||
|
loc_cond.value,
|
||||||
|
cond_var,
|
||||||
|
procs,
|
||||||
|
layout_cache,
|
||||||
|
branching_symbol,
|
||||||
|
env.arena.alloc(stmt),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
stmt
|
||||||
|
} else {
|
||||||
|
let assigned_in_jump = env.unique_symbol();
|
||||||
|
let id = JoinPointId(env.unique_symbol());
|
||||||
|
|
||||||
// add condition
|
let terminator = env
|
||||||
stmt = with_hole(
|
.arena
|
||||||
env,
|
.alloc(Stmt::Jump(id, env.arena.alloc([assigned_in_jump])));
|
||||||
loc_cond.value,
|
|
||||||
cond_var,
|
let mut stmt = with_hole(
|
||||||
procs,
|
env,
|
||||||
layout_cache,
|
final_else.value,
|
||||||
branching_symbol,
|
branch_var,
|
||||||
env.arena.alloc(stmt),
|
procs,
|
||||||
);
|
layout_cache,
|
||||||
}
|
assigned_in_jump,
|
||||||
stmt
|
terminator,
|
||||||
} else {
|
);
|
||||||
let assigned_in_jump = env.unique_symbol();
|
|
||||||
let id = JoinPointId(env.unique_symbol());
|
for (loc_cond, loc_then) in branches.into_iter().rev() {
|
||||||
|
let branching_symbol =
|
||||||
let terminator = env
|
possible_reuse_symbol(env, procs, &loc_cond.value);
|
||||||
.arena
|
|
||||||
.alloc(Stmt::Jump(id, env.arena.alloc([assigned_in_jump])));
|
let then = with_hole(
|
||||||
|
env,
|
||||||
let mut stmt = with_hole(
|
loc_then.value,
|
||||||
env,
|
branch_var,
|
||||||
final_else.value,
|
procs,
|
||||||
branch_var,
|
layout_cache,
|
||||||
procs,
|
assigned_in_jump,
|
||||||
layout_cache,
|
terminator,
|
||||||
assigned_in_jump,
|
);
|
||||||
terminator,
|
|
||||||
);
|
stmt = cond(env, branching_symbol, cond_layout, then, stmt, ret_layout);
|
||||||
|
|
||||||
for (loc_cond, loc_then) in branches.into_iter().rev() {
|
// add condition
|
||||||
let branching_symbol = possible_reuse_symbol(env, procs, &loc_cond.value);
|
stmt = assign_to_symbol(
|
||||||
|
env,
|
||||||
let then = with_hole(
|
procs,
|
||||||
env,
|
layout_cache,
|
||||||
loc_then.value,
|
cond_var,
|
||||||
branch_var,
|
loc_cond,
|
||||||
procs,
|
branching_symbol,
|
||||||
layout_cache,
|
stmt,
|
||||||
assigned_in_jump,
|
);
|
||||||
terminator,
|
}
|
||||||
);
|
|
||||||
|
let layout = layout_cache
|
||||||
stmt = cond(env, branching_symbol, cond_layout, then, stmt, ret_layout);
|
.from_var(env.arena, branch_var, env.subs)
|
||||||
|
.unwrap_or_else(|err| {
|
||||||
// add condition
|
panic!("TODO turn fn_var into a RuntimeError {:?}", err)
|
||||||
stmt = assign_to_symbol(
|
});
|
||||||
env,
|
|
||||||
procs,
|
let param = Param {
|
||||||
layout_cache,
|
symbol: assigned,
|
||||||
cond_var,
|
layout,
|
||||||
loc_cond,
|
borrow: false,
|
||||||
branching_symbol,
|
};
|
||||||
stmt,
|
|
||||||
);
|
Stmt::Join {
|
||||||
}
|
id,
|
||||||
|
parameters: env.arena.alloc([param]),
|
||||||
let layout = layout_cache
|
remainder: env.arena.alloc(stmt),
|
||||||
.from_var(env.arena, branch_var, env.subs)
|
body: hole,
|
||||||
.unwrap_or_else(|err| panic!("TODO turn fn_var into a RuntimeError {:?}", err));
|
}
|
||||||
|
}
|
||||||
let param = Param {
|
|
||||||
symbol: assigned,
|
|
||||||
layout,
|
|
||||||
borrow: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
Stmt::Join {
|
|
||||||
id,
|
|
||||||
parameters: env.arena.alloc([param]),
|
|
||||||
remainder: env.arena.alloc(stmt),
|
|
||||||
body: hole,
|
|
||||||
}
|
}
|
||||||
|
(Err(_), _) => Stmt::RuntimeError("invalid ret_layout"),
|
||||||
|
(_, Err(_)) => Stmt::RuntimeError("invalid cond_layout"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue