mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 00:01:16 +00:00
Add macro to expect runtime error panic through llvm backend, and a test
This commit is contained in:
parent
903fa7d363
commit
823e32961f
3 changed files with 104 additions and 16 deletions
|
@ -1,6 +1,9 @@
|
||||||
#[cfg(feature = "gen-llvm")]
|
#[cfg(feature = "gen-llvm")]
|
||||||
use crate::helpers::llvm::assert_evals_to;
|
use crate::helpers::llvm::assert_evals_to;
|
||||||
|
|
||||||
|
#[cfg(feature = "gen-llvm")]
|
||||||
|
use crate::helpers::llvm::expect_runtime_error_panic;
|
||||||
|
|
||||||
#[cfg(feature = "gen-dev")]
|
#[cfg(feature = "gen-dev")]
|
||||||
use crate::helpers::dev::assert_evals_to;
|
use crate::helpers::dev::assert_evals_to;
|
||||||
|
|
||||||
|
@ -1007,3 +1010,22 @@ fn both_have_unique_fields() {
|
||||||
i64
|
i64
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
|
#[should_panic(
|
||||||
|
// TODO: something upstream is escaping the '
|
||||||
|
expected = r#"Roc failed with message: "Can\'t create record with improper layout""#
|
||||||
|
)]
|
||||||
|
fn call_with_bad_record_runtime_error() {
|
||||||
|
expect_runtime_error_panic!(indoc!(
|
||||||
|
r#"
|
||||||
|
app "test" provides [ main ] to "./platform"
|
||||||
|
|
||||||
|
main =
|
||||||
|
get : {a: Bool} -> Bool
|
||||||
|
get = \{a} -> a
|
||||||
|
get {b: ""}
|
||||||
|
"#
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
|
@ -28,8 +28,6 @@ pub fn test_builtin_defs(symbol: Symbol, var_store: &mut VarStore) -> Option<Def
|
||||||
builtin_defs_map(symbol, var_store)
|
builtin_defs_map(symbol, var_store)
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is not actually dead code, but only used by cfg_test modules
|
|
||||||
// so "normally" it is dead, only at testing time is it used
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn create_llvm_module<'a>(
|
fn create_llvm_module<'a>(
|
||||||
arena: &'a bumpalo::Bump,
|
arena: &'a bumpalo::Bump,
|
||||||
|
@ -511,16 +509,31 @@ where
|
||||||
|
|
||||||
#[allow(unused_macros)]
|
#[allow(unused_macros)]
|
||||||
macro_rules! assert_wasm_evals_to {
|
macro_rules! assert_wasm_evals_to {
|
||||||
($src:expr, $expected:expr, $ty:ty, $transform:expr, $ignore_problems:expr) => {
|
($src:expr, $expected:expr, $ty:ty, $transform:expr, $ignore_problems:expr, $expect_failure:expr) => {
|
||||||
match $crate::helpers::llvm::assert_wasm_evals_to_help::<$ty>($src, $ignore_problems) {
|
match $crate::helpers::llvm::assert_wasm_evals_to_help::<$ty>($src, $ignore_problems) {
|
||||||
Err(msg) => panic!("Wasm test failed: {:?}", msg),
|
Err(msg) => panic!("Wasm test failed: {:?}", msg),
|
||||||
Ok(actual) => {
|
Ok(actual) => {
|
||||||
#[allow(clippy::bool_assert_comparison)]
|
if $expect_failure {
|
||||||
assert_eq!($transform(actual), $expected, "Wasm test failed")
|
assert!(false, "Expected failure during wasm execution!")
|
||||||
|
} else {
|
||||||
|
#[allow(clippy::bool_assert_comparison)]
|
||||||
|
assert_eq!($transform(actual), $expected, "Wasm test failed")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
($src:expr, $expected:expr, $ty:ty, $transform:expr, $ignore_problems:expr) => {
|
||||||
|
$crate::helpers::llvm::assert_wasm_evals_to!(
|
||||||
|
$src,
|
||||||
|
$expected,
|
||||||
|
$ty,
|
||||||
|
$crate::helpers::llvm::identity,
|
||||||
|
$ignore_problems,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
($src:expr, $expected:expr, $ty:ty) => {
|
($src:expr, $expected:expr, $ty:ty) => {
|
||||||
$crate::helpers::llvm::assert_wasm_evals_to!(
|
$crate::helpers::llvm::assert_wasm_evals_to!(
|
||||||
$src,
|
$src,
|
||||||
|
@ -538,7 +551,7 @@ macro_rules! assert_wasm_evals_to {
|
||||||
|
|
||||||
#[allow(unused_macros)]
|
#[allow(unused_macros)]
|
||||||
macro_rules! assert_llvm_evals_to {
|
macro_rules! assert_llvm_evals_to {
|
||||||
($src:expr, $expected:expr, $ty:ty, $transform:expr, $ignore_problems:expr) => {
|
($src:expr, $expected:expr, $ty:ty, $transform:expr, $ignore_problems:expr, $expect_rt_error:expr) => {
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
use inkwell::context::Context;
|
use inkwell::context::Context;
|
||||||
use roc_gen_llvm::run_jit_function;
|
use roc_gen_llvm::run_jit_function;
|
||||||
|
@ -560,26 +573,47 @@ macro_rules! assert_llvm_evals_to {
|
||||||
);
|
);
|
||||||
|
|
||||||
let transform = |success| {
|
let transform = |success| {
|
||||||
let expected = $expected;
|
if $expect_rt_error {
|
||||||
#[allow(clippy::redundant_closure_call)]
|
assert_eq!(
|
||||||
let given = $transform(success);
|
true, false,
|
||||||
assert_eq!(&given, &expected, "LLVM test failed");
|
"Runtime error expected, but evaluation succeeded!"
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
let expected = $expected;
|
||||||
|
#[allow(clippy::redundant_closure_call)]
|
||||||
|
let given = $transform(success);
|
||||||
|
assert_eq!(&given, &expected, "LLVM test failed");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
run_jit_function!(lib, main_fn_name, $ty, transform, errors)
|
run_jit_function!(lib, main_fn_name, $ty, transform, errors)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
($src:expr, $expected:expr, $ty:ty, $transform:expr, $ignore_problems:expr) => {
|
||||||
|
$crate::helpers::llvm::assert_llvm_evals_to!(
|
||||||
|
$src,
|
||||||
|
$expected,
|
||||||
|
$ty,
|
||||||
|
$transform,
|
||||||
|
$ignore_problems,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
($src:expr, $expected:expr, $ty:ty) => {
|
($src:expr, $expected:expr, $ty:ty) => {
|
||||||
$crate::helpers::llvm::assert_llvm_evals_to!(
|
$crate::helpers::llvm::assert_llvm_evals_to!(
|
||||||
$src,
|
$src,
|
||||||
$expected,
|
$expected,
|
||||||
$ty,
|
$ty,
|
||||||
$crate::helpers::llvm::identity,
|
$crate::helpers::llvm::identity,
|
||||||
|
false,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
($src:expr, $expected:expr, $ty:ty, $transform:expr) => {
|
($src:expr, $expected:expr, $ty:ty, $transform:expr) => {
|
||||||
$crate::helpers::llvm::assert_llvm_evals_to!($src, $expected, $ty, $transform, false);
|
$crate::helpers::llvm::assert_llvm_evals_to!(
|
||||||
|
$src, $expected, $ty, $transform, false, false
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -589,16 +623,43 @@ macro_rules! assert_evals_to {
|
||||||
assert_evals_to!($src, $expected, $ty, $crate::helpers::llvm::identity);
|
assert_evals_to!($src, $expected, $ty, $crate::helpers::llvm::identity);
|
||||||
}};
|
}};
|
||||||
($src:expr, $expected:expr, $ty:ty, $transform:expr) => {
|
($src:expr, $expected:expr, $ty:ty, $transform:expr) => {
|
||||||
// Same as above, except with an additional transformation argument.
|
// same as above, except with an additional transformation argument.
|
||||||
{
|
{
|
||||||
#[cfg(feature = "wasm-cli-run")]
|
#[cfg(feature = "wasm-cli-run")]
|
||||||
$crate::helpers::llvm::assert_wasm_evals_to!($src, $expected, $ty, $transform, false);
|
$crate::helpers::llvm::assert_wasm_evals_to!(
|
||||||
|
$src, $expected, $ty, $transform, false, false
|
||||||
|
);
|
||||||
|
|
||||||
$crate::helpers::llvm::assert_llvm_evals_to!($src, $expected, $ty, $transform, false);
|
$crate::helpers::llvm::assert_llvm_evals_to!(
|
||||||
|
$src, $expected, $ty, $transform, false, false
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! expect_runtime_error_panic {
|
||||||
|
($src:expr) => {{
|
||||||
|
#[cfg(feature = "wasm-cli-run")]
|
||||||
|
$crate::helpers::llvm::assert_wasm_evals_to!(
|
||||||
|
$src,
|
||||||
|
false, // fake value/type for eval
|
||||||
|
bool,
|
||||||
|
$crate::helpers::llvm::identity,
|
||||||
|
true, // ignore problems
|
||||||
|
true // expect runtime error
|
||||||
|
);
|
||||||
|
|
||||||
|
$crate::helpers::llvm::assert_llvm_evals_to!(
|
||||||
|
$src,
|
||||||
|
false, // fake value/type for eval
|
||||||
|
bool,
|
||||||
|
$crate::helpers::llvm::identity,
|
||||||
|
true, // ignore problems
|
||||||
|
true // expect runtime error
|
||||||
|
);
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn identity<T>(value: T) -> T {
|
pub fn identity<T>(value: T) -> T {
|
||||||
value
|
value
|
||||||
|
@ -617,7 +678,7 @@ macro_rules! assert_non_opt_evals_to {
|
||||||
($src:expr, $expected:expr, $ty:ty, $transform:expr) => {
|
($src:expr, $expected:expr, $ty:ty, $transform:expr) => {
|
||||||
// Same as above, except with an additional transformation argument.
|
// Same as above, except with an additional transformation argument.
|
||||||
{
|
{
|
||||||
$crate::helpers::llvm::assert_llvm_evals_to!($src, $expected, $ty, $transform, false);
|
$crate::helpers::llvm::assert_llvm_evals_to!($src, $expected, $ty, $transform);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
($src:expr, $expected:expr, $ty:ty, $transform:expr) => {{
|
($src:expr, $expected:expr, $ty:ty, $transform:expr) => {{
|
||||||
|
@ -633,3 +694,5 @@ pub(crate) use assert_llvm_evals_to;
|
||||||
pub(crate) use assert_non_opt_evals_to;
|
pub(crate) use assert_non_opt_evals_to;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
pub(crate) use assert_wasm_evals_to;
|
pub(crate) use assert_wasm_evals_to;
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
pub(crate) use expect_runtime_error_panic;
|
||||||
|
|
|
@ -3,4 +3,7 @@ app "hello-world"
|
||||||
imports []
|
imports []
|
||||||
provides [ main ] to pf
|
provides [ main ] to pf
|
||||||
|
|
||||||
main = "Hello, World!\n"
|
main =
|
||||||
|
get : {a: Bool} -> Bool
|
||||||
|
get = \{a} -> a
|
||||||
|
get {b: ""}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue