From c02a6f64b1920ec5a1a05e20df34227cc95d7b0a Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Thu, 25 Jul 2024 10:43:43 -0300 Subject: [PATCH] fix: let trait calls work in globals (#5602) # Description ## Problem Resolves #5029 ## Summary Trait constraints weren't checked after elaborating a global. ## Additional Context I couldn't just call `check_and_pop_function_context()` because that also defaults type variables... and if we do that the usage of a global will not have an effect on its type. I guess this is one scenario: ```rust global x = 1; // What's the type of x? ``` We don't know. I guess it ends up being `Field` later on (where?) But if we have this: ```rust global x = 1; fn main() { let y: i32 = 0; assert_eq(x, y); } ``` now x's type will be `i32` because of that comparison. So if we eagerly bind `1` to its default type, this will break. All of this to say: in Rust a global's type (well, for a `const`) must be explicitly specified. I guess that if we also did that in Noir then this wouldn't be a problem. And given that globals are, well, global, it might be strange to have `global x = 1` expecting that to be a Field, used as a Field in many places, but you accidentally compare it to an `i32` and the type changes under the hood. But that's a bigger discussion, so maybe the fix in this PR is good for now? ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[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 | 1 + .../compile_success_empty/trait_call_in_global/Nargo.toml | 6 ++++++ .../compile_success_empty/trait_call_in_global/src/main.nr | 5 +++++ 3 files changed, 12 insertions(+) create mode 100644 test_programs/compile_success_empty/trait_call_in_global/Nargo.toml create mode 100644 test_programs/compile_success_empty/trait_call_in_global/src/main.nr diff --git a/compiler/noirc_frontend/src/elaborator/mod.rs b/compiler/noirc_frontend/src/elaborator/mod.rs index e0affad1fbf..1c5f791ac38 100644 --- a/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/compiler/noirc_frontend/src/elaborator/mod.rs @@ -248,6 +248,7 @@ impl<'context> Elaborator<'context> { let (comptime_items, runtime_items) = Self::filter_comptime_items(items); this.elaborate_items(comptime_items); this.elaborate_items(runtime_items); + this.check_and_pop_function_context(); this } diff --git a/test_programs/compile_success_empty/trait_call_in_global/Nargo.toml b/test_programs/compile_success_empty/trait_call_in_global/Nargo.toml new file mode 100644 index 00000000000..005fec5bf36 --- /dev/null +++ b/test_programs/compile_success_empty/trait_call_in_global/Nargo.toml @@ -0,0 +1,6 @@ +[package] +name = "trait_call_in_global" +type = "bin" +authors = [""] + +[dependencies] diff --git a/test_programs/compile_success_empty/trait_call_in_global/src/main.nr b/test_programs/compile_success_empty/trait_call_in_global/src/main.nr new file mode 100644 index 00000000000..775cb5f3b7d --- /dev/null +++ b/test_programs/compile_success_empty/trait_call_in_global/src/main.nr @@ -0,0 +1,5 @@ +global s: BoundedVec = From::from([0]); + +fn main() { + let _ = s; +}