Skip to content

Commit 3fb7ef4

Browse files
committed
Don't build type aggregator when populating import iterator
Signed-off-by: Ryan Levick <ryan.levick@fermyon.com>
1 parent 1a3d3cc commit 3fb7ef4

File tree

2 files changed

+92
-72
lines changed

2 files changed

+92
-72
lines changed

crates/wac-graph/src/graph.rs

Lines changed: 91 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,37 +1260,9 @@ impl CompositionGraph {
12601260
}
12611261
}
12621262

1263-
/// Yields an iterator over the resolved imports of the graph.
1264-
pub fn imports(&self) -> Result<impl Iterator<Item = (&str, NodeId)>, EncodeError> {
1265-
let import_nodes = self
1266-
.node_ids()
1267-
.filter_map(|n| match &self[n].kind() {
1268-
NodeKind::Import(_) => Some(n),
1269-
_ => None,
1270-
})
1271-
.collect();
1272-
let mut implicit_imports = Default::default();
1273-
let mut explicit_imports = Default::default();
1274-
let _ = self.resolve_imports(import_nodes, &mut implicit_imports, &mut explicit_imports)?;
1275-
1276-
Ok(implicit_imports.into_iter().chain(explicit_imports))
1277-
}
1278-
1279-
/// Resolves the imports (both implicit and explicit) of the given nodes.
1280-
///
1281-
/// Populates hashmaps that map the implicit and explicit import nodes to their import names.
1282-
/// Returns a type aggregator that contains the resolved types of the imports.
1283-
pub fn resolve_imports<'a>(
1284-
&'a self,
1285-
import_nodes: Vec<NodeId>,
1286-
implicit_imports: &mut HashMap<&'a str, NodeId>,
1287-
explicit_imports: &mut HashMap<&'a str, NodeId>,
1288-
) -> Result<TypeAggregator, EncodeError> {
1289-
let mut instantiations = HashMap::new();
1290-
let mut aggregator = TypeAggregator::default();
1291-
let mut cache = Default::default();
1292-
let mut checker = SubtypeChecker::new(&mut cache);
1293-
log::debug!("populating implicit imports");
1263+
/// Yields an iterator over the resolved imports (both implicit and explicit) of the graph.
1264+
pub fn imports(&self) -> impl Iterator<Item = (&str, NodeId)> {
1265+
let mut imports = HashMap::new();
12941266
for index in self.graph.node_indices() {
12951267
let node = &self.graph[index];
12961268
if !matches!(node.kind, NodeKind::Instantiation(_)) {
@@ -1307,40 +1279,18 @@ impl CompositionGraph {
13071279
.filter(|(i, _)| !node.is_arg_satisfied(*i));
13081280

13091281
// Go through the unsatisfied arguments and import them
1310-
for (_, (name, kind)) in unsatisfied_args {
1311-
if let Some(import) = self.imports.get(name).copied() {
1312-
return Err(EncodeError::ImplicitImportConflict {
1313-
import: NodeId(import),
1314-
instantiation: NodeId(index),
1315-
package: PackageKey::new(package),
1316-
name: name.to_string(),
1317-
});
1318-
}
1319-
1320-
instantiations.entry(name).or_insert(index);
1321-
1322-
aggregator = aggregator
1323-
.aggregate(name, &self.types, *kind, &mut checker)
1324-
.map_err(|e| EncodeError::ImportTypeMergeConflict {
1325-
import: name.clone(),
1326-
first: NodeId(instantiations[&name]),
1327-
second: NodeId(index),
1328-
source: e,
1329-
})?;
1330-
implicit_imports.insert(name, NodeId(index));
1282+
for (_, (name, _)) in unsatisfied_args {
1283+
imports.insert(name.as_str(), NodeId(index));
13311284
}
13321285
}
1333-
log::debug!("populating explicit imports");
1334-
for n in import_nodes {
1286+
1287+
for n in self.node_ids() {
13351288
let node = &self.graph[n.0];
13361289
if let NodeKind::Import(name) = &node.kind {
1337-
explicit_imports.insert(name.as_str(), n);
1338-
aggregator = aggregator
1339-
.aggregate(name, self.types(), node.item_kind, &mut checker)
1340-
.unwrap();
1290+
imports.insert(name.as_str(), n);
13411291
}
13421292
}
1343-
Ok(aggregator)
1293+
imports.into_iter()
13441294
}
13451295
}
13461296

@@ -1465,9 +1415,8 @@ impl<'a> CompositionGraphEncoder<'a> {
14651415
.toposort()
14661416
.map_err(|n| EncodeError::GraphContainsCycle { node: NodeId(n) })?
14671417
.into_iter()
1468-
.map(NodeId)
14691418
.partition::<Vec<_>, _>(|index| {
1470-
let node = &self.0.graph[index.0];
1419+
let node = &self.0.graph[*index];
14711420
matches!(node.kind, NodeKind::Import(_))
14721421
});
14731422

@@ -1476,16 +1425,16 @@ impl<'a> CompositionGraphEncoder<'a> {
14761425

14771426
// Encode non-import nodes in the graph in topographical order
14781427
for n in other_nodes {
1479-
let node = &self.0.graph[n.0];
1428+
let node = &self.0.graph[n];
14801429
let index = match &node.kind {
14811430
NodeKind::Definition => self.definition(&mut state, node),
1482-
NodeKind::Instantiation(_) => self.instantiation(&mut state, n.0, node, options),
1483-
NodeKind::Alias => self.alias(&mut state, n.0),
1431+
NodeKind::Instantiation(_) => self.instantiation(&mut state, n, node, options),
1432+
NodeKind::Alias => self.alias(&mut state, n),
14841433
// `other_nodes` does not contain any import nodes
14851434
NodeKind::Import(_) => unreachable!(),
14861435
};
14871436

1488-
let prev = state.node_indexes.insert(n.0, index);
1437+
let prev = state.node_indexes.insert(n, index);
14891438
assert!(prev.is_none());
14901439
}
14911440

@@ -1578,13 +1527,12 @@ impl<'a> CompositionGraphEncoder<'a> {
15781527
fn encode_imports(
15791528
&self,
15801529
state: &mut State,
1581-
import_nodes: Vec<NodeId>,
1530+
import_nodes: Vec<NodeIndex>,
15821531
) -> Result<(), EncodeError> {
15831532
let mut explicit_imports = HashMap::new();
1584-
let mut implicit_imports = HashMap::new();
1533+
let mut implicit_imports = Vec::new();
15851534
let aggregator =
1586-
self.0
1587-
.resolve_imports(import_nodes, &mut implicit_imports, &mut explicit_imports)?;
1535+
self.resolve_imports(import_nodes, &mut implicit_imports, &mut explicit_imports)?;
15881536

15891537
let mut encoded = HashMap::new();
15901538

@@ -1600,20 +1548,92 @@ impl<'a> CompositionGraphEncoder<'a> {
16001548
let (kind, index) = encoded[name];
16011549
state
16021550
.implicit_args
1603-
.entry(node.0)
1551+
.entry(node)
16041552
.or_default()
16051553
.push((name.to_owned(), kind, index));
16061554
}
16071555

16081556
// Finally, populate the node indexes with the encoded explicit imports
16091557
for (name, node_index) in explicit_imports {
16101558
let (_, encoded_index) = encoded[name];
1611-
state.node_indexes.insert(node_index.0, encoded_index);
1559+
state.node_indexes.insert(node_index, encoded_index);
16121560
}
16131561

16141562
Ok(())
16151563
}
16161564

1565+
/// Resolves the imports (both implicit and explicit) of the given nodes.
1566+
///
1567+
/// Populates hashmaps that map the implicit and explicit import nodes to their import names.
1568+
/// Returns a type aggregator that contains the resolved types of the imports.
1569+
fn resolve_imports(
1570+
&'a self,
1571+
import_nodes: Vec<NodeIndex>,
1572+
implicit_imports: &mut Vec<(&'a str, NodeIndex)>,
1573+
explicit_imports: &mut HashMap<&'a str, NodeIndex>,
1574+
) -> Result<TypeAggregator, EncodeError> {
1575+
let mut instantiations = HashMap::new();
1576+
let mut aggregator = TypeAggregator::default();
1577+
let mut cache = Default::default();
1578+
let mut checker = SubtypeChecker::new(&mut cache);
1579+
1580+
log::debug!("populating implicit imports");
1581+
1582+
// Enumerate the instantiation nodes and populate the import types
1583+
for index in self.0.graph.node_indices() {
1584+
let node = &self.0.graph[index];
1585+
if !matches!(node.kind, NodeKind::Instantiation(_)) {
1586+
continue;
1587+
}
1588+
1589+
let package = &self.0[node.package.unwrap()];
1590+
let world = &self.0.types[package.ty()];
1591+
1592+
let unsatisfied_args = world
1593+
.imports
1594+
.iter()
1595+
.enumerate()
1596+
.filter(|(i, _)| !node.is_arg_satisfied(*i));
1597+
1598+
// Go through the unsatisfied arguments and import them
1599+
for (_, (name, kind)) in unsatisfied_args {
1600+
if let Some(import) = self.0.imports.get(name).copied() {
1601+
return Err(EncodeError::ImplicitImportConflict {
1602+
import: NodeId(import),
1603+
instantiation: NodeId(index),
1604+
package: PackageKey::new(package),
1605+
name: name.to_string(),
1606+
});
1607+
}
1608+
1609+
instantiations.entry(name).or_insert(index);
1610+
1611+
aggregator = aggregator
1612+
.aggregate(name, &self.0.types, *kind, &mut checker)
1613+
.map_err(|e| EncodeError::ImportTypeMergeConflict {
1614+
import: name.clone(),
1615+
first: NodeId(instantiations[&name]),
1616+
second: NodeId(index),
1617+
source: e,
1618+
})?;
1619+
implicit_imports.push((name, index));
1620+
}
1621+
}
1622+
1623+
log::debug!("populating explicit imports");
1624+
1625+
for n in import_nodes {
1626+
let node = &self.0.graph[n];
1627+
if let NodeKind::Import(name) = &node.kind {
1628+
explicit_imports.insert(name.as_str(), n);
1629+
aggregator = aggregator
1630+
.aggregate(name, self.0.types(), node.item_kind, &mut checker)
1631+
.unwrap();
1632+
}
1633+
}
1634+
Ok(aggregator)
1635+
}
1636+
16171637
fn definition(&self, state: &mut State, node: &Node) -> u32 {
16181638
let name = node.export.as_deref().unwrap();
16191639

crates/wac-parser/src/resolution.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2717,7 +2717,7 @@ impl<'a> AstResolver<'a> {
27172717

27182718
// The output is allowed to import a subset of the world's imports
27192719
checker.invert();
2720-
for (name, import) in state.graph.imports().unwrap() {
2720+
for (name, import) in state.graph.imports() {
27212721
let expected = world
27222722
.imports
27232723
.get(name)

0 commit comments

Comments
 (0)