mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 23:04:49 +00:00
Merge branch 'docs-exposed-values' of github.com:rtfeldman/roc into docs-exposed-values
This commit is contained in:
commit
c23d77a931
14 changed files with 824 additions and 303 deletions
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue