diff --git a/hugr-core/src/hugr/serialize.rs b/hugr-core/src/hugr/serialize.rs index 8df7cf8357..5ddc9e3ae5 100644 --- a/hugr-core/src/hugr/serialize.rs +++ b/hugr-core/src/hugr/serialize.rs @@ -8,6 +8,7 @@ use thiserror::Error; use crate::core::NodeIndex; use crate::hugr::Hugr; use crate::ops::OpType; +use crate::types::EdgeKind; use crate::{Node, PortIndex}; use portgraph::hierarchy::AttachError; use portgraph::{Direction, LinkError, PortView}; @@ -215,7 +216,9 @@ impl TryFrom<&Hugr> for SerHugrLatest { let op = hugr.get_optype(node); let is_value_port = offset < op.value_port_count(dir); let is_static_input = op.static_port(dir).is_some_and(|p| p.index() == offset); - let offset = (is_value_port || is_static_input).then_some(offset as u32); + let other_port_is_not_order = op.other_port_kind(dir) != Some(EdgeKind::StateOrder); + let offset = (is_value_port || is_static_input || other_port_is_not_order) + .then_some(offset as u32); (node_rekey[&node], offset) }; diff --git a/hugr-core/src/hugr/serialize/test.rs b/hugr-core/src/hugr/serialize/test.rs index 2c7997468d..12546a8e43 100644 --- a/hugr-core/src/hugr/serialize/test.rs +++ b/hugr-core/src/hugr/serialize/test.rs @@ -5,6 +5,7 @@ use crate::builder::{ Container, DFGBuilder, Dataflow, DataflowHugr, DataflowSubContainer, HugrBuilder, ModuleBuilder, endo_sig, inout_sig, test::closed_dfg_root_hugr, }; +use crate::envelope::{EnvelopeConfig, read_envelope, write_envelope}; use crate::extension::ExtensionRegistry; use crate::extension::prelude::Noop; use crate::extension::prelude::{bool_t, qb_t, usize_t}; @@ -16,15 +17,21 @@ use crate::hugr::validate::ValidationError; use crate::hugr::views::ExtractionResult; use crate::ops::custom::{ExtensionOp, OpaqueOp, OpaqueOpError}; use crate::ops::{self, DFG, Input, Module, Output, Value, dataflow::IOTrait}; +use crate::package::Package; use crate::std_extensions::arithmetic::float_types::float64_type; use crate::std_extensions::arithmetic::int_types::{ConstInt, INT_TYPES}; use crate::std_extensions::logic::LogicOp; +use crate::std_extensions::std_reg; +use crate::test_file; use crate::types::type_param::TypeParam; use crate::types::{ FuncValueType, PolyFuncType, PolyFuncTypeRV, Signature, SumType, Type, TypeArg, TypeBound, TypeRV, }; use crate::{OutgoingPort, Visibility, type_row}; +use std::fs::File; +use std::io::{BufReader, Cursor}; + use std::sync::LazyLock; use itertools::Itertools; @@ -625,6 +632,25 @@ fn std_extensions_valid() { } } +#[test] +#[cfg_attr(miri, ignore)] // Opening files is not supported in (isolated) miri +// https://github.com/CQCL/hugr/issues/2600 +fn cfg_edge_ordering() { + let pkg: Package = Package::load( + BufReader::new(File::open(test_file!("issue-2600.hugr")).unwrap()), + None, + ) + .unwrap(); + pkg.validate().unwrap(); + + let mut data1: Vec = Vec::new(); + let _ = write_envelope(&mut data1, &pkg, EnvelopeConfig::text()); + + let buff1 = Cursor::new(data1); + let (_, pkg1) = read_envelope(buff1, &std_reg()).unwrap(); + pkg1.validate().unwrap(); +} + mod proptest { use super::check_testing_roundtrip; use super::{NodeSer, SimpleOpDef}; diff --git a/hugr-py/src/hugr/hugr/base.py b/hugr-py/src/hugr/hugr/base.py index bf20c6c634..968714c221 100644 --- a/hugr-py/src/hugr/hugr/base.py +++ b/hugr-py/src/hugr/hugr/base.py @@ -971,7 +971,7 @@ def _serialize_link( def _constrain_offset(self, p: P) -> PortOffset | None: """Constrain an offset to be a valid encoded port offset. - Order edges and control flow edges should be encoded without an offset. + Order edges should be encoded without an offset. """ if p.offset < 0: assert p.offset == -1, "Only order edges are allowed with offset < 0" diff --git a/resources/test/issue-2600.hugr b/resources/test/issue-2600.hugr new file mode 100644 index 0000000000..1f6cb01c10 Binary files /dev/null and b/resources/test/issue-2600.hugr differ