Skip to content

Commit f19344c

Browse files
authored
feat: add FunctionDefinition::module and StructDefinition::module (#5956)
# Description ## Problem Resolves #5953 ## Summary ## Additional Context ## Documentation Check one: - [ ] No documentation needed. - [x] 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.
1 parent f57ce85 commit f19344c

File tree

9 files changed

+91
-8
lines changed

9 files changed

+91
-8
lines changed

compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs

+40-4
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,13 @@ use crate::{
2525
FunctionReturnType, IntegerBitSize, LValue, Literal, Statement, StatementKind, UnaryOp,
2626
UnresolvedType, UnresolvedTypeData, Visibility,
2727
},
28-
hir::comptime::{
29-
errors::IResult,
30-
value::{ExprValue, TypedExpr},
31-
InterpreterError, Value,
28+
hir::{
29+
comptime::{
30+
errors::IResult,
31+
value::{ExprValue, TypedExpr},
32+
InterpreterError, Value,
33+
},
34+
def_map::ModuleId,
3235
},
3336
hir_def::function::FunctionBody,
3437
lexer::Lexer,
@@ -102,6 +105,7 @@ impl<'local, 'context> Interpreter<'local, 'context> {
102105
"function_def_has_named_attribute" => {
103106
function_def_has_named_attribute(interner, arguments, location)
104107
}
108+
"function_def_module" => function_def_module(interner, arguments, location),
105109
"function_def_name" => function_def_name(interner, arguments, location),
106110
"function_def_parameters" => function_def_parameters(interner, arguments, location),
107111
"function_def_return_type" => function_def_return_type(interner, arguments, location),
@@ -142,6 +146,7 @@ impl<'local, 'context> Interpreter<'local, 'context> {
142146
"struct_def_has_named_attribute" => {
143147
struct_def_has_named_attribute(interner, arguments, location)
144148
}
149+
"struct_def_module" => struct_def_module(self, arguments, location),
145150
"struct_def_set_fields" => struct_def_set_fields(interner, arguments, location),
146151
"to_le_radix" => to_le_radix(arguments, return_type, location),
147152
"trait_constraint_eq" => trait_constraint_eq(interner, arguments, location),
@@ -399,6 +404,25 @@ fn struct_def_fields(
399404
Ok(Value::Slice(fields, typ))
400405
}
401406

407+
// fn module(self) -> Module
408+
fn struct_def_module(
409+
interpreter: &Interpreter,
410+
arguments: Vec<(Value, Location)>,
411+
location: Location,
412+
) -> IResult<Value> {
413+
let self_argument = check_one_argument(arguments, location)?;
414+
let struct_id = get_struct(self_argument)?;
415+
let struct_module_id = struct_id.module_id();
416+
417+
// A struct's module is its own module. To get the module where its defined we need
418+
// to look for its parent.
419+
let module_data = interpreter.elaborator.get_module(struct_module_id);
420+
let parent_local_id = module_data.parent.expect("Expected struct module parent to exist");
421+
let parent = ModuleId { krate: struct_module_id.krate, local_id: parent_local_id };
422+
423+
Ok(Value::ModuleDefinition(parent))
424+
}
425+
402426
/// fn set_fields(self, new_fields: [(Quoted, Type)]) {}
403427
/// Returns (name, type) pairs of each field of this StructDefinition
404428
fn struct_def_set_fields(
@@ -1827,6 +1851,18 @@ fn function_def_has_named_attribute(
18271851
Ok(Value::Bool(has_named_attribute(&name, attributes, location)))
18281852
}
18291853

1854+
// fn module(self) -> Module
1855+
fn function_def_module(
1856+
interner: &NodeInterner,
1857+
arguments: Vec<(Value, Location)>,
1858+
location: Location,
1859+
) -> IResult<Value> {
1860+
let self_argument = check_one_argument(arguments, location)?;
1861+
let func_id = get_function_def(self_argument)?;
1862+
let module = interner.function_module(func_id);
1863+
Ok(Value::ModuleDefinition(module))
1864+
}
1865+
18301866
// fn name(self) -> Quoted
18311867
fn function_def_name(
18321868
interner: &NodeInterner,

compiler/noirc_frontend/src/hir/comptime/value.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,13 @@ impl<'value, 'interner> Display for ValuePrinter<'value, 'interner> {
653653
Value::FunctionDefinition(function_id) => {
654654
write!(f, "{}", self.interner.function_name(function_id))
655655
}
656-
Value::ModuleDefinition(_) => write!(f, "(module)"),
656+
Value::ModuleDefinition(module_id) => {
657+
if let Some(attributes) = self.interner.try_module_attributes(module_id) {
658+
write!(f, "{}", &attributes.name)
659+
} else {
660+
write!(f, "(crate root)")
661+
}
662+
}
657663
Value::Zeroed(typ) => write!(f, "(zeroed {typ})"),
658664
Value::Type(typ) => write!(f, "{:?}", typ),
659665
Value::Expr(ExprValue::Expression(expr)) => {

docs/docs/noir/standard_library/meta/function_def.md

+6
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ This means any functions called at compile-time are invalid targets for this met
2929

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

32+
### module
33+
34+
#include_code module noir_stdlib/src/meta/function_def.nr rust
35+
36+
Returns the module where the function is defined.
37+
3238
### name
3339

3440
#include_code name noir_stdlib/src/meta/function_def.nr rust

docs/docs/noir/standard_library/meta/struct_def.md

+6
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ Returns each field of this struct as a pair of (field name, field type).
5656

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

59+
### module
60+
61+
#include_code module noir_stdlib/src/meta/struct_def.nr rust
62+
63+
Returns the module where the struct is defined.
64+
5965
### set_fields
6066

6167
#include_code set_fields noir_stdlib/src/meta/struct_def.nr rust

noir_stdlib/src/meta/function_def.nr

+5
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ impl FunctionDefinition {
1414
fn has_named_attribute(self, name: Quoted) -> bool {}
1515
// docs:end:has_named_attribute
1616

17+
#[builtin(function_def_module)]
18+
// docs:start:module
19+
fn module(self) -> Module {}
20+
// docs:end:module
21+
1722
#[builtin(function_def_name)]
1823
// docs:start:name
1924
fn name(self) -> Quoted {}

noir_stdlib/src/meta/struct_def.nr

+5
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ impl StructDefinition {
2929
fn fields(self) -> [(Quoted, Type)] {}
3030
// docs:end:fields
3131

32+
#[builtin(struct_def_module)]
33+
// docs:start:module
34+
fn module(self) -> Module {}
35+
// docs:end:module
36+
3237
/// Sets the fields of this struct to the given fields list.
3338
/// All existing fields of the struct will be overridden with the given fields.
3439
/// Each element of the fields list corresponds to the name and type of a field.

test_programs/compile_success_empty/comptime_function_definition/src/main.nr

+9
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,12 @@ contract some_contract {
6969
fn set_pub_return(f: FunctionDefinition) {
7070
f.set_return_public(true);
7171
}
72+
73+
mod foo {
74+
#[attr]
75+
pub fn some() {}
76+
77+
fn attr(f: FunctionDefinition) {
78+
assert_eq(f.module().name(), quote { foo });
79+
}
80+
}

test_programs/compile_success_empty/comptime_type_definition/Nargo.toml test_programs/compile_success_empty/comptime_struct_definition/Nargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[package]
2-
name = "comptime_type_definition"
2+
name = "comptime_struct_definition"
33
type = "bin"
44
authors = [""]
55
compiler_version = ">=0.31.0"

test_programs/compile_success_empty/comptime_type_definition/src/main.nr test_programs/compile_success_empty/comptime_struct_definition/src/main.nr

+12-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
fn main() {}
2-
31
#[my_comptime_fn]
42
struct MyType<A, B, C> {
53
field1: [A; 10],
@@ -24,3 +22,15 @@ comptime fn mutate_struct_fields(s: StructDefinition) {
2422
];
2523
s.set_fields(fields);
2624
}
25+
26+
mod foo {
27+
#[attr]
28+
struct Foo {}
29+
30+
fn attr(s: StructDefinition) {
31+
assert_eq(s.module().name(), quote { foo });
32+
}
33+
}
34+
35+
fn main() {}
36+

0 commit comments

Comments
 (0)