From c2a1a87a6bcfc161ef5f550a17b603b0bccbab8e Mon Sep 17 00:00:00 2001 From: jfecher Date: Fri, 16 Aug 2024 13:43:14 -0500 Subject: [PATCH] fix: Allow comptime code to use break without also being `unconstrained` (#5744) # Description ## Problem\* Resolves ## Summary\* Allows `comptime` code to use `break` and `continue` without also marking the functions `unconstrained`. This is more important with the `unsafe { }` change since we don't want to have to wrap comptime code in unsafe blocks, nor do we want to mark unconstrained functions used in a comptime block as requiring `unsafe { }`. ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [ ] Documentation included in this PR. - [x] **[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. --- compiler/noirc_frontend/src/elaborator/mod.rs | 11 +++++++---- noir_stdlib/src/meta/mod.nr | 2 +- .../macros_in_comptime/src/main.nr | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/compiler/noirc_frontend/src/elaborator/mod.rs b/compiler/noirc_frontend/src/elaborator/mod.rs index da35ca77316..78241ce95a4 100644 --- a/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/compiler/noirc_frontend/src/elaborator/mod.rs @@ -1458,9 +1458,12 @@ impl<'context> Elaborator<'context> { /// True if we're currently within a constrained function. /// Defaults to `true` if the current function is unknown. fn in_constrained_function(&self) -> bool { - self.current_item.map_or(true, |id| match id { - DependencyId::Function(id) => !self.interner.function_modifiers(&id).is_unconstrained, - _ => true, - }) + !self.in_comptime_context() + && self.current_item.map_or(true, |id| match id { + DependencyId::Function(id) => { + !self.interner.function_modifiers(&id).is_unconstrained + } + _ => true, + }) } } diff --git a/noir_stdlib/src/meta/mod.nr b/noir_stdlib/src/meta/mod.nr index beaee8e44ea..d16a8648bc2 100644 --- a/noir_stdlib/src/meta/mod.nr +++ b/noir_stdlib/src/meta/mod.nr @@ -45,7 +45,7 @@ pub comptime fn derive(s: StructDefinition, traits: [TraitDefinition]) -> Quoted result } -unconstrained pub comptime fn derive_via(t: TraitDefinition, f: DeriveFunction) { +pub comptime fn derive_via(t: TraitDefinition, f: DeriveFunction) { HANDLERS.insert(t, f); } diff --git a/test_programs/compile_success_empty/macros_in_comptime/src/main.nr b/test_programs/compile_success_empty/macros_in_comptime/src/main.nr index 31d08d2762d..c5cc7880112 100644 --- a/test_programs/compile_success_empty/macros_in_comptime/src/main.nr +++ b/test_programs/compile_success_empty/macros_in_comptime/src/main.nr @@ -13,7 +13,7 @@ fn main() { // Call a different function from the interpreter, then have the // elaborator switch to the middle of foo from its previous scope in main -unconstrained comptime fn foo(x: Field) { +comptime fn foo(x: Field) { assert(modulus_num_bits() != 0); let cond = quote { modulus_num_bits() != 0 };