@@ -1377,22 +1377,28 @@ impl<'a> CompositionGraphEncoder<'a> {
13771377 fn encode ( self , options : EncodeOptions ) -> Result < Vec < u8 > , EncodeError > {
13781378 let mut state = State :: new ( ) ;
13791379
1380- // First populate the state with the implicit instantiation arguments
1381- self . populate_implicit_args ( & mut state) ?;
1382-
1383- // Encode each node in the graph in topographical order
1384- for n in self
1380+ // Separate import nodes from other nodes keeping topological order
1381+ let ( import_nodes, other_nodes) = self
13851382 . toposort ( )
13861383 . map_err ( |n| EncodeError :: GraphContainsCycle { node : NodeId ( n) } ) ?
1387- {
1384+ . into_iter ( )
1385+ . partition :: < Vec < _ > , _ > ( |index| {
1386+ let node = & self . 0 . graph [ * index] ;
1387+ matches ! ( node. kind, NodeKind :: Import ( _) )
1388+ } ) ;
1389+
1390+ // First populate the state with both implicit instantiation arguments and explicit imports
1391+ self . encode_imports ( & mut state, import_nodes) ?;
1392+
1393+ // Encode non-import nodes in the graph in topographical order
1394+ for n in other_nodes {
13881395 let node = & self . 0 . graph [ n] ;
13891396 let index = match & node. kind {
13901397 NodeKind :: Definition => self . definition ( & mut state, node) ,
1391- NodeKind :: Import ( name) => {
1392- self . import ( & mut state, name, & self . 0 . types , node. item_kind )
1393- }
13941398 NodeKind :: Instantiation ( _) => self . instantiation ( & mut state, n, node, options) ,
13951399 NodeKind :: Alias => self . alias ( & mut state, n) ,
1400+ // `other_nodes` does not contain any import nodes
1401+ NodeKind :: Import ( _) => unreachable ! ( ) ,
13961402 } ;
13971403
13981404 let prev = state. node_indexes . insert ( n, index) ;
@@ -1482,13 +1488,19 @@ impl<'a> CompositionGraphEncoder<'a> {
14821488 Ok ( finish_stack)
14831489 }
14841490
1485- fn populate_implicit_args ( & self , state : & mut State ) -> Result < ( ) , EncodeError > {
1491+ /// Encode both implicit and explicit imports.
1492+ fn encode_imports (
1493+ & self ,
1494+ state : & mut State ,
1495+ import_nodes : Vec < NodeIndex > ,
1496+ ) -> Result < ( ) , EncodeError > {
14861497 let mut aggregator = TypeAggregator :: default ( ) ;
14871498 let mut instantiations = HashMap :: new ( ) ;
14881499 let mut arguments = Vec :: new ( ) ;
14891500 let mut encoded = HashMap :: new ( ) ;
14901501 let mut cache = Default :: default ( ) ;
14911502 let mut checker = SubtypeChecker :: new ( & mut cache) ;
1503+ let mut explicit_imports = HashMap :: new ( ) ;
14921504
14931505 log:: debug!( "populating implicit imports" ) ;
14941506
@@ -1502,13 +1514,14 @@ impl<'a> CompositionGraphEncoder<'a> {
15021514 let package = & self . 0 [ node. package . unwrap ( ) ] ;
15031515 let world = & self . 0 . types [ package. ty ( ) ] ;
15041516
1505- // Go through the unsatisfied arguments and import them
1506- for ( _, ( name, kind) ) in world
1517+ let unsatisfied_args = world
15071518 . imports
15081519 . iter ( )
15091520 . enumerate ( )
1510- . filter ( |( i, _) | !node. is_arg_satisfied ( * i) )
1511- {
1521+ . filter ( |( i, _) | !node. is_arg_satisfied ( * i) ) ;
1522+
1523+ // Go through the unsatisfied arguments and import them
1524+ for ( _, ( name, kind) ) in unsatisfied_args {
15121525 if let Some ( import) = self . 0 . imports . get ( name) . copied ( ) {
15131526 return Err ( EncodeError :: ImplicitImportConflict {
15141527 import : NodeId ( import) ,
@@ -1532,14 +1545,26 @@ impl<'a> CompositionGraphEncoder<'a> {
15321545 }
15331546 }
15341547
1548+ log:: debug!( "populating explicit imports" ) ;
1549+
1550+ for n in import_nodes {
1551+ let node = & self . 0 . graph [ n] ;
1552+ if let NodeKind :: Import ( name) = & node. kind {
1553+ explicit_imports. insert ( name. as_str ( ) , n) ;
1554+ aggregator = aggregator
1555+ . aggregate ( name, self . 0 . types ( ) , node. item_kind , & mut checker)
1556+ . unwrap ( ) ;
1557+ }
1558+ }
1559+
15351560 // Next encode the imports
15361561 for ( name, kind) in aggregator. imports ( ) {
1537- log:: debug!( "import `{name}` is being implicitly imported" ) ;
1562+ log:: debug!( "import `{name}` is being imported" ) ;
15381563 let index = self . import ( state, name, aggregator. types ( ) , kind) ;
15391564 encoded. insert ( name, ( kind. into ( ) , index) ) ;
15401565 }
15411566
1542- // Finally populate the implicit argument map
1567+ // Populate the implicit argument map
15431568 for ( node, name) in arguments {
15441569 let ( kind, index) = encoded[ name. as_str ( ) ] ;
15451570 state
@@ -1549,6 +1574,12 @@ impl<'a> CompositionGraphEncoder<'a> {
15491574 . push ( ( name. clone ( ) , kind, index) ) ;
15501575 }
15511576
1577+ // Finally, populate the node indexes with the encoded explicit imports
1578+ for ( name, node_index) in explicit_imports {
1579+ let ( _, encoded_index) = encoded[ name] ;
1580+ state. node_indexes . insert ( node_index, encoded_index) ;
1581+ }
1582+
15521583 Ok ( ( ) )
15531584 }
15541585
0 commit comments