diff --git a/lib/runtime-core/src/typed_func.rs b/lib/runtime-core/src/typed_func.rs index c5ece859431..23a84873822 100644 --- a/lib/runtime-core/src/typed_func.rs +++ b/lib/runtime-core/src/typed_func.rs @@ -230,7 +230,7 @@ impl WasmTypeList for Infallible { unreachable!() } fn types() -> &'static [Type] { - unreachable!() + &[] } #[allow(non_snake_case)] unsafe fn call( diff --git a/lib/runtime/tests/error_propagation.rs b/lib/runtime/tests/error_propagation.rs new file mode 100644 index 00000000000..1b9f9fccfbf --- /dev/null +++ b/lib/runtime/tests/error_propagation.rs @@ -0,0 +1,49 @@ +#[test] +fn error_propagation() { + use std::convert::Infallible; + use wabt::wat2wasm; + use wasmer_runtime::{compile, error::RuntimeError, imports, Ctx, Func}; + + static WAT: &'static str = r#" + (module + (type (;0;) (func)) + (import "env" "ret_err" (func $ret_err (type 0))) + (func $call_panic + call $ret_err + ) + (export "call_err" (func $call_panic)) + ) + "#; + + #[derive(Debug)] + struct ExitCode { + code: i32, + } + + fn ret_err(_ctx: &mut Ctx) -> Result { + Err(ExitCode { code: 42 }) + } + + let wasm = wat2wasm(WAT).unwrap(); + + let module = compile(&wasm).unwrap(); + + let instance = module + .instantiate(&imports! { + "env" => { + "ret_err" => Func::new(ret_err), + }, + }) + .unwrap(); + + let foo: Func<(), ()> = instance.func("call_err").unwrap(); + + let result = foo.call(); + + if let Err(RuntimeError::Error { data }) = result { + let exit_code = data.downcast::().unwrap(); + assert_eq!(exit_code.code, 42); + } else { + panic!("didn't return RuntimeError::Error") + } +}