Skip to content

Commit

Permalink
fix: allow function calls in global definitions (#4320)
Browse files Browse the repository at this point in the history
# Description

## Problem\*

Resolves #4318 

## Summary\*

I've added the necessary `Option` handling for us to make calls from the
global context.

## Additional Context



## Documentation\*

Check one:
- [x] No documentation needed.
- [ ] Documentation included in this PR.
- [ ] **[Exceptional Case]** 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.

---------

Co-authored-by: jfecher <[email protected]>
  • Loading branch information
TomAFrench and jfecher authored Feb 9, 2024
1 parent bd15d30 commit 0dc205c
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 14 deletions.
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.follow_bindings(), Type::MutableReference(_)) {
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

0 comments on commit 0dc205c

Please sign in to comment.