Merge remote-tracking branch 'origin/trunk' into nullable-tags

This commit is contained in:
Folkert 2021-01-17 02:37:57 +01:00
commit 8cd744342b
54 changed files with 1208 additions and 724 deletions

View file

@ -3599,7 +3599,7 @@ fn run_low_level<'a, 'ctx, 'env>(
build_num_binop(env, parent, lhs_arg, lhs_layout, rhs_arg, rhs_layout, op)
}
NumBitwiseAnd => {
NumBitwiseAnd | NumBitwiseXor => {
debug_assert_eq!(args.len(), 2);
let (lhs_arg, lhs_layout) = load_symbol_and_layout(env, scope, &args[0]);
@ -3953,6 +3953,7 @@ fn build_int_binop<'a, 'ctx, 'env>(
NumDivUnchecked => bd.build_int_signed_div(lhs, rhs, "div_int").into(),
NumPowInt => call_bitcode_fn(env, &[lhs.into(), rhs.into()], &bitcode::NUM_POW_INT),
NumBitwiseAnd => bd.build_and(lhs, rhs, "int_bitwise_and").into(),
NumBitwiseXor => bd.build_xor(lhs, rhs, "int_bitwise_xor").into(),
_ => {
unreachable!("Unrecognized int binary operation: {:?}", op);
}

View file

@ -757,6 +757,14 @@ mod gen_num {
assert_evals_to!("Num.bitwiseAnd 200 0", 0, i64);
}
#[test]
fn bitwise_xor() {
assert_evals_to!("Num.bitwiseXor 20 20", 0, i64);
assert_evals_to!("Num.bitwiseXor 15 14", 1, i64);
assert_evals_to!("Num.bitwiseXor 7 15", 8, i64);
assert_evals_to!("Num.bitwiseXor 200 0", 200, i64);
}
#[test]
fn lt_i64() {
assert_evals_to!("1 < 2", true, bool);

View file

@ -1901,6 +1901,26 @@ mod gen_primitives {
);
}
#[test]
fn case_or_pattern() {
// the `0` branch body should only be generated once in the future
// it is currently duplicated
assert_evals_to!(
indoc!(
r#"
x : [ Red, Green, Blue ]
x = Red
when x is
Red | Green -> 0
Blue -> 1
"#
),
0,
i64
);
}
#[test]
#[ignore]
fn rosetree_basic() {
@ -1932,4 +1952,29 @@ mod gen_primitives {
bool
);
}
#[test]
fn case_jump() {
// the decision tree will generate a jump to the `1` branch here
assert_evals_to!(
indoc!(
r#"
app "test" provides [ main ] to "./platform"
ConsList a : [ Cons a (ConsList a), Nil ]
x : ConsList I64
x = Nil
main =
when Pair x x is
Pair Nil _ -> 1
Pair _ Nil -> 2
Pair (Cons a _) (Cons b _) -> a + b + 3
"#
),
1,
i64
);
}
}

View file

@ -19,7 +19,7 @@ fn promote_expr_to_module(src: &str) -> String {
pub fn helper<'a>(
arena: &'a bumpalo::Bump,
src: &str,
stdlib: roc_builtins::std::StdLib,
stdlib: &'a roc_builtins::std::StdLib,
leak: bool,
context: &'a inkwell::context::Context,
) -> (&'static str, String, Library) {
@ -295,40 +295,6 @@ pub fn helper<'a>(
(main_fn_name, delayed_errors.join("\n"), lib)
}
// TODO this is almost all code duplication with assert_llvm_evals_to
// the only difference is that this calls uniq_expr instead of can_expr.
// Should extract the common logic into test helpers.
#[macro_export]
macro_rules! assert_opt_evals_to {
($src:expr, $expected:expr, $ty:ty, $transform:expr, $leak:expr) => {
use bumpalo::Bump;
use inkwell::context::Context;
use roc_gen::run_jit_function;
let arena = Bump::new();
let context = Context::create();
// don't use uniqueness types any more
// let stdlib = roc_builtins::unique::uniq_stdlib();
let stdlib = roc_builtins::std::standard_stdlib();
let (main_fn_name, errors, lib) =
$crate::helpers::eval::helper(&arena, $src, stdlib, $leak, &context);
let transform = |success| {
let expected = $expected;
let given = $transform(success);
assert_eq!(&given, &expected);
};
run_jit_function!(lib, main_fn_name, $ty, transform, errors)
};
($src:expr, $expected:expr, $ty:ty, $transform:expr) => {
assert_opt_evals_to!($src, $expected, $ty, $transform, true)
};
}
#[macro_export]
macro_rules! assert_llvm_evals_to {
($src:expr, $expected:expr, $ty:ty, $transform:expr, $leak:expr) => {
@ -337,9 +303,10 @@ macro_rules! assert_llvm_evals_to {
use roc_gen::run_jit_function;
let arena = Bump::new();
let context = Context::create();
let stdlib = roc_builtins::std::standard_stdlib();
// NOTE the stdlib must be in the arena; just taking a reference will segfault
let stdlib = arena.alloc(roc_builtins::std::standard_stdlib());
let (main_fn_name, errors, lib) =
$crate::helpers::eval::helper(&arena, $src, stdlib, $leak, &context);
@ -377,7 +344,8 @@ macro_rules! assert_evals_to {
assert_llvm_evals_to!($src, $expected, $ty, $transform, $leak);
}
{
assert_opt_evals_to!($src, $expected, $ty, $transform, $leak);
// NOTE at the moment, the optimized tests do the same thing
// assert_opt_evals_to!($src, $expected, $ty, $transform, $leak);
}
};
}