From 05039568e317c16cecc173717e63288e7ca3890c Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Thu, 1 Aug 2024 16:21:26 -0300 Subject: [PATCH] feat: add `std::meta::type_of` and `impl Eq for Type` (#5669) # Description ## Problem Part of #5668 ## Summary I originally wanted to just add `type_of`, but in order to test it in some way I thought of comparing two types and checking whether they are equal or not... which required implementing `Eq` for `Type`, which I guess is useful any way. ## Additional Context Another way could have been to be able to turn a `Type` into a string and check that, but there's no unbounded `String` type at comptime... Another way would be to `println` the type and check the program's output, but there's no quick way to do it right now... but I think asserting on equality is fine too, especially because the implementation of `type_of` is very simple. ## Documentation\* Check one: - [ ] No documentation needed. - [ ] Documentation included in this PR. - [x] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../src/hir/comptime/interpreter/builtin.rs | 18 ++++++++++++++++++ noir_stdlib/src/meta/mod.nr | 5 +++++ noir_stdlib/src/meta/typ.nr | 10 ++++++++++ .../comptime_type/Nargo.toml | 7 +++++++ .../comptime_type/src/main.nr | 16 ++++++++++++++++ 5 files changed, 56 insertions(+) create mode 100644 noir_stdlib/src/meta/typ.nr create mode 100644 test_programs/compile_success_empty/comptime_type/Nargo.toml create mode 100644 test_programs/compile_success_empty/comptime_type/src/main.nr diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index b35790fd3d4..1904eaa02b9 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -55,6 +55,8 @@ impl<'local, 'context> Interpreter<'local, 'context> { } "quoted_as_trait_constraint" => quoted_as_trait_constraint(self, arguments, location), "quoted_as_type" => quoted_as_type(self, arguments, location), + "type_eq" => type_eq(arguments, location), + "type_of" => type_of(arguments, location), "zeroed" => zeroed(return_type), _ => { let item = format!("Comptime evaluation for builtin function {name}"); @@ -434,6 +436,22 @@ fn quoted_as_type( Ok(Value::Type(typ)) } +fn type_eq(mut arguments: Vec<(Value, Location)>, location: Location) -> IResult { + check_argument_count(2, &arguments, location)?; + + let value1 = arguments.pop().unwrap().0; + let value2 = arguments.pop().unwrap().0; + Ok(Value::Bool(value1 == value2)) +} + +fn type_of(mut arguments: Vec<(Value, Location)>, location: Location) -> IResult { + check_argument_count(1, &arguments, location)?; + + let value = arguments.pop().unwrap().0; + let typ = value.get_type().into_owned(); + Ok(Value::Type(typ)) +} + // fn constraint_hash(constraint: TraitConstraint) -> Field fn trait_constraint_hash( _interner: &mut NodeInterner, diff --git a/noir_stdlib/src/meta/mod.nr b/noir_stdlib/src/meta/mod.nr index 395f09a453e..351e128fa9a 100644 --- a/noir_stdlib/src/meta/mod.nr +++ b/noir_stdlib/src/meta/mod.nr @@ -1,5 +1,6 @@ mod trait_constraint; mod trait_def; +mod typ; mod type_def; mod quoted; @@ -9,3 +10,7 @@ mod quoted; pub comptime fn unquote(code: Quoted) -> Quoted { code } + +#[builtin(type_of)] +pub comptime fn type_of(x: T) -> Type {} + diff --git a/noir_stdlib/src/meta/typ.nr b/noir_stdlib/src/meta/typ.nr new file mode 100644 index 00000000000..197c41a482c --- /dev/null +++ b/noir_stdlib/src/meta/typ.nr @@ -0,0 +1,10 @@ +use crate::cmp::Eq; + +impl Eq for Type { + fn eq(self, other: Self) -> bool { + type_eq(self, other) + } +} + +#[builtin(type_eq)] +fn type_eq(_first: Type, _second: Type) -> bool {} diff --git a/test_programs/compile_success_empty/comptime_type/Nargo.toml b/test_programs/compile_success_empty/comptime_type/Nargo.toml new file mode 100644 index 00000000000..c5b9ca89240 --- /dev/null +++ b/test_programs/compile_success_empty/comptime_type/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "comptime_type" +type = "bin" +authors = [""] +compiler_version = ">=0.31.0" + +[dependencies] \ No newline at end of file diff --git a/test_programs/compile_success_empty/comptime_type/src/main.nr b/test_programs/compile_success_empty/comptime_type/src/main.nr new file mode 100644 index 00000000000..e74cc0a4d14 --- /dev/null +++ b/test_programs/compile_success_empty/comptime_type/src/main.nr @@ -0,0 +1,16 @@ +use std::meta::type_of; + +fn main() { + comptime + { + // Check type_of works correctly (relies on Eq for Type) + let a_field = 0; + let another_field = 1; + let an_i32: i32 = 0; + let field_type_1 = type_of(a_field); + let field_type_2 = type_of(another_field); + let i32_type = type_of(an_i32); + assert(field_type_1 == field_type_2); + assert(field_type_1 != i32_type); + } +}