Skip to content

Commit

Permalink
feat: add Type::as_struct (#5680)
Browse files Browse the repository at this point in the history
# Description

## Problem

Part of #5668

## Summary

## Additional Context

None.

## Documentation

Check one:
- [x] No documentation needed.
- [ ] Documentation included in this PR.
- [ ] **[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.
  • Loading branch information
asterite authored Aug 5, 2024
1 parent d466d49 commit ade69a9
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 0 deletions.
22 changes: 22 additions & 0 deletions compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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<Value> {
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::Slice(
generics.into_iter().map(Value::Type).collect(),
Type::Slice(Box::new(Type::Quoted(QuotedType::Type))),
),
]))
} else {
None
}
})
}

// fn as_tuple(self) -> Option<[Type]>
fn type_as_tuple(
arguments: Vec<(Value, Location)>,
Expand Down
3 changes: 3 additions & 0 deletions noir_stdlib/src/meta/typ.nr
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ impl Type {
#[builtin(type_as_slice)]
fn as_slice(self) -> Option<Type> {}

#[builtin(type_as_struct)]
fn as_struct(self) -> Option<(StructDefinition, [Type])> {}

#[builtin(type_as_tuple)]
fn as_tuple(self) -> Option<[Type]> {}

Expand Down
16 changes: 16 additions & 0 deletions test_programs/compile_success_empty/comptime_type/src/main.nr
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use std::meta::type_of;

struct Foo<T> {
x: T
}

fn main() {
comptime
{
Expand Down Expand Up @@ -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);
}
}

0 comments on commit ade69a9

Please sign in to comment.