Fix error messages reporting number of expected vs actual params

We previously had some off-by-one errors in our error messages and this led to
very confusing messages like "expected 0 types, found 0" that were quite
annoying to debug as an API consumer.
This commit is contained in:
Nick Fitzgerald
2021-07-07 11:32:40 -07:00
parent 57375588f2
commit be60fec6ba
2 changed files with 52 additions and 4 deletions

View File

@@ -347,17 +347,23 @@ macro_rules! impl_wasm_params {
fn typecheck(mut params: impl ExactSizeIterator<Item = crate::ValType>) -> Result<()> {
let mut _n = 0;
$(
match params.next() {
Some(t) => $t::typecheck(t)?,
None => bail!("expected {} types, found {}", $n, _n),
}
Some(t) => {
_n += 1;
$t::typecheck(t)?
},
None => bail!("expected {} types, found {}", $n, params.len() + _n),
}
)*
match params.next() {
None => Ok(()),
Some(_) => bail!("expected {} types, found {}", $n, params.len() + _n),
Some(_) => {
_n += 1;
bail!("expected {} types, found {}", $n, params.len() + _n)
},
}
}

View File

@@ -884,3 +884,45 @@ fn wasm_ty_roundtrip() -> Result<(), anyhow::Error> {
foo.call(&mut store, (-1, 1, 2.0, -3, 3, 4.0))?;
Ok(())
}
#[test]
fn typed_funcs_count_params_correctly_in_error_messages() -> anyhow::Result<()> {
let mut store = Store::<()>::default();
let module = Module::new(
store.engine(),
r#"
(module
(func (export "f") (param i32 i32))
)
"#,
)?;
let instance = Instance::new(&mut store, &module, &[])?;
// Too few parameters.
match instance.get_typed_func::<(), (), _>(&mut store, "f") {
Ok(_) => panic!("should be wrong signature"),
Err(e) => {
let msg = format!("{:?}", e);
assert!(dbg!(msg).contains("expected 0 types, found 2"))
}
}
match instance.get_typed_func::<(i32,), (), _>(&mut store, "f") {
Ok(_) => panic!("should be wrong signature"),
Err(e) => {
let msg = format!("{:?}", e);
assert!(dbg!(msg).contains("expected 1 types, found 2"))
}
}
// Too many parameters.
match instance.get_typed_func::<(i32, i32, i32), (), _>(&mut store, "f") {
Ok(_) => panic!("should be wrong signature"),
Err(e) => {
let msg = format!("{:?}", e);
assert!(dbg!(msg).contains("expected 3 types, found 2"))
}
}
Ok(())
}