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(); 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); + } } }