Skip to content

Commit

Permalink
fix: bindgen trappable_errors using unversion/versioned packages (byt…
Browse files Browse the repository at this point in the history
…ecodealliance#8305)

Signed-off-by: Brian H <brian.hardock@fermyon.com>
  • Loading branch information
fibonacci1729 authored and alexcrichton committed Apr 5, 2024
1 parent ff528a2 commit 5ce9c38
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 9 deletions.
27 changes: 27 additions & 0 deletions crates/component-macro/tests/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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: "
Expand Down
12 changes: 12 additions & 0 deletions crates/component-macro/tests/codegen/unversioned-foo.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package foo:foo;

interface a {
variant error {
other(string),
}
g: func() -> result<_, error>;
}

world nope {
import a;
}
27 changes: 18 additions & 9 deletions crates/wit-bindgen/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -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,
Expand All @@ -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}`")
Expand Down

0 comments on commit 5ce9c38

Please sign in to comment.