diff --git a/compiler/noirc_frontend/src/hir/type_check/expr.rs b/compiler/noirc_frontend/src/hir/type_check/expr.rs index 998abeedcec..b3180e0dd20 100644 --- a/compiler/noirc_frontend/src/hir/type_check/expr.rs +++ b/compiler/noirc_frontend/src/hir/type_check/expr.rs @@ -153,11 +153,10 @@ impl<'interner> TypeChecker<'interner> { HirExpression::Call(call_expr) => { // Need to setup these flags here as `self` is borrowed mutably to type check the rest of the call expression // These flags are later used to type check calls to unconstrained functions from constrained functions - let current_func = self - .current_function - .expect("Can only have call expression inside of a function body"); - let func_mod = self.interner.function_modifiers(¤t_func); - let is_current_func_constrained = !func_mod.is_unconstrained; + let current_func = self.current_function; + let func_mod = current_func.map(|func| self.interner.function_modifiers(&func)); + let is_current_func_constrained = + func_mod.map_or(true, |func_mod| !func_mod.is_unconstrained); let is_unconstrained_call = self.is_unconstrained_call(&call_expr.func); self.check_if_deprecated(&call_expr.func); @@ -170,15 +169,14 @@ impl<'interner> TypeChecker<'interner> { }); // Check that we are not passing a mutable reference from a constrained runtime to an unconstrained runtime - for (typ, _, _) in args.iter() { - if is_current_func_constrained - && is_unconstrained_call - && matches!(&typ, Type::MutableReference(_)) - { - self.errors.push(TypeCheckError::ConstrainedReferenceToUnconstrained { - span: self.interner.expr_span(expr_id), - }); - return Type::Error; + if is_current_func_constrained && is_unconstrained_call { + for (typ, _, _) in args.iter() { + if matches!(&typ.follow_bindings(), Type::MutableReference(_)) { + self.errors.push(TypeCheckError::ConstrainedReferenceToUnconstrained { + span: self.interner.expr_span(expr_id), + }); + return Type::Error; + } } } diff --git a/test_programs/execution_success/global_consts/src/main.nr b/test_programs/execution_success/global_consts/src/main.nr index 4b22940b3d1..25cc0e4dd36 100644 --- a/test_programs/execution_success/global_consts/src/main.nr +++ b/test_programs/execution_success/global_consts/src/main.nr @@ -20,6 +20,13 @@ struct Test { global VALS: [Test; 1] = [Test { v: 100 }]; global NESTED = [VALS, VALS]; +unconstrained fn calculate_global_value() -> Field { + 42 +} + +// Regression test for https://github.com/noir-lang/noir/issues/4318 +global CALCULATED_GLOBAL: Field = calculate_global_value(); + fn main( a: [Field; M + N - N], b: [Field; 30 + N / 2], @@ -74,6 +81,8 @@ fn main( foo::from_foo(d); baz::from_baz(c); assert(DERIVED == M + L); + + assert(CALCULATED_GLOBAL == 42); } fn multiplyByM(x: Field) -> Field {