Merge branch 'docs-exposed-values' of github.com:rtfeldman/roc into docs-exposed-values

This commit is contained in:
Chadtech 2021-07-05 13:03:13 -04:00
commit c23d77a931
14 changed files with 824 additions and 303 deletions

View file

@ -3150,118 +3150,123 @@ pub fn with_hole<'a>(
branches,
final_else,
} => {
let ret_layout = layout_cache
.from_var(env.arena, branch_var, env.subs)
.expect("invalid ret_layout");
let cond_layout = layout_cache
.from_var(env.arena, cond_var, env.subs)
.expect("invalid cond_layout");
match (
layout_cache.from_var(env.arena, branch_var, env.subs),
layout_cache.from_var(env.arena, cond_var, env.subs),
) {
(Ok(ret_layout), Ok(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
// branches together again, we can just immediately return
let is_terminated = matches!(hole, Stmt::Ret(_));
if is_terminated {
let terminator = hole;
if is_terminated {
let terminator = hole;
let mut stmt = with_hole(
env,
final_else.value,
branch_var,
procs,
layout_cache,
assigned,
terminator,
);
let mut stmt = with_hole(
env,
final_else.value,
branch_var,
procs,
layout_cache,
assigned,
terminator,
);
for (loc_cond, loc_then) in branches.into_iter().rev() {
let branching_symbol = env.unique_symbol();
for (loc_cond, loc_then) in branches.into_iter().rev() {
let branching_symbol = env.unique_symbol();
let then = with_hole(
env,
loc_then.value,
branch_var,
procs,
layout_cache,
assigned,
terminator,
);
let then = with_hole(
env,
loc_then.value,
branch_var,
procs,
layout_cache,
assigned,
terminator,
);
stmt = cond(env, branching_symbol, cond_layout, then, stmt, ret_layout);
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
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());
let terminator = env
.arena
.alloc(Stmt::Jump(id, env.arena.alloc([assigned_in_jump])));
let mut stmt = with_hole(
env,
final_else.value,
branch_var,
procs,
layout_cache,
assigned_in_jump,
terminator,
);
for (loc_cond, loc_then) in branches.into_iter().rev() {
let branching_symbol = possible_reuse_symbol(env, procs, &loc_cond.value);
let then = with_hole(
env,
loc_then.value,
branch_var,
procs,
layout_cache,
assigned_in_jump,
terminator,
);
stmt = cond(env, branching_symbol, cond_layout, then, stmt, ret_layout);
// add condition
stmt = assign_to_symbol(
env,
procs,
layout_cache,
cond_var,
loc_cond,
branching_symbol,
stmt,
);
}
let layout = layout_cache
.from_var(env.arena, branch_var, env.subs)
.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,
let terminator = env
.arena
.alloc(Stmt::Jump(id, env.arena.alloc([assigned_in_jump])));
let mut stmt = with_hole(
env,
final_else.value,
branch_var,
procs,
layout_cache,
assigned_in_jump,
terminator,
);
for (loc_cond, loc_then) in branches.into_iter().rev() {
let branching_symbol =
possible_reuse_symbol(env, procs, &loc_cond.value);
let then = with_hole(
env,
loc_then.value,
branch_var,
procs,
layout_cache,
assigned_in_jump,
terminator,
);
stmt = cond(env, branching_symbol, cond_layout, then, stmt, ret_layout);
// add condition
stmt = assign_to_symbol(
env,
procs,
layout_cache,
cond_var,
loc_cond,
branching_symbol,
stmt,
);
}
let layout = layout_cache
.from_var(env.arena, branch_var, env.subs)
.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"),
}
}
@ -4126,17 +4131,17 @@ fn convert_tag_union<'a>(
hole,
),
ByteUnion(tag_names) => {
let tag_id = tag_names
.iter()
.position(|key| key == &tag_name)
.expect("tag must be in its own type");
let opt_tag_id = tag_names.iter().position(|key| key == &tag_name);
Stmt::Let(
assigned,
Expr::Literal(Literal::Byte(tag_id as u8)),
Layout::Builtin(Builtin::Int8),
hole,
)
match opt_tag_id {
Some(tag_id) => Stmt::Let(
assigned,
Expr::Literal(Literal::Byte(tag_id as u8)),
Layout::Builtin(Builtin::Int8),
hole,
),
None => Stmt::RuntimeError("tag must be in its own type"),
}
}
Newtype {

View file

@ -1939,3 +1939,23 @@ fn list_sort_with() {
RocList<i64>
);
}
#[test]
#[should_panic(expected = r#"Roc failed with message: "invalid ret_layout""#)]
fn lists_with_incompatible_type_param_in_if() {
assert_evals_to!(
indoc!(
r#"
list1 = [ {} ]
list2 = [ "" ]
x = if True then list1 else list2
""
"#
),
RocStr::empty(),
RocStr
);
}

View file

@ -1033,3 +1033,20 @@ fn applied_tag_function_linked_list() {
i64
);
}
#[test]
#[should_panic(expected = "")]
fn tag_must_be_its_own_type() {
assert_evals_to!(
indoc!(
r#"
z : [ A, B, C ]
z = Z
z
"#
),
1,
i64
);
}