From 8d91f66b8efc3ee82a56ea7da0d2893124f7fa5d Mon Sep 17 00:00:00 2001 From: Seyon Sivarajah Date: Mon, 6 Nov 2023 17:50:34 +0000 Subject: [PATCH] add test for non-dominating edge validation --- src/builder/cfg.rs | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/builder/cfg.rs b/src/builder/cfg.rs index 275782906..7b87caff0 100644 --- a/src/builder/cfg.rs +++ b/src/builder/cfg.rs @@ -325,6 +325,8 @@ mod test { use crate::builder::build_traits::HugrBuilder; use crate::builder::{DataflowSubContainer, ModuleBuilder}; + use crate::hugr::validate::InterGraphEdgeError; + use crate::hugr::ValidationError; use crate::{builder::test::NAT, type_row}; use cool_asserts::assert_matches; @@ -408,17 +410,52 @@ mod test { entry_b.finish_with_outputs(sum, [])? }; - let exit = cfg_builder.exit_block(); let mut middle_b = cfg_builder.simple_block_builder(FunctionType::new(type_row![], type_row![NAT]), 1)?; let middle = { let c = middle_b.load_const(&sum_tuple_const)?; middle_b.finish_with_outputs(c, [inw])? }; + let exit = cfg_builder.exit_block(); cfg_builder.branch(&entry, 0, &middle)?; cfg_builder.branch(&middle, 0, &exit)?; assert_matches!(cfg_builder.finish_prelude_hugr(), Ok(_)); Ok(()) } + + #[test] + fn test_non_dom_edge() -> Result<(), BuildError> { + let mut cfg_builder = CFGBuilder::new(FunctionType::new(type_row![NAT], type_row![NAT]))?; + let sum_tuple_const = + cfg_builder.add_constant(ops::Const::unary_unit_sum(), ExtensionSet::new())?; + let sum_variants = vec![type_row![]]; + let mut middle_b = cfg_builder + .simple_block_builder(FunctionType::new(type_row![NAT], type_row![NAT]), 1)?; + let [inw] = middle_b.input_wires_arr(); + let middle = { + let c = middle_b.load_const(&sum_tuple_const)?; + middle_b.finish_with_outputs(c, [inw])? + }; + + let mut entry_b = + cfg_builder.entry_builder(sum_variants.clone(), type_row![NAT], ExtensionSet::new())?; + let entry = { + let sum = entry_b.load_const(&sum_tuple_const)?; + // entry block uses wire from middle block even though middle block + // does not dominate entry + entry_b.finish_with_outputs(sum, [inw])? + }; + let exit = cfg_builder.exit_block(); + cfg_builder.branch(&entry, 0, &middle)?; + cfg_builder.branch(&middle, 0, &exit)?; + assert_matches!( + cfg_builder.finish_prelude_hugr(), + Err(ValidationError::InterGraphEdgeError( + InterGraphEdgeError::NonDominatedAncestor { .. } + )) + ); + + Ok(()) + } }