diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index 0efe944fd68..4276f07641c 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -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, @@ -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), @@ -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), @@ -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 { + 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( @@ -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 { + 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, diff --git a/compiler/noirc_frontend/src/hir/comptime/value.rs b/compiler/noirc_frontend/src/hir/comptime/value.rs index 9387e6b1733..04c557552bd 100644 --- a/compiler/noirc_frontend/src/hir/comptime/value.rs +++ b/compiler/noirc_frontend/src/hir/comptime/value.rs @@ -653,7 +653,13 @@ impl<'value, 'interner> Display for ValuePrinter<'value, 'interner> { 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)) => { diff --git a/docs/docs/noir/standard_library/meta/function_def.md b/docs/docs/noir/standard_library/meta/function_def.md index 7c7531fb24a..7503fdaf4c5 100644 --- a/docs/docs/noir/standard_library/meta/function_def.md +++ b/docs/docs/noir/standard_library/meta/function_def.md @@ -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 diff --git a/docs/docs/noir/standard_library/meta/struct_def.md b/docs/docs/noir/standard_library/meta/struct_def.md index 5da4a458d88..221f7fc77e3 100644 --- a/docs/docs/noir/standard_library/meta/struct_def.md +++ b/docs/docs/noir/standard_library/meta/struct_def.md @@ -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 diff --git a/noir_stdlib/src/meta/function_def.nr b/noir_stdlib/src/meta/function_def.nr index 0bff86ef102..67ccd7c6cae 100644 --- a/noir_stdlib/src/meta/function_def.nr +++ b/noir_stdlib/src/meta/function_def.nr @@ -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 {} diff --git a/noir_stdlib/src/meta/struct_def.nr b/noir_stdlib/src/meta/struct_def.nr index 6c0270a8eec..aa71fd6696f 100644 --- a/noir_stdlib/src/meta/struct_def.nr +++ b/noir_stdlib/src/meta/struct_def.nr @@ -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. diff --git a/test_programs/compile_success_empty/comptime_function_definition/src/main.nr b/test_programs/compile_success_empty/comptime_function_definition/src/main.nr index 48651022b31..6fe4efe9d5f 100644 --- a/test_programs/compile_success_empty/comptime_function_definition/src/main.nr +++ b/test_programs/compile_success_empty/comptime_function_definition/src/main.nr @@ -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 }); + } +} diff --git a/test_programs/compile_success_empty/comptime_type_definition/Nargo.toml b/test_programs/compile_success_empty/comptime_struct_definition/Nargo.toml similarity index 69% rename from test_programs/compile_success_empty/comptime_type_definition/Nargo.toml rename to test_programs/compile_success_empty/comptime_struct_definition/Nargo.toml index 099545a9e71..4495d27e028 100644 --- a/test_programs/compile_success_empty/comptime_type_definition/Nargo.toml +++ b/test_programs/compile_success_empty/comptime_struct_definition/Nargo.toml @@ -1,5 +1,5 @@ [package] -name = "comptime_type_definition" +name = "comptime_struct_definition" type = "bin" authors = [""] compiler_version = ">=0.31.0" diff --git a/test_programs/compile_success_empty/comptime_type_definition/src/main.nr b/test_programs/compile_success_empty/comptime_struct_definition/src/main.nr similarity index 78% rename from test_programs/compile_success_empty/comptime_type_definition/src/main.nr rename to test_programs/compile_success_empty/comptime_struct_definition/src/main.nr index aca8d067dde..f2be2bd0d5c 100644 --- a/test_programs/compile_success_empty/comptime_type_definition/src/main.nr +++ b/test_programs/compile_success_empty/comptime_struct_definition/src/main.nr @@ -1,5 +1,3 @@ -fn main() {} - #[my_comptime_fn] struct MyType { field1: [A; 10], @@ -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() {} +