diff --git a/tket2/src/passes/tuple_unpack.rs b/tket2/src/passes/tuple_unpack.rs index 84d5875d2..d13a27283 100644 --- a/tket2/src/passes/tuple_unpack.rs +++ b/tket2/src/passes/tuple_unpack.rs @@ -96,10 +96,31 @@ fn remove_pack_unpack( let mut nodes = unpack_nodes; nodes.push(pack_node); let subcirc = Subcircuit::try_from_nodes(nodes, circ).unwrap(); + let subcirc_signature = subcirc.signature(circ); + + // The output port order in `Subcircuit::try_from_nodes` is not too well defined. + // Check that the outputs are in the expected order. + if cfg!(debug) { + let tuple_type = Type::new_tuple(tuple_types.to_vec()); + debug_assert!( + itertools::equal( + subcirc_signature.output().iter(), + tuple_types + .iter() + .cycle() + .take(num_unpack_outputs) + .chain(itertools::repeat_n(&tuple_type, num_other_outputs)) + ), + "Unpacked tuple values must come before tupled values" + ); + } - let mut replacement = DFGBuilder::new(subcirc.signature(circ)).unwrap(); + let mut replacement = DFGBuilder::new(subcirc_signature).unwrap(); let mut outputs = Vec::with_capacity(num_unpack_outputs + num_other_outputs); + // Wire the inputs directly to the unpack outputs + outputs.extend(replacement.input_wires().cycle().take(num_unpack_outputs)); + // If needed, re-add the tuple pack node and connect its output to the tuple outputs. if num_other_outputs > 0 { let op = MakeTuple::new(tuple_types.to_vec().into()); @@ -110,9 +131,6 @@ fn remove_pack_unpack( outputs.extend(std::iter::repeat(tuple).take(num_other_outputs)) } - // Wire the inputs directly to the unpack outputs - outputs.extend(replacement.input_wires().cycle().take(num_unpack_outputs)); - let replacement = replacement .finish_prelude_hugr_with_outputs(outputs) .unwrap_or_else(|e| {