From a4f53c9514361db06bed3c38d6870b83d351b63a Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Wed, 24 Jul 2024 14:16:58 -0300 Subject: [PATCH 1/4] fix: let trait calls work in globals --- compiler/noirc_frontend/src/elaborator/mod.rs | 29 +++++++++++++++---- .../trait_call_in_global/Nargo.toml | 6 ++++ .../trait_call_in_global/src/main.nr | 5 ++++ 3 files changed, 34 insertions(+), 6 deletions(-) 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..24a74534e26 100644 --- a/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/compiler/noirc_frontend/src/elaborator/mod.rs @@ -193,6 +193,17 @@ struct FunctionContext { trait_constraints: Vec<(TraitConstraint, ExprId)>, } +impl FunctionContext { + fn default_type_variables(&self) { + for typ in &self.type_variables { + if let Type::TypeVariable(variable, kind) = typ.follow_bindings() { + let msg = "TypeChecker should only track defaultable type vars"; + variable.bind(kind.default_type().expect(msg)); + } + } + } +} + impl<'context> Elaborator<'context> { pub fn new( context: &'context mut Context, @@ -449,14 +460,17 @@ impl<'context> Elaborator<'context> { /// all still-unsolved trait constraints in this context. fn check_and_pop_function_context(&mut self) { let context = self.function_context.pop().expect("Imbalanced function_context pushes"); + context.default_type_variables(); + self.verify_trait_constraints(context); + } - for typ in context.type_variables { - if let Type::TypeVariable(variable, kind) = typ.follow_bindings() { - let msg = "TypeChecker should only track defaultable type vars"; - variable.bind(kind.default_type().expect(msg)); - } - } + /// Similar to `check_and_pop_function_context` but doesn't default all type varialbes. + fn check_trait_constraints_and_pop_function_context(&mut self) { + let context = self.function_context.pop().expect("Imbalanced function_context pushes"); + self.verify_trait_constraints(context); + } + fn verify_trait_constraints(&mut self, context: FunctionContext) { for (mut constraint, expr_id) in context.trait_constraints { let span = self.interner.expr_span(&expr_id); @@ -1339,7 +1353,10 @@ impl<'context> Elaborator<'context> { let comptime = let_stmt.comptime; + self.function_context.push(FunctionContext::default()); let (let_statement, _typ) = self.elaborate_let(let_stmt, Some(global_id)); + self.check_trait_constraints_and_pop_function_context(); + let statement_id = self.interner.get_global(global_id).let_statement; self.interner.replace_statement(statement_id, let_statement); 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..df6c6e7e28e --- /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() { + println(s); +} From 77199dbe479471d3b4aaa57eabc2e78f05733d20 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Wed, 24 Jul 2024 15:05:04 -0300 Subject: [PATCH 2/4] Remove println --- .../compile_success_empty/trait_call_in_global/src/main.nr | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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 index df6c6e7e28e..99f1e3aa008 100644 --- 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 @@ -1,5 +1,3 @@ global s: BoundedVec = From::from([0]); -fn main() { - println(s); -} +fn main() {} From fc4baa3c466a84172f855d6062114c7e6b310047 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Wed, 24 Jul 2024 15:07:54 -0300 Subject: [PATCH 3/4] Use `s` --- .../compile_success_empty/trait_call_in_global/src/main.nr | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 index 99f1e3aa008..775cb5f3b7d 100644 --- 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 @@ -1,3 +1,5 @@ global s: BoundedVec = From::from([0]); -fn main() {} +fn main() { + let _ = s; +} From 0e508b76ee702fe59e5c7d64c25c2719c5fc15c9 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Thu, 25 Jul 2024 10:21:45 -0300 Subject: [PATCH 4/4] Pop function context after finishing elaborating everything --- compiler/noirc_frontend/src/elaborator/mod.rs | 30 +++++-------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/compiler/noirc_frontend/src/elaborator/mod.rs b/compiler/noirc_frontend/src/elaborator/mod.rs index 24a74534e26..1c5f791ac38 100644 --- a/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/compiler/noirc_frontend/src/elaborator/mod.rs @@ -193,17 +193,6 @@ struct FunctionContext { trait_constraints: Vec<(TraitConstraint, ExprId)>, } -impl FunctionContext { - fn default_type_variables(&self) { - for typ in &self.type_variables { - if let Type::TypeVariable(variable, kind) = typ.follow_bindings() { - let msg = "TypeChecker should only track defaultable type vars"; - variable.bind(kind.default_type().expect(msg)); - } - } - } -} - impl<'context> Elaborator<'context> { pub fn new( context: &'context mut Context, @@ -259,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 } @@ -460,17 +450,14 @@ impl<'context> Elaborator<'context> { /// all still-unsolved trait constraints in this context. fn check_and_pop_function_context(&mut self) { let context = self.function_context.pop().expect("Imbalanced function_context pushes"); - context.default_type_variables(); - self.verify_trait_constraints(context); - } - /// Similar to `check_and_pop_function_context` but doesn't default all type varialbes. - fn check_trait_constraints_and_pop_function_context(&mut self) { - let context = self.function_context.pop().expect("Imbalanced function_context pushes"); - self.verify_trait_constraints(context); - } + for typ in context.type_variables { + if let Type::TypeVariable(variable, kind) = typ.follow_bindings() { + let msg = "TypeChecker should only track defaultable type vars"; + variable.bind(kind.default_type().expect(msg)); + } + } - fn verify_trait_constraints(&mut self, context: FunctionContext) { for (mut constraint, expr_id) in context.trait_constraints { let span = self.interner.expr_span(&expr_id); @@ -1353,10 +1340,7 @@ impl<'context> Elaborator<'context> { let comptime = let_stmt.comptime; - self.function_context.push(FunctionContext::default()); let (let_statement, _typ) = self.elaborate_let(let_stmt, Some(global_id)); - self.check_trait_constraints_and_pop_function_context(); - let statement_id = self.interner.get_global(global_id).let_statement; self.interner.replace_statement(statement_id, let_statement);