feat(mono): return Stmt::RuntimeError on bad layouts for If

This commit is contained in:
rvcas 2021-07-03 13:05:30 -04:00
parent 16542f0e1e
commit 39d39c218f

View file

@ -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"),
} }
} }