Browse Source

fix: bindgen trappable_errors using unversion/versioned packages (#8305) (#8307)

Signed-off-by: Brian H <brian.hardock@fermyon.com>
Co-authored-by: Brian <brian.hardock@fermyon.com>
pull/8325/head
Alex Crichton 7 months ago
committed by GitHub
parent
commit
9014507994
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 27
      crates/component-macro/tests/codegen.rs
  2. 12
      crates/component-macro/tests/codegen/unversioned-foo.wit
  3. 27
      crates/wit-bindgen/src/lib.rs

27
crates/component-macro/tests/codegen.rs

@ -107,6 +107,33 @@ mod with_key_and_resources {
}
}
mod trappable_errors_with_versioned_and_unversioned_packages {
wasmtime::component::bindgen!({
inline: "
package foo:foo@0.1.0;
interface a {
variant error {
other(string),
}
f: func() -> result<_, error>;
}
world foo {
import a;
}
",
path: "tests/codegen/unversioned-foo.wit",
trappable_error_type: {
"foo:foo/a@0.1.0/error" => MyX,
},
});
#[allow(dead_code)]
type MyX = u64;
}
mod trappable_errors {
wasmtime::component::bindgen!({
inline: "

12
crates/component-macro/tests/codegen/unversioned-foo.wit

@ -0,0 +1,12 @@
package foo:foo;
interface a {
variant error {
other(string),
}
g: func() -> result<_, error>;
}
world nope {
import a;
}

27
crates/wit-bindgen/src/lib.rs

@ -1,6 +1,6 @@
use crate::rust::{to_rust_ident, to_rust_upper_camel_case, RustGenerator, TypeMode};
use crate::types::{TypeInfo, Types};
use anyhow::{anyhow, bail, Context};
use anyhow::{bail, Context};
use heck::*;
use indexmap::{IndexMap, IndexSet};
use std::collections::{BTreeMap, HashMap, HashSet};
@ -859,9 +859,13 @@ fn resolve_type_in_package(resolve: &Resolve, wit_path: &str) -> anyhow::Result<
.flat_map(|l| l)
.collect::<HashSet<_>>();
let mut found_interface = false;
// Look for an interface whose assigned prefix starts `wit_path`. Not
// exactly the most efficient thing ever but is sufficient for now.
for (id, interface) in resolve.interfaces.iter() {
found_interface = true;
let iface_name = match &interface.name {
Some(name) => name,
None => continue,
@ -879,15 +883,20 @@ fn resolve_type_in_package(resolve: &Resolve, wit_path: &str) -> anyhow::Result<
Some(rest) => rest,
None => continue,
};
let wit_path = wit_path
.strip_prefix('/')
.ok_or_else(|| anyhow!("expected `/` after interface name"))?;
return interface
.types
.get(wit_path)
.copied()
.ok_or_else(|| anyhow!("no types found to match `{wit_path}` in interface"));
let wit_path = match wit_path.strip_prefix('/') {
Some(rest) => rest,
None => continue,
};
match interface.types.get(wit_path).copied() {
Some(type_id) => return Ok(type_id),
None => continue,
}
}
if found_interface {
bail!("no types found to match `{wit_path}` in interface");
}
bail!("no package/interface found to match `{wit_path}`")

Loading…
Cancel
Save