Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions compiler/noirc_frontend/src/hir_def/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2368,6 +2368,17 @@ impl BinaryTypeOperator {

/// Return the operator that will "undo" this operation if applied to the rhs
fn inverse(self) -> Option<BinaryTypeOperator> {
match self {
BinaryTypeOperator::Addition => Some(BinaryTypeOperator::Subtraction),
BinaryTypeOperator::Subtraction => Some(BinaryTypeOperator::Addition),
BinaryTypeOperator::Multiplication => None,
BinaryTypeOperator::Division => None,
BinaryTypeOperator::Modulo => None,
}
}

/// Return the operator that will "undo" this operation if applied to the rhs
fn approx_inverse(self) -> Option<BinaryTypeOperator> {
match self {
BinaryTypeOperator::Addition => Some(BinaryTypeOperator::Subtraction),
BinaryTypeOperator::Subtraction => Some(BinaryTypeOperator::Addition),
Expand Down
10 changes: 5 additions & 5 deletions compiler/noirc_frontend/src/hir_def/types/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ impl Type {

// Note that this is exact, syntactic equality, not unification.
// `rhs` is expected to already be in canonical form.
if l_op.inverse() != Some(op) || l_rhs.canonicalize() != *rhs {
if l_op.approx_inverse() != Some(op) || l_rhs.canonicalize() != *rhs {
Comment thread
jfecher marked this conversation as resolved.
Outdated
return None;
}

Expand Down Expand Up @@ -204,7 +204,7 @@ impl Type {
(Addition | Subtraction, Addition | Subtraction) => {
// If l_op is a subtraction we want to inverse the rhs operator.
if l_op == Subtraction {
op = op.inverse()?;
op = op.approx_inverse()?;
}
let result = op.function(l_const, r_const, &lhs.infix_kind(rhs))?;
let constant = Type::Constant(result, lhs.infix_kind(rhs));
Expand All @@ -213,7 +213,7 @@ impl Type {
(Multiplication | Division, Multiplication | Division) => {
// If l_op is a division we want to inverse the rhs operator.
if l_op == Division {
op = op.inverse()?;
op = op.approx_inverse()?;
}
// If op is a division we need to ensure it divides evenly
if op == Division && (r_const == 0 || l_const % r_const != 0) {
Expand All @@ -236,7 +236,7 @@ impl Type {
bindings: &mut TypeBindings,
) -> Result<(), UnificationError> {
if let Type::InfixExpr(lhs_a, op_a, rhs_a) = self {
if let Some(inverse) = op_a.inverse() {
if let Some(inverse) = op_a.approx_inverse() {
if let Some(rhs_a_u32) = rhs_a.evaluate_to_u32() {
let rhs_a = Box::new(Type::Constant(rhs_a_u32, lhs_a.infix_kind(rhs_a)));
let new_other = Type::InfixExpr(Box::new(other.clone()), inverse, rhs_a);
Expand All @@ -251,7 +251,7 @@ impl Type {
}

if let Type::InfixExpr(lhs_b, op_b, rhs_b) = other {
if let Some(inverse) = op_b.inverse() {
if let Some(inverse) = op_b.approx_inverse() {
if let Some(rhs_b_u32) = rhs_b.evaluate_to_u32() {
let rhs_b = Box::new(Type::Constant(rhs_b_u32, lhs_b.infix_kind(rhs_b)));
let new_self = Type::InfixExpr(Box::new(self.clone()), inverse, rhs_b);
Expand Down