From 0a9fdddd3438ba24d1cb8b5dbbdd3c1aa088fcaf Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Mon, 5 Aug 2024 09:50:57 -0300 Subject: [PATCH 1/3] feat: add `Type::as_struct` --- .../src/hir/comptime/interpreter/builtin.rs | 22 +++++++++++++++++++ noir_stdlib/src/meta/typ.nr | 3 +++ .../comptime_type/src/main.nr | 16 ++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index ebdbddb1c41..00a12feb84e 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -61,6 +61,7 @@ impl<'local, 'context> Interpreter<'local, 'context> { "type_as_constant" => type_as_constant(arguments, return_type, location), "type_as_integer" => type_as_integer(arguments, return_type, location), "type_as_slice" => type_as_slice(arguments, return_type, location), + "type_as_struct" => type_as_struct(arguments, return_type, location), "type_as_tuple" => type_as_tuple(arguments, return_type, location), "type_eq" => type_eq(arguments, location), "type_is_bool" => type_is_bool(arguments, location), @@ -550,6 +551,27 @@ fn type_as_slice( }) } +// fn as_struct(self) -> Option<(StructDefinition, [Type])> +fn type_as_struct( + arguments: Vec<(Value, Location)>, + return_type: Type, + location: Location, +) -> IResult { + type_as(arguments, return_type, location, |typ| { + if let Type::Struct(struct_type, generics) = typ { + Some(Value::Tuple(vec![ + Value::StructDefinition(struct_type.borrow().id), + Value::Array( + generics.into_iter().map(Value::Type).collect(), + Type::Quoted(QuotedType::Type), + ), + ])) + } else { + None + } + }) +} + // fn as_tuple(self) -> Option<[Type]> fn type_as_tuple( arguments: Vec<(Value, Location)>, diff --git a/noir_stdlib/src/meta/typ.nr b/noir_stdlib/src/meta/typ.nr index 2a043b373bc..33c0a6799e9 100644 --- a/noir_stdlib/src/meta/typ.nr +++ b/noir_stdlib/src/meta/typ.nr @@ -14,6 +14,9 @@ impl Type { #[builtin(type_as_slice)] fn as_slice(self) -> Option {} + #[builtin(type_as_struct)] + fn as_struct(self) -> Option<(StructDefinition, [Type])> {} + #[builtin(type_as_tuple)] fn as_tuple(self) -> Option<[Type]> {} diff --git a/test_programs/compile_success_empty/comptime_type/src/main.nr b/test_programs/compile_success_empty/comptime_type/src/main.nr index b2b724db6fd..e3a924ee41e 100644 --- a/test_programs/compile_success_empty/comptime_type/src/main.nr +++ b/test_programs/compile_success_empty/comptime_type/src/main.nr @@ -1,5 +1,9 @@ use std::meta::type_of; +struct Foo { + x: T +} + fn main() { comptime { @@ -66,5 +70,17 @@ fn main() { let yes = true; let bool_type = type_of(yes); assert(bool_type.is_bool()); + + // Check Type::as_struct + assert(u8_type.as_struct().is_none()); + + let foo = Foo { x: 0 }; + let foo_type = type_of(foo); + let (struct_definition, generics) = foo_type.as_struct().unwrap(); + let fields = struct_definition.fields(); + assert_eq(fields.len(), 1); + + assert_eq(generics.len(), 1); + assert_eq(generics[0], field_type_1); } } From 004e9ff3313d806c95032c64e7a679bc86e7f603 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Mon, 5 Aug 2024 10:26:20 -0300 Subject: [PATCH 2/3] Return a Slice, not an Array --- compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index 00a12feb84e..f72de81d95b 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -561,7 +561,7 @@ fn type_as_struct( if let Type::Struct(struct_type, generics) = typ { Some(Value::Tuple(vec![ Value::StructDefinition(struct_type.borrow().id), - Value::Array( + Value::Slice( generics.into_iter().map(Value::Type).collect(), Type::Quoted(QuotedType::Type), ), From a3db93f83e2792176d8e2a31a11920161bb0e0eb Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Mon, 5 Aug 2024 14:00:29 -0300 Subject: [PATCH 3/3] Fix slice type --- compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index f72de81d95b..4fb747b74c6 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -563,7 +563,7 @@ fn type_as_struct( Value::StructDefinition(struct_type.borrow().id), Value::Slice( generics.into_iter().map(Value::Type).collect(), - Type::Quoted(QuotedType::Type), + Type::Slice(Box::new(Type::Quoted(QuotedType::Type))), ), ])) } else {