Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add FunctionDefinition::module and StructDefinition::module #5956

Merged
merged 5 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
44 changes: 40 additions & 4 deletions compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,13 @@ use crate::{
FunctionReturnType, IntegerBitSize, LValue, Literal, Statement, StatementKind, UnaryOp,
UnresolvedType, UnresolvedTypeData, Visibility,
},
hir::comptime::{
errors::IResult,
value::{ExprValue, TypedExpr},
InterpreterError, Value,
hir::{
comptime::{
errors::IResult,
value::{ExprValue, TypedExpr},
InterpreterError, Value,
},
def_map::ModuleId,
},
hir_def::function::FunctionBody,
lexer::Lexer,
Expand Down Expand Up @@ -102,6 +105,7 @@ impl<'local, 'context> Interpreter<'local, 'context> {
"function_def_has_named_attribute" => {
function_def_has_named_attribute(interner, arguments, location)
}
"function_def_module" => function_def_module(interner, arguments, location),
"function_def_name" => function_def_name(interner, arguments, location),
"function_def_parameters" => function_def_parameters(interner, arguments, location),
"function_def_return_type" => function_def_return_type(interner, arguments, location),
Expand Down Expand Up @@ -142,6 +146,7 @@ impl<'local, 'context> Interpreter<'local, 'context> {
"struct_def_has_named_attribute" => {
struct_def_has_named_attribute(interner, arguments, location)
}
"struct_def_module" => struct_def_module(self, arguments, location),
"struct_def_set_fields" => struct_def_set_fields(interner, arguments, location),
"to_le_radix" => to_le_radix(arguments, return_type, location),
"trait_constraint_eq" => trait_constraint_eq(interner, arguments, location),
Expand Down Expand Up @@ -399,6 +404,25 @@ fn struct_def_fields(
Ok(Value::Slice(fields, typ))
}

// fn module(self) -> Module
fn struct_def_module(
interpreter: &Interpreter,
arguments: Vec<(Value, Location)>,
location: Location,
) -> IResult<Value> {
let self_argument = check_one_argument(arguments, location)?;
let struct_id = get_struct(self_argument)?;
let struct_module_id = struct_id.module_id();

// A struct's module is its own module. To get the module where its defined we need
// to look for its parent.
let module_data = interpreter.elaborator.get_module(struct_module_id);
let parent_local_id = module_data.parent.expect("Expected struct module parent to exist");
let parent = ModuleId { krate: struct_module_id.krate, local_id: parent_local_id };

Ok(Value::ModuleDefinition(parent))
}

/// fn set_fields(self, new_fields: [(Quoted, Type)]) {}
/// Returns (name, type) pairs of each field of this StructDefinition
fn struct_def_set_fields(
Expand Down Expand Up @@ -1827,6 +1851,18 @@ fn function_def_has_named_attribute(
Ok(Value::Bool(has_named_attribute(&name, attributes, location)))
}

// fn module(self) -> Module
fn function_def_module(
interner: &NodeInterner,
arguments: Vec<(Value, Location)>,
location: Location,
) -> IResult<Value> {
let self_argument = check_one_argument(arguments, location)?;
let func_id = get_function_def(self_argument)?;
let module = interner.function_module(func_id);
Ok(Value::ModuleDefinition(module))
}

// fn name(self) -> Quoted
fn function_def_name(
interner: &NodeInterner,
Expand Down
8 changes: 7 additions & 1 deletion compiler/noirc_frontend/src/hir/comptime/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@
Value::Expr(ExprValue::Statement(statement))
}

pub(crate) fn lvalue(lvaue: LValue) -> Self {

Check warning on line 98 in compiler/noirc_frontend/src/hir/comptime/value.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (lvaue)
Value::Expr(ExprValue::LValue(lvaue))

Check warning on line 99 in compiler/noirc_frontend/src/hir/comptime/value.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (lvaue)
}

pub(crate) fn get_type(&self) -> Cow<Type> {
Expand Down Expand Up @@ -653,7 +653,13 @@
Value::FunctionDefinition(function_id) => {
write!(f, "{}", self.interner.function_name(function_id))
}
Value::ModuleDefinition(_) => write!(f, "(module)"),
Value::ModuleDefinition(module_id) => {
if let Some(attributes) = self.interner.try_module_attributes(module_id) {
write!(f, "{}", &attributes.name)
} else {
write!(f, "(crate root)")
}
}
Value::Zeroed(typ) => write!(f, "(zeroed {typ})"),
Value::Type(typ) => write!(f, "{:?}", typ),
Value::Expr(ExprValue::Expression(expr)) => {
Expand Down
6 changes: 6 additions & 0 deletions docs/docs/noir/standard_library/meta/function_def.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ This means any functions called at compile-time are invalid targets for this met

Returns true if this function has a custom attribute with the given name.

### module

#include_code module noir_stdlib/src/meta/function_def.nr rust

Returns the module where the function is defined.

### name

#include_code name noir_stdlib/src/meta/function_def.nr rust
Expand Down
6 changes: 6 additions & 0 deletions docs/docs/noir/standard_library/meta/struct_def.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ Returns each field of this struct as a pair of (field name, field type).

Returns true if this struct has a custom attribute with the given name.

### module

#include_code module noir_stdlib/src/meta/struct_def.nr rust

Returns the module where the struct is defined.

### set_fields

#include_code set_fields noir_stdlib/src/meta/struct_def.nr rust
Expand Down
5 changes: 5 additions & 0 deletions noir_stdlib/src/meta/function_def.nr
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ impl FunctionDefinition {
fn has_named_attribute(self, name: Quoted) -> bool {}
// docs:end:has_named_attribute

#[builtin(function_def_module)]
// docs:start:module
fn module(self) -> Module {}
// docs:end:module

#[builtin(function_def_name)]
// docs:start:name
fn name(self) -> Quoted {}
Expand Down
5 changes: 5 additions & 0 deletions noir_stdlib/src/meta/struct_def.nr
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ impl StructDefinition {
fn fields(self) -> [(Quoted, Type)] {}
// docs:end:fields

#[builtin(struct_def_module)]
// docs:start:module
fn module(self) -> Module {}
// docs:end:module

/// Sets the fields of this struct to the given fields list.
/// All existing fields of the struct will be overridden with the given fields.
/// Each element of the fields list corresponds to the name and type of a field.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,12 @@ contract some_contract {
fn set_pub_return(f: FunctionDefinition) {
f.set_return_public(true);
}

mod foo {
#[attr]
pub fn some() {}

fn attr(f: FunctionDefinition) {
assert_eq(f.module().name(), quote { foo });
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "comptime_type_definition"
name = "comptime_struct_definition"
type = "bin"
authors = [""]
compiler_version = ">=0.31.0"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
fn main() {}

#[my_comptime_fn]
struct MyType<A, B, C> {
field1: [A; 10],
Expand All @@ -24,3 +22,15 @@ comptime fn mutate_struct_fields(s: StructDefinition) {
];
s.set_fields(fields);
}

mod foo {
#[attr]
struct Foo {}

fn attr(s: StructDefinition) {
assert_eq(s.module().name(), quote { foo });
}
}

fn main() {}

Loading