From 4e9308402a55661eb41c86d430d5ec7d10c3c711 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Mon, 3 Feb 2025 14:42:55 -0300 Subject: [PATCH 1/2] Early check type equality in `try_unify` --- compiler/noirc_frontend/src/hir_def/types.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/compiler/noirc_frontend/src/hir_def/types.rs b/compiler/noirc_frontend/src/hir_def/types.rs index a98c892eb34..a79af9a7630 100644 --- a/compiler/noirc_frontend/src/hir_def/types.rs +++ b/compiler/noirc_frontend/src/hir_def/types.rs @@ -1742,6 +1742,13 @@ impl Type { ) -> Result<(), UnificationError> { use Type::*; + // If the two types are exactly the same then they trivially unify. + // This check avoids potentially unifying very complex types (usually infix + // expressions) when they are the same. + if self == other { + return Ok(()); + } + let lhs = self.follow_bindings_shallow(); let rhs = other.follow_bindings_shallow(); From ccf9c99d6d53739d407e141c7f43b2a0b01c1852 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Mon, 3 Feb 2025 14:43:09 -0300 Subject: [PATCH 2/2] Avoid evaluating to field elements at the same time --- .../src/hir_def/types/arithmetic.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/compiler/noirc_frontend/src/hir_def/types/arithmetic.rs b/compiler/noirc_frontend/src/hir_def/types/arithmetic.rs index 5750365c62d..ce9125cd5f0 100644 --- a/compiler/noirc_frontend/src/hir_def/types/arithmetic.rs +++ b/compiler/noirc_frontend/src/hir_def/types/arithmetic.rs @@ -63,12 +63,15 @@ impl Type { let dummy_span = Span::default(); // evaluate_to_field_element also calls canonicalize so if we just called // `self.evaluate_to_field_element(..)` we'd get infinite recursion. - if let (Ok(lhs_value), Ok(rhs_value)) = ( - lhs.evaluate_to_field_element_helper(&kind, dummy_span, run_simplifications), - rhs.evaluate_to_field_element_helper(&kind, dummy_span, run_simplifications), - ) { - if let Ok(result) = op.function(lhs_value, rhs_value, &kind, dummy_span) { - return Type::Constant(result, kind); + if let Ok(lhs_value) = + lhs.evaluate_to_field_element_helper(&kind, dummy_span, run_simplifications) + { + if let Ok(rhs_value) = + rhs.evaluate_to_field_element_helper(&kind, dummy_span, run_simplifications) + { + if let Ok(result) = op.function(lhs_value, rhs_value, &kind, dummy_span) { + return Type::Constant(result, kind); + } } }