diff --git a/src/builder.rs b/src/builder.rs index c0cecfc655..044fef3a43 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -235,15 +235,13 @@ pub(crate) mod test { ops::Input { types: signature.input, }, - ) - .unwrap(); + ); hugr.add_node_with_parent( hugr.root(), ops::Output { types: signature.output, }, - ) - .unwrap(); + ); hugr } } diff --git a/src/builder/build_traits.rs b/src/builder/build_traits.rs index 7b1b4621ef..43902b7481 100644 --- a/src/builder/build_traits.rs +++ b/src/builder/build_traits.rs @@ -47,12 +47,12 @@ pub trait Container { /// Add an [`OpType`] as the final child of the container. fn add_child_op(&mut self, op: impl Into) -> Result { let parent = self.container_node(); - Ok(self.hugr_mut().add_node_with_parent(parent, op)?) + Ok(self.hugr_mut().add_node_with_parent(parent, op)) } /// Add a [`NodeType`] as the final child of the container. fn add_child_node(&mut self, node: NodeType) -> Result { let parent = self.container_node(); - Ok(self.hugr_mut().add_node_with_parent(parent, node)?) + Ok(self.hugr_mut().add_node_with_parent(parent, node)) } /// Adds a non-dataflow edge between two nodes. The kind is given by the operation's [`other_inputs`] or [`other_outputs`] @@ -60,7 +60,7 @@ pub trait Container { /// [`other_inputs`]: crate::ops::OpTrait::other_input /// [`other_outputs`]: crate::ops::OpTrait::other_output fn add_other_wire(&mut self, src: Node, dst: Node) -> Result { - let (src_port, _) = self.hugr_mut().add_other_edge(src, dst)?; + let (src_port, _) = self.hugr_mut().add_other_edge(src, dst); Ok(Wire::new(src, src_port)) } @@ -102,20 +102,20 @@ pub trait Container { /// Insert a HUGR as a child of the container. fn add_hugr(&mut self, child: Hugr) -> Result { let parent = self.container_node(); - Ok(self.hugr_mut().insert_hugr(parent, child)?) + Ok(self.hugr_mut().insert_hugr(parent, child)) } /// Insert a copy of a HUGR as a child of the container. fn add_hugr_view(&mut self, child: &impl HugrView) -> Result { let parent = self.container_node(); - Ok(self.hugr_mut().insert_from_view(parent, child)?) + Ok(self.hugr_mut().insert_from_view(parent, child)) } /// Add metadata to the container node. fn set_metadata(&mut self, key: impl AsRef, meta: impl Into) { let parent = self.container_node(); // Implementor's container_node() should be a valid node - self.hugr_mut().set_metadata(parent, key, meta).unwrap(); + self.hugr_mut().set_metadata(parent, key, meta); } /// Add metadata to a child node. @@ -127,7 +127,7 @@ pub trait Container { key: impl AsRef, meta: impl Into, ) -> Result<(), BuildError> { - self.hugr_mut().set_metadata(child, key, meta)?; + self.hugr_mut().set_metadata(child, key, meta); Ok(()) } } @@ -604,7 +604,7 @@ pub trait Dataflow: Container { let src_port = self.hugr_mut().num_outputs(function.node()) - 1; self.hugr_mut() - .connect(function.node(), src_port, op_id.node(), const_in_port)?; + .connect(function.node(), src_port, op_id.node(), const_in_port); Ok(op_id) } @@ -695,7 +695,7 @@ fn wire_up( && !OpTag::BasicBlock.is_superset(base.get_optype(src_sibling).tag()) { // Add a state order constraint unless one of the nodes is a CFG BasicBlock - base.add_other_edge(src, src_sibling)?; + base.add_other_edge(src, src_sibling); } } else if !typ.copyable() & base.linked_ports(src, src_port).next().is_some() { // Don't copy linear edges. @@ -705,7 +705,7 @@ fn wire_up( data_builder .hugr_mut() - .connect(src, src_port, dst, dst_port)?; + .connect(src, src_port, dst, dst_port); Ok(local_source && matches!( data_builder diff --git a/src/builder/cfg.rs b/src/builder/cfg.rs index b9b7e26212..88ae2ffd91 100644 --- a/src/builder/cfg.rs +++ b/src/builder/cfg.rs @@ -190,7 +190,7 @@ impl + AsRef> CFGBuilder { let exit_node = base .as_mut() // Make the extensions a parameter - .add_node_with_parent(cfg_node, exit_block_type)?; + .add_node_with_parent(cfg_node, exit_block_type); Ok(Self { base, cfg_node, @@ -246,7 +246,7 @@ impl + AsRef> CFGBuilder { } else { // TODO: Make extensions a parameter self.hugr_mut().add_node_with_parent(parent, op) - }?; + }; BlockBuilder::create(self.hugr_mut(), block_n) } @@ -323,7 +323,8 @@ impl + AsRef> CFGBuilder { ) -> Result<(), BuildError> { let from = predecessor.node(); let to = successor.node(); - Ok(self.hugr_mut().connect(from, branch, to, 0)?) + self.hugr_mut().connect(from, branch, to, 0); + Ok(()) } } diff --git a/src/builder/conditional.rs b/src/builder/conditional.rs index 426f80512e..8af4751278 100644 --- a/src/builder/conditional.rs +++ b/src/builder/conditional.rs @@ -127,7 +127,7 @@ impl + AsRef> ConditionalBuilder { let case_node = // add case before any existing subsequent cases if let Some(&sibling_node) = self.case_nodes[case + 1..].iter().flatten().next() { - self.hugr_mut().add_node_before(sibling_node, case_op)? + self.hugr_mut().add_node_before(sibling_node, case_op) } else { self.add_child_op(case_op)? }; diff --git a/src/builder/dataflow.rs b/src/builder/dataflow.rs index 2aa4718827..d11c394fec 100644 --- a/src/builder/dataflow.rs +++ b/src/builder/dataflow.rs @@ -50,14 +50,14 @@ impl + AsRef> DFGBuilder { types: signature.output().clone(), }; base.as_mut() - .add_node_with_parent(parent, NodeType::new(input, input_extensions.clone()))?; + .add_node_with_parent(parent, NodeType::new(input, input_extensions.clone())); base.as_mut().add_node_with_parent( parent, NodeType::new( output, input_extensions.map(|inp| inp.union(signature.extension_reqs)), ), - )?; + ); Ok(Self { base, diff --git a/src/extension/infer/test.rs b/src/extension/infer/test.rs index f070abcf18..86fa509c43 100644 --- a/src/extension/infer/test.rs +++ b/src/extension/infer/test.rs @@ -52,8 +52,8 @@ fn from_graph() -> Result<(), Box> { let input = ops::Input::new(type_row![NAT, NAT]); let output = ops::Output::new(type_row![NAT]); - let input = hugr.add_node_with_parent(hugr.root(), input)?; - let output = hugr.add_node_with_parent(hugr.root(), output)?; + let input = hugr.add_node_with_parent(hugr.root(), input); + let output = hugr.add_node_with_parent(hugr.root(), output); assert_matches!(hugr.get_io(hugr.root()), Some(_)); @@ -71,34 +71,34 @@ fn from_graph() -> Result<(), Box> { ops::DFG { signature: add_a_sig, }, - )?; + ); let add_b = hugr.add_node_with_parent( hugr.root(), ops::DFG { signature: add_b_sig, }, - )?; + ); let add_ab = hugr.add_node_with_parent( hugr.root(), ops::DFG { signature: add_ab_sig, }, - )?; + ); let mult_c = hugr.add_node_with_parent( hugr.root(), ops::DFG { signature: mult_c_sig, }, - )?; + ); - hugr.connect(input, 0, add_a, 0)?; - hugr.connect(add_a, 0, add_b, 0)?; - hugr.connect(add_b, 0, mult_c, 0)?; + hugr.connect(input, 0, add_a, 0); + hugr.connect(add_a, 0, add_b, 0); + hugr.connect(add_b, 0, mult_c, 0); - hugr.connect(input, 1, add_ab, 0)?; - hugr.connect(add_ab, 0, mult_c, 1)?; + hugr.connect(input, 1, add_ab, 0); + hugr.connect(add_ab, 0, mult_c, 1); - hugr.connect(mult_c, 0, output, 0)?; + hugr.connect(mult_c, 0, output, 0); let (_, closure) = infer_extensions(&hugr)?; let empty = ExtensionSet::new(); @@ -153,7 +153,7 @@ fn plus() -> Result<(), InferExtensionError> { #[test] // This generates a solution that causes validation to fail // because of a missing lift node -fn missing_lift_node() -> Result<(), Box> { +fn missing_lift_node() { let mut hugr = Hugr::new(NodeType::new_pure(ops::DFG { signature: FunctionType::new(type_row![NAT], type_row![NAT]).with_extension_delta(A), })); @@ -163,16 +163,16 @@ fn missing_lift_node() -> Result<(), Box> { NodeType::new_pure(ops::Input { types: type_row![NAT], }), - )?; + ); let output = hugr.add_node_with_parent( hugr.root(), NodeType::new_pure(ops::Output { types: type_row![NAT], }), - )?; + ); - hugr.connect(input, 0, output, 0)?; + hugr.connect(input, 0, output, 0); // Fail to catch the actual error because it's a difference between I/O // nodes and their parents and `report_mismatch` isn't yet smart enough @@ -181,7 +181,6 @@ fn missing_lift_node() -> Result<(), Box> { hugr.update_validate(&PRELUDE_REGISTRY), Err(ValidationError::CantInfer(_)) ); - Ok(()) } #[test] @@ -229,12 +228,12 @@ fn dangling_src() -> Result<(), Box> { ops::DFG { signature: add_r_sig, }, - )?; + ); // Dangling thingy let src_sig = FunctionType::new(type_row![], type_row![NAT]); - let src = hugr.add_node_with_parent(hugr.root(), ops::DFG { signature: src_sig })?; + let src = hugr.add_node_with_parent(hugr.root(), ops::DFG { signature: src_sig }); let mult_sig = FunctionType::new(type_row![NAT, NAT], type_row![NAT]); // Mult has open extension requirements, which we should solve to be "R" @@ -243,12 +242,12 @@ fn dangling_src() -> Result<(), Box> { ops::DFG { signature: mult_sig, }, - )?; + ); - hugr.connect(input, 0, add_r, 0)?; - hugr.connect(add_r, 0, mult, 0)?; - hugr.connect(src, 0, mult, 1)?; - hugr.connect(mult, 0, output, 0)?; + hugr.connect(input, 0, add_r, 0); + hugr.connect(add_r, 0, mult, 0); + hugr.connect(src, 0, mult, 1); + hugr.connect(mult, 0, output, 0); let closure = hugr.infer_extensions()?; assert!(closure.is_empty()); @@ -286,19 +285,19 @@ fn create_with_io( ) -> Result<[Node; 3], Box> { let op: OpType = op.into(); - let node = hugr.add_node_with_parent(parent, op)?; + let node = hugr.add_node_with_parent(parent, op); let input = hugr.add_node_with_parent( node, ops::Input { types: op_sig.input, }, - )?; + ); let output = hugr.add_node_with_parent( node, ops::Output { types: op_sig.output, }, - )?; + ); Ok([node, input, output]) } @@ -321,7 +320,7 @@ fn test_conditional_inference() -> Result<(), Box> { type_row: type_row![NAT], new_extension: first_ext, }, - )?; + ); let lift2 = hugr.add_node_with_parent( case, @@ -329,11 +328,11 @@ fn test_conditional_inference() -> Result<(), Box> { type_row: type_row![NAT], new_extension: second_ext, }, - )?; + ); - hugr.connect(case_in, 0, lift1, 0)?; - hugr.connect(lift1, 0, lift2, 0)?; - hugr.connect(lift2, 0, case_out, 0)?; + hugr.connect(case_in, 0, lift1, 0); + hugr.connect(lift1, 0, lift2, 0); + hugr.connect(lift2, 0, case_out, 0); Ok(case) } @@ -392,13 +391,13 @@ fn extension_adding_sequence() -> Result<(), Box> { ops::Input { types: type_row![NAT], }, - )?; + ); let output = hugr.add_node_with_parent( root, ops::Output { types: type_row![NAT], }, - )?; + ); // Make identical dataflow nodes which add extension requirement "A" or "B" let df_nodes: Vec = vec![A, A, B, B, A, B] @@ -415,18 +414,16 @@ fn extension_adding_sequence() -> Result<(), Box> { ) .unwrap(); - let lift = hugr - .add_node_with_parent( - node, - ops::LeafOp::Lift { - type_row: type_row![NAT], - new_extension: ext, - }, - ) - .unwrap(); + let lift = hugr.add_node_with_parent( + node, + ops::LeafOp::Lift { + type_row: type_row![NAT], + new_extension: ext, + }, + ); - hugr.connect(input, 0, lift, 0).unwrap(); - hugr.connect(lift, 0, output, 0).unwrap(); + hugr.connect(input, 0, lift, 0); + hugr.connect(lift, 0, output, 0); node }) @@ -435,7 +432,7 @@ fn extension_adding_sequence() -> Result<(), Box> { // Connect nodes in order (0 -> 1 -> 2 ...) let nodes = [vec![input], df_nodes, vec![output]].concat(); for (src, tgt) in nodes.into_iter().tuple_windows() { - hugr.connect(src, 0, tgt, 0)?; + hugr.connect(src, 0, tgt, 0); } hugr.update_validate(&PRELUDE_REGISTRY)?; Ok(()) @@ -467,10 +464,10 @@ fn make_block( let [bb, bb_in, bb_out] = create_with_io(hugr, bb_parent, dfb, dfb_sig)?; - let dfg = hugr.add_node_with_parent(bb, op)?; + let dfg = hugr.add_node_with_parent(bb, op); - hugr.connect(bb_in, 0, dfg, 0)?; - hugr.connect(dfg, 0, bb_out, 0)?; + hugr.connect(bb_in, 0, dfg, 0); + hugr.connect(dfg, 0, bb_out, 0); Ok(bb) } @@ -504,16 +501,16 @@ fn create_entry_exit( ops::ExitBlock { cfg_outputs: exit_types.into(), }, - )?; + ); - let entry = hugr.add_node_before(exit, dfb)?; - let entry_in = hugr.add_node_with_parent(entry, ops::Input { types: inputs })?; + let entry = hugr.add_node_before(exit, dfb); + let entry_in = hugr.add_node_with_parent(entry, ops::Input { types: inputs }); let entry_out = hugr.add_node_with_parent( entry, ops::Output { types: vec![entry_tuple_sum].into(), }, - )?; + ); Ok(([entry, entry_in, entry_out], exit)) } @@ -566,11 +563,11 @@ fn infer_cfg_test() -> Result<(), Box> { A, FunctionType::new(vec![NAT], twoway(NAT)).with_extension_delta(A), ), - )?; + ); // Internal wiring for DFGs - hugr.connect(entry_in, 0, mkpred, 0)?; - hugr.connect(mkpred, 0, entry_out, 0)?; + hugr.connect(entry_in, 0, mkpred, 0); + hugr.connect(mkpred, 0, entry_out, 0); let bb0 = make_block( &mut hugr, @@ -605,14 +602,14 @@ fn infer_cfg_test() -> Result<(), Box> { )?; // CFG Wiring - hugr.connect(entry, 0, bb0, 0)?; - hugr.connect(entry, 0, bb1, 0)?; - hugr.connect(bb1, 0, bb10, 0)?; - hugr.connect(bb1, 0, bb11, 0)?; + hugr.connect(entry, 0, bb0, 0); + hugr.connect(entry, 0, bb1, 0); + hugr.connect(bb1, 0, bb10, 0); + hugr.connect(bb1, 0, bb11, 0); - hugr.connect(bb0, 0, exit, 0)?; - hugr.connect(bb10, 0, exit, 0)?; - hugr.connect(bb11, 0, exit, 0)?; + hugr.connect(bb0, 0, exit, 0); + hugr.connect(bb10, 0, exit, 0); + hugr.connect(bb11, 0, exit, 0); hugr.infer_extensions()?; @@ -659,10 +656,10 @@ fn multi_entry() -> Result<(), Box> { let entry_mid = hugr.add_node_with_parent( entry, make_opaque(UNKNOWN_EXTENSION, FunctionType::new(vec![NAT], twoway(NAT))), - )?; + ); - hugr.connect(entry_in, 0, entry_mid, 0)?; - hugr.connect(entry_mid, 0, entry_out, 0)?; + hugr.connect(entry_in, 0, entry_mid, 0); + hugr.connect(entry_mid, 0, entry_out, 0); let bb0 = make_block( &mut hugr, @@ -688,11 +685,11 @@ fn multi_entry() -> Result<(), Box> { ExtensionSet::new(), )?; - hugr.connect(entry, 0, bb0, 0)?; - hugr.connect(entry, 0, bb1, 0)?; - hugr.connect(bb0, 0, bb2, 0)?; - hugr.connect(bb1, 0, bb2, 0)?; - hugr.connect(bb2, 0, exit, 0)?; + hugr.connect(entry, 0, bb0, 0); + hugr.connect(entry, 0, bb1, 0); + hugr.connect(bb0, 0, bb2, 0); + hugr.connect(bb1, 0, bb2, 0); + hugr.connect(bb2, 0, exit, 0); hugr.update_validate(&PRELUDE_REGISTRY)?; @@ -751,10 +748,10 @@ fn make_looping_cfg( UNKNOWN_EXTENSION, FunctionType::new(vec![NAT], oneway(NAT)).with_extension_delta(entry_ext), ), - )?; + ); - hugr.connect(entry_in, 0, entry_dfg, 0)?; - hugr.connect(entry_dfg, 0, entry_out, 0)?; + hugr.connect(entry_in, 0, entry_dfg, 0); + hugr.connect(entry_dfg, 0, entry_out, 0); let bb1 = make_block( &mut hugr, @@ -772,10 +769,10 @@ fn make_looping_cfg( bb2_ext.clone(), )?; - hugr.connect(entry, 0, bb1, 0)?; - hugr.connect(bb1, 0, bb2, 0)?; - hugr.connect(bb1, 0, exit, 0)?; - hugr.connect(bb2, 0, entry, 0)?; + hugr.connect(entry, 0, bb1, 0); + hugr.connect(bb1, 0, bb2, 0); + hugr.connect(bb1, 0, exit, 0); + hugr.connect(bb2, 0, entry, 0); Ok(hugr) } @@ -825,10 +822,10 @@ fn simple_cfg_loop() -> Result<(), Box> { let entry_mid = hugr.add_node_with_parent( entry, make_opaque(UNKNOWN_EXTENSION, FunctionType::new(vec![NAT], oneway(NAT))), - )?; + ); - hugr.connect(entry_in, 0, entry_mid, 0)?; - hugr.connect(entry_mid, 0, entry_out, 0)?; + hugr.connect(entry_in, 0, entry_mid, 0); + hugr.connect(entry_mid, 0, entry_out, 0); let bb = make_block( &mut hugr, @@ -838,9 +835,9 @@ fn simple_cfg_loop() -> Result<(), Box> { just_a.clone(), )?; - hugr.connect(entry, 0, bb, 0)?; - hugr.connect(bb, 0, bb, 0)?; - hugr.connect(bb, 0, exit, 0)?; + hugr.connect(entry, 0, bb, 0); + hugr.connect(bb, 0, bb, 0); + hugr.connect(bb, 0, exit, 0); hugr.update_validate(&PRELUDE_REGISTRY)?; diff --git a/src/hugr.rs b/src/hugr.rs index 514c8dcbce..7251c4dc00 100644 --- a/src/hugr.rs +++ b/src/hugr.rs @@ -397,9 +397,9 @@ mod test { type_row: type_row![BIT], new_extension: "R".try_into().unwrap(), }, - )?; - hugr.connect(input, 0, lift, 0)?; - hugr.connect(lift, 0, output, 0)?; + ); + hugr.connect(input, 0, lift, 0); + hugr.connect(lift, 0, output, 0); hugr.infer_extensions()?; assert_eq!( diff --git a/src/hugr/hugrmut.rs b/src/hugr/hugrmut.rs index 44753a1c18..8e70c3d92b 100644 --- a/src/hugr/hugrmut.rs +++ b/src/hugr/hugrmut.rs @@ -282,12 +282,15 @@ impl + AsMut> HugrMut for T { let dst_port = dst_port.into(); panic_invalid_port(self, src, src_port); panic_invalid_port(self, dst, dst_port); - self.as_mut().graph.link_nodes( - src.pg_index(), - src_port.index(), - dst.pg_index(), - dst_port.index(), - ); + self.as_mut() + .graph + .link_nodes( + src.pg_index(), + src_port.index(), + dst.pg_index(), + dst_port.index(), + ) + .expect("The ports should exist at this point."); } fn disconnect(&mut self, node: Node, port: impl Into) { @@ -637,21 +640,24 @@ pub(crate) mod sealed { self.hugr_mut().hierarchy.detach(node.pg_index()); self.hugr_mut() .hierarchy - .push_child(node.pg_index(), parent.pg_index()); + .push_child(node.pg_index(), parent.pg_index()) + .expect("Inserting a newly-created node into the hierarchy should never fail."); } fn move_after_sibling(&mut self, node: Node, after: Node) { self.hugr_mut().hierarchy.detach(node.pg_index()); self.hugr_mut() .hierarchy - .insert_after(node.pg_index(), after.pg_index()); + .insert_after(node.pg_index(), after.pg_index()) + .expect("Inserting a newly-created node into the hierarchy should never fail."); } fn move_before_sibling(&mut self, node: Node, before: Node) { self.hugr_mut().hierarchy.detach(node.pg_index()); self.hugr_mut() .hierarchy - .insert_before(node.pg_index(), before.pg_index()); + .insert_before(node.pg_index(), before.pg_index()) + .expect("Inserting a newly-created node into the hierarchy should never fail."); } fn replace_op(&mut self, node: Node, op: NodeType) -> Result { @@ -677,7 +683,7 @@ mod test { const NAT: Type = USIZE_T; #[test] - fn simple_function() { + fn simple_function() -> Result<(), Box> { let mut hugr = Hugr::default(); // Create the root module definition @@ -703,6 +709,8 @@ mod test { hugr.connect(noop, 0, f_out, 1); } - hugr.update_validate(&PRELUDE_REGISTRY); + hugr.update_validate(&PRELUDE_REGISTRY)?; + + Ok(()) } } diff --git a/src/hugr/rewrite.rs b/src/hugr/rewrite.rs index 3b1ccaa09b..151fcaca01 100644 --- a/src/hugr/rewrite.rs +++ b/src/hugr/rewrite.rs @@ -75,18 +75,19 @@ impl Rewrite for Transactional { } // Try to backup just the contents of this HugrMut. let mut backup = Hugr::new(h.root_type().clone()); - backup.insert_from_view(backup.root(), h).unwrap(); + backup.insert_from_view(backup.root(), h); let r = self.underlying.apply(h); fn first_child(h: &impl HugrView) -> Option { h.children(h.root()).next() } if r.is_err() { // Try to restore backup. - h.replace_op(h.root(), backup.root_type().clone()).unwrap(); + h.replace_op(h.root(), backup.root_type().clone()) + .expect("The root replacement should always match the old root type"); while let Some(child) = first_child(h) { - h.remove_node(child).unwrap(); + h.remove_node(child); } - h.insert_from_view(h.root(), &backup).unwrap(); + h.insert_from_view(h.root(), &backup); } r } diff --git a/src/hugr/rewrite/consts.rs b/src/hugr/rewrite/consts.rs index e1a0fd4874..c2ec4f2d63 100644 --- a/src/hugr/rewrite/consts.rs +++ b/src/hugr/rewrite/consts.rs @@ -65,7 +65,7 @@ impl Rewrite for RemoveLoadConstant { .exactly_one() .ok() .expect("Validation should check a Const is connected to LoadConstant."); - h.remove_node(node)?; + h.remove_node(node); Ok(source) } @@ -109,7 +109,7 @@ impl Rewrite for RemoveConst { let parent = h .get_parent(node) .expect("Const node without a parent shouldn't happen."); - h.remove_node(node)?; + h.remove_node(node); Ok(parent) } @@ -189,7 +189,7 @@ mod test { ); // remove the use - h.remove_node(tup_node)?; + h.remove_node(tup_node); // remove first load let reported_con_node = h.apply_rewrite(remove_1)?; diff --git a/src/hugr/rewrite/inline_dfg.rs b/src/hugr/rewrite/inline_dfg.rs index 0d576e292a..0c54432638 100644 --- a/src/hugr/rewrite/inline_dfg.rs +++ b/src/hugr/rewrite/inline_dfg.rs @@ -53,14 +53,14 @@ impl Rewrite for InlineDFG { let parent = h.get_parent(n).unwrap(); let [input, output] = h.get_io(n).unwrap(); for ch in h.children(n).skip(2).collect::>().into_iter() { - h.set_parent(ch, parent).unwrap(); + h.set_parent(ch, parent); } // DFG Inputs. Deal with Order inputs first for (src_n, src_p) in h.linked_outputs(n, oth_in).collect::>() { // Order edge from src_n to DFG => add order edge to each successor of Input node debug_assert_eq!(Some(src_p), h.get_optype(src_n).other_output_port()); for tgt_n in h.output_neighbours(input).collect::>() { - h.add_other_edge(src_n, tgt_n).unwrap(); + h.add_other_edge(src_n, tgt_n); } } // And remaining (Value) inputs @@ -73,24 +73,24 @@ impl Rewrite for InlineDFG { }; // Hugr is invalid if there is no output linked to the DFG input. let (src_n, src_p) = h.single_linked_output(n, inp).unwrap(); - h.disconnect(n, inp).unwrap(); // These disconnects allow permutations to work trivially. + h.disconnect(n, inp); let outp = OutgoingPort::from(inp.index()); let targets = h.linked_inputs(input, outp).collect::>(); - h.disconnect(input, outp).unwrap(); + h.disconnect(input, outp); for (tgt_n, tgt_p) in targets { - h.connect(src_n, src_p, tgt_n, tgt_p).unwrap(); + h.connect(src_n, src_p, tgt_n, tgt_p); } // Ensure order-successors of Input node execute after any node producing an input for (tgt, _) in input_ord_succs.iter() { - h.add_other_edge(src_n, *tgt).unwrap(); + h.add_other_edge(src_n, *tgt); } } // DFG Outputs. Deal with Order outputs first. for (tgt_n, tgt_p) in h.linked_inputs(n, oth_out).collect::>() { debug_assert_eq!(Some(tgt_p), h.get_optype(tgt_n).other_input_port()); for src_n in h.input_neighbours(output).collect::>() { - h.add_other_edge(src_n, tgt_n).unwrap(); + h.add_other_edge(src_n, tgt_n); } } // And remaining (Value) outputs @@ -104,21 +104,21 @@ impl Rewrite for InlineDFG { let inpp = IncomingPort::from(outport.index()); // Hugr is invalid if the Output node has no corresponding input let (src_n, src_p) = h.single_linked_output(output, inpp).unwrap(); - h.disconnect(output, inpp).unwrap(); + h.disconnect(output, inpp); for (tgt_n, tgt_p) in h.linked_inputs(n, outport).collect::>() { - h.connect(src_n, src_p, tgt_n, tgt_p).unwrap(); + h.connect(src_n, src_p, tgt_n, tgt_p); // Ensure order-predecessors of Output node execute before any node consuming a DFG output for (src, _) in output_ord_preds.iter() { - h.add_other_edge(*src, tgt_n).unwrap(); + h.add_other_edge(*src, tgt_n); } } - h.disconnect(n, outport).unwrap(); + h.disconnect(n, outport); } - h.remove_node(input).unwrap(); - h.remove_node(output).unwrap(); + h.remove_node(input); + h.remove_node(output); assert!(h.children(n).next().is_none()); - h.remove_node(n).unwrap(); + h.remove_node(n); Ok([n, input, output]) } diff --git a/src/hugr/rewrite/insert_identity.rs b/src/hugr/rewrite/insert_identity.rs index e3fd293186..540ff05ccb 100644 --- a/src/hugr/rewrite/insert_identity.rs +++ b/src/hugr/rewrite/insert_identity.rs @@ -75,21 +75,17 @@ impl Rewrite for IdentityInsertion { .single_linked_output(self.post_node, self.post_port) .expect("Value kind input can only have one connection."); - h.disconnect(self.post_node, self.post_port).unwrap(); + h.disconnect(self.post_node, self.post_port); let parent = h .get_parent(self.post_node) .ok_or(IdentityInsertionError::InvalidParentNode)?; if !OpTag::DataflowParent.is_superset(h.get_optype(parent).tag()) { return Err(IdentityInsertionError::InvalidParentNode); } - let new_node = h - .add_node_with_parent(parent, LeafOp::Noop { ty }) - .expect("Parent validity already checked."); - h.connect(pre_node, pre_port, new_node, 0) - .expect("Should only fail if ports don't exist."); - - h.connect(new_node, 0, self.post_node, self.post_port) - .expect("Should only fail if ports don't exist."); + let new_node = h.add_node_with_parent(parent, LeafOp::Noop { ty }); + h.connect(pre_node, pre_port, new_node, 0); + + h.connect(new_node, 0, self.post_node, self.post_port); Ok(new_node) } diff --git a/src/hugr/rewrite/outline_cfg.rs b/src/hugr/rewrite/outline_cfg.rs index 42156433a4..c773d5da70 100644 --- a/src/hugr/rewrite/outline_cfg.rs +++ b/src/hugr/rewrite/outline_cfg.rs @@ -150,9 +150,7 @@ impl Rewrite for OutlineCfg { new_block_bldr .set_outputs(pred_wire, cfg.outputs()) .unwrap(); - let ins_res = h - .insert_hugr(outer_cfg, new_block_bldr.hugr().clone()) - .unwrap(); + let ins_res = h.insert_hugr(outer_cfg, new_block_bldr.hugr().clone()); ( ins_res.new_root, *ins_res.node_map.get(&cfg.node()).unwrap(), @@ -165,14 +163,14 @@ impl Rewrite for OutlineCfg { .collect(); for (pred, br) in preds { if !self.blocks.contains(&pred) { - h.disconnect(pred, br).unwrap(); - h.connect(pred, br, new_block, 0).unwrap(); + h.disconnect(pred, br); + h.connect(pred, br, new_block, 0); } } if entry == outer_entry { // new_block must be the entry node, i.e. first child, of the enclosing CFG // (the current entry node will be reparented inside new_block below) - h.move_before_sibling(new_block, outer_entry).unwrap(); + h.move_before_sibling(new_block, outer_entry); } // 4(a). Exit edges. @@ -187,9 +185,9 @@ impl Rewrite for OutlineCfg { .exactly_one() .ok() // NodePorts does not implement Debug .unwrap(); - h.disconnect(exit, exit_port).unwrap(); + h.disconnect(exit, exit_port); // And connect new_block to outside instead - h.connect(new_block, 0, outside, 0).unwrap(); + h.connect(new_block, 0, outside, 0); // 5. Children of new CFG. let inner_exit = { @@ -198,12 +196,12 @@ impl Rewrite for OutlineCfg { let h = h.hugr_mut(); let inner_exit = h.children(cfg_node).exactly_one().ok().unwrap(); // Entry node must be first - h.move_before_sibling(entry, inner_exit).unwrap(); + h.move_before_sibling(entry, inner_exit); // And remaining nodes for n in self.blocks { // Do not move the entry node, as we have already if n != entry { - h.set_parent(n, cfg_node).unwrap(); + h.set_parent(n, cfg_node); } } inner_exit @@ -215,7 +213,7 @@ impl Rewrite for OutlineCfg { SiblingMut::try_new(h, new_block).unwrap(); let mut in_cfg_view: SiblingMut<'_, CfgID> = SiblingMut::try_new(&mut in_bb_view, cfg_node).unwrap(); - in_cfg_view.connect(exit, exit_port, inner_exit, 0).unwrap(); + in_cfg_view.connect(exit, exit_port, inner_exit, 0); Ok((new_block, cfg_node)) } diff --git a/src/hugr/rewrite/replace.rs b/src/hugr/rewrite/replace.rs index 8639653767..45824e0db4 100644 --- a/src/hugr/rewrite/replace.rs +++ b/src/hugr/rewrite/replace.rs @@ -274,8 +274,7 @@ impl Rewrite for Replacement { // 1. Add all the new nodes. Note this includes replacement.root(), which we don't want. // TODO what would an error here mean? e.g. malformed self.replacement?? - let InsertionResult { new_root, node_map } = - h.insert_hugr(parent, self.replacement).unwrap(); + let InsertionResult { new_root, node_map } = h.insert_hugr(parent, self.replacement); // 2. Add new edges from existing to copied nodes according to mu_in let translate_idx = |n| node_map.get(&n).copied().ok_or(WhichHugr::Replacement); @@ -298,13 +297,13 @@ impl Rewrite for Replacement { let mut remove_top_sibs = self.removal.iter(); for new_node in h.children(new_root).collect::>().into_iter() { if let Some(top_sib) = remove_top_sibs.next() { - h.move_before_sibling(new_node, *top_sib).unwrap(); + h.move_before_sibling(new_node, *top_sib); } else { - h.set_parent(new_node, parent).unwrap(); + h.set_parent(new_node, parent); } } debug_assert!(h.children(new_root).next().is_none()); - h.remove_node(new_root).unwrap(); + h.remove_node(new_root); // 6. Transfer to keys of `transfers` children of the corresponding values. for (new_parent, &old_parent) in self.adoptions.iter() { @@ -315,14 +314,12 @@ impl Rewrite for Replacement { None => break, Some(c) => c, }; - h.set_parent(ch, *new_parent).unwrap(); + h.set_parent(ch, *new_parent); } } // 7. Remove remaining nodes - to_remove - .into_iter() - .for_each(|n| h.remove_node(n).unwrap()); + to_remove.into_iter().for_each(|n| h.remove_node(n)); Ok(()) } @@ -357,16 +354,16 @@ fn transfer_edges<'a>( e.check_tgt(h, oe)?; match e.kind { NewEdgeKind::Order => { - h.add_other_edge(e.src, e.tgt).unwrap(); + h.add_other_edge(e.src, e.tgt); } NewEdgeKind::Value { src_pos, tgt_pos } | NewEdgeKind::Static { src_pos, tgt_pos } => { if let Some(legal_src_ancestors) = legal_src_ancestors { e.check_existing_edge(h, legal_src_ancestors, || oe.clone())?; - h.disconnect(e.tgt, tgt_pos).unwrap(); + h.disconnect(e.tgt, tgt_pos); } - h.connect(e.src, src_pos, e.tgt, tgt_pos).unwrap(); + h.connect(e.src, src_pos, e.tgt, tgt_pos); } - NewEdgeKind::ControlFlow { src_pos } => h.connect(e.src, src_pos, e.tgt, 0).unwrap(), + NewEdgeKind::ControlFlow { src_pos } => h.connect(e.src, src_pos, e.tgt, 0), } } Ok(()) @@ -525,7 +522,7 @@ mod test { // at least when https://github.com/CQCL/issues/388 is fixed extension_delta: ExtensionSet::new(), }, - )?; + ); let r_df1 = replacement.add_node_with_parent( r_bb, DFG { @@ -534,16 +531,16 @@ mod test { simple_unary_plus(intermed.clone()), ), }, - )?; + ); let r_df2 = replacement.add_node_with_parent( r_bb, DFG { signature: FunctionType::new(intermed, simple_unary_plus(just_list.clone())), }, - )?; + ); [0, 1] .iter() - .try_for_each(|p| replacement.connect(r_df1, *p + 1, r_df2, *p))?; + .for_each(|p| replacement.connect(r_df1, *p + 1, r_df2, *p)); { let inp = replacement.add_node_before( @@ -551,16 +548,16 @@ mod test { ops::Input { types: just_list.clone(), }, - )?; + ); let out = replacement.add_node_before( r_df1, ops::Output { types: simple_unary_plus(just_list), }, - )?; - replacement.connect(inp, 0, r_df1, 0)?; - replacement.connect(r_df2, 0, out, 0)?; - replacement.connect(r_df2, 1, out, 1)?; + ); + replacement.connect(inp, 0, r_df1, 0); + replacement.connect(r_df2, 0, out, 0); + replacement.connect(r_df2, 1, out, 1); } h.apply_rewrite(Replacement { @@ -685,13 +682,13 @@ mod test { Case { signature: utou.clone(), }, - )?; + ); let r2 = rep1.add_node_with_parent( rep1.root(), Case { signature: utou.clone(), }, - )?; + ); let mut r = Replacement { removal: vec![case1, case2], replacement: rep1, diff --git a/src/hugr/rewrite/simple_replace.rs b/src/hugr/rewrite/simple_replace.rs index 694faa835d..f7d836d585 100644 --- a/src/hugr/rewrite/simple_replace.rs +++ b/src/hugr/rewrite/simple_replace.rs @@ -101,12 +101,12 @@ impl Rewrite for SimpleReplacement { for &node in replacement_inner_nodes { // Add the nodes. let op: &OpType = self.replacement.get_optype(node); - let new_node = h.add_node_after(self_output_node, op.clone()).unwrap(); + let new_node = h.add_node_after(self_output_node, op.clone()); index_map.insert(node, new_node); // Move the metadata let meta: Option = self.replacement.take_node_metadata(node); - h.overwrite_node_metadata(new_node, meta).unwrap(); + h.overwrite_node_metadata(new_node, meta); } // Add edges between all newly added nodes matching those in replacement. // TODO This will probably change when implicit copies are implemented. @@ -116,8 +116,7 @@ impl Rewrite for SimpleReplacement { for target in self.replacement.linked_inputs(node, outport) { if self.replacement.get_optype(target.0).tag() != OpTag::Output { let new_target = index_map.get(&target.0).unwrap(); - h.connect(*new_node, outport, *new_target, target.1) - .unwrap(); + h.connect(*new_node, outport, *new_target, target.1); } } } @@ -130,15 +129,14 @@ impl Rewrite for SimpleReplacement { let (rem_inp_pred_node, rem_inp_pred_port) = h .single_linked_output(*rem_inp_node, *rem_inp_port) .unwrap(); - h.disconnect(*rem_inp_node, *rem_inp_port).unwrap(); + h.disconnect(*rem_inp_node, *rem_inp_port); let new_inp_node = index_map.get(rep_inp_node).unwrap(); h.connect( rem_inp_pred_node, rem_inp_pred_port, *new_inp_node, *rep_inp_port, - ) - .unwrap(); + ); } } // 3.3. For each q = self.nu_out[p] such that the predecessor of q is not an Input port, add an @@ -150,14 +148,13 @@ impl Rewrite for SimpleReplacement { .unwrap(); if self.replacement.get_optype(rep_out_pred_node).tag() != OpTag::Input { let new_out_node = index_map.get(&rep_out_pred_node).unwrap(); - h.disconnect(*rem_out_node, *rem_out_port).unwrap(); + h.disconnect(*rem_out_node, *rem_out_port); h.connect( *new_out_node, rep_out_pred_port, *rem_out_node, *rem_out_port, - ) - .unwrap(); + ); } } // 3.4. For each q = self.nu_out[p1], p0 = self.nu_inp[q], add an edge from the predecessor of p0 @@ -169,20 +166,19 @@ impl Rewrite for SimpleReplacement { let (rem_inp_pred_node, rem_inp_pred_port) = h .single_linked_output(*rem_inp_node, *rem_inp_port) .unwrap(); - h.disconnect(*rem_inp_node, *rem_inp_port).unwrap(); - h.disconnect(*rem_out_node, *rem_out_port).unwrap(); + h.disconnect(*rem_inp_node, *rem_inp_port); + h.disconnect(*rem_out_node, *rem_out_port); h.connect( rem_inp_pred_node, rem_inp_pred_port, *rem_out_node, *rem_out_port, - ) - .unwrap(); + ); } } // 3.5. Remove all nodes in self.removal and edges between them. for &node in self.subgraph.nodes() { - h.remove_node(node).unwrap(); + h.remove_node(node); } Ok(()) } @@ -635,8 +631,8 @@ pub(in crate::hugr::rewrite) mod test { } }) .collect(); - replacement.remove_node(in_).unwrap(); - replacement.remove_node(out).unwrap(); + replacement.remove_node(in_); + replacement.remove_node(out); Replacement { removal: s.subgraph.nodes().to_vec(), replacement, diff --git a/src/hugr/serialize.rs b/src/hugr/serialize.rs index 3488ecf1b3..9209f64aa9 100644 --- a/src/hugr/serialize.rs +++ b/src/hugr/serialize.rs @@ -209,7 +209,7 @@ impl TryFrom for Hugr { hugr.add_node_with_parent( node_ser.parent, NodeType::new(node_ser.op, node_ser.input_extensions), - )?; + ); } for (node, metadata) in metadata.into_iter().enumerate() { @@ -240,7 +240,7 @@ impl TryFrom for Hugr { let src_port = unwrap_offset(src, from_offset, Direction::Outgoing, &hugr)?; let dst_port = unwrap_offset(dst, to_offset, Direction::Incoming, &hugr)?; - hugr.connect(src, src_port, dst, dst_port)?; + hugr.connect(src, src_port, dst, dst_port); } Ok(hugr) @@ -501,22 +501,23 @@ pub mod test { } #[test] - fn hierarchy_order() { + fn hierarchy_order() -> Result<(), Box> { let mut hugr = closed_dfg_root_hugr(FunctionType::new(vec![QB], vec![QB])); let [old_in, out] = hugr.get_io(hugr.root()).unwrap(); - hugr.connect(old_in, 0, out, 0).unwrap(); + hugr.connect(old_in, 0, out, 0); // Now add a new input let new_in = hugr.add_node(Input::new([QB].to_vec()).into()); - hugr.disconnect(old_in, OutgoingPort::from(0)).unwrap(); - hugr.connect(new_in, 0, out, 0).unwrap(); - hugr.move_before_sibling(new_in, old_in).unwrap(); - hugr.remove_node(old_in).unwrap(); - hugr.update_validate(&PRELUDE_REGISTRY).unwrap(); + hugr.disconnect(old_in, OutgoingPort::from(0)); + hugr.connect(new_in, 0, out, 0); + hugr.move_before_sibling(new_in, old_in); + hugr.remove_node(old_in); + hugr.update_validate(&PRELUDE_REGISTRY)?; let new_hugr: Hugr = check_hugr_roundtrip(&hugr); new_hugr.validate(&EMPTY_REG).unwrap_err(); - new_hugr.validate(&PRELUDE_REGISTRY).unwrap(); + new_hugr.validate(&PRELUDE_REGISTRY)?; + Ok(()) } #[test] diff --git a/src/hugr/validate/test.rs b/src/hugr/validate/test.rs index 5f82108070..ceabd4bd99 100644 --- a/src/hugr/validate/test.rs +++ b/src/hugr/validate/test.rs @@ -33,7 +33,7 @@ fn make_simple_hugr(copies: usize) -> (Hugr, Node) { let mut b = Hugr::default(); let root = b.root(); - let def = b.add_node_with_parent(root, def_op).unwrap(); + let def = b.add_node_with_parent(root, def_op); let _ = add_df_children(&mut b, def, copies); (b, def) @@ -43,19 +43,13 @@ fn make_simple_hugr(copies: usize) -> (Hugr, Node) { /// /// Returns the node indices of each of the operations. fn add_df_children(b: &mut Hugr, parent: Node, copies: usize) -> (Node, Node, Node) { - let input = b - .add_node_with_parent(parent, ops::Input::new(type_row![BOOL_T])) - .unwrap(); - let output = b - .add_node_with_parent(parent, ops::Output::new(vec![BOOL_T; copies])) - .unwrap(); - let copy = b - .add_node_with_parent(parent, LeafOp::Noop { ty: BOOL_T }) - .unwrap(); + let input = b.add_node_with_parent(parent, ops::Input::new(type_row![BOOL_T])); + let output = b.add_node_with_parent(parent, ops::Output::new(vec![BOOL_T; copies])); + let copy = b.add_node_with_parent(parent, LeafOp::Noop { ty: BOOL_T }); - b.connect(input, 0, copy, 0).unwrap(); + b.connect(input, 0, copy, 0); for i in 0..copies { - b.connect(copy, 0, output, i).unwrap(); + b.connect(copy, 0, output, i); } (input, copy, output) @@ -79,7 +73,7 @@ fn invalid_root() { b.validate(&EMPTY_REG), Err(ValidationError::NoParent { node }) => assert_eq!(node, other) ); - b.set_parent(other, root).unwrap(); + b.set_parent(other, root); b.replace_op(other, NodeType::new_pure(declare_op)).unwrap(); b.add_ports(other, Direction::Outgoing, 1); assert_eq!(b.validate(&EMPTY_REG), Ok(())); @@ -136,15 +130,13 @@ fn children_restrictions() { // Add a definition without children let def_sig = FunctionType::new(type_row![BOOL_T], type_row![BOOL_T, BOOL_T]); - let new_def = b - .add_node_with_parent( - root, - ops::FuncDefn { - signature: def_sig.into(), - name: "main".into(), - }, - ) - .unwrap(); + let new_def = b.add_node_with_parent( + root, + ops::FuncDefn { + signature: def_sig.into(), + name: "main".into(), + }, + ); assert_matches!( b.update_validate(&EMPTY_REG), Err(ValidationError::ContainerWithoutChildren { node, .. }) => assert_eq!(node, new_def) @@ -152,19 +144,17 @@ fn children_restrictions() { // Add children to the definition, but move it to be a child of the copy add_df_children(&mut b, new_def, 2); - b.set_parent(new_def, copy).unwrap(); + b.set_parent(new_def, copy); assert_matches!( b.update_validate(&EMPTY_REG), Err(ValidationError::NonContainerWithChildren { node, .. }) => assert_eq!(node, copy) ); let closure = b.infer_extensions().unwrap(); - b.set_parent(new_def, root).unwrap(); + b.set_parent(new_def, root); // After moving the previous definition to a valid place, // add an input node to the module subgraph - let new_input = b - .add_node_with_parent(root, ops::Input::new(type_row![])) - .unwrap(); + let new_input = b.add_node_with_parent(root, ops::Input::new(type_row![])); assert_matches!( b.validate_with_extension_closure(closure, &EMPTY_REG), Err(ValidationError::InvalidParentOp { parent, child, .. }) => {assert_eq!(parent, root); assert_eq!(child, new_input)} @@ -234,26 +224,26 @@ fn test_ext_edge() -> Result<(), HugrError> { ops::DFG { signature: FunctionType::new_endo(type_row![BOOL_T]), }, - )?; + ); // this Xor has its 2nd input unconnected let sub_op = { - let sub_input = h.add_node_with_parent(sub_dfg, ops::Input::new(type_row![BOOL_T]))?; - let sub_output = h.add_node_with_parent(sub_dfg, ops::Output::new(type_row![BOOL_T]))?; - let sub_op = h.add_node_with_parent(sub_dfg, and_op())?; - h.connect(sub_input, 0, sub_op, 0)?; - h.connect(sub_op, 0, sub_output, 0)?; + let sub_input = h.add_node_with_parent(sub_dfg, ops::Input::new(type_row![BOOL_T])); + let sub_output = h.add_node_with_parent(sub_dfg, ops::Output::new(type_row![BOOL_T])); + let sub_op = h.add_node_with_parent(sub_dfg, and_op()); + h.connect(sub_input, 0, sub_op, 0); + h.connect(sub_op, 0, sub_output, 0); sub_op }; - h.connect(input, 0, sub_dfg, 0)?; - h.connect(sub_dfg, 0, output, 0)?; + h.connect(input, 0, sub_dfg, 0); + h.connect(sub_dfg, 0, output, 0); assert_matches!( h.update_validate(&EMPTY_REG), Err(ValidationError::UnconnectedPort { .. }) ); - h.connect(input, 1, sub_op, 1)?; + h.connect(input, 1, sub_op, 1); assert_matches!( h.update_validate(&EMPTY_REG), Err(ValidationError::InterGraphEdgeError( @@ -261,7 +251,7 @@ fn test_ext_edge() -> Result<(), HugrError> { )) ); //Order edge. This will need metadata indicating its purpose. - h.add_other_edge(input, sub_dfg)?; + h.add_other_edge(input, sub_dfg); h.update_validate(&EMPTY_REG).unwrap(); Ok(()) } @@ -270,9 +260,9 @@ fn test_ext_edge() -> Result<(), HugrError> { fn test_local_const() -> Result<(), HugrError> { let mut h = closed_dfg_root_hugr(FunctionType::new(type_row![BOOL_T], type_row![BOOL_T])); let [input, output] = h.get_io(h.root()).unwrap(); - let and = h.add_node_with_parent(h.root(), and_op())?; - h.connect(input, 0, and, 0)?; - h.connect(and, 0, output, 0)?; + let and = h.add_node_with_parent(h.root(), and_op()); + h.connect(input, 0, and, 0); + h.connect(and, 0, output, 0); assert_eq!( h.update_validate(&EMPTY_REG), Err(ValidationError::UnconnectedPort { @@ -287,11 +277,11 @@ fn test_local_const() -> Result<(), HugrError> { .typed_value() .clone(); // Second input of Xor from a constant - let cst = h.add_node_with_parent(h.root(), const_op)?; - let lcst = h.add_node_with_parent(h.root(), ops::LoadConstant { datatype: BOOL_T })?; + let cst = h.add_node_with_parent(h.root(), const_op); + let lcst = h.add_node_with_parent(h.root(), ops::LoadConstant { datatype: BOOL_T }); - h.connect(cst, 0, lcst, 0)?; - h.connect(lcst, 0, and, 1)?; + h.connect(cst, 0, lcst, 0); + h.connect(lcst, 0, and, 1); assert_eq!(h.static_source(lcst), Some(cst)); // There is no edge from Input to LoadConstant, but that's OK: h.update_validate(&EMPTY_REG).unwrap(); @@ -305,14 +295,14 @@ fn dfg_with_cycles() -> Result<(), HugrError> { type_row![BOOL_T], )); let [input, output] = h.get_io(h.root()).unwrap(); - let or = h.add_node_with_parent(h.root(), or_op())?; - let not1 = h.add_node_with_parent(h.root(), NotOp)?; - let not2 = h.add_node_with_parent(h.root(), NotOp)?; - h.connect(input, 0, or, 0)?; - h.connect(or, 0, not1, 0)?; - h.connect(not1, 0, or, 1)?; - h.connect(input, 1, not2, 0)?; - h.connect(not2, 0, output, 0)?; + let or = h.add_node_with_parent(h.root(), or_op()); + let not1 = h.add_node_with_parent(h.root(), NotOp); + let not2 = h.add_node_with_parent(h.root(), NotOp); + h.connect(input, 0, or, 0); + h.connect(or, 0, not1, 0); + h.connect(not1, 0, or, 1); + h.connect(input, 1, not2, 0); + h.connect(not2, 0, output, 0); // The graph contains a cycle: assert_matches!(h.validate(&EMPTY_REG), Err(ValidationError::NotADag { .. })); Ok(()) @@ -322,21 +312,17 @@ fn identity_hugr_with_type(t: Type) -> (Hugr, Node) { let mut b = Hugr::default(); let row: TypeRow = vec![t].into(); - let def = b - .add_node_with_parent( - b.root(), - ops::FuncDefn { - name: "main".into(), - signature: FunctionType::new(row.clone(), row.clone()).into(), - }, - ) - .unwrap(); + let def = b.add_node_with_parent( + b.root(), + ops::FuncDefn { + name: "main".into(), + signature: FunctionType::new(row.clone(), row.clone()).into(), + }, + ); - let input = b - .add_node_with_parent(def, ops::Input::new(row.clone())) - .unwrap(); - let output = b.add_node_with_parent(def, ops::Output::new(row)).unwrap(); - b.connect(input, 0, output, 0).unwrap(); + let input = b.add_node_with_parent(def, ops::Input::new(row.clone())); + let output = b.add_node_with_parent(def, ops::Output::new(row)); + b.connect(input, 0, output, 0); (b, def) } #[test] @@ -586,21 +572,16 @@ mod extension_tests { let const_op = ops::Const::unit_sum(0, tuple_sum_size as u8); let tag_type = Type::new_unit_sum(tuple_sum_size as u8); - let input = b - .add_node_with_parent(parent, ops::Input::new(type_row![BOOL_T])) - .unwrap(); - let output = b - .add_node_with_parent(parent, ops::Output::new(vec![tag_type.clone(), BOOL_T])) - .unwrap(); - let tag_def = b.add_node_with_parent(b.root(), const_op).unwrap(); - let tag = b - .add_node_with_parent(parent, ops::LoadConstant { datatype: tag_type }) - .unwrap(); + let input = b.add_node_with_parent(parent, ops::Input::new(type_row![BOOL_T])); + let output = + b.add_node_with_parent(parent, ops::Output::new(vec![tag_type.clone(), BOOL_T])); + let tag_def = b.add_node_with_parent(b.root(), const_op); + let tag = b.add_node_with_parent(parent, ops::LoadConstant { datatype: tag_type }); - b.connect(tag_def, 0, tag, 0).unwrap(); - b.add_other_edge(input, tag).unwrap(); - b.connect(tag, 0, output, 0).unwrap(); - b.connect(input, 0, output, 1).unwrap(); + b.connect(tag_def, 0, tag, 0); + b.add_other_edge(input, tag); + b.connect(tag, 0, output, 0); + b.connect(input, 0, output, 1); (input, tag_def, tag, output) } @@ -634,46 +615,40 @@ mod extension_tests { let cfg = copy; // Construct a valid CFG, with one BasicBlock node and one exit node - let block = b - .add_node_with_parent( - cfg, - ops::DataflowBlock { - inputs: type_row![BOOL_T], - tuple_sum_rows: vec![type_row![]], - other_outputs: type_row![BOOL_T], - extension_delta: ExtensionSet::new(), - }, - ) - .unwrap(); + let block = b.add_node_with_parent( + cfg, + ops::DataflowBlock { + inputs: type_row![BOOL_T], + tuple_sum_rows: vec![type_row![]], + other_outputs: type_row![BOOL_T], + extension_delta: ExtensionSet::new(), + }, + ); add_block_children(&mut b, block, 1); - let exit = b - .add_node_with_parent( - cfg, - ops::ExitBlock { - cfg_outputs: type_row![BOOL_T], - }, - ) - .unwrap(); - b.add_other_edge(block, exit).unwrap(); + let exit = b.add_node_with_parent( + cfg, + ops::ExitBlock { + cfg_outputs: type_row![BOOL_T], + }, + ); + b.add_other_edge(block, exit); assert_eq!(b.update_validate(&EMPTY_REG), Ok(())); // Test malformed errors // Add an internal exit node - let exit2 = b - .add_node_after( - exit, - ops::ExitBlock { - cfg_outputs: type_row![BOOL_T], - }, - ) - .unwrap(); + let exit2 = b.add_node_after( + exit, + ops::ExitBlock { + cfg_outputs: type_row![BOOL_T], + }, + ); assert_matches!( b.validate(&EMPTY_REG), Err(ValidationError::InvalidChildren { parent, source: ChildrenValidationError::InternalExitChildren { child, .. }, .. }) => {assert_eq!(parent, cfg); assert_eq!(child, exit2.pg_index())} ); - b.remove_node(exit2).unwrap(); + b.remove_node(exit2); // Change the types in the BasicBlock node to work on qubits instead of bits b.replace_op( @@ -714,38 +689,32 @@ mod extension_tests { signature: FunctionType::new(type_row![USIZE_T], type_row![USIZE_T]), })); - let input = hugr - .add_node_with_parent( - hugr.root(), - NodeType::new_pure(ops::Input { + let input = hugr.add_node_with_parent( + hugr.root(), + NodeType::new_pure(ops::Input { + types: type_row![USIZE_T], + }), + ); + let output = hugr.add_node_with_parent( + hugr.root(), + NodeType::new( + ops::Output { types: type_row![USIZE_T], - }), - ) - .unwrap(); - let output = hugr - .add_node_with_parent( - hugr.root(), - NodeType::new( - ops::Output { - types: type_row![USIZE_T], - }, - Some(XB.into()), - ), - ) - .unwrap(); + }, + Some(XB.into()), + ), + ); - let lift = hugr - .add_node_with_parent( - hugr.root(), - NodeType::new_pure(ops::LeafOp::Lift { - type_row: type_row![USIZE_T], - new_extension: XB, - }), - ) - .unwrap(); + let lift = hugr.add_node_with_parent( + hugr.root(), + NodeType::new_pure(ops::LeafOp::Lift { + type_row: type_row![USIZE_T], + new_extension: XB, + }), + ); - hugr.connect(input, 0, lift, 0).unwrap(); - hugr.connect(lift, 0, output, 0).unwrap(); + hugr.connect(input, 0, lift, 0); + hugr.connect(lift, 0, output, 0); let result = hugr.validate(&PRELUDE_REGISTRY); assert_matches!( @@ -873,7 +842,7 @@ mod extension_tests { } #[test] - fn parent_signature_mismatch() -> Result<(), BuildError> { + fn parent_signature_mismatch() { let main_signature = FunctionType::new(type_row![NAT], type_row![NAT]).with_extension_delta(XA); @@ -885,7 +854,7 @@ mod extension_tests { NodeType::new_pure(ops::Input { types: type_row![NAT], }), - )?; + ); let output = hugr.add_node_with_parent( hugr.root(), NodeType::new( @@ -894,8 +863,8 @@ mod extension_tests { }, Some(XA.into()), ), - )?; - hugr.connect(input, 0, output, 0)?; + ); + hugr.connect(input, 0, output, 0); assert_matches!( hugr.validate(&PRELUDE_REGISTRY), @@ -903,6 +872,5 @@ mod extension_tests { ExtensionError::TgtExceedsSrcExtensionsAtPort { .. } )) ); - Ok(()) } } diff --git a/src/hugr/views/root_checked.rs b/src/hugr/views/root_checked.rs index 242ac8ee71..9e5c41dd25 100644 --- a/src/hugr/views/root_checked.rs +++ b/src/hugr/views/root_checked.rs @@ -130,6 +130,6 @@ mod test { // And it's a HugrMut: let nodetype = NodeType::new_pure(LeafOp::MakeTuple { tys: type_row![] }); - bb_v.add_node_with_parent(bb_v.root(), nodetype).unwrap(); + bb_v.add_node_with_parent(bb_v.root(), nodetype); } } diff --git a/src/hugr/views/sibling_subgraph.rs b/src/hugr/views/sibling_subgraph.rs index 23cbfa812d..9741b08c78 100644 --- a/src/hugr/views/sibling_subgraph.rs +++ b/src/hugr/views/sibling_subgraph.rs @@ -18,7 +18,7 @@ use portgraph::{view::Subgraph, Direction, PortView}; use thiserror::Error; use crate::builder::{Container, FunctionBuilder}; -use crate::hugr::{HugrError, HugrMut, HugrView, RootTagged}; +use crate::hugr::{HugrMut, HugrView, RootTagged}; use crate::ops::dataflow::DataflowOpTrait; use crate::ops::handle::{ContainerHandle, DataflowOpID}; use crate::ops::{OpTag, OpTrait}; @@ -405,31 +405,27 @@ impl SiblingSubgraph { /// /// The new Hugr will contain a [FuncDefn][crate::ops::FuncDefn] root /// with the same signature as the subgraph and the specified `name` - pub fn extract_subgraph( - &self, - hugr: &impl HugrView, - name: impl Into, - ) -> Result { + pub fn extract_subgraph(&self, hugr: &impl HugrView, name: impl Into) -> Hugr { let mut builder = FunctionBuilder::new(name, self.signature(hugr).into()).unwrap(); // Take the unfinished Hugr from the builder, to avoid unnecessary // validation checks that require connecting the inputs and outputs. let mut extracted = mem::take(builder.hugr_mut()); - let node_map = extracted.insert_subgraph(extracted.root(), hugr, self)?; + let node_map = extracted.insert_subgraph(extracted.root(), hugr, self); // Connect the inserted nodes in-between the input and output nodes. let [inp, out] = extracted.get_io(extracted.root()).unwrap(); for (inp_port, repl_ports) in extracted.node_outputs(inp).zip(self.inputs.iter()) { for (repl_node, repl_port) in repl_ports { - extracted.connect(inp, inp_port, node_map[repl_node], *repl_port)?; + extracted.connect(inp, inp_port, node_map[repl_node], *repl_port); } } for (out_port, (repl_node, repl_port)) in extracted.node_inputs(out).zip(self.outputs.iter()) { - extracted.connect(node_map[repl_node], *repl_port, out, out_port)?; + extracted.connect(node_map[repl_node], *repl_port, out, out_port); } - Ok(extracted) + extracted } } @@ -968,13 +964,12 @@ mod tests { #[test] fn extract_subgraph() -> Result<(), Box> { - let (hugr, func_root) = build_hugr().unwrap(); - let func_graph: SiblingGraph<'_, FuncID> = - SiblingGraph::try_new(&hugr, func_root).unwrap(); - let subgraph = SiblingSubgraph::try_new_dataflow_subgraph(&func_graph).unwrap(); - let extracted = subgraph.extract_subgraph(&hugr, "region")?; + let (hugr, func_root) = build_hugr()?; + let func_graph: SiblingGraph<'_, FuncID> = SiblingGraph::try_new(&hugr, func_root)?; + let subgraph = SiblingSubgraph::try_new_dataflow_subgraph(&func_graph)?; + let extracted = subgraph.extract_subgraph(&hugr, "region"); - extracted.validate(&PRELUDE_REGISTRY).unwrap(); + extracted.validate(&PRELUDE_REGISTRY)?; Ok(()) }