Skip to content

Commit 01c0828

Browse files
committed
Fix duplicate import encoding.
This fixes a bug where a duplicate import might occur when an import with dependencies on other interfaces is encoded and then later on an import for one of those dependencies is also explicitly encoded. It skips the import if it has already been imported and also ensures that the full interface definition is provided when encoding at the root state (i.e. for the composition itself and not an instance/component type). As such, we don't need to process dependencies of implicit imports during resolution.
1 parent e02dc7f commit 01c0828

2 files changed

Lines changed: 8 additions & 23 deletions

File tree

crates/wac-parser/src/resolution/ast.rs

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1768,28 +1768,6 @@ impl<'a> AstResolver<'a> {
17681768
) -> ResolutionResult<ItemId> {
17691769
assert!(state.scopes.is_empty());
17701770

1771-
// If the item is an instance, we need to recurse on its dependencies
1772-
if let ItemKind::Instance(id) = kind {
1773-
let interface = &self.definitions.interfaces[id];
1774-
let deps = interface
1775-
.uses
1776-
.keys()
1777-
.map(|id| {
1778-
(
1779-
*id,
1780-
self.definitions.interfaces[*id]
1781-
.id
1782-
.as_ref()
1783-
.unwrap()
1784-
.clone(),
1785-
)
1786-
})
1787-
.collect::<Vec<_>>();
1788-
for (dep, name) in deps {
1789-
self.implicit_import(state, name, ItemKind::Instance(dep), package, span)?;
1790-
}
1791-
}
1792-
17931771
if let Some(import) = state.imports.get(&name) {
17941772
// Check if the implicit import would conflict with an explicit import
17951773
if import.package.is_none() {

crates/wac-parser/src/resolution/encoding.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,13 @@ impl<'a> Encoder<'a> {
167167
ItemKind::Type(ty) => ComponentTypeRef::Type(TypeBounds::Eq(encoder.ty(state, ty)?)),
168168
ItemKind::Func(id) => ComponentTypeRef::Func(encoder.ty(state, Type::Func(id))?),
169169
ItemKind::Instance(id) => {
170+
// Check to see if the instance has already been imported
171+
// This may occur when an interface uses another
172+
if let Some(index) = state.current.instances.get(&id) {
173+
log::debug!("skipping import of interface {id} as it was already imported with instance index {index}", id = id.index());
174+
return Ok(*index);
175+
}
176+
170177
ComponentTypeRef::Instance(encoder.ty(state, Type::Interface(id))?)
171178
}
172179
ItemKind::Component(id) => {
@@ -710,7 +717,7 @@ impl<'a> TypeEncoder<'a> {
710717

711718
log::debug!("encoding dependency on interface {id}", id = id.index());
712719

713-
let index = self.instance(state, id, true)?;
720+
let index = self.instance(state, id, !state.scopes.is_empty())?;
714721
let import_index = state.current.encodable.instance_count();
715722

716723
state

0 commit comments

Comments
 (0)