Skip to content

Commit 14aff6c

Browse files
authored
feat!: Replace GATs with impl Iterator returns (RPITIT) on HugrView (#1660)
This will simplify the update to the next portgraph release (which also moved to RPITIT), avoiding the need to use boxes around iterators to be able to name them. - drops the dependency on `context-iterators` - drive-by: Cleanup the implementations of `SiblingGraph` / `SiblingMut` to avoid `collect_vec().into_iter()`s. BREAKING CHANGE: Removed `HugrView` associated iterator types, replaced with `impl Iterator` returns.
1 parent 0e20576 commit 14aff6c

File tree

16 files changed

+366
-336
lines changed

16 files changed

+366
-336
lines changed

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ portgraph = { version = "0.12.2" }
2727
insta = { version = "1.34.0" }
2828
bitvec = "1.0.1"
2929
cgmath = "0.18.0"
30-
context-iterators = "0.2.0"
3130
cool_asserts = "2.0.3"
3231
criterion = "0.5.1"
3332
delegate = "0.13.0"

hugr-core/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ bitvec = { workspace = true, features = ["serde"] }
4747
enum_dispatch = { workspace = true }
4848
lazy_static = { workspace = true }
4949
petgraph = { workspace = true }
50-
context-iterators = { workspace = true }
5150
serde_json = { workspace = true }
5251
delegate = { workspace = true }
5352
paste = { workspace = true }

hugr-core/src/export.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ impl<'a> Context<'a> {
6969
/// Exports the root module of the HUGR graph.
7070
pub fn export_root(&mut self) {
7171
let hugr_children = self.hugr.children(self.hugr.root());
72-
let mut children = Vec::with_capacity(hugr_children.len());
72+
let mut children = Vec::with_capacity(hugr_children.size_hint().0);
7373

7474
for child in self.hugr.children(self.hugr.root()) {
7575
children.push(self.export_node(child));
@@ -110,7 +110,7 @@ impl<'a> Context<'a> {
110110
num_ports: usize,
111111
) -> &'a [model::LinkRef<'a>] {
112112
let ports = self.hugr.node_ports(node, direction);
113-
let mut links = BumpVec::with_capacity_in(ports.len(), self.bump);
113+
let mut links = BumpVec::with_capacity_in(ports.size_hint().0, self.bump);
114114

115115
for port in ports.take(num_ports) {
116116
links.push(model::LinkRef::Id(self.get_link_id(node, port)));
@@ -579,7 +579,7 @@ impl<'a> Context<'a> {
579579
let targets = self.make_ports(output_node, Direction::Incoming, output_op.types.len());
580580

581581
// Export the remaining children of the node.
582-
let mut region_children = BumpVec::with_capacity_in(children.len(), self.bump);
582+
let mut region_children = BumpVec::with_capacity_in(children.size_hint().0, self.bump);
583583

584584
for child in children {
585585
region_children.push(self.export_node(child));
@@ -609,7 +609,7 @@ impl<'a> Context<'a> {
609609
/// Creates a control flow region from the given node's children.
610610
pub fn export_cfg(&mut self, node: Node) -> model::RegionId {
611611
let mut children = self.hugr.children(node);
612-
let mut region_children = BumpVec::with_capacity_in(children.len() + 1, self.bump);
612+
let mut region_children = BumpVec::with_capacity_in(children.size_hint().0 + 1, self.bump);
613613

614614
// The first child is the entry block.
615615
// We create a source port on the control flow region and connect it to the
@@ -623,16 +623,16 @@ impl<'a> Context<'a> {
623623
let source = model::LinkRef::Id(self.get_link_id(entry_block, IncomingPort::from(0)));
624624
region_children.push(self.export_node(entry_block));
625625

626-
// Export the remaining children of the node, except for the last one.
627-
for _ in 0..children.len() - 1 {
628-
region_children.push(self.export_node(children.next().unwrap()));
629-
}
630-
631626
// The last child is the exit block.
632627
// Contrary to the entry block, the exit block does not have a dataflow subgraph.
633628
// We therefore do not export the block itself, but simply use its output ports
634629
// as the target ports of the control flow region.
635-
let exit_block = children.next().unwrap();
630+
let exit_block = children.next_back().unwrap();
631+
632+
// Export the remaining children of the node, except for the last one.
633+
for child in children {
634+
region_children.push(self.export_node(child));
635+
}
636636

637637
let OpType::ExitBlock(_) = self.hugr.get_optype(exit_block) else {
638638
panic!("expected an `ExitBlock` node as the last child node");
@@ -657,7 +657,7 @@ impl<'a> Context<'a> {
657657
/// Export the `Case` node children of a `Conditional` node as data flow regions.
658658
pub fn export_conditional_regions(&mut self, node: Node) -> &'a [model::RegionId] {
659659
let children = self.hugr.children(node);
660-
let mut regions = BumpVec::with_capacity_in(children.len(), self.bump);
660+
let mut regions = BumpVec::with_capacity_in(children.size_hint().0, self.bump);
661661

662662
for child in children {
663663
let OpType::Case(case_op) = self.hugr.get_optype(child) else {

hugr-core/src/extension/op_def.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ impl OpDef {
436436
}
437437

438438
/// Iterate over all miscellaneous data in the [OpDef].
439+
#[allow(unused)] // Unused when no features are enabled
439440
pub(crate) fn iter_misc(&self) -> impl ExactSizeIterator<Item = (&str, &serde_json::Value)> {
440441
self.misc.iter().map(|(k, v)| (k.as_str(), v))
441442
}

hugr-core/src/hugr/rewrite/inline_dfg.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ mod test {
208208

209209
// Sanity checks
210210
assert_eq!(
211-
outer.children(inner.node()).len(),
211+
outer.children(inner.node()).count(),
212212
if nonlocal { 3 } else { 6 }
213213
); // Input, Output, add; + const, load_const, lift
214214
assert_eq!(find_dfgs(&outer), vec![outer.root(), inner.node()]);
@@ -217,7 +217,7 @@ mod test {
217217
outer.get_parent(outer.get_parent(add).unwrap()),
218218
outer.get_parent(sub)
219219
);
220-
assert_eq!(outer.nodes().len(), 11); // 6 above + inner DFG + outer (DFG + Input + Output + sub)
220+
assert_eq!(outer.nodes().count(), 11); // 6 above + inner DFG + outer (DFG + Input + Output + sub)
221221
{
222222
// Check we can't inline the outer DFG
223223
let mut h = outer.clone();
@@ -230,7 +230,7 @@ mod test {
230230

231231
outer.apply_rewrite(InlineDFG(*inner.handle()))?;
232232
outer.validate(&reg)?;
233-
assert_eq!(outer.nodes().len(), 8);
233+
assert_eq!(outer.nodes().count(), 8);
234234
assert_eq!(find_dfgs(&outer), vec![outer.root()]);
235235
let [_lift, add, sub] = extension_ops(&outer).try_into().unwrap();
236236
assert_eq!(outer.get_parent(add), Some(outer.root()));
@@ -265,8 +265,8 @@ mod test {
265265

266266
let mut h = h.finish_hugr_with_outputs(cx.outputs(), &reg)?;
267267
assert_eq!(find_dfgs(&h), vec![h.root(), swap.node()]);
268-
assert_eq!(h.nodes().len(), 8); // Dfg+I+O, H, CX, Dfg+I+O
269-
// No permutation outside the swap DFG:
268+
assert_eq!(h.nodes().count(), 8); // Dfg+I+O, H, CX, Dfg+I+O
269+
// No permutation outside the swap DFG:
270270
assert_eq!(
271271
h.node_connections(p_h.node(), swap.node())
272272
.collect::<Vec<_>>(),
@@ -292,7 +292,7 @@ mod test {
292292

293293
h.apply_rewrite(InlineDFG(*swap.handle()))?;
294294
assert_eq!(find_dfgs(&h), vec![h.root()]);
295-
assert_eq!(h.nodes().len(), 5); // Dfg+I+O
295+
assert_eq!(h.nodes().count(), 5); // Dfg+I+O
296296
let mut ops = extension_ops(&h);
297297
ops.sort_by_key(|n| h.num_outputs(*n)); // Put H before CX
298298
let [h_gate, cx] = ops.try_into().unwrap();

hugr-core/src/hugr/rewrite/outline_cfg.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -453,8 +453,8 @@ mod test {
453453
// `add_hugr_with_wires` does not return an InsertionResult, so recover the nodes manually:
454454
let cfg = cfg.node();
455455
let exit_node = h.children(cfg).nth(1).unwrap();
456-
let tail = h.input_neighbours(exit_node).exactly_one().unwrap();
457-
let head = h.input_neighbours(tail).exactly_one().unwrap();
456+
let tail = h.input_neighbours(exit_node).exactly_one().ok().unwrap();
457+
let head = h.input_neighbours(tail).exactly_one().ok().unwrap();
458458
// Just sanity-check we have the correct nodes
459459
assert!(h.get_optype(exit_node).is_exit_block());
460460
assert_eq!(

0 commit comments

Comments
 (0)