diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index d520674c7f0..c3aeac4aec4 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -106,6 +106,9 @@ impl<'local, 'context> Interpreter<'local, 'context> { "function_def_has_named_attribute" => { function_def_has_named_attribute(interner, arguments, location) } + "function_def_is_unconstrained" => { + function_def_is_unconstrained(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), @@ -118,6 +121,9 @@ impl<'local, 'context> Interpreter<'local, 'context> { "function_def_set_return_public" => { function_def_set_return_public(self, arguments, location) } + "function_def_set_unconstrained" => { + function_def_set_unconstrained(self, arguments, location) + } "module_add_item" => module_add_item(self, arguments, location), "module_functions" => module_functions(self, arguments, location), "module_has_named_attribute" => module_has_named_attribute(self, arguments, location), @@ -1927,6 +1933,18 @@ fn function_def_has_named_attribute( Ok(Value::Bool(has_named_attribute(&name, attributes, location))) } +// fn is_unconstrained(self) -> bool +fn function_def_is_unconstrained( + 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 is_unconstrained = interner.function_modifiers(&func_id).is_unconstrained; + Ok(Value::Bool(is_unconstrained)) +} + // fn module(self) -> Module fn function_def_module( interner: &NodeInterner, @@ -2124,6 +2142,25 @@ fn function_def_set_return_public( Ok(Value::Unit) } +// fn set_unconstrained(self, value: bool) +fn function_def_set_unconstrained( + interpreter: &mut Interpreter, + arguments: Vec<(Value, Location)>, + location: Location, +) -> IResult { + let (self_argument, unconstrained) = check_two_arguments(arguments, location)?; + + let func_id = get_function_def(self_argument)?; + check_function_not_yet_resolved(interpreter, func_id, location)?; + + let unconstrained = get_bool(unconstrained)?; + + let modifiers = interpreter.elaborator.interner.function_modifiers_mut(&func_id); + modifiers.is_unconstrained = unconstrained; + + Ok(Value::Unit) +} + // fn add_item(self, item: Quoted) fn module_add_item( interpreter: &mut Interpreter, diff --git a/docs/docs/noir/standard_library/meta/function_def.md b/docs/docs/noir/standard_library/meta/function_def.md index 7503fdaf4c5..7fae5fc381a 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. +### is_unconstrained + +#include_code is_unconstrained noir_stdlib/src/meta/function_def.nr rust + +Returns true if this function is unconstrained. + ### module #include_code module noir_stdlib/src/meta/function_def.nr rust @@ -86,4 +92,12 @@ This means any functions called at compile-time are invalid targets for this met Mutates the function's return visibility to public (if `true` is given) or private (if `false` is given). This is only valid on functions in the current crate which have not yet been resolved. +This means any functions called at compile-time are invalid targets for this method. + +### set_unconstrained + +#include_code set_unconstrained noir_stdlib/src/meta/function_def.nr rust + +Mutates the function to be unconstrained (if `true` is given) or not (if `false` is given). +This is only valid on functions in the current crate which have not yet been resolved. This means any functions called at compile-time are invalid targets for this method. \ No newline at end of file diff --git a/noir_stdlib/src/meta/function_def.nr b/noir_stdlib/src/meta/function_def.nr index 67ccd7c6cae..5ce3dbeabff 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_is_unconstrained)] + // docs:start:is_unconstrained + fn is_unconstrained(self) -> bool {} + // docs:end:is_unconstrained + #[builtin(function_def_module)] // docs:start:module fn module(self) -> Module {} @@ -53,4 +58,9 @@ impl FunctionDefinition { // docs:start:set_return_public fn set_return_public(self, public: bool) {} // docs:end:set_return_public + + #[builtin(function_def_set_unconstrained)] + // docs:start:set_unconstrained + fn set_unconstrained(self, value: bool) {} + // docs:end:set_unconstrained } 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 6fe4efe9d5f..62f119cc0c0 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 @@ -76,5 +76,13 @@ mod foo { fn attr(f: FunctionDefinition) { assert_eq(f.module().name(), quote { foo }); + + assert(!f.is_unconstrained()); + + f.set_unconstrained(true); + assert(f.is_unconstrained()); + + f.set_unconstrained(false); + assert(!f.is_unconstrained()); } }