Skip to content

Commit d0a8dee

Browse files
committed
Add public:bool to FuncDefn
1 parent 2222b8c commit d0a8dee

File tree

12 files changed

+113
-110
lines changed

12 files changed

+113
-110
lines changed

hugr-core/src/builder.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,8 +281,7 @@ pub(crate) mod test {
281281

282282
#[fixture]
283283
pub(crate) fn simple_funcdef_hugr() -> Hugr {
284-
let fn_builder =
285-
FunctionBuilder::new("test", Signature::new(vec![bool_t()], vec![bool_t()])).unwrap();
284+
let fn_builder = FunctionBuilder::new("test", Signature::new_endo(bool_t())).unwrap();
286285
let [i1] = fn_builder.input_wires_arr();
287286
fn_builder.finish_hugr_with_outputs([i1]).unwrap()
288287
}

hugr-core/src/builder/build_traits.rs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ pub trait Container {
8383
}
8484

8585
/// Add a [`ops::FuncDefn`] node and returns a builder to define the function
86-
/// body graph.
86+
/// body graph. The function has the default [ops::FuncDefn::public] for the parent
87+
/// (`false` with the default impl.)
8788
///
8889
/// # Errors
8990
///
@@ -93,13 +94,26 @@ pub trait Container {
9394
&mut self,
9495
name: impl Into<String>,
9596
signature: impl Into<PolyFuncType>,
97+
) -> Result<FunctionBuilder<&mut Hugr>, BuildError> {
98+
self.define_function_vis(name, signature, false)
99+
}
100+
101+
/// Add a [`ops::FuncDefn`] node with the specified [visibility](ops::FuncDefn::public)
102+
/// and returns a builder to define the function body graph.
103+
///
104+
/// # Errors
105+
///
106+
/// This function will return an error if there is an error in adding the
107+
/// [`ops::FuncDefn`] node.
108+
fn define_function_vis(
109+
&mut self,
110+
name: impl Into<String>,
111+
signature: impl Into<PolyFuncType>,
112+
public: bool,
96113
) -> Result<FunctionBuilder<&mut Hugr>, BuildError> {
97114
let signature = signature.into();
98115
let body = signature.body().clone();
99-
let f_node = self.add_child_node(ops::FuncDefn {
100-
name: name.into(),
101-
signature,
102-
});
116+
let f_node = self.add_child_node(ops::FuncDefn::new(name.into(), signature, public));
103117

104118
// Add the extensions used by the function types.
105119
self.use_extensions(

hugr-core/src/builder/dataflow.rs

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -138,20 +138,32 @@ impl<B, T> DFGWrapper<B, T> {
138138
pub type FunctionBuilder<B> = DFGWrapper<B, BuildHandle<FuncID<true>>>;
139139

140140
impl FunctionBuilder<Hugr> {
141-
/// Initialize a builder for a FuncDefn rooted HUGR
141+
/// Initialize a builder for a FuncDefn-rooted HUGR; the function will be public.
142+
/// (See also [Self::new_vis].)
143+
///
142144
/// # Errors
143145
///
144146
/// Error in adding DFG child nodes.
145147
pub fn new(
146148
name: impl Into<String>,
147149
signature: impl Into<PolyFuncType>,
148150
) -> Result<Self, BuildError> {
149-
let signature = signature.into();
150-
let body = signature.body().clone();
151-
let op = ops::FuncDefn {
152-
signature,
153-
name: name.into(),
154-
};
151+
Self::new_vis(name, signature, true)
152+
}
153+
154+
/// Initialize a builder for a FuncDefn-rooted HUGR, with the specified
155+
/// [visibility](ops::FuncDefn::public).
156+
///
157+
/// # Errors
158+
///
159+
/// Error in adding DFG child nodes.
160+
pub fn new_vis(
161+
name: impl Into<String>,
162+
signature: impl Into<PolyFuncType>,
163+
public: bool,
164+
) -> Result<Self, BuildError> {
165+
let op = ops::FuncDefn::new(name.into(), signature.into(), public);
166+
let body = op.signature.body().clone();
155167

156168
let base = Hugr::new(op);
157169
let root = base.root();
@@ -243,24 +255,13 @@ impl FunctionBuilder<Hugr> {
243255
/// Returns a reference to the new optype.
244256
fn update_fn_signature(&mut self, f: impl FnOnce(Signature) -> Signature) -> &ops::FuncDefn {
245257
let parent = self.container_node();
246-
let old_optype = self
247-
.hugr()
248-
.get_optype(parent)
249-
.as_func_defn()
250-
.expect("FunctionBuilder node must be a FuncDefn");
251-
let signature = old_optype.inner_signature().into_owned();
252-
let name = old_optype.name.clone();
253-
self.hugr_mut()
254-
.replace_op(
255-
parent,
256-
ops::FuncDefn {
257-
signature: f(signature).into(),
258-
name,
259-
},
260-
)
261-
.expect("Could not replace FunctionBuilder operation");
258+
let fn_optype = self.hugr_mut().optype_mut(parent);
262259

263-
self.hugr().get_optype(parent).as_func_defn().unwrap()
260+
let ops::OpType::FuncDefn(fd) = fn_optype else {
261+
panic!("FunctionBuilder node must be a FuncDefn")
262+
};
263+
fd.signature = f(fd.inner_signature().into_owned()).into();
264+
fn_optype.as_func_defn().unwrap()
264265
}
265266
}
266267

@@ -528,8 +529,8 @@ pub(crate) mod test {
528529
let mut module_builder = ModuleBuilder::new();
529530

530531
let (dfg_node, f_node) = {
531-
let mut f_build = module_builder
532-
.define_function("main", Signature::new(vec![bool_t()], vec![bool_t()]))?;
532+
let mut f_build =
533+
module_builder.define_function("main", Signature::new_endo(bool_t()))?;
533534

534535
let [i1] = f_build.input_wires_arr();
535536
let dfg = f_build.add_hugr_with_wires(dfg_hugr, [i1])?;

hugr-core/src/builder/module.rs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@ use crate::hugr::internal::HugrMutInternals;
88
use crate::hugr::views::HugrView;
99
use crate::hugr::ValidationError;
1010
use crate::ops;
11-
use crate::types::{PolyFuncType, Type, TypeBound};
12-
1311
use crate::ops::handle::{AliasID, FuncID, NodeHandle};
12+
use crate::types::{PolyFuncType, Type, TypeBound};
1413

1514
use crate::{Hugr, Node};
1615
use smol_str::SmolStr;
@@ -33,6 +32,14 @@ impl<T: AsMut<Hugr> + AsRef<Hugr>> Container for ModuleBuilder<T> {
3332
fn hugr(&self) -> &Hugr {
3433
self.0.as_ref()
3534
}
35+
36+
fn define_function(
37+
&mut self,
38+
name: impl Into<String>,
39+
signature: impl Into<PolyFuncType>,
40+
) -> Result<FunctionBuilder<&mut Hugr>, BuildError> {
41+
self.define_function_vis(name, signature, true)
42+
}
3643
}
3744

3845
impl ModuleBuilder<Hugr> {
@@ -60,7 +67,7 @@ impl HugrBuilder for ModuleBuilder<Hugr> {
6067
}
6168

6269
impl<T: AsMut<Hugr> + AsRef<Hugr>> ModuleBuilder<T> {
63-
/// Replace a [`ops::FuncDecl`] with [`ops::FuncDefn`] and return a builder for
70+
/// Replace a [`ops::FuncDecl`] with public [`ops::FuncDefn`] and return a builder for
6471
/// the defining graph.
6572
///
6673
/// # Errors
@@ -72,19 +79,16 @@ impl<T: AsMut<Hugr> + AsRef<Hugr>> ModuleBuilder<T> {
7279
f_id: &FuncID<false>,
7380
) -> Result<FunctionBuilder<&mut Hugr>, BuildError> {
7481
let f_node = f_id.node();
75-
let ops::FuncDecl { signature, name } = self
76-
.hugr()
77-
.get_optype(f_node)
78-
.as_func_decl()
79-
.ok_or(BuildError::UnexpectedType {
82+
let opty = self.hugr_mut().optype_mut(f_node);
83+
let ops::OpType::FuncDecl(ops::FuncDecl { signature, name }) = opty else {
84+
return Err(BuildError::UnexpectedType {
8085
node: f_node,
8186
op_desc: "crate::ops::OpType::FuncDecl",
82-
})?
83-
.clone();
87+
});
88+
};
89+
8490
let body = signature.body().clone();
85-
self.hugr_mut()
86-
.replace_op(f_node, ops::FuncDefn { name, signature })
87-
.expect("Replacing a FuncDecl node with a FuncDefn should always be valid");
91+
*opty = ops::FuncDefn::new_public(name, signature.clone()).into();
8892

8993
let db = DFGBuilder::create_with_io(self.hugr_mut(), f_node, body)?;
9094
Ok(FunctionBuilder::from_dfg_builder(db))
@@ -203,10 +207,7 @@ mod test {
203207

204208
let f_build = module_builder.define_function(
205209
"main",
206-
Signature::new(
207-
vec![qubit_state_type.get_alias_type()],
208-
vec![qubit_state_type.get_alias_type()],
209-
),
210+
Signature::new_endo(qubit_state_type.get_alias_type()),
210211
)?;
211212
n_identity(f_build)?;
212213
module_builder.finish_hugr()

hugr-core/src/hugr/hugrmut.rs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -653,12 +653,10 @@ mod test {
653653
// Start a main function with two nat inputs.
654654
let f: Node = hugr.add_node_with_parent(
655655
module,
656-
ops::FuncDefn {
657-
name: "main".into(),
658-
signature: Signature::new(vec![usize_t()], vec![usize_t(), usize_t()])
659-
.with_prelude()
660-
.into(),
661-
},
656+
ops::FuncDefn::new_public(
657+
"main",
658+
Signature::new(vec![usize_t()], vec![usize_t(), usize_t()]).with_prelude(),
659+
),
662660
);
663661

664662
{
@@ -703,10 +701,7 @@ mod test {
703701
let [foo, bar] = ["foo", "bar"].map(|name| {
704702
let fd = hugr.add_node_with_parent(
705703
root,
706-
FuncDefn {
707-
name: name.to_string(),
708-
signature: Signature::new_endo(usize_t()).into(),
709-
},
704+
FuncDefn::new_private(name, Signature::new_endo(usize_t())),
710705
);
711706
let inp = hugr.add_node_with_parent(fd, Input::new(usize_t()));
712707
let out = hugr.add_node_with_parent(fd, Output::new(usize_t()));

hugr-core/src/hugr/serialize/test.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,8 @@ fn roundtrip_polyfunctype_varlen(#[case] poly_func_type: PolyFuncTypeRV) {
533533

534534
#[rstest]
535535
#[case(ops::Module::new())]
536-
#[case(ops::FuncDefn { name: "polyfunc1".into(), signature: polyfunctype1()})]
536+
#[case(ops::FuncDefn { name: "polyfunc1".into(), signature: polyfunctype1(), public: true})]
537+
#[case(ops::FuncDefn { name: "polyfunc1".into(), signature: polyfunctype1(), public: false})]
537538
#[case(ops::FuncDecl { name: "polyfunc2".into(), signature: polyfunctype1()})]
538539
#[case(ops::AliasDefn { name: "aliasdefn".into(), definition: Type::new_unit_sum(4)})]
539540
#[case(ops::AliasDecl { name: "aliasdecl".into(), bound: TypeBound::Any})]

hugr-core/src/hugr/validate/test.rs

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,10 @@ use crate::{
3434
///
3535
/// Returns the hugr and the node index of the definition.
3636
fn make_simple_hugr(copies: usize) -> (Hugr, Node) {
37-
let def_op: OpType = ops::FuncDefn {
38-
name: "main".into(),
39-
signature: Signature::new(vec![bool_t()], vec![bool_t(); copies])
40-
.with_prelude()
41-
.into(),
42-
}
37+
let def_op: OpType = ops::FuncDefn::new_public(
38+
"main",
39+
Signature::new(bool_t(), vec![bool_t(); copies]).with_prelude(),
40+
)
4341
.into();
4442

4543
let mut b = Hugr::default();
@@ -150,13 +148,7 @@ fn children_restrictions() {
150148

151149
// Add a definition without children
152150
let def_sig = Signature::new(vec![bool_t()], vec![bool_t(), bool_t()]);
153-
let new_def = b.add_node_with_parent(
154-
root,
155-
ops::FuncDefn {
156-
signature: def_sig.into(),
157-
name: "main".into(),
158-
},
159-
);
151+
let new_def = b.add_node_with_parent(root, ops::FuncDefn::new_private("main", def_sig));
160152
assert_matches!(
161153
b.validate(),
162154
Err(ValidationError::ContainerWithoutChildren { node, .. }) => assert_eq!(node, new_def)
@@ -349,10 +341,7 @@ fn identity_hugr_with_type(t: Type) -> (Hugr, Node) {
349341

350342
let def = b.add_node_with_parent(
351343
b.root(),
352-
ops::FuncDefn {
353-
name: "main".into(),
354-
signature: Signature::new(row.clone(), row.clone()).into(),
355-
},
344+
ops::FuncDefn::new_public("main", Signature::new_endo(row.clone())),
356345
);
357346

358347
let input = b.add_node_with_parent(def, ops::Input::new(row.clone()));

hugr-core/src/hugr/views/sibling_subgraph.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,8 +457,9 @@ impl SiblingSubgraph {
457457
&self,
458458
hugr: &impl HugrView<Node = Node>,
459459
name: impl Into<String>,
460+
public: bool,
460461
) -> Hugr {
461-
let mut builder = FunctionBuilder::new(name, self.signature(hugr)).unwrap();
462+
let mut builder = FunctionBuilder::new_vis(name, self.signature(hugr), public).unwrap();
462463
// Take the unfinished Hugr from the builder, to avoid unnecessary
463464
// validation checks that require connecting the inputs and outputs.
464465
let mut extracted = mem::take(builder.hugr_mut());
@@ -1175,7 +1176,7 @@ mod tests {
11751176
let func_graph: SiblingGraph<'_, FuncID<true>> =
11761177
SiblingGraph::try_new(&hugr, func_root).unwrap();
11771178
let subgraph = SiblingSubgraph::try_new_dataflow_subgraph(&func_graph).unwrap();
1178-
let extracted = subgraph.extract_subgraph(&hugr, "region");
1179+
let extracted = subgraph.extract_subgraph(&hugr, "region", true);
11791180

11801181
extracted.validate().unwrap();
11811182
}

hugr-core/src/ops/module.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,29 @@ pub struct FuncDefn {
5858
pub name: String,
5959
/// Signature of the function
6060
pub signature: PolyFuncType,
61+
/// Is the function public? (Can it be linked against and called externally?)
62+
pub public: bool,
63+
}
64+
65+
impl FuncDefn {
66+
/// Create a new instance with the specified visibility
67+
pub fn new(name: impl ToString, signature: impl Into<PolyFuncType>, public: bool) -> Self {
68+
Self {
69+
name: name.to_string(),
70+
signature: signature.into(),
71+
public,
72+
}
73+
}
74+
75+
/// Create a new instance with [Self::public] set
76+
pub fn new_public(name: impl ToString, signature: impl Into<PolyFuncType>) -> Self {
77+
Self::new(name, signature, true)
78+
}
79+
80+
/// Create a new function that is not for external calls or linkage
81+
pub fn new_private(name: impl ToString, signature: impl Into<PolyFuncType>) -> Self {
82+
Self::new(name, signature, false)
83+
}
6184
}
6285

6386
impl_op_name!(FuncDefn);

hugr-core/src/package.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -347,14 +347,8 @@ fn to_module_hugr(mut hugr: Hugr) -> Result<Hugr, PackageError> {
347347

348348
// Convert the DFG into a `FuncDefn`
349349
hugr.set_num_ports(root, 0, 1);
350-
hugr.replace_op(
351-
root,
352-
FuncDefn {
353-
name: "main".to_string(),
354-
signature: signature.into_owned().into(),
355-
},
356-
)
357-
.expect("Hugr accepts any root node");
350+
hugr.replace_op(root, FuncDefn::new_public("main", signature.into_owned()))
351+
.expect("Hugr accepts any root node");
358352

359353
// Wrap it in a module.
360354
let new_root = hugr.add_node(Module::new().into());

0 commit comments

Comments
 (0)