Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: allow function calls in global definitions #4320

Merged
merged 5 commits into from
Feb 9, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 12 additions & 14 deletions compiler/noirc_frontend/src/hir/type_check/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(&current_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);
Expand All @@ -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, Type::MutableReference(_)) {
jfecher marked this conversation as resolved.
Show resolved Hide resolved
self.errors.push(TypeCheckError::ConstrainedReferenceToUnconstrained {
span: self.interner.expr_span(expr_id),
});
return Type::Error;
}
}
}

Expand Down
9 changes: 9 additions & 0 deletions test_programs/execution_success/global_consts/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand Down Expand Up @@ -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 {
Expand Down
Loading