From 7ca5817f66f386fb69262b7310e142a95e55c70f Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Mon, 15 Jul 2024 09:04:48 -0300 Subject: [PATCH 1/4] fix: let unary traits work at comptime --- .../src/hir/comptime/interpreter.rs | 24 +++++++++++++++++++ .../comptime_traits/src/main.nr | 21 ++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs index 02714f77605..126d0e12ef2 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs @@ -593,6 +593,11 @@ impl<'a> Interpreter<'a> { fn evaluate_prefix(&mut self, prefix: HirPrefixExpression, id: ExprId) -> IResult { let rhs = self.evaluate(prefix.rhs)?; + + if self.interner.get_selected_impl_for_expression(id).is_some() { + return self.evaluate_overloaded_prefix(prefix, rhs, id); + } + self.evaluate_prefix_with_value(rhs, prefix.operator, id) } @@ -925,6 +930,25 @@ impl<'a> Interpreter<'a> { } } + fn evaluate_overloaded_prefix( + &mut self, + prefix: HirPrefixExpression, + rhs: Value, + id: ExprId, + ) -> IResult { + let method = + prefix.trait_method_id.expect("ice: expected prefix operator trait at this point"); + let operator = prefix.operator; + + let method_id = resolve_trait_method(self.interner, method, id)?; + let type_bindings = self.interner.get_instantiation_bindings(id).clone(); + + let rhs = (rhs, self.interner.expr_location(&prefix.rhs)); + + let location = self.interner.expr_location(&id); + self.call_function(method_id, vec![rhs], type_bindings, location) + } + /// Given the result of a `cmp` operation, convert it into the boolean result of the given operator. /// - `<`: `ordering == Ordering::Less` /// - `<=`: `ordering != Ordering::Greater` diff --git a/test_programs/compile_success_empty/comptime_traits/src/main.nr b/test_programs/compile_success_empty/comptime_traits/src/main.nr index 143c9cda274..91e804ef6fd 100644 --- a/test_programs/compile_success_empty/comptime_traits/src/main.nr +++ b/test_programs/compile_success_empty/comptime_traits/src/main.nr @@ -1,3 +1,5 @@ +use std::ops::Neg; + fn main() { comptime { @@ -13,3 +15,22 @@ fn main() { assert([1, 2] != array); } } + +struct MyType { + value: i32, +} + +impl Neg for MyType { + comptime fn neg(self) -> Self { + self + } +} + +fn neg_at_comptime() { + comptime + { + let value = MyType { value: 1 }; + let _result = -value; + } +} + From 10bd82cee8d26c12055e2cbe5bf01117ee60bcf1 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Mon, 15 Jul 2024 11:27:22 -0300 Subject: [PATCH 2/4] Update compiler/noirc_frontend/src/hir/comptime/interpreter.rs Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com> --- compiler/noirc_frontend/src/hir/comptime/interpreter.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs index 126d0e12ef2..3ee3c9a07c0 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs @@ -595,10 +595,10 @@ impl<'a> Interpreter<'a> { let rhs = self.evaluate(prefix.rhs)?; if self.interner.get_selected_impl_for_expression(id).is_some() { - return self.evaluate_overloaded_prefix(prefix, rhs, id); + self.evaluate_overloaded_prefix(prefix, rhs, id); + } else { + self.evaluate_prefix_with_value(rhs, prefix.operator, id) } - - self.evaluate_prefix_with_value(rhs, prefix.operator, id) } fn evaluate_prefix_with_value( From bc1fa77d57658aca3d6b1907cc574eb9d6dd23b5 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 15 Jul 2024 15:43:11 +0100 Subject: [PATCH 3/4] Update compiler/noirc_frontend/src/hir/comptime/interpreter.rs --- compiler/noirc_frontend/src/hir/comptime/interpreter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs index 3ee3c9a07c0..8a2549b5f9a 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs @@ -595,7 +595,7 @@ impl<'a> Interpreter<'a> { let rhs = self.evaluate(prefix.rhs)?; if self.interner.get_selected_impl_for_expression(id).is_some() { - self.evaluate_overloaded_prefix(prefix, rhs, id); + self.evaluate_overloaded_prefix(prefix, rhs, id) } else { self.evaluate_prefix_with_value(rhs, prefix.operator, id) } From 134473c8b9372e95972f8b388f1214d0a2e13d65 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Fri, 19 Jul 2024 11:46:18 -0300 Subject: [PATCH 4/4] Fix test program --- test_programs/compile_success_empty/comptime_traits/src/main.nr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_programs/compile_success_empty/comptime_traits/src/main.nr b/test_programs/compile_success_empty/comptime_traits/src/main.nr index 91e804ef6fd..8b1f81e6594 100644 --- a/test_programs/compile_success_empty/comptime_traits/src/main.nr +++ b/test_programs/compile_success_empty/comptime_traits/src/main.nr @@ -20,7 +20,7 @@ struct MyType { value: i32, } -impl Neg for MyType { +comptime impl Neg for MyType { comptime fn neg(self) -> Self { self }