@@ -190,6 +190,31 @@ impl<'a> TypeEncoder<'a> {
190190 Self ( types)
191191 }
192192
193+ // Aliases a value type from an imported instance that exports it, rather
194+ // than re-encoding it locally: a type import must reference a named type,
195+ // not a local definition.
196+ fn alias_from_instance_export ( & self , state : & mut State , ty : ValueType ) -> Option < u32 > {
197+ if state. current . instances . is_empty ( ) {
198+ return None ;
199+ }
200+ let ty = Type :: Value ( ty) ;
201+ let ( instance, name) = self . 0 . interfaces ( ) . find_map ( |interface| {
202+ let iid = interface. id . as_ref ( ) ?;
203+ let instance = * state. current . instances . get ( iid) ?;
204+ interface. exports . iter ( ) . find_map ( |( name, kind) | {
205+ ( * kind == ItemKind :: Type ( ty) ) . then ( || ( instance, name. clone ( ) ) )
206+ } )
207+ } ) ?;
208+ let index = state. current . encodable . type_count ( ) ;
209+ state. current . encodable . alias ( Alias :: InstanceExport {
210+ instance,
211+ kind : ComponentExportKind :: Type ,
212+ name : & name,
213+ } ) ;
214+ state. current . type_indexes . insert ( ty, index) ;
215+ Some ( index)
216+ }
217+
193218 pub fn ty ( & self , state : & mut State , ty : Type , name : Option < & str > ) -> u32 {
194219 if let Some ( index) = state. current . type_indexes . get ( & ty) {
195220 return * index;
@@ -264,7 +289,12 @@ impl<'a> TypeEncoder<'a> {
264289 index
265290 }
266291
267- fn use_aliases ( & self , state : & mut State , uses : & ' a IndexMap < String , UsedType > ) {
292+ fn use_aliases (
293+ & self ,
294+ state : & mut State ,
295+ uses : & ' a IndexMap < String , UsedType > ,
296+ items : & ' a IndexMap < String , ItemKind > ,
297+ ) {
268298 state. current . type_aliases . clear ( ) ;
269299
270300 for ( name, used) in uses {
@@ -286,6 +316,17 @@ impl<'a> TypeEncoder<'a> {
286316 ) ;
287317
288318 state. current . type_aliases . insert ( name. clone ( ) , index) ;
319+
320+ // Record the alias under both ids that denote this used type (the
321+ // interface's export and the using entity's own item) so a later
322+ // id-keyed reference reuses it instead of re-encoding a local copy:
323+ // a type import must reference a named type, not a local definition.
324+ if let ItemKind :: Type ( ty) = kind {
325+ state. current . type_indexes . insert ( * ty, index) ;
326+ }
327+ if let Some ( ItemKind :: Type ( ty) ) = items. get ( name) {
328+ state. current . type_indexes . insert ( * ty, index) ;
329+ }
289330 }
290331 }
291332
@@ -297,7 +338,7 @@ impl<'a> TypeEncoder<'a> {
297338 }
298339
299340 // Encode any required aliases
300- self . use_aliases ( state, & interface. uses ) ;
341+ self . use_aliases ( state, & interface. uses , & interface . exports ) ;
301342 state. push ( Encodable :: Instance ( InstanceType :: default ( ) ) ) ;
302343
303344 // Otherwise, export all exports
@@ -335,7 +376,7 @@ impl<'a> TypeEncoder<'a> {
335376 self . import_deps ( state, used. interface ) ;
336377 }
337378
338- self . use_aliases ( state, & world. uses ) ;
379+ self . use_aliases ( state, & world. uses , & world . imports ) ;
339380
340381 for ( name, kind) in & world. imports {
341382 self . import ( state, name, * kind) ;
@@ -516,6 +557,10 @@ impl<'a> TypeEncoder<'a> {
516557 return ComponentValType :: Type ( * index) ;
517558 }
518559
560+ if let Some ( index) = self . alias_from_instance_export ( state, ty) {
561+ return ComponentValType :: Type ( index) ;
562+ }
563+
519564 let index = match ty {
520565 ValueType :: Primitive ( ty) => return ComponentValType :: Primitive ( ty. into ( ) ) ,
521566 ValueType :: Borrow ( id) => self . borrow ( state, id) ,
0 commit comments