diff --git a/src/algorithm/nest_cfgs.rs b/src/algorithm/nest_cfgs.rs index 80b4ee8c6..f5035aa55 100644 --- a/src/algorithm/nest_cfgs.rs +++ b/src/algorithm/nest_cfgs.rs @@ -397,8 +397,11 @@ impl EdgeClassifier { #[cfg(test)] pub(crate) mod test { use super::*; - use crate::builder::{BuildError, CFGBuilder, Container, DataflowSubContainer, HugrBuilder}; + use crate::builder::{ + BuildError, Buildable, CFGBuilder, Container, DataflowSubContainer, HugrBuilder, + }; use crate::hugr::region::{FlatRegionView, Region}; + use crate::hugr::HugrMut; use crate::ops::{ handle::{BasicBlockID, ConstID, NodeHandle}, ConstValue, @@ -577,7 +580,7 @@ pub(crate) mod test { dataflow_builder.finish_with_outputs([u].into_iter().chain(w)) } - fn build_if_then_else_merge + AsRef>( + fn build_if_then_else_merge( cfg: &mut CFGBuilder, const_pred: &ConstID, unit_const: &ConstID, @@ -590,7 +593,7 @@ pub(crate) mod test { Ok((split, merge)) } - fn build_then_else_merge_from_if + AsRef>( + fn build_then_else_merge_from_if( cfg: &mut CFGBuilder, unit_const: &ConstID, split: BasicBlockID, @@ -615,7 +618,7 @@ pub(crate) mod test { } // Returns loop tail - caller must link header to tail, and provide 0th successor of tail - fn build_loop_from_header + AsRef>( + fn build_loop_from_header( cfg: &mut CFGBuilder, const_pred: &ConstID, header: BasicBlockID, @@ -629,7 +632,7 @@ pub(crate) mod test { } // Result is header and tail. Caller must provide 0th successor of header (linking to tail), and 0th successor of tail. - fn build_loop + AsRef>( + fn build_loop( cfg: &mut CFGBuilder, const_pred: &ConstID, unit_const: &ConstID, diff --git a/src/builder.rs b/src/builder.rs index 910c3dd30..51fffd03c 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -11,7 +11,7 @@ pub use handle::BuildHandle; mod build_traits; pub use build_traits::{ - Container, Dataflow, DataflowHugr, DataflowSubContainer, HugrBuilder, SubContainer, + Buildable, Container, Dataflow, DataflowHugr, DataflowSubContainer, HugrBuilder, SubContainer, }; mod dataflow; diff --git a/src/builder/build_traits.rs b/src/builder/build_traits.rs index a76c6214c..aa2098e1e 100644 --- a/src/builder/build_traits.rs +++ b/src/builder/build_traits.rs @@ -1,3 +1,4 @@ +#![allow(missing_docs)] use crate::hugr::validate::InterGraphEdgeError; use crate::hugr::view::HugrView; use crate::hugr::{Node, NodeMetadata, Port, ValidationError}; @@ -29,17 +30,40 @@ use crate::Hugr; use crate::hugr::HugrMut; +pub trait Buildable { + type BaseMut<'a>: Buildable + HugrMut + where + Self: 'a; + type BaseView<'a>: HugrView + where + Self: 'a; + /// The underlying [`Hugr`] being built + fn hugr_mut(&mut self) -> Self::BaseMut<'_>; + /// Immutable reference to HUGR being built + fn hugr(&self) -> Self::BaseView<'_>; +} + +impl + AsRef> Buildable for T { + type BaseMut<'a> = &'a mut Hugr where Self: 'a; + + type BaseView<'a> = &'a Hugr where Self: 'a; + + fn hugr_mut(&mut self) -> Self::BaseMut<'_> { + self.as_mut() + } + + fn hugr(&self) -> Self::BaseView<'_> { + self.as_ref() + } +} + /// Trait for HUGR container builders. /// Containers are nodes that are parents of sibling graphs. /// Implementations of this trait allow the child sibling graph to be added to /// the HUGR. -pub trait Container { +pub trait Container: Buildable { /// The container node. fn container_node(&self) -> Node; - /// The underlying [`Hugr`] being built - fn hugr_mut(&mut self) -> &mut Hugr; - /// Immutable reference to HUGR being built - fn hugr(&self) -> &Hugr; /// 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(); @@ -79,7 +103,7 @@ pub trait Container { &mut self, name: impl Into, signature: Signature, - ) -> Result, BuildError> { + ) -> Result>, BuildError> { let f_node = self.add_child_op(ops::FuncDefn { name: name.into(), signature: signature.clone(), @@ -252,7 +276,7 @@ pub trait Dataflow: Container { &mut self, signature: Signature, input_wires: impl IntoIterator, - ) -> Result, BuildError> { + ) -> Result>, BuildError> { let (dfg_n, _) = add_op_with_wires( self, ops::DFG { @@ -278,7 +302,7 @@ pub trait Dataflow: Container { &mut self, inputs: impl IntoIterator, output_types: SimpleRow, - ) -> Result, BuildError> { + ) -> Result>, BuildError> { let (input_types, input_wires): (Vec, Vec) = inputs.into_iter().unzip(); let inputs: SimpleRow = input_types.into(); @@ -337,7 +361,7 @@ pub trait Dataflow: Container { just_inputs: impl IntoIterator, inputs_outputs: impl IntoIterator, just_out_types: ClassicRow, - ) -> Result, BuildError> { + ) -> Result>, BuildError> { let (input_types, mut input_wires): (Vec, Vec) = just_inputs.into_iter().unzip(); let (rest_types, rest_input_wires): (Vec, Vec) = @@ -371,7 +395,7 @@ pub trait Dataflow: Container { (predicate_inputs, predicate_wire): (impl IntoIterator, Wire), other_inputs: impl IntoIterator, output_types: SimpleRow, - ) -> Result, BuildError> { + ) -> Result>, BuildError> { let mut input_wires = vec![predicate_wire]; let (input_types, rest_input_wires): (Vec, Vec) = other_inputs.into_iter().unzip(); @@ -526,9 +550,7 @@ pub trait Dataflow: Container { function: &FuncID, input_wires: impl IntoIterator, ) -> Result, BuildError> { - let hugr = self.hugr(); - let def_op = hugr.get_optype(function.node()); - let signature = match def_op { + let signature = match self.hugr().get_optype(function.node()) { OpType::FuncDefn(ops::FuncDefn { signature, .. }) | OpType::FuncDecl(ops::FuncDecl { signature, .. }) => signature.clone(), _ => { @@ -540,7 +562,7 @@ pub trait Dataflow: Container { }; let const_in_port = signature.output.len(); let op_id = self.add_dataflow_op(ops::Call { signature }, input_wires)?; - let src_port = self.hugr_mut().num_outputs(function.node()) - 1; + let src_port = self.hugr().num_outputs(function.node()) - 1; self.hugr_mut() .connect(function.node(), src_port, op_id.node(), const_in_port)?; @@ -586,9 +608,10 @@ fn wire_up_inputs( dst_port, )?; } - let base = data_builder.hugr_mut(); + let base = data_builder.hugr(); let op = base.get_optype(op_node); let some_df_outputs = !op.signature().output.is_empty(); + drop(base); if !any_local_df_inputs && some_df_outputs { // If op has no inputs add a StateOrder edge from input to place in // causal cone of Input node @@ -605,7 +628,7 @@ fn wire_up( dst: Node, dst_port: usize, ) -> Result { - let base = data_builder.hugr_mut(); + let mut base = data_builder.hugr_mut(); let src_offset = Port::new_outgoing(src_port); let src_parent = base.get_parent(src); @@ -652,14 +675,10 @@ fn wire_up( } } - data_builder - .hugr_mut() - .connect(src, src_port, dst, dst_port)?; + base.connect(src, src_port, dst, dst_port)?; Ok(local_source && matches!( - data_builder - .hugr_mut() - .get_optype(dst) + base.get_optype(dst) .port_kind(Port::new_incoming(dst_port)) .unwrap(), EdgeKind::Value(_) diff --git a/src/builder/cfg.rs b/src/builder/cfg.rs index 85df2a4f6..5ab71137c 100644 --- a/src/builder/cfg.rs +++ b/src/builder/cfg.rs @@ -1,7 +1,7 @@ use itertools::Itertools; use super::{ - build_traits::SubContainer, + build_traits::{Buildable, SubContainer}, dataflow::{DFGBuilder, DFGWrapper}, handle::BuildHandle, BasicBlockID, BuildError, CfgID, Container, Dataflow, HugrBuilder, Wire, @@ -25,24 +25,28 @@ pub struct CFGBuilder { pub(super) n_out_wires: usize, } -impl + AsRef> Container for CFGBuilder { +impl Buildable for CFGBuilder { + type BaseMut<'a> = B::BaseMut<'a> where Self: 'a; + type BaseView<'a> = B::BaseView<'a> where Self: 'a; #[inline] - fn container_node(&self) -> Node { - self.cfg_node + fn hugr_mut(&mut self) -> Self::BaseMut<'_> { + self.base.hugr_mut() } #[inline] - fn hugr_mut(&mut self) -> &mut Hugr { - self.base.as_mut() + fn hugr(&self) -> Self::BaseView<'_> { + self.base.hugr() } +} +impl Container for CFGBuilder { #[inline] - fn hugr(&self) -> &Hugr { - self.base.as_ref() + fn container_node(&self) -> Node { + self.cfg_node } } -impl + AsRef> SubContainer for CFGBuilder { +impl SubContainer for CFGBuilder { type ContainerHandle = BuildHandle; #[inline] fn finish_sub_container(self) -> Result { @@ -76,7 +80,7 @@ impl HugrBuilder for CFGBuilder { } } -impl + AsRef> CFGBuilder { +impl CFGBuilder { pub(super) fn create( mut base: B, cfg_node: Node, @@ -88,7 +92,7 @@ impl + AsRef> CFGBuilder { cfg_outputs: output, }); let exit_node = base - .as_mut() + .hugr_mut() .add_op_with_parent(cfg_node, exit_block_type)?; Ok(Self { base, @@ -126,7 +130,7 @@ impl + AsRef> CFGBuilder { inputs: SimpleRow, predicate_variants: Vec, other_outputs: SimpleRow, - ) -> Result, BuildError> { + ) -> Result::BaseMut<'_>>, BuildError> { self.any_block_builder(inputs, predicate_variants, other_outputs, false) } @@ -136,7 +140,7 @@ impl + AsRef> CFGBuilder { predicate_variants: Vec, other_outputs: SimpleRow, entry: bool, - ) -> Result, BuildError> { + ) -> Result::BaseMut<'_>>, BuildError> { let op = OpType::BasicBlock(BasicBlock::DFB { inputs: inputs.clone(), other_outputs: other_outputs.clone(), @@ -170,7 +174,7 @@ impl + AsRef> CFGBuilder { inputs: SimpleRow, outputs: SimpleRow, n_cases: usize, - ) -> Result, BuildError> { + ) -> Result::BaseMut<'_>>, BuildError> { self.block_builder(inputs, vec![type_row![]; n_cases], outputs) } @@ -185,7 +189,7 @@ impl + AsRef> CFGBuilder { &mut self, predicate_variants: Vec, other_outputs: SimpleRow, - ) -> Result, BuildError> { + ) -> Result::BaseMut<'_>>, BuildError> { let inputs = self .inputs .take() @@ -203,7 +207,7 @@ impl + AsRef> CFGBuilder { &mut self, outputs: SimpleRow, n_cases: usize, - ) -> Result, BuildError> { + ) -> Result::BaseMut<'_>>, BuildError> { self.entry_builder(vec![type_row![]; n_cases], outputs) } @@ -232,7 +236,7 @@ impl + AsRef> CFGBuilder { /// Builder for a [`BasicBlock::DFB`] child graph. pub type BlockBuilder = DFGWrapper; -impl + AsRef> BlockBuilder { +impl BlockBuilder { /// Set the outputs of the block, with `branch_wire` being the value of the /// predicate. `outputs` are the remaining outputs. pub fn set_outputs( @@ -242,6 +246,7 @@ impl + AsRef> BlockBuilder { ) -> Result<(), BuildError> { Dataflow::set_outputs(self, [branch_wire].into_iter().chain(outputs.into_iter())) } + fn create( base: B, block_n: Node, @@ -257,8 +262,7 @@ impl + AsRef> BlockBuilder { let db = DFGBuilder::create_with_io(base, block_n, signature)?; Ok(BlockBuilder::from_dfg_builder(db)) } -} -impl + AsRef> BlockBuilder { + /// [Set outputs](BlockBuilder::set_outputs) and [finish](`BlockBuilder::finish_sub_container`). pub fn finish_with_outputs( mut self, @@ -371,9 +375,12 @@ mod test { Ok(()) } - fn build_basic_cfg + AsRef>( + fn build_basic_cfg( cfg_builder: &mut CFGBuilder, - ) -> Result<(), BuildError> { + ) -> Result<(), BuildError> + where + CFGBuilder: Container, + { let sum2_variants = vec![ classic_row![ClassicType::i64()], classic_row![ClassicType::i64()], diff --git a/src/builder/conditional.rs b/src/builder/conditional.rs index f57c3c3cb..c0ee5fe75 100644 --- a/src/builder/conditional.rs +++ b/src/builder/conditional.rs @@ -4,7 +4,7 @@ use crate::types::{ClassicRow, Signature, SimpleRow}; use crate::ops; use crate::ops::handle::CaseID; -use super::build_traits::SubContainer; +use super::build_traits::{Buildable, SubContainer}; use super::handle::BuildHandle; use super::HugrBuilder; use super::{ @@ -48,24 +48,28 @@ pub struct ConditionalBuilder { pub(super) case_nodes: Vec>, } -impl + AsRef> Container for ConditionalBuilder { +impl Buildable for ConditionalBuilder { + type BaseMut<'a> = B::BaseMut<'a> where Self: 'a; + type BaseView<'a> = B::BaseView<'a> where Self: 'a; #[inline] - fn container_node(&self) -> Node { - self.conditional_node + fn hugr_mut(&mut self) -> Self::BaseMut<'_> { + self.base.hugr_mut() } #[inline] - fn hugr_mut(&mut self) -> &mut Hugr { - self.base.as_mut() + fn hugr(&self) -> Self::BaseView<'_> { + self.base.hugr() } +} +impl Container for ConditionalBuilder { #[inline] - fn hugr(&self) -> &Hugr { - self.base.as_ref() + fn container_node(&self) -> Node { + self.conditional_node } } -impl + AsRef> SubContainer for ConditionalBuilder { +impl SubContainer for ConditionalBuilder { type ContainerHandle = BuildHandle; fn finish_sub_container(self) -> Result { @@ -85,7 +89,7 @@ impl + AsRef> SubContainer for ConditionalBuilder { Ok((self.conditional_node, self.n_out_wires).into()) } } -impl + AsRef> ConditionalBuilder { +impl ConditionalBuilder { /// Return a builder the Case node with index `case`. /// /// # Panics @@ -96,12 +100,14 @@ impl + AsRef> ConditionalBuilder { /// /// This function will return an error if the case has already been built, /// `case` is not a valid index or if there is an error adding nodes. - pub fn case_builder(&mut self, case: usize) -> Result, BuildError> { + pub fn case_builder( + &mut self, + case: usize, + ) -> Result::BaseMut<'_>>, BuildError> { let conditional = self.conditional_node; - let control_op = self.hugr().get_optype(self.conditional_node); + let control_op = self.hugr().get_optype(self.conditional_node).clone(); let cond: ops::Conditional = control_op - .clone() .try_into() .expect("Parent node does not have Conditional optype."); let inputs = cond diff --git a/src/builder/dataflow.rs b/src/builder/dataflow.rs index 421c3842a..20b8f49f6 100644 --- a/src/builder/dataflow.rs +++ b/src/builder/dataflow.rs @@ -1,4 +1,4 @@ -use super::build_traits::{HugrBuilder, SubContainer}; +use super::build_traits::{Buildable, HugrBuilder, SubContainer}; use super::handle::BuildHandle; use super::{BuildError, Container, Dataflow, DfgID, FuncID}; @@ -21,7 +21,7 @@ pub struct DFGBuilder { pub(crate) num_out_wires: usize, } -impl + AsRef> DFGBuilder { +impl DFGBuilder { pub(super) fn create_with_io( mut base: T, parent: Node, @@ -29,14 +29,14 @@ impl + AsRef> DFGBuilder { ) -> Result { let num_in_wires = signature.input.len(); let num_out_wires = signature.output.len(); - base.as_mut().add_op_with_parent( + base.hugr_mut().add_op_with_parent( parent, ops::Input { types: signature.input.clone(), resources: signature.input_resources, }, )?; - base.as_mut().add_op_with_parent( + base.hugr_mut().add_op_with_parent( parent, ops::Output { types: signature.output.clone(), @@ -82,24 +82,28 @@ impl HugrBuilder for DFGBuilder { } } -impl + AsRef> Container for DFGBuilder { +impl Buildable for DFGBuilder { + type BaseMut<'a> = B::BaseMut<'a> where Self: 'a; + type BaseView<'a> = B::BaseView<'a> where Self: 'a; #[inline] - fn container_node(&self) -> Node { - self.dfg_node + fn hugr_mut(&mut self) -> Self::BaseMut<'_> { + self.base.hugr_mut() } #[inline] - fn hugr_mut(&mut self) -> &mut Hugr { - self.base.as_mut() + fn hugr(&self) -> Self::BaseView<'_> { + self.base.hugr() } +} +impl Container for DFGBuilder { #[inline] - fn hugr(&self) -> &Hugr { - self.base.as_ref() + fn container_node(&self) -> Node { + self.dfg_node } } -impl + AsRef> SubContainer for DFGBuilder { +impl SubContainer for DFGBuilder { type ContainerHandle = BuildHandle; #[inline] fn finish_sub_container(self) -> Result { @@ -107,7 +111,7 @@ impl + AsRef> SubContainer for DFGBuilder { } } -impl + AsRef> Dataflow for DFGBuilder { +impl Dataflow for DFGBuilder { #[inline] fn num_inputs(&self) -> usize { self.num_in_wires @@ -147,31 +151,35 @@ impl FunctionBuilder { } } -impl + AsRef, T> Container for DFGWrapper { +impl Buildable for DFGWrapper { + type BaseMut<'a> = B::BaseMut<'a> where Self: 'a; + type BaseView<'a> = B::BaseView<'a> where Self: 'a; #[inline] - fn container_node(&self) -> Node { - self.0.container_node() + fn hugr_mut(&mut self) -> Self::BaseMut<'_> { + self.0.hugr_mut() } #[inline] - fn hugr_mut(&mut self) -> &mut Hugr { - self.0.hugr_mut() + fn hugr(&self) -> Self::BaseView<'_> { + self.0.hugr() } +} +impl Container for DFGWrapper { #[inline] - fn hugr(&self) -> &Hugr { - self.0.hugr() + fn container_node(&self) -> Node { + self.0.container_node() } } -impl + AsRef, T> Dataflow for DFGWrapper { +impl Dataflow for DFGWrapper { #[inline] fn num_inputs(&self) -> usize { - self.0.num_inputs() + Dataflow::num_inputs(&self.0) } } -impl + AsRef, T: From>> SubContainer for DFGWrapper { +impl>> SubContainer for DFGWrapper { type ContainerHandle = T; #[inline] diff --git a/src/builder/module.rs b/src/builder/module.rs index 8c7acb28f..7a402d83a 100644 --- a/src/builder/module.rs +++ b/src/builder/module.rs @@ -1,14 +1,10 @@ use super::{ - build_traits::HugrBuilder, + build_traits::{Buildable, HugrBuilder}, dataflow::{DFGBuilder, FunctionBuilder}, BuildError, Container, }; -use crate::{ - hugr::{view::HugrView, ValidationError}, - ops, - types::SimpleType, -}; +use crate::{hugr::ValidationError, ops, types::SimpleType, HugrView}; use crate::ops::handle::{AliasID, FuncID, NodeHandle}; use crate::ops::OpType; @@ -23,20 +19,24 @@ use crate::{hugr::HugrMut, Hugr}; /// Builder for a HUGR module. #[derive(Debug, Clone, PartialEq)] pub struct ModuleBuilder(pub(super) T); +impl Buildable for ModuleBuilder { + type BaseMut<'a> = B::BaseMut<'a> where Self: 'a; + type BaseView<'a> = B::BaseView<'a> where Self: 'a; -impl + AsRef> Container for ModuleBuilder { #[inline] - fn container_node(&self) -> Node { - self.0.as_ref().root() + fn hugr_mut(&mut self) -> Self::BaseMut<'_> { + self.0.hugr_mut() } - #[inline] - fn hugr_mut(&mut self) -> &mut Hugr { - self.0.as_mut() + fn hugr(&self) -> Self::BaseView<'_> { + self.0.hugr() } +} - fn hugr(&self) -> &Hugr { - self.0.as_ref() +impl Container for ModuleBuilder { + #[inline] + fn container_node(&self) -> Node { + self.0.root() } } @@ -61,7 +61,7 @@ impl HugrBuilder for ModuleBuilder { } } -impl + AsRef> ModuleBuilder { +impl ModuleBuilder { /// Replace a [`ops::FuncDecl`] with [`ops::FuncDefn`] and return a builder for /// the defining graph. /// @@ -72,7 +72,7 @@ impl + AsRef> ModuleBuilder { pub fn define_declaration( &mut self, f_id: &FuncID, - ) -> Result, BuildError> { + ) -> Result::BaseMut<'_>>, BuildError> { let f_node = f_id.node(); let (signature, name) = if let OpType::FuncDecl(ops::FuncDecl { signature, name }) = self.hugr().get_optype(f_node) diff --git a/src/builder/tail_loop.rs b/src/builder/tail_loop.rs index 58a846265..3c55715e5 100644 --- a/src/builder/tail_loop.rs +++ b/src/builder/tail_loop.rs @@ -1,10 +1,11 @@ +use crate::hugr::HugrMut; use crate::ops::{self, OpType}; use crate::hugr::view::HugrView; use crate::types::{ClassicRow, Signature, SimpleRow}; use crate::{Hugr, Node}; -use super::build_traits::SubContainer; +use super::build_traits::{Buildable, SubContainer}; use super::handle::BuildHandle; use super::{ dataflow::{DFGBuilder, DFGWrapper}, @@ -14,7 +15,7 @@ use super::{ /// Builder for a [`ops::TailLoop`] node. pub type TailLoopBuilder = DFGWrapper>; -impl + AsRef> TailLoopBuilder { +impl TailLoopBuilder { pub(super) fn create_with_io( base: B, loop_node: Node, @@ -37,9 +38,9 @@ impl + AsRef> TailLoopBuilder { /// Get a reference to the [`ops::TailLoop`] /// that defines the signature of the [`ops::TailLoop`] - pub fn loop_signature(&self) -> Result<&ops::TailLoop, BuildError> { + pub fn loop_signature(&self) -> Result { if let OpType::TailLoop(tail_loop) = self.hugr().get_optype(self.container_node()) { - Ok(tail_loop) + Ok(tail_loop.clone()) } else { Err(BuildError::UnexpectedType { node: self.container_node(), @@ -50,11 +51,9 @@ impl + AsRef> TailLoopBuilder { /// The output types of the child graph, including the predicate as the first. pub fn internal_output_row(&self) -> Result { - self.loop_signature().map(ops::TailLoop::body_output_row) + self.loop_signature().map(|tl| tl.body_output_row()) } -} -impl + AsRef> TailLoopBuilder { /// Set outputs and finish, see [`TailLoopBuilder::set_outputs`] pub fn finish_with_outputs( mut self, @@ -112,7 +111,7 @@ mod test { let [i1] = loop_b.input_wires_arr(); let const_wire = loop_b.add_load_const(ConstValue::i64(1))?; - let break_wire = loop_b.make_break(loop_b.loop_signature()?.clone(), [const_wire])?; + let break_wire = loop_b.make_break(loop_b.loop_signature()?, [const_wire])?; loop_b.set_outputs(break_wire, [i1])?; loop_b.finish_hugr() }; @@ -135,7 +134,7 @@ mod test { vec![], classic_row![ClassicType::i64()], )?; - let signature = loop_b.loop_signature()?.clone(); + let signature = loop_b.loop_signature()?; let const_wire = loop_b.add_load_const(ConstValue::true_val())?; let [b1] = loop_b.input_wires_arr(); let conditional_id = { diff --git a/src/hugr/hugrmut.rs b/src/hugr/hugrmut.rs index 35bf268fc..248332d51 100644 --- a/src/hugr/hugrmut.rs +++ b/src/hugr/hugrmut.rs @@ -12,7 +12,7 @@ use crate::{Hugr, Port}; use super::NodeMetadata; /// Functions for low-level building of a HUGR. (Or, in the future, a subregion thereof) -pub(crate) trait HugrMut { +pub trait HugrMut: HugrView { /// Add a node to the graph. fn add_op(&mut self, op: impl Into) -> Node; diff --git a/src/hugr/rewrite/outline_cfg.rs b/src/hugr/rewrite/outline_cfg.rs index dc9051ae5..168026e0a 100644 --- a/src/hugr/rewrite/outline_cfg.rs +++ b/src/hugr/rewrite/outline_cfg.rs @@ -4,7 +4,7 @@ use std::collections::HashSet; use itertools::Itertools; use thiserror::Error; -use crate::builder::{CFGBuilder, Container, Dataflow, SubContainer}; +use crate::builder::{Buildable, CFGBuilder, Container, Dataflow, SubContainer}; use crate::hugr::rewrite::Rewrite; use crate::hugr::{HugrMut, HugrView}; use crate::ops::handle::NodeHandle;