mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
make List.first/List.last work
This commit is contained in:
parent
679ef168b1
commit
917ec9c44c
4 changed files with 51 additions and 10 deletions
|
@ -292,13 +292,16 @@ mod repl_eval {
|
||||||
expect_success("List.sum [ 1.1, 2.2, 3.3 ]", "6.6 : F64");
|
expect_success("List.sum [ 1.1, 2.2, 3.3 ]", "6.6 : F64");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO add test cases for empty lists once error messages in the repl are correct
|
|
||||||
#[test]
|
#[test]
|
||||||
fn list_first() {
|
fn list_first() {
|
||||||
expect_success(
|
expect_success(
|
||||||
"List.first [ 12, 9, 6, 3 ]",
|
"List.first [ 12, 9, 6, 3 ]",
|
||||||
"Ok 12 : Result (Num *) [ ListWasEmpty ]*",
|
"Ok 12 : Result (Num *) [ ListWasEmpty ]*",
|
||||||
);
|
);
|
||||||
|
expect_success(
|
||||||
|
"List.first []",
|
||||||
|
"Err (ListWasEmpty) : Result * [ ListWasEmpty ]*",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -307,6 +310,11 @@ mod repl_eval {
|
||||||
"List.last [ 12, 9, 6, 3 ]",
|
"List.last [ 12, 9, 6, 3 ]",
|
||||||
"Ok 3 : Result (Num *) [ ListWasEmpty ]*",
|
"Ok 3 : Result (Num *) [ ListWasEmpty ]*",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
expect_success(
|
||||||
|
"List.last []",
|
||||||
|
"Err (ListWasEmpty) : Result * [ ListWasEmpty ]*",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -2585,13 +2585,23 @@ pub fn with_hole<'a>(
|
||||||
|
|
||||||
let mut field_symbols_temp = Vec::with_capacity_in(args.len(), env.arena);
|
let mut field_symbols_temp = Vec::with_capacity_in(args.len(), env.arena);
|
||||||
|
|
||||||
for (var, arg) in args.drain(..) {
|
for (var, mut arg) in args.drain(..) {
|
||||||
// Layout will unpack this unwrapped tack if it only has one (non-zero-sized) field
|
// Layout will unpack this unwrapped tack if it only has one (non-zero-sized) field
|
||||||
let layout = layout_cache
|
let layout = match layout_cache.from_var(env.arena, var, env.subs) {
|
||||||
.from_var(env.arena, var, env.subs)
|
Ok(cached) => cached,
|
||||||
.unwrap_or_else(|err| {
|
Err(LayoutProblem::UnresolvedTypeVar(_)) => {
|
||||||
panic!("TODO turn fn_var into a RuntimeError {:?}", err)
|
// this argument has type `forall a. a`, which is isomorphic to
|
||||||
});
|
// the empty type (Void, Never, the empty tag union `[]`)
|
||||||
|
use roc_can::expr::Expr;
|
||||||
|
use roc_problem::can::RuntimeError;
|
||||||
|
arg.value = Expr::RuntimeError(RuntimeError::VoidValue);
|
||||||
|
Layout::Struct(&[])
|
||||||
|
}
|
||||||
|
Err(LayoutProblem::Erroneous) => {
|
||||||
|
// something went very wrong
|
||||||
|
panic!("TODO turn fn_var into a RuntimeError")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let alignment = layout.alignment_bytes(8);
|
let alignment = layout.alignment_bytes(8);
|
||||||
|
|
||||||
|
@ -3575,9 +3585,23 @@ pub fn with_hole<'a>(
|
||||||
let arg_symbols = arg_symbols.into_bump_slice();
|
let arg_symbols = arg_symbols.into_bump_slice();
|
||||||
|
|
||||||
// layout of the return type
|
// layout of the return type
|
||||||
let layout = layout_cache
|
let layout = match layout_cache.from_var(env.arena, ret_var, env.subs) {
|
||||||
.from_var(env.arena, ret_var, env.subs)
|
Ok(cached) => cached,
|
||||||
.unwrap_or_else(|err| todo!("TODO turn fn_var into a RuntimeError {:?}", err));
|
Err(LayoutProblem::UnresolvedTypeVar(_)) => {
|
||||||
|
return Stmt::RuntimeError(env.arena.alloc(format!(
|
||||||
|
"UnresolvedTypeVar {} line {}",
|
||||||
|
file!(),
|
||||||
|
line!()
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
Err(LayoutProblem::Erroneous) => {
|
||||||
|
return Stmt::RuntimeError(env.arena.alloc(format!(
|
||||||
|
"Erroneous {} line {}",
|
||||||
|
file!(),
|
||||||
|
line!()
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let result = Stmt::Let(assigned, Expr::RunLowLevel(op, arg_symbols), layout, hole);
|
let result = Stmt::Let(assigned, Expr::RunLowLevel(op, arg_symbols), layout, hole);
|
||||||
|
|
||||||
|
|
|
@ -147,6 +147,9 @@ pub enum RuntimeError {
|
||||||
/// When the author specifies a type annotation but no implementation
|
/// When the author specifies a type annotation but no implementation
|
||||||
NoImplementation,
|
NoImplementation,
|
||||||
|
|
||||||
|
/// cases where the `[]` value (or equivalently, `forall a. a`) pops up
|
||||||
|
VoidValue,
|
||||||
|
|
||||||
ExposedButNotDefined(Symbol),
|
ExposedButNotDefined(Symbol),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -338,6 +338,12 @@ fn pretty_runtime_error<'b>(
|
||||||
runtime_error: RuntimeError,
|
runtime_error: RuntimeError,
|
||||||
) -> RocDocBuilder<'b> {
|
) -> RocDocBuilder<'b> {
|
||||||
match runtime_error {
|
match runtime_error {
|
||||||
|
RuntimeError::VoidValue => {
|
||||||
|
// is used to communicate to the compiler that
|
||||||
|
// a branch is unreachable; this should never reach a user
|
||||||
|
unreachable!("")
|
||||||
|
}
|
||||||
|
|
||||||
RuntimeError::Shadowing {
|
RuntimeError::Shadowing {
|
||||||
original_region,
|
original_region,
|
||||||
shadow,
|
shadow,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue