Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor!: Separate Signature from FunctionType #1044

Closed
wants to merge 11 commits into from
8 changes: 4 additions & 4 deletions hugr-passes/src/merge_bbs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ fn mk_rep(
let output = replacement.add_node_with_parent(
merged,
Output {
types: succ_sig.output.clone(),
types: succ_sig.output().clone(),
},
);

Expand All @@ -96,7 +96,7 @@ fn mk_rep(
signature: succ_sig.clone(),
},
);
for (i, _) in succ_sig.output.iter().enumerate() {
for i in 0..succ_sig.output_count() {
replacement.connect(dfg2, i, output, i)
}

Expand Down Expand Up @@ -318,8 +318,8 @@ mod test {
let [res_t] = tst_op
.dataflow_signature()
.unwrap()
.output
.into_owned()
.output()
.to_vec()
.try_into()
.unwrap();
let mut h = CFGBuilder::new(
Expand Down
35 changes: 17 additions & 18 deletions hugr/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@
//! # }
//! # doctest().unwrap();
//! ```
use std::convert::Infallible;

use thiserror::Error;

use crate::extension::SignatureError;
Expand Down Expand Up @@ -183,6 +185,13 @@ pub enum BuildError {
},
}

impl From<Infallible> for BuildError {
fn from(value: Infallible) -> Self {
match value {
}
}
}

#[derive(Debug, Clone, PartialEq, Error)]
#[non_exhaustive]
/// Error raised when wiring up a node during the build process.
Expand Down Expand Up @@ -222,7 +231,7 @@ pub(crate) mod test {

use crate::hugr::{views::HugrView, HugrMut, NodeType};
use crate::ops;
use crate::types::{FunctionType, PolyFuncType, Type};
use crate::types::{FunctionType, PolyFuncType, Signature, Type};
use crate::{type_row, Hugr};

use super::handle::BuildHandle;
Expand All @@ -245,7 +254,7 @@ pub(crate) mod test {
}

pub(super) fn build_main(
signature: PolyFuncType,
signature: PolyFuncType<false>,
f: impl FnOnce(FunctionBuilder<&mut Hugr>) -> Result<BuildHandle<FuncID<true>>, BuildError>,
) -> Result<Hugr, BuildError> {
let mut module_builder = ModuleBuilder::new();
Expand Down Expand Up @@ -275,22 +284,12 @@ pub(crate) mod test {
/// for tests which want to avoid having open extension variables after
/// inference. Using DFGBuilder will default to a root node with an open
/// extension variable
pub(crate) fn closed_dfg_root_hugr(signature: FunctionType) -> Hugr {
let mut hugr = Hugr::new(NodeType::new_pure(ops::DFG {
signature: signature.clone(),
}));
hugr.add_node_with_parent(
hugr.root(),
ops::Input {
types: signature.input,
},
);
hugr.add_node_with_parent(
hugr.root(),
ops::Output {
types: signature.output,
},
);
pub(crate) fn closed_dfg_root_hugr(signature: Signature) -> Hugr {
let in_types = signature.input().clone();
let out_types = signature.output().clone();
let mut hugr = Hugr::new(NodeType::new_pure(ops::DFG { signature }));
hugr.add_node_with_parent(hugr.root(), ops::Input { types: in_types });
hugr.add_node_with_parent(hugr.root(), ops::Output { types: out_types });
hugr
}
}
27 changes: 10 additions & 17 deletions hugr/src/builder/build_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ use crate::{
types::EdgeKind,
};

use crate::extension::{ExtensionRegistry, ExtensionSet, SignatureError, PRELUDE_REGISTRY};
use crate::types::{FunctionType, PolyFuncType, Type, TypeArg, TypeRow};
use crate::extension::{ExtensionRegistry, ExtensionSet, PRELUDE_REGISTRY};
use crate::types::{FunctionType, PolyFuncType, Signature, Type, TypeArg, TypeRow};

use itertools::Itertools;

Expand Down Expand Up @@ -85,7 +85,7 @@ pub trait Container {
fn define_function(
&mut self,
name: impl Into<String>,
signature: PolyFuncType,
signature: PolyFuncType<false>,
) -> Result<FunctionBuilder<&mut Hugr>, BuildError> {
let body = signature.body().clone();
let f_node = self.add_child_node(NodeType::new_pure(ops::FuncDefn {
Expand Down Expand Up @@ -294,19 +294,21 @@ pub trait Dataflow: Container {
/// This function will return an error if there is an error when building
/// the DFG node.
// TODO: Should this be one function, or should there be a temporary "op" one like with the others?
fn dfg_builder(
fn dfg_builder<S: TryInto<Signature>>(
&mut self,
signature: FunctionType,
signature: S,
input_extensions: Option<ExtensionSet>,
input_wires: impl IntoIterator<Item = Wire>,
) -> Result<DFGBuilder<&mut Hugr>, BuildError> {
) -> Result<DFGBuilder<&mut Hugr>, BuildError>
where BuildError: From<<S as TryInto<Signature>>::Error> {
let signature = signature.try_into()?;
let op = ops::DFG {
signature: signature.clone(),
};
let nodetype = NodeType::new(op, input_extensions.clone());
let (dfg_n, _) = add_node_with_wires(self, nodetype, input_wires)?;

DFGBuilder::create_with_io(self.hugr_mut(), dfg_n, signature, input_extensions)
DFGBuilder::create_with_io::<Signature>(self.hugr_mut(), dfg_n, signature, input_extensions)
}

/// Return a builder for a [`crate::ops::CFG`] node,
Expand Down Expand Up @@ -334,7 +336,7 @@ pub trait Dataflow: Container {
self,
NodeType::new(
ops::CFG {
signature: FunctionType::new(inputs.clone(), output_types.clone())
signature: Signature::try_new(inputs.clone(), output_types.clone())?
.with_extension_delta(extension_delta),
},
input_extensions.into(),
Expand Down Expand Up @@ -645,15 +647,6 @@ fn add_node_with_wires<T: Dataflow + ?Sized>(
inputs: impl IntoIterator<Item = Wire>,
) -> Result<(Node, usize), BuildError> {
let nodetype: NodeType = nodetype.into();
// Check there are no row variables, as that would prevent us
// from indexing into the node's ports in order to wire up
nodetype
.op_signature()
.as_ref()
.and_then(FunctionType::find_rowvar)
.map_or(Ok(()), |(idx, _)| {
Err(SignatureError::RowVarWhereTypeExpected { idx })
})?;
let num_outputs = nodetype.op().value_output_count();
let op_node = data_builder.add_child_node(nodetype.clone());

Expand Down
22 changes: 9 additions & 13 deletions hugr/src/builder/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use super::{
BasicBlockID, BuildError, CfgID, Container, Dataflow, HugrBuilder, Wire,
};

use crate::ops::{self, handle::NodeHandle, DataflowBlock, DataflowParent, ExitBlock, OpType};
use crate::{ops::{self, handle::NodeHandle, DataflowBlock, DataflowParent, ExitBlock, OpType}, types::Signature};
use crate::{
extension::{ExtensionRegistry, ExtensionSet},
types::FunctionType,
Expand Down Expand Up @@ -153,14 +153,14 @@ impl<H: AsMut<Hugr> + AsRef<Hugr>> SubContainer for CFGBuilder<H> {

impl CFGBuilder<Hugr> {
/// New CFG rooted HUGR builder
pub fn new(signature: FunctionType) -> Result<Self, BuildError> {
let cfg_op = ops::CFG {
signature: signature.clone(),
};
pub fn new(signature: Signature) -> Result<Self, BuildError> {
let input = signature.input().clone();
let output = signature.output().clone();
let cfg_op = ops::CFG { signature };

let base = Hugr::new(NodeType::new_open(cfg_op));
let cfg_node = base.root();
CFGBuilder::create(base, cfg_node, signature.input, signature.output)
CFGBuilder::create(base, cfg_node, input, output)
}
}

Expand Down Expand Up @@ -251,15 +251,11 @@ impl<B: AsMut<Hugr> + AsRef<Hugr>> CFGBuilder<B> {
/// This function will return an error if there is an error adding the node.
pub fn simple_block_builder(
&mut self,
signature: FunctionType,
signature: Signature,
n_cases: usize,
) -> Result<BlockBuilder<&mut Hugr>, BuildError> {
self.block_builder(
signature.input,
vec![type_row![]; n_cases],
signature.extension_reqs,
signature.output,
)
let (input, extension_reqs, output) = signature.into_tuple();
self.block_builder(input, vec![type_row![]; n_cases], extension_reqs, output)
}

/// Return a builder for the entry [`DataflowBlock`] child graph with `inputs`
Expand Down
4 changes: 2 additions & 2 deletions hugr/src/builder/conditional.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::extension::ExtensionRegistry;
use crate::hugr::views::HugrView;
use crate::ops::dataflow::DataflowOpTrait;
use crate::types::{FunctionType, TypeRow};
use crate::types::{FunctionType, Signature, TypeRow};

use crate::ops;
use crate::ops::handle::CaseID;
Expand Down Expand Up @@ -192,7 +192,7 @@ impl ConditionalBuilder<Hugr> {

impl CaseBuilder<Hugr> {
/// Initialize a Case rooted HUGR
pub fn new(signature: FunctionType) -> Result<Self, BuildError> {
pub fn new(signature: Signature) -> Result<Self, BuildError> {
let op = ops::Case {
signature: signature.clone(),
};
Expand Down
24 changes: 16 additions & 8 deletions hugr/src/builder/dataflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ use std::marker::PhantomData;
use crate::hugr::{HugrView, NodeType, ValidationError};
use crate::ops;

use crate::types::{FunctionType, PolyFuncType};
use crate::types::{FunctionType, PolyFuncType, Signature};

use crate::extension::{ExtensionRegistry, ExtensionSet};
use crate::extension::{ExtensionRegistry, ExtensionSet, SignatureError};
use crate::Node;
use crate::{hugr::HugrMut, Hugr};

Expand All @@ -23,12 +23,15 @@ pub struct DFGBuilder<T> {
}

impl<T: AsMut<Hugr> + AsRef<Hugr>> DFGBuilder<T> {
pub(super) fn create_with_io(
pub(super) fn create_with_io<S: TryInto<Signature>>(
mut base: T,
parent: Node,
signature: FunctionType,
signature: S,
input_extensions: Option<ExtensionSet>,
) -> Result<Self, BuildError> {
) -> Result<Self, BuildError>
where BuildError: From<<S as TryInto<Signature>>::Error>
{
let signature = signature.try_into()?;
let num_in_wires = signature.input().len();
let num_out_wires = signature.output().len();
/* For a given dataflow graph with extension requirements IR -> IR + dR,
Expand Down Expand Up @@ -75,13 +78,15 @@ impl DFGBuilder<Hugr> {
/// # Errors
///
/// Error in adding DFG child nodes.
pub fn new(signature: FunctionType) -> Result<DFGBuilder<Hugr>, BuildError> {
pub fn new<S: TryInto<Signature>>(signature: S) -> Result<DFGBuilder<Hugr>, BuildError>
where BuildError: From<<S as TryInto<Signature>>::Error> {
let signature = signature.try_into()?;
let dfg_op = ops::DFG {
signature: signature.clone(),
};
let base = Hugr::new(NodeType::new_open(dfg_op));
let root = base.root();
DFGBuilder::create_with_io(base, root, signature, None)
DFGBuilder::create_with_io::<Signature>(base, root, signature, None)
}
}

Expand Down Expand Up @@ -146,7 +151,10 @@ impl FunctionBuilder<Hugr> {
/// # Errors
///
/// Error in adding DFG child nodes.
pub fn new(name: impl Into<String>, signature: PolyFuncType) -> Result<Self, BuildError> {
pub fn new(
name: impl Into<String>,
signature: PolyFuncType<false>,
) -> Result<Self, BuildError> {
let body = signature.body().clone();
let op = ops::FuncDefn {
signature,
Expand Down
2 changes: 1 addition & 1 deletion hugr/src/builder/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ impl<T: AsMut<Hugr> + AsRef<Hugr>> ModuleBuilder<T> {
pub fn declare(
&mut self,
name: impl Into<String>,
signature: PolyFuncType,
signature: PolyFuncType<false>,
) -> Result<FuncID<false>, BuildError> {
// TODO add param names to metadata
let declare_n = self.add_child_node(NodeType::new_pure(ops::FuncDecl {
Expand Down
5 changes: 3 additions & 2 deletions hugr/src/builder/tail_loop.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::ops;

use crate::hugr::{views::HugrView, NodeType};
use crate::types::{FunctionType, TypeRow};
use crate::types::{FunctionType, Signature, TypeRow};
use crate::{Hugr, Node};

use super::build_traits::SubContainer;
Expand All @@ -20,7 +20,8 @@ impl<B: AsMut<Hugr> + AsRef<Hugr>> TailLoopBuilder<B> {
loop_node: Node,
tail_loop: &ops::TailLoop,
) -> Result<Self, BuildError> {
let signature = FunctionType::new(tail_loop.body_input_row(), tail_loop.body_output_row());
// ALAN this could be a new_unchecked *iff* TailLoop checked there were noRVs
let signature = Signature::try_new(tail_loop.body_input_row(), tail_loop.body_output_row())?;
let dfg_build = DFGBuilder::create_with_io(base, loop_node, signature, None)?;

Ok(TailLoopBuilder::from_dfg_builder(dfg_build))
Expand Down
9 changes: 5 additions & 4 deletions hugr/src/extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::ops::constant::{ValueName, ValueNameRef};
use crate::ops::custom::{ExtensionOp, OpaqueOp};
use crate::ops::{self, OpName, OpNameRef};
use crate::types::type_param::{TypeArg, TypeArgError, TypeParam};
use crate::types::Signature;
use crate::types::{check_typevar_decl, CustomType, Substitution, TypeBound, TypeName};
use crate::types::{FunctionType, TypeNameRef};

Expand Down Expand Up @@ -172,8 +173,8 @@ pub enum SignatureError {
"Incorrect result of type application in Call - cached {cached} but expected {expected}"
)]
CallIncorrectlyAppliesType {
cached: FunctionType,
expected: FunctionType,
cached: Signature,
expected: Signature,
},
/// The result of the type application stored in a [LoadFunction]
/// is not what we get by applying the type-args to the polymorphic function
Expand All @@ -183,8 +184,8 @@ pub enum SignatureError {
"Incorrect result of type application in LoadFunction - cached {cached} but expected {expected}"
)]
LoadFunctionIncorrectlyAppliesType {
cached: FunctionType,
expected: FunctionType,
cached: Signature,
expected: Signature,
},
}

Expand Down
7 changes: 2 additions & 5 deletions hugr/src/extension/declarative/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,8 @@ impl SignatureDeclaration {
Ok(types.into())
};

let body = FunctionType {
input: make_type_row(&self.inputs)?,
output: make_type_row(&self.outputs)?,
extension_reqs: self.extensions.clone(),
};
let body = FunctionType::new(make_type_row(&self.inputs)?, make_type_row(&self.outputs)?)
.with_extension_delta(self.extensions.clone());

let poly_func = PolyFuncType::new(op_params, body);
Ok(SignatureFunc::TypeScheme(CustomValidator::from_polyfunc(
Expand Down
Loading
Loading