Skip to content

Commit d255a23

Browse files
committed
Modules test that their exported children have distinct names
1 parent ddfd973 commit d255a23

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

hugr-core/src/ops/constant.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ impl Const {
4545

4646
/// Create a new [`Const`] operation available for linking
4747
pub fn new_public(value: Value, name: impl ToString) -> Self {
48-
Self {value, name: Some(name.to_string()) }
48+
Self {
49+
value,
50+
name: Some(name.to_string()),
51+
}
4952
}
5053

5154
/// The inner value of the [`Const`]

hugr-core/src/ops/validate.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
//! It also defines a `validate_op_children` method for more complex tests that
77
//! require traversing the children.
88
9+
use std::collections::HashMap;
10+
911
use itertools::Itertools;
1012
use portgraph::{NodeIndex, PortOffset};
1113
use thiserror::Error;
@@ -60,6 +62,34 @@ impl ValidateOp for super::Module {
6062
..Default::default()
6163
}
6264
}
65+
66+
fn validate_op_children<'a>(
67+
&self,
68+
children: impl DoubleEndedIterator<Item = (NodeIndex, &'a OpType)>,
69+
) -> Result<(), ChildrenValidationError> {
70+
let mut ops_by_name = HashMap::new();
71+
for (node, op) in children {
72+
let name = match op {
73+
OpType::FuncDecl(fd) => Some(&fd.name),
74+
OpType::FuncDefn(fd) => fd.public.then_some(&fd.name),
75+
OpType::Const(c) => c.name.as_ref(),
76+
_ => None,
77+
};
78+
if let Some(name) = name {
79+
ops_by_name.entry(name).or_insert(Vec::new()).push(node)
80+
}
81+
}
82+
for (name, nodes) in ops_by_name {
83+
let mut nodes = nodes.iter().copied();
84+
let fst = nodes.next().unwrap();
85+
let Some(snd) = nodes.next() else { continue };
86+
return Err(ChildrenValidationError::DuplicateExternalNames {
87+
name: name.clone(),
88+
children: [fst, snd],
89+
});
90+
}
91+
Ok(())
92+
}
6393
}
6494

6595
impl ValidateOp for super::Conditional {
@@ -194,6 +224,14 @@ pub enum ChildrenValidationError {
194224
expected_count: usize,
195225
actual_sum_rows: Vec<TypeRow>,
196226
},
227+
/// Multiple nodes were exported using the same name from a [Module](super::Module)
228+
#[error("Node is exported under same name {name} as earlier node {:?}", children[0])]
229+
DuplicateExternalNames {
230+
/// The name of a [FuncDecl], public [FuncDefn](super::FuncDefn) or [Const]
231+
name: String,
232+
/// Two nodes node exported under that name
233+
children: [NodeIndex; 2],
234+
},
197235
}
198236

199237
impl ChildrenValidationError {
@@ -205,6 +243,7 @@ impl ChildrenValidationError {
205243
ChildrenValidationError::ConditionalCaseSignature { child, .. } => *child,
206244
ChildrenValidationError::IOSignatureMismatch { child, .. } => *child,
207245
ChildrenValidationError::InvalidConditionalSum { child, .. } => *child,
246+
ChildrenValidationError::DuplicateExternalNames { children, .. } => children[1],
208247
}
209248
}
210249
}

0 commit comments

Comments
 (0)