From 359f47a7386690a5a8444d804cd8e27dbe7f8a56 Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Sun, 17 Aug 2025 13:49:41 +0200 Subject: [PATCH] Fix interface resolution for components exporting interface instances Resolves composition failures when source components export interface instances but target components expect individual function imports. Enhanced the instance_exports() method to search inside interface instances for missing function exports when direct lookup fails. Fixes: https://github.com/bytecodealliance/wac/issues/172 --- crates/wac-types/src/checker.rs | 46 ++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/crates/wac-types/src/checker.rs b/crates/wac-types/src/checker.rs index 1c17fb2..448393c 100644 --- a/crates/wac-types/src/checker.rs +++ b/crates/wac-types/src/checker.rs @@ -231,20 +231,42 @@ impl<'a> SubtypeChecker<'a> { self.is_subtype(*a, at, *b, bt) .with_context(|| format!("mismatched type for export `{k}`"))?; } - None => match self.kind() { - SubtypeCheck::Covariant => { - bail!( - "instance is missing expected {kind} export `{k}`", - kind = b.desc(bt) - ) + None => { + // Check if any interface instance exports in the source can provide this export + let mut found_in_interface = false; + for (_source_name, source_kind) in a.iter() { + if let ItemKind::Instance(interface_id) = source_kind { + let interface = &at[*interface_id]; + + if let Some(interface_export) = interface.exports.get(k) { + // Check if the export type matches what's expected + if self.is_subtype(*interface_export, at, *b, bt).is_ok() { + found_in_interface = true; + break; + } + } + } } - SubtypeCheck::Contravariant => { - bail!( - "instance has unexpected {kind} export `{k}`", - kind = b.desc(bt) - ) + + if found_in_interface { + // Found a compatible export in an interface instance, continue to next export + continue; } - }, + match self.kind() { + SubtypeCheck::Covariant => { + bail!( + "instance is missing expected {kind} export `{k}`", + kind = b.desc(bt) + ) + } + SubtypeCheck::Contravariant => { + bail!( + "instance has unexpected {kind} export `{k}`", + kind = b.desc(bt) + ) + } + } + } } }