Skip to content

Commit 321c40b

Browse files
committed
Ensure resources' owning interfaces are also imported
Signed-off-by: Ryan Levick <ryan.levick@fermyon.com>
1 parent 2f60bf8 commit 321c40b

3 files changed

Lines changed: 85 additions & 12 deletions

File tree

crates/wac-graph/src/graph.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1533,7 +1533,7 @@ impl<'a> CompositionGraphEncoder<'a> {
15331533
}
15341534

15351535
// Next encode the imports
1536-
for (name, kind) in aggregator.iter() {
1536+
for (name, kind) in aggregator.imports() {
15371537
log::debug!("import `{name}` is being implicitly imported");
15381538
let index = self.import(state, name, aggregator.types(), kind);
15391539
encoded.insert(name, (kind.into(), index));
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
(component
2+
(type (;0;)
3+
(instance
4+
(export (;0;) "x" (type (sub resource)))
5+
)
6+
)
7+
(import "foo:dependency/types" (instance (;0;) (type 0)))
8+
(alias export 0 "x" (type (;1;)))
9+
(import "x" (type (;2;) (eq 1)))
10+
(alias export 0 "x" (type (;3;)))
11+
(type (;4;)
12+
(instance
13+
(alias outer 1 3 (type (;0;)))
14+
(export (;1;) "x" (type (eq 0)))
15+
(type (;2;) (own 1))
16+
(type (;3;) (func (result 2)))
17+
(export (;0;) "my-func" (func (type 3)))
18+
)
19+
)
20+
(import "foo:test-import/my-interface" (instance (;1;) (type 4)))
21+
(type (;5;)
22+
(component
23+
(type (;0;)
24+
(instance
25+
(export (;0;) "x" (type (sub resource)))
26+
)
27+
)
28+
(export (;0;) "foo:dependency/types" (instance (type 0)))
29+
)
30+
)
31+
(import "unlocked-dep=<test:bar>" (component (;0;) (type 5)))
32+
(instance (;2;) (instantiate 0))
33+
(alias export 1 "my-func" (func (;0;)))
34+
(alias export 2 "foo:dependency/types" (instance (;3;)))
35+
(type (;6;)
36+
(component
37+
(type (;0;)
38+
(instance
39+
(export (;0;) "x" (type (sub resource)))
40+
)
41+
)
42+
(import "foo:dependency/types" (instance (;0;) (type 0)))
43+
(alias outer 1 3 (type (;1;)))
44+
(import "x" (type (;2;) (eq 1)))
45+
(type (;3;) (own 2))
46+
(type (;4;) (func (result 3)))
47+
(import "my-func" (func (;0;) (type 4)))
48+
)
49+
)
50+
(import "unlocked-dep=<test:baz>" (component (;1;) (type 6)))
51+
(instance (;4;) (instantiate 1
52+
(with "foo:dependency/types" (instance 3))
53+
(with "my-func" (func 0))
54+
(with "x" (type 2))
55+
)
56+
)
57+
)

crates/wac-types/src/aggregator.rs

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub struct TypeAggregator {
2323
/// The aggregated types collection.
2424
types: Types,
2525
/// The map from import name to aggregated item kind.
26-
names: IndexMap<String, ItemKind>,
26+
imports: IndexMap<String, ItemKind>,
2727
/// A map from foreign type to remapped local type.
2828
remapped: HashMap<Type, Type>,
2929
/// A map of interface names to remapped interface id.
@@ -41,9 +41,9 @@ impl TypeAggregator {
4141
&self.types
4242
}
4343

44-
/// Iterates the named types in the aggregator.
45-
pub fn iter(&self) -> impl Iterator<Item = (&str, ItemKind)> {
46-
self.names.iter().map(|(n, k)| (n.as_str(), *k))
44+
/// Iterates the imported types in the aggregator.
45+
pub fn imports(&self) -> impl Iterator<Item = (&str, ItemKind)> {
46+
self.imports.iter().map(|(n, k)| (n.as_str(), *k))
4747
}
4848

4949
/// Aggregates a item kind from a specified type collection using the given
@@ -60,13 +60,13 @@ impl TypeAggregator {
6060
// First check if this import has already been remapped into our
6161
// types collection.
6262
// If it has already been remapped, do a merge; otherwise, remap it.
63-
if let Some(existing) = self.names.get(name).copied() {
63+
if let Some(existing) = self.imports.get(name).copied() {
6464
self.merge_item_kind(existing, types, kind, checker)?;
6565
return Ok(self);
6666
}
6767

68-
let ty = self.remap_item_kind(types, kind, checker)?;
69-
let prev = self.names.insert(name.to_string(), ty);
68+
let remapped = self.remap_item_kind(types, kind, checker)?;
69+
let prev = self.imports.insert(name.to_string(), remapped);
7070
assert!(prev.is_none());
7171
Ok(self)
7272
}
@@ -549,11 +549,27 @@ impl TypeAggregator {
549549
alias: resource
550550
.alias
551551
.map(|a| -> Result<_> {
552+
let owner = a
553+
.owner
554+
.map(|id| {
555+
// There's no need to merge the interface here as
556+
// merging is done as part of the interface remapping
557+
self.remap_interface(types, id, checker)
558+
})
559+
.transpose()?;
560+
// If there is an owning interface, ensure it is imported
561+
if let Some(owner) = owner {
562+
let name = self.types()[owner]
563+
.id
564+
.as_deref()
565+
.expect("interface has no id");
566+
if !self.imports.contains_key(name) {
567+
self.imports
568+
.insert(name.to_owned(), ItemKind::Instance(owner));
569+
}
570+
}
552571
Ok(ResourceAlias {
553-
owner: a
554-
.owner
555-
.map(|id| self.remap_interface(types, id, checker))
556-
.transpose()?,
572+
owner,
557573
source: self.remap_resource(types, a.source, checker)?,
558574
})
559575
})

0 commit comments

Comments
 (0)