From b305f323519b7eb632099eed61a3fc1cfcb46bcd Mon Sep 17 00:00:00 2001 From: Alex Vitkov Date: Mon, 11 Sep 2023 14:42:08 +0300 Subject: [PATCH 1/7] Add trait method signature type checks --- compiler/noirc_frontend/src/ast/expression.rs | 9 ++++++++ .../src/hir/def_collector/dc_crate.rs | 2 +- compiler/noirc_frontend/src/hir_def/mod.rs | 1 + .../impl_trait_for_non_type/Nargo.toml | 7 ++++++ .../impl_trait_for_non_type/Prover.toml | 2 ++ .../impl_trait_for_non_type/src/main.nr | 15 +++++++++++++ .../Nargo.toml | 7 ++++++ .../Prover.toml | 2 ++ .../src/main.nr | 21 ++++++++++++++++++ .../trait_wrong_parameter2/Nargo.toml | 7 ++++++ .../trait_wrong_parameter2/Prover.toml | 2 ++ .../trait_wrong_parameter2/src/main.nr | 22 +++++++++++++++++++ .../execution_success/trait_self/Nargo.toml | 7 ++++++ .../execution_success/trait_self/src/main.nr | 18 +++++++++++++++ 14 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 crates/nargo_cli/tests/compile_failure/impl_trait_for_non_type/Nargo.toml create mode 100644 crates/nargo_cli/tests/compile_failure/impl_trait_for_non_type/Prover.toml create mode 100644 crates/nargo_cli/tests/compile_failure/impl_trait_for_non_type/src/main.nr create mode 100644 crates/nargo_cli/tests/compile_failure/trait_wrong_method_return_type2/Nargo.toml create mode 100644 crates/nargo_cli/tests/compile_failure/trait_wrong_method_return_type2/Prover.toml create mode 100644 crates/nargo_cli/tests/compile_failure/trait_wrong_method_return_type2/src/main.nr create mode 100644 crates/nargo_cli/tests/compile_failure/trait_wrong_parameter2/Nargo.toml create mode 100644 crates/nargo_cli/tests/compile_failure/trait_wrong_parameter2/Prover.toml create mode 100644 crates/nargo_cli/tests/compile_failure/trait_wrong_parameter2/src/main.nr create mode 100644 crates/nargo_cli/tests/execution_success/trait_self/Nargo.toml create mode 100644 crates/nargo_cli/tests/execution_success/trait_self/src/main.nr diff --git a/compiler/noirc_frontend/src/ast/expression.rs b/compiler/noirc_frontend/src/ast/expression.rs index 285431d2040..9c3cf373225 100644 --- a/compiler/noirc_frontend/src/ast/expression.rs +++ b/compiler/noirc_frontend/src/ast/expression.rs @@ -689,12 +689,21 @@ impl Display for FunctionDefinition { } impl FunctionReturnType { +<<<<<<< HEAD pub fn get_type(&self) -> Cow { match self { FunctionReturnType::Default(span) => { Cow::Owned(UnresolvedType { typ: UnresolvedTypeData::Unit, span: Some(*span) }) } FunctionReturnType::Ty(typ) => Cow::Borrowed(typ), +======= + pub fn get_type(&self) -> UnresolvedType { + match self { + FunctionReturnType::Default(span) => { + UnresolvedType { typ: UnresolvedTypeData::Unit, span: Some(*span) } + } + FunctionReturnType::Ty(typ) => typ.clone(), +>>>>>>> c200bfeaa (Add trait method signature type checks) } } } diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index 407dafc0e38..24e2224d162 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -11,7 +11,7 @@ use crate::hir::resolution::{ }; use crate::hir::type_check::{type_check_func, TypeCheckError, TypeChecker}; use crate::hir::Context; -use crate::hir_def::traits::{TraitConstant, TraitFunction, TraitType}; +use crate::hir_def::traits::{TraitType, TraitConstant, TraitFunction}; use crate::node_interner::{FuncId, NodeInterner, StmtId, StructId, TraitId, TypeAliasId}; use crate::{ ExpressionKind, Generics, Ident, LetStatement, Literal, NoirFunction, NoirStruct, NoirTrait, diff --git a/compiler/noirc_frontend/src/hir_def/mod.rs b/compiler/noirc_frontend/src/hir_def/mod.rs index 206fc3ddda5..2c5f038953d 100644 --- a/compiler/noirc_frontend/src/hir_def/mod.rs +++ b/compiler/noirc_frontend/src/hir_def/mod.rs @@ -20,3 +20,4 @@ pub mod function; pub mod stmt; pub mod traits; pub mod types; +pub mod traits; diff --git a/crates/nargo_cli/tests/compile_failure/impl_trait_for_non_type/Nargo.toml b/crates/nargo_cli/tests/compile_failure/impl_trait_for_non_type/Nargo.toml new file mode 100644 index 00000000000..35f174bf546 --- /dev/null +++ b/crates/nargo_cli/tests/compile_failure/impl_trait_for_non_type/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "impl_trait_for_non_type" +type = "bin" +authors = [""] +compiler_version = "0.9.0" + +[dependencies] diff --git a/crates/nargo_cli/tests/compile_failure/impl_trait_for_non_type/Prover.toml b/crates/nargo_cli/tests/compile_failure/impl_trait_for_non_type/Prover.toml new file mode 100644 index 00000000000..2c1854573a4 --- /dev/null +++ b/crates/nargo_cli/tests/compile_failure/impl_trait_for_non_type/Prover.toml @@ -0,0 +1,2 @@ +x = 1 +y = 2 diff --git a/crates/nargo_cli/tests/compile_failure/impl_trait_for_non_type/src/main.nr b/crates/nargo_cli/tests/compile_failure/impl_trait_for_non_type/src/main.nr new file mode 100644 index 00000000000..8bd6aae8064 --- /dev/null +++ b/crates/nargo_cli/tests/compile_failure/impl_trait_for_non_type/src/main.nr @@ -0,0 +1,15 @@ +use dep::std; + +trait Default { + fn default(x: Field, y: Field) -> Field; +} + + +impl Default for main { + fn default(x: Field, y: Field) -> Field { + x + y + } +} + +fn main(x: Field, y: Field) { +} diff --git a/crates/nargo_cli/tests/compile_failure/trait_wrong_method_return_type2/Nargo.toml b/crates/nargo_cli/tests/compile_failure/trait_wrong_method_return_type2/Nargo.toml new file mode 100644 index 00000000000..95e3e222ca3 --- /dev/null +++ b/crates/nargo_cli/tests/compile_failure/trait_wrong_method_return_type2/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "trait_wrong_method_return_type" +type = "bin" +authors = [""] +compiler_version = "0.9.0" + +[dependencies] \ No newline at end of file diff --git a/crates/nargo_cli/tests/compile_failure/trait_wrong_method_return_type2/Prover.toml b/crates/nargo_cli/tests/compile_failure/trait_wrong_method_return_type2/Prover.toml new file mode 100644 index 00000000000..2c1854573a4 --- /dev/null +++ b/crates/nargo_cli/tests/compile_failure/trait_wrong_method_return_type2/Prover.toml @@ -0,0 +1,2 @@ +x = 1 +y = 2 diff --git a/crates/nargo_cli/tests/compile_failure/trait_wrong_method_return_type2/src/main.nr b/crates/nargo_cli/tests/compile_failure/trait_wrong_method_return_type2/src/main.nr new file mode 100644 index 00000000000..22d65a2d622 --- /dev/null +++ b/crates/nargo_cli/tests/compile_failure/trait_wrong_method_return_type2/src/main.nr @@ -0,0 +1,21 @@ +use dep::std; + +trait Default { + fn default(x: Field, y: Field) -> Self; +} + +struct Foo { + bar: Field, + array: [Field; 2], +} + +impl Default for Foo { + fn default(x: Field, y: Field) -> Field { + x + } +} + +fn main(x: Field, y: Field) { + let first = Foo::default(x,y); + assert(first == x); +} diff --git a/crates/nargo_cli/tests/compile_failure/trait_wrong_parameter2/Nargo.toml b/crates/nargo_cli/tests/compile_failure/trait_wrong_parameter2/Nargo.toml new file mode 100644 index 00000000000..7299ec69e7a --- /dev/null +++ b/crates/nargo_cli/tests/compile_failure/trait_wrong_parameter2/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "trait_wrong_parameter" +type = "bin" +authors = [""] +compiler_version = "0.9.0" + +[dependencies] \ No newline at end of file diff --git a/crates/nargo_cli/tests/compile_failure/trait_wrong_parameter2/Prover.toml b/crates/nargo_cli/tests/compile_failure/trait_wrong_parameter2/Prover.toml new file mode 100644 index 00000000000..2c1854573a4 --- /dev/null +++ b/crates/nargo_cli/tests/compile_failure/trait_wrong_parameter2/Prover.toml @@ -0,0 +1,2 @@ +x = 1 +y = 2 diff --git a/crates/nargo_cli/tests/compile_failure/trait_wrong_parameter2/src/main.nr b/crates/nargo_cli/tests/compile_failure/trait_wrong_parameter2/src/main.nr new file mode 100644 index 00000000000..6cbc59086db --- /dev/null +++ b/crates/nargo_cli/tests/compile_failure/trait_wrong_parameter2/src/main.nr @@ -0,0 +1,22 @@ +use dep::std; + +trait Default { + fn default(x: Field, y: Field) -> Self; +} + +struct Foo { + bar: Field, + array: [Field; 2], +} + +impl Default for Foo { + fn default(x: Field, y: Foo) -> Self { + Self { bar: x, array: [x, y.bar] } + } +} + +fn main(x: Field, y: Field) { + let foo = Foo { bar: x, array: [x, y] }; + let first = Foo::default(x,foo); + assert(first.bar == x); +} diff --git a/crates/nargo_cli/tests/execution_success/trait_self/Nargo.toml b/crates/nargo_cli/tests/execution_success/trait_self/Nargo.toml new file mode 100644 index 00000000000..0dfaea44862 --- /dev/null +++ b/crates/nargo_cli/tests/execution_success/trait_self/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "trait_self" +type = "bin" +authors = [""] +compiler_version = "0.10.5" + +[dependencies] \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/trait_self/src/main.nr b/crates/nargo_cli/tests/execution_success/trait_self/src/main.nr new file mode 100644 index 00000000000..f4f73822cc3 --- /dev/null +++ b/crates/nargo_cli/tests/execution_success/trait_self/src/main.nr @@ -0,0 +1,18 @@ +struct Foo { + x: Field +} + +trait Asd { + fn asd() -> Self; +} + +impl Asd for Foo { + // the Self should typecheck properly + fn asd() -> Self { + Foo{x: 100} + } +} + +fn main() { + assert(Foo::asd().x == 100); +} \ No newline at end of file From 940420a11096ad586659b316fdaaf55955ea3c28 Mon Sep 17 00:00:00 2001 From: Alex Vitkov Date: Tue, 12 Sep 2023 08:40:09 +0300 Subject: [PATCH 2/7] cleanup --- compiler/noirc_frontend/src/ast/expression.rs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/compiler/noirc_frontend/src/ast/expression.rs b/compiler/noirc_frontend/src/ast/expression.rs index 9c3cf373225..285431d2040 100644 --- a/compiler/noirc_frontend/src/ast/expression.rs +++ b/compiler/noirc_frontend/src/ast/expression.rs @@ -689,21 +689,12 @@ impl Display for FunctionDefinition { } impl FunctionReturnType { -<<<<<<< HEAD pub fn get_type(&self) -> Cow { match self { FunctionReturnType::Default(span) => { Cow::Owned(UnresolvedType { typ: UnresolvedTypeData::Unit, span: Some(*span) }) } FunctionReturnType::Ty(typ) => Cow::Borrowed(typ), -======= - pub fn get_type(&self) -> UnresolvedType { - match self { - FunctionReturnType::Default(span) => { - UnresolvedType { typ: UnresolvedTypeData::Unit, span: Some(*span) } - } - FunctionReturnType::Ty(typ) => typ.clone(), ->>>>>>> c200bfeaa (Add trait method signature type checks) } } } From c29593251543fff0673338fd88b0bb1f5a061f72 Mon Sep 17 00:00:00 2001 From: Alex Vitkov Date: Tue, 12 Sep 2023 08:57:36 +0300 Subject: [PATCH 3/7] cleanup --- .../impl_trait_for_non_type/Nargo.toml | 7 ------ .../impl_trait_for_non_type/Prover.toml | 2 -- .../impl_trait_for_non_type/src/main.nr | 15 ------------ .../Nargo.toml | 7 ------ .../Prover.toml | 2 -- .../src/main.nr | 21 ----------------- .../trait_wrong_parameter2/Nargo.toml | 7 ------ .../trait_wrong_parameter2/Prover.toml | 2 -- .../trait_wrong_parameter2/src/main.nr | 22 ------------------ .../execution_success/trait_self/src/main.nr | 23 +++++++++++++------ 10 files changed, 16 insertions(+), 92 deletions(-) delete mode 100644 crates/nargo_cli/tests/compile_failure/impl_trait_for_non_type/Nargo.toml delete mode 100644 crates/nargo_cli/tests/compile_failure/impl_trait_for_non_type/Prover.toml delete mode 100644 crates/nargo_cli/tests/compile_failure/impl_trait_for_non_type/src/main.nr delete mode 100644 crates/nargo_cli/tests/compile_failure/trait_wrong_method_return_type2/Nargo.toml delete mode 100644 crates/nargo_cli/tests/compile_failure/trait_wrong_method_return_type2/Prover.toml delete mode 100644 crates/nargo_cli/tests/compile_failure/trait_wrong_method_return_type2/src/main.nr delete mode 100644 crates/nargo_cli/tests/compile_failure/trait_wrong_parameter2/Nargo.toml delete mode 100644 crates/nargo_cli/tests/compile_failure/trait_wrong_parameter2/Prover.toml delete mode 100644 crates/nargo_cli/tests/compile_failure/trait_wrong_parameter2/src/main.nr diff --git a/crates/nargo_cli/tests/compile_failure/impl_trait_for_non_type/Nargo.toml b/crates/nargo_cli/tests/compile_failure/impl_trait_for_non_type/Nargo.toml deleted file mode 100644 index 35f174bf546..00000000000 --- a/crates/nargo_cli/tests/compile_failure/impl_trait_for_non_type/Nargo.toml +++ /dev/null @@ -1,7 +0,0 @@ -[package] -name = "impl_trait_for_non_type" -type = "bin" -authors = [""] -compiler_version = "0.9.0" - -[dependencies] diff --git a/crates/nargo_cli/tests/compile_failure/impl_trait_for_non_type/Prover.toml b/crates/nargo_cli/tests/compile_failure/impl_trait_for_non_type/Prover.toml deleted file mode 100644 index 2c1854573a4..00000000000 --- a/crates/nargo_cli/tests/compile_failure/impl_trait_for_non_type/Prover.toml +++ /dev/null @@ -1,2 +0,0 @@ -x = 1 -y = 2 diff --git a/crates/nargo_cli/tests/compile_failure/impl_trait_for_non_type/src/main.nr b/crates/nargo_cli/tests/compile_failure/impl_trait_for_non_type/src/main.nr deleted file mode 100644 index 8bd6aae8064..00000000000 --- a/crates/nargo_cli/tests/compile_failure/impl_trait_for_non_type/src/main.nr +++ /dev/null @@ -1,15 +0,0 @@ -use dep::std; - -trait Default { - fn default(x: Field, y: Field) -> Field; -} - - -impl Default for main { - fn default(x: Field, y: Field) -> Field { - x + y - } -} - -fn main(x: Field, y: Field) { -} diff --git a/crates/nargo_cli/tests/compile_failure/trait_wrong_method_return_type2/Nargo.toml b/crates/nargo_cli/tests/compile_failure/trait_wrong_method_return_type2/Nargo.toml deleted file mode 100644 index 95e3e222ca3..00000000000 --- a/crates/nargo_cli/tests/compile_failure/trait_wrong_method_return_type2/Nargo.toml +++ /dev/null @@ -1,7 +0,0 @@ -[package] -name = "trait_wrong_method_return_type" -type = "bin" -authors = [""] -compiler_version = "0.9.0" - -[dependencies] \ No newline at end of file diff --git a/crates/nargo_cli/tests/compile_failure/trait_wrong_method_return_type2/Prover.toml b/crates/nargo_cli/tests/compile_failure/trait_wrong_method_return_type2/Prover.toml deleted file mode 100644 index 2c1854573a4..00000000000 --- a/crates/nargo_cli/tests/compile_failure/trait_wrong_method_return_type2/Prover.toml +++ /dev/null @@ -1,2 +0,0 @@ -x = 1 -y = 2 diff --git a/crates/nargo_cli/tests/compile_failure/trait_wrong_method_return_type2/src/main.nr b/crates/nargo_cli/tests/compile_failure/trait_wrong_method_return_type2/src/main.nr deleted file mode 100644 index 22d65a2d622..00000000000 --- a/crates/nargo_cli/tests/compile_failure/trait_wrong_method_return_type2/src/main.nr +++ /dev/null @@ -1,21 +0,0 @@ -use dep::std; - -trait Default { - fn default(x: Field, y: Field) -> Self; -} - -struct Foo { - bar: Field, - array: [Field; 2], -} - -impl Default for Foo { - fn default(x: Field, y: Field) -> Field { - x - } -} - -fn main(x: Field, y: Field) { - let first = Foo::default(x,y); - assert(first == x); -} diff --git a/crates/nargo_cli/tests/compile_failure/trait_wrong_parameter2/Nargo.toml b/crates/nargo_cli/tests/compile_failure/trait_wrong_parameter2/Nargo.toml deleted file mode 100644 index 7299ec69e7a..00000000000 --- a/crates/nargo_cli/tests/compile_failure/trait_wrong_parameter2/Nargo.toml +++ /dev/null @@ -1,7 +0,0 @@ -[package] -name = "trait_wrong_parameter" -type = "bin" -authors = [""] -compiler_version = "0.9.0" - -[dependencies] \ No newline at end of file diff --git a/crates/nargo_cli/tests/compile_failure/trait_wrong_parameter2/Prover.toml b/crates/nargo_cli/tests/compile_failure/trait_wrong_parameter2/Prover.toml deleted file mode 100644 index 2c1854573a4..00000000000 --- a/crates/nargo_cli/tests/compile_failure/trait_wrong_parameter2/Prover.toml +++ /dev/null @@ -1,2 +0,0 @@ -x = 1 -y = 2 diff --git a/crates/nargo_cli/tests/compile_failure/trait_wrong_parameter2/src/main.nr b/crates/nargo_cli/tests/compile_failure/trait_wrong_parameter2/src/main.nr deleted file mode 100644 index 6cbc59086db..00000000000 --- a/crates/nargo_cli/tests/compile_failure/trait_wrong_parameter2/src/main.nr +++ /dev/null @@ -1,22 +0,0 @@ -use dep::std; - -trait Default { - fn default(x: Field, y: Field) -> Self; -} - -struct Foo { - bar: Field, - array: [Field; 2], -} - -impl Default for Foo { - fn default(x: Field, y: Foo) -> Self { - Self { bar: x, array: [x, y.bar] } - } -} - -fn main(x: Field, y: Field) { - let foo = Foo { bar: x, array: [x, y] }; - let first = Foo::default(x,foo); - assert(first.bar == x); -} diff --git a/crates/nargo_cli/tests/execution_success/trait_self/src/main.nr b/crates/nargo_cli/tests/execution_success/trait_self/src/main.nr index f4f73822cc3..62e652f4622 100644 --- a/crates/nargo_cli/tests/execution_success/trait_self/src/main.nr +++ b/crates/nargo_cli/tests/execution_success/trait_self/src/main.nr @@ -1,18 +1,27 @@ +trait ATrait { + fn asd() -> Self; +} + struct Foo { x: Field } - -trait Asd { - fn asd() -> Self; +impl ATrait for Foo { + fn asd() -> Self { + // This should pass as Self should be bound to Foo while typechecking this + Foo{x: 100} + } } -impl Asd for Foo { - // the Self should typecheck properly - fn asd() -> Self { +struct Bar { + x: Field +} +impl ATrait for Bar { + // The trait method is declared as returning `Self` + // but explicitly specifying the type in the impl should work + fn asd() -> Bar { Foo{x: 100} } } fn main() { - assert(Foo::asd().x == 100); } \ No newline at end of file From b8ea3e187a9b9ddfacd586f38023287a0527d50e Mon Sep 17 00:00:00 2001 From: Alex Vitkov Date: Tue, 12 Sep 2023 10:29:04 +0300 Subject: [PATCH 4/7] cargo fmt --- compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs | 2 +- compiler/noirc_frontend/src/hir_def/mod.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index 24e2224d162..407dafc0e38 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -11,7 +11,7 @@ use crate::hir::resolution::{ }; use crate::hir::type_check::{type_check_func, TypeCheckError, TypeChecker}; use crate::hir::Context; -use crate::hir_def::traits::{TraitType, TraitConstant, TraitFunction}; +use crate::hir_def::traits::{TraitConstant, TraitFunction, TraitType}; use crate::node_interner::{FuncId, NodeInterner, StmtId, StructId, TraitId, TypeAliasId}; use crate::{ ExpressionKind, Generics, Ident, LetStatement, Literal, NoirFunction, NoirStruct, NoirTrait, diff --git a/compiler/noirc_frontend/src/hir_def/mod.rs b/compiler/noirc_frontend/src/hir_def/mod.rs index 2c5f038953d..206fc3ddda5 100644 --- a/compiler/noirc_frontend/src/hir_def/mod.rs +++ b/compiler/noirc_frontend/src/hir_def/mod.rs @@ -20,4 +20,3 @@ pub mod function; pub mod stmt; pub mod traits; pub mod types; -pub mod traits; From 2e3c0ee22ff4b25366d3acc3d8e078ee7d3602bd Mon Sep 17 00:00:00 2001 From: Yordan Madzhunkov Date: Tue, 12 Sep 2023 14:35:43 +0300 Subject: [PATCH 5/7] Add trait self test with 2 different types --- .../execution_success/trait_self/Nargo.toml | 7 ----- .../execution_success/trait_self/src/main.nr | 27 ------------------- 2 files changed, 34 deletions(-) delete mode 100644 crates/nargo_cli/tests/execution_success/trait_self/Nargo.toml delete mode 100644 crates/nargo_cli/tests/execution_success/trait_self/src/main.nr diff --git a/crates/nargo_cli/tests/execution_success/trait_self/Nargo.toml b/crates/nargo_cli/tests/execution_success/trait_self/Nargo.toml deleted file mode 100644 index 0dfaea44862..00000000000 --- a/crates/nargo_cli/tests/execution_success/trait_self/Nargo.toml +++ /dev/null @@ -1,7 +0,0 @@ -[package] -name = "trait_self" -type = "bin" -authors = [""] -compiler_version = "0.10.5" - -[dependencies] \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/trait_self/src/main.nr b/crates/nargo_cli/tests/execution_success/trait_self/src/main.nr deleted file mode 100644 index 62e652f4622..00000000000 --- a/crates/nargo_cli/tests/execution_success/trait_self/src/main.nr +++ /dev/null @@ -1,27 +0,0 @@ -trait ATrait { - fn asd() -> Self; -} - -struct Foo { - x: Field -} -impl ATrait for Foo { - fn asd() -> Self { - // This should pass as Self should be bound to Foo while typechecking this - Foo{x: 100} - } -} - -struct Bar { - x: Field -} -impl ATrait for Bar { - // The trait method is declared as returning `Self` - // but explicitly specifying the type in the impl should work - fn asd() -> Bar { - Foo{x: 100} - } -} - -fn main() { -} \ No newline at end of file From e902a9b04837a884ed53b131b526612e3619f10a Mon Sep 17 00:00:00 2001 From: Alex Vitkov Date: Fri, 15 Sep 2023 09:39:56 +0300 Subject: [PATCH 6/7] Implement trait constraints early passes --- compiler/noirc_frontend/src/ast/expression.rs | 8 +- compiler/noirc_frontend/src/ast/traits.rs | 19 +-- .../src/hir/def_collector/dc_crate.rs | 23 +++- .../src/hir/def_collector/dc_mod.rs | 124 ++++++++++-------- .../src/hir/def_map/item_scope.rs | 21 ++- .../src/hir/def_map/module_data.rs | 6 +- .../src/hir/resolution/resolver.rs | 19 ++- .../noirc_frontend/src/hir_def/function.rs | 3 + compiler/noirc_frontend/src/node_interner.rs | 48 +++---- compiler/noirc_frontend/src/parser/mod.rs | 10 +- compiler/noirc_frontend/src/parser/parser.rs | 28 ++-- 11 files changed, 190 insertions(+), 119 deletions(-) diff --git a/compiler/noirc_frontend/src/ast/expression.rs b/compiler/noirc_frontend/src/ast/expression.rs index 285431d2040..62e033b3332 100644 --- a/compiler/noirc_frontend/src/ast/expression.rs +++ b/compiler/noirc_frontend/src/ast/expression.rs @@ -3,8 +3,8 @@ use std::fmt::Display; use crate::token::{Attributes, Token}; use crate::{ - Distinctness, Ident, Path, Pattern, Recoverable, Statement, TraitConstraint, UnresolvedType, - UnresolvedTypeData, Visibility, + Distinctness, Ident, Path, Pattern, Recoverable, Statement, UnresolvedTraitConstraint, + UnresolvedType, UnresolvedTypeData, Visibility, }; use acvm::FieldElement; use iter_extended::vecmap; @@ -368,7 +368,7 @@ pub struct FunctionDefinition { pub parameters: Vec<(Pattern, UnresolvedType, Visibility)>, pub body: BlockExpression, pub span: Span, - pub where_clause: Vec, + pub where_clause: Vec, pub return_type: FunctionReturnType, pub return_visibility: Visibility, pub return_distinctness: Distinctness, @@ -634,7 +634,7 @@ impl FunctionDefinition { generics: &UnresolvedGenerics, parameters: &[(Ident, UnresolvedType)], body: &BlockExpression, - where_clause: &[TraitConstraint], + where_clause: &[UnresolvedTraitConstraint], return_type: &FunctionReturnType, ) -> FunctionDefinition { let p = parameters diff --git a/compiler/noirc_frontend/src/ast/traits.rs b/compiler/noirc_frontend/src/ast/traits.rs index 0120b70e5e8..4078ea72cbe 100644 --- a/compiler/noirc_frontend/src/ast/traits.rs +++ b/compiler/noirc_frontend/src/ast/traits.rs @@ -4,8 +4,8 @@ use iter_extended::vecmap; use noirc_errors::Span; use crate::{ - BlockExpression, Expression, FunctionReturnType, Ident, NoirFunction, UnresolvedGenerics, - UnresolvedType, + node_interner::TraitId, BlockExpression, Expression, FunctionReturnType, Ident, NoirFunction, + UnresolvedGenerics, UnresolvedType, }; /// AST node for trait definitions: @@ -14,7 +14,7 @@ use crate::{ pub struct NoirTrait { pub name: Ident, pub generics: Vec, - pub where_clause: Vec, + pub where_clause: Vec, pub span: Span, pub items: Vec, } @@ -28,7 +28,7 @@ pub enum TraitItem { generics: Vec, parameters: Vec<(Ident, UnresolvedType)>, return_type: FunctionReturnType, - where_clause: Vec, + where_clause: Vec, body: Option, }, Constant { @@ -54,7 +54,7 @@ pub struct TypeImpl { /// Ast node for an implementation of a trait for a particular type /// `impl trait_name for object_type where where_clauses { ... items ... }` #[derive(Clone, Debug)] -pub struct TraitImpl { +pub struct NoirTraitImpl { pub impl_generics: UnresolvedGenerics, pub trait_name: Ident, @@ -63,7 +63,7 @@ pub struct TraitImpl { pub object_type: UnresolvedType, pub object_type_span: Span, - pub where_clause: Vec, + pub where_clause: Vec, pub items: Vec, } @@ -75,7 +75,7 @@ pub struct TraitImpl { /// `Foo: TraitX` /// `Foo: TraitY` #[derive(Clone, Debug, PartialEq, Eq)] -pub struct TraitConstraint { +pub struct UnresolvedTraitConstraint { pub typ: UnresolvedType, pub trait_bound: TraitBound, } @@ -84,6 +84,7 @@ pub struct TraitConstraint { #[derive(Clone, Debug, PartialEq, Eq)] pub struct TraitBound { pub trait_name: Ident, + pub trait_id: Option, // initially None, gets assigned during DC pub trait_generics: Vec, } @@ -167,7 +168,7 @@ impl Display for TraitItem { } } -impl Display for TraitConstraint { +impl Display for UnresolvedTraitConstraint { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}: {}", self.typ, self.trait_bound) } @@ -184,7 +185,7 @@ impl Display for TraitBound { } } -impl Display for TraitImpl { +impl Display for NoirTraitImpl { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let generics = vecmap(&self.trait_generics, |generic| generic.to_string()); let generics = generics.join(", "); diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index 407dafc0e38..ad16d7cf1bc 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -11,8 +11,10 @@ use crate::hir::resolution::{ }; use crate::hir::type_check::{type_check_func, TypeCheckError, TypeChecker}; use crate::hir::Context; -use crate::hir_def::traits::{TraitConstant, TraitFunction, TraitType}; -use crate::node_interner::{FuncId, NodeInterner, StmtId, StructId, TraitId, TypeAliasId}; +use crate::hir_def::traits::{TraitConstant, TraitFunction, TraitImpl, TraitType}; +use crate::node_interner::{ + FuncId, NodeInterner, StmtId, StructId, TraitId, TraitImplKey, TypeAliasId, +}; use crate::{ ExpressionKind, Generics, Ident, LetStatement, Literal, NoirFunction, NoirStruct, NoirTrait, NoirTypeAlias, ParsedModule, Shared, StructType, TraitItem, Type, TypeBinding, @@ -696,6 +698,13 @@ fn resolve_trait_impls( errors, ); + let resolved_trait_impl = Shared::new(TraitImpl { + ident: trait_impl.trait_impl_ident.clone(), + typ: self_type.clone(), + trait_id, + methods: vecmap(&impl_methods, |(_, func_id)| *func_id), + }); + let mut new_resolver = Resolver::new(interner, &path_resolver, &context.def_maps, trait_impl.file_id); new_resolver.set_self_type(Some(self_type.clone())); @@ -703,17 +712,17 @@ fn resolve_trait_impls( check_methods_signatures(&mut new_resolver, &impl_methods, trait_id, errors); let trait_definition_ident = &trait_impl.trait_impl_ident; - let key = (self_type.clone(), trait_id); - if let Some(prev_trait_impl_ident) = interner.get_previous_trait_implementation(&key) { + let key = TraitImplKey { typ: self_type.clone(), trait_id }; + + if let Some(prev_trait_impl_ident) = interner.get_trait_implementation(&key) { let err = DefCollectorErrorKind::Duplicate { typ: DuplicateType::TraitImplementation, - first_def: prev_trait_impl_ident.clone(), + first_def: prev_trait_impl_ident.borrow().ident.clone(), second_def: trait_definition_ident.clone(), }; errors.push(err.into_file_diagnostic(trait_impl.methods.file_id)); } else { - let _func_ids = - interner.add_trait_implementaion(&key, trait_definition_ident, &trait_impl.methods); + interner.add_trait_implementation(&key, resolved_trait_impl.clone()); } methods.append(&mut impl_methods); diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs index a72e30ea97e..63539787e1f 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -5,11 +5,14 @@ use noirc_errors::{FileDiagnostic, Location}; use crate::{ graph::CrateId, - hir::def_collector::dc_crate::{UnresolvedStruct, UnresolvedTrait}, + hir::{ + def_collector::dc_crate::{UnresolvedStruct, UnresolvedTrait}, + def_map::ScopeResolveError, + }, node_interner::TraitId, parser::SubModule, - FunctionDefinition, Ident, LetStatement, NoirFunction, NoirStruct, NoirTrait, NoirTypeAlias, - ParsedModule, TraitImpl, TraitImplItem, TraitItem, TypeImpl, + FunctionDefinition, Ident, LetStatement, NoirFunction, NoirStruct, NoirTrait, NoirTraitImpl, + NoirTypeAlias, ParsedModule, TraitImplItem, TraitItem, TypeImpl, }; use super::{ @@ -19,7 +22,7 @@ use super::{ }, errors::{DefCollectorErrorKind, DuplicateType}, }; -use crate::hir::def_map::{parse_file, LocalModuleId, ModuleData, ModuleDefId, ModuleId}; +use crate::hir::def_map::{parse_file, LocalModuleId, ModuleData, ModuleId}; use crate::hir::resolution::import::ImportDirective; use crate::hir::Context; @@ -131,73 +134,71 @@ impl<'a> ModCollector<'a> { fn collect_trait_impls( &mut self, context: &mut Context, - impls: Vec, + impls: Vec, errors: &mut Vec, ) { for trait_impl in impls { - let trait_name = trait_impl.trait_name.clone(); + let trait_name = &trait_impl.trait_name; let module = &self.def_collector.def_map.modules[self.module_id.0]; - match module.find_name(&trait_name).types { - Some((module_def_id, _visibility)) => { - if let Some(collected_trait) = self.get_unresolved_trait(module_def_id) { - let unresolved_functions = self.collect_trait_implementations( - context, - &trait_impl, - &collected_trait.trait_def, - errors, - ); - - for (_, func_id, noir_function) in &unresolved_functions.functions { - let name = noir_function.name().to_owned(); - - context.def_interner.push_function_definition(name, *func_id); - } - let unresolved_trait_impl = UnresolvedTraitImpl { - file_id: self.file_id, - module_id: self.module_id, - the_trait: collected_trait, - methods: unresolved_functions, - trait_impl_ident: trait_impl.trait_name.clone(), - }; - - let trait_id = match module_def_id { - ModuleDefId::TraitId(trait_id) => trait_id, - _ => unreachable!(), - }; - - let key = (trait_impl.object_type, self.module_id, trait_id); - self.def_collector - .collected_traits_impls - .insert(key, unresolved_trait_impl); - } else { - let error = DefCollectorErrorKind::NotATrait { - not_a_trait_name: trait_name.clone(), - }; - errors.push(error.into_file_diagnostic(self.file_id)); - } - } - None => { - let error = DefCollectorErrorKind::TraitNotFound { trait_ident: trait_name }; - errors.push(error.into_file_diagnostic(self.file_id)); + if let Some(trait_id) = self.find_trait_or_emit_error(module, trait_name, errors) { + let collected_trait = + self.def_collector.collected_traits.get(&trait_id).cloned().unwrap(); + + let unresolved_functions = self.collect_trait_implementations( + context, + &trait_impl, + &collected_trait.trait_def, + errors, + ); + + for (_, func_id, noir_function) in &unresolved_functions.functions { + let name = noir_function.name().to_owned(); + + context.def_interner.push_function_definition(name, *func_id); } + + let unresolved_trait_impl = UnresolvedTraitImpl { + file_id: self.file_id, + module_id: self.module_id, + the_trait: collected_trait, + methods: unresolved_functions, + trait_impl_ident: trait_impl.trait_name.clone(), + }; + + let key = (trait_impl.object_type, self.module_id, trait_id); + self.def_collector.collected_traits_impls.insert(key, unresolved_trait_impl); } } } - fn get_unresolved_trait(&self, module_def_id: ModuleDefId) -> Option { - match module_def_id { - ModuleDefId::TraitId(trait_id) => { - self.def_collector.collected_traits.get(&trait_id).cloned() + fn find_trait_or_emit_error( + &self, + module: &ModuleData, + trait_name: &Ident, + errors: &mut Vec, + ) -> Option { + match module.find_trait_with_name(trait_name) { + Ok(trait_id) => Some(trait_id), + Err(ScopeResolveError::WrongKind) => { + let error = + DefCollectorErrorKind::NotATrait { not_a_trait_name: trait_name.clone() }; + errors.push(error.into_file_diagnostic(self.file_id)); + None + } + Err(ScopeResolveError::NotFound) => { + let error = + DefCollectorErrorKind::TraitNotFound { trait_ident: trait_name.clone() }; + errors.push(error.into_file_diagnostic(self.file_id)); + None } - _ => None, } } fn collect_trait_implementations( &mut self, context: &mut Context, - trait_impl: &TraitImpl, + trait_impl: &NoirTraitImpl, trait_def: &NoirTrait, errors: &mut Vec, ) -> UnresolvedFunctions { @@ -296,7 +297,7 @@ impl<'a> ModCollector<'a> { let mut unresolved_functions = UnresolvedFunctions { file_id: self.file_id, functions: Vec::new() }; - for function in functions { + for mut function in functions { let name = function.name_ident().clone(); // First create dummy function in the DefInterner @@ -304,6 +305,19 @@ impl<'a> ModCollector<'a> { let func_id = context.def_interner.push_empty_fn(); context.def_interner.push_function_definition(name.0.contents.clone(), func_id); + // Then go over the where clause and assign trait_ids to the constraints + for constraint in &mut function.def.where_clause { + let module = &self.def_collector.def_map.modules[self.module_id.0]; + + if let Some(trait_id) = self.find_trait_or_emit_error( + module, + &constraint.trait_bound.trait_name, + errors, + ) { + constraint.trait_bound.trait_id = Some(trait_id); + } + } + // Now link this func_id to a crate level map with the noir function and the module id // Encountering a NoirFunction, we retrieve it's module_data to get the namespace // Once we have lowered it to a HirFunction, we retrieve it's Id from the DefInterner diff --git a/compiler/noirc_frontend/src/hir/def_map/item_scope.rs b/compiler/noirc_frontend/src/hir/def_map/item_scope.rs index 7dcc5051a0c..490e046a9d9 100644 --- a/compiler/noirc_frontend/src/hir/def_map/item_scope.rs +++ b/compiler/noirc_frontend/src/hir/def_map/item_scope.rs @@ -1,5 +1,8 @@ use super::{namespace::PerNs, ModuleDefId, ModuleId}; -use crate::{node_interner::FuncId, Ident}; +use crate::{ + node_interner::{FuncId, TraitId}, + Ident, +}; use std::collections::{hash_map::Entry, HashMap}; #[derive(Debug, PartialEq, Eq, Copy, Clone)] @@ -15,6 +18,14 @@ pub struct ItemScope { defs: Vec, } +pub enum ScopeResolveError { + /// the ident we attempted to resolve isn't declared + NotFound, + + /// The ident we attempted to resolve is declared, but is the wrong kind - e.g. we want a trait, but it's a function + WrongKind, +} + impl ItemScope { pub fn add_definition( &mut self, @@ -69,6 +80,14 @@ impl ItemScope { _ => None, } } + pub fn find_trait_with_name(&self, trait_name: &Ident) -> Result { + let (module_def, _) = self.types.get(trait_name).ok_or(ScopeResolveError::NotFound)?; + + match module_def { + ModuleDefId::TraitId(id) => Ok(*id), + _ => Err(ScopeResolveError::WrongKind), + } + } pub fn find_name(&self, name: &Ident) -> PerNs { PerNs { types: self.types.get(name).cloned(), values: self.values.get(name).cloned() } diff --git a/compiler/noirc_frontend/src/hir/def_map/module_data.rs b/compiler/noirc_frontend/src/hir/def_map/module_data.rs index 1a5b1692208..1f1fa44108d 100644 --- a/compiler/noirc_frontend/src/hir/def_map/module_data.rs +++ b/compiler/noirc_frontend/src/hir/def_map/module_data.rs @@ -7,7 +7,7 @@ use crate::{ Ident, }; -use super::{ItemScope, LocalModuleId, ModuleDefId, ModuleId, PerNs}; +use super::{ItemScope, LocalModuleId, ModuleDefId, ModuleId, PerNs, ScopeResolveError}; /// Contains the actual contents of a module: its parent (if one exists), /// children, and scope with all definitions defined within the scope. @@ -85,6 +85,10 @@ impl ModuleData { self.scope.find_func_with_name(name) } + pub fn find_trait_with_name(&self, name: &Ident) -> Result { + self.scope.find_trait_with_name(name) + } + pub fn import(&mut self, name: Ident, id: ModuleDefId) -> Result<(), (Ident, Ident)> { self.scope.add_item_to_namespace(name, id) } diff --git a/compiler/noirc_frontend/src/hir/resolution/resolver.rs b/compiler/noirc_frontend/src/hir/resolution/resolver.rs index ddc2d38b2f7..4d8f9524fba 100644 --- a/compiler/noirc_frontend/src/hir/resolution/resolver.rs +++ b/compiler/noirc_frontend/src/hir/resolution/resolver.rs @@ -17,7 +17,7 @@ use crate::hir_def::expr::{ HirIfExpression, HirIndexExpression, HirInfixExpression, HirLambda, HirLiteral, HirMemberAccess, HirMethodCallExpression, HirPrefixExpression, }; -use crate::hir_def::traits::Trait; +use crate::hir_def::traits::{Trait, TraitConstraint}; use crate::token::PrimaryAttribute; use regex::Regex; use std::collections::{BTreeMap, HashSet}; @@ -37,8 +37,8 @@ use crate::{ use crate::{ ArrayLiteral, ContractFunctionType, Distinctness, Generics, LValue, NoirStruct, NoirTypeAlias, Path, Pattern, Shared, StructType, Type, TypeAliasType, TypeBinding, TypeVariable, UnaryOp, - UnresolvedGenerics, UnresolvedType, UnresolvedTypeData, UnresolvedTypeExpression, Visibility, - ERROR_IDENT, + UnresolvedGenerics, UnresolvedTraitConstraint, UnresolvedType, UnresolvedTypeData, + UnresolvedTypeExpression, Visibility, ERROR_IDENT, }; use fm::FileId; use iter_extended::vecmap; @@ -669,6 +669,18 @@ impl<'a> Resolver<'a> { } } + /// TODO: This is currently only respected for generic free functions + /// there's a bunch of other places where this guy can pop up + fn resolve_trait_constraints( + &mut self, + where_clause: &Vec, + ) -> Vec { + vecmap(where_clause, |constraint| TraitConstraint { + typ: self.resolve_type(constraint.typ.clone()), + trait_id: constraint.trait_bound.trait_id, + }) + } + /// Extract metadata from a NoirFunction /// to be used in analysis and intern the function parameters /// Prerequisite: self.add_generics() has already been called with the given @@ -767,6 +779,7 @@ impl<'a> Resolver<'a> { return_visibility: func.def.return_visibility, return_distinctness: func.def.return_distinctness, has_body: !func.def.body.is_empty(), + trait_constraints: self.resolve_trait_constraints(&func.def.where_clause), } } diff --git a/compiler/noirc_frontend/src/hir_def/function.rs b/compiler/noirc_frontend/src/hir_def/function.rs index c552100c919..d5d3047c972 100644 --- a/compiler/noirc_frontend/src/hir_def/function.rs +++ b/compiler/noirc_frontend/src/hir_def/function.rs @@ -3,6 +3,7 @@ use noirc_errors::{Location, Span}; use super::expr::{HirBlockExpression, HirExpression, HirIdent}; use super::stmt::HirPattern; +use super::traits::TraitConstraint; use crate::hir::def_map::ModuleId; use crate::node_interner::{ExprId, NodeInterner}; use crate::{token::Attributes, FunctionKind}; @@ -130,6 +131,8 @@ pub struct FuncMeta { // This flag is needed for the attribute check pass pub has_body: bool, + + pub trait_constraints: Vec, } impl FuncMeta { diff --git a/compiler/noirc_frontend/src/node_interner.rs b/compiler/noirc_frontend/src/node_interner.rs index 10a007bdbdb..ae99f10157c 100644 --- a/compiler/noirc_frontend/src/node_interner.rs +++ b/compiler/noirc_frontend/src/node_interner.rs @@ -7,18 +7,17 @@ use noirc_errors::{Location, Span, Spanned}; use crate::ast::Ident; use crate::graph::CrateId; -use crate::hir::def_collector::dc_crate::{ - UnresolvedFunctions, UnresolvedStruct, UnresolvedTrait, UnresolvedTypeAlias, -}; +use crate::hir::def_collector::dc_crate::{UnresolvedStruct, UnresolvedTrait, UnresolvedTypeAlias}; use crate::hir::def_map::{LocalModuleId, ModuleId}; use crate::hir::StorageSlot; use crate::hir_def::stmt::HirLetStatement; +use crate::hir_def::traits::Trait; +use crate::hir_def::traits::TraitImpl; use crate::hir_def::types::{StructType, Type}; use crate::hir_def::{ expr::HirExpression, function::{FuncMeta, HirFunction}, stmt::HirStatement, - traits::Trait, }; use crate::token::Attributes; use crate::{ @@ -26,6 +25,13 @@ use crate::{ TypeVariableKind, }; +#[derive(Eq, PartialEq, Hash, Clone)] +pub struct TraitImplKey { + pub typ: Type, + pub trait_id: TraitId, + // pub generics: Generics - TODO +} + /// The node interner is the central storage location of all nodes in Noir's Hir (the /// various node types can be found in hir_def). The interner is also used to collect /// extra information about the Hir, such as the type of each node, information about @@ -78,7 +84,7 @@ pub struct NodeInterner { // Trait implementation map // For each type that implements a given Trait ( corresponding TraitId), there should be an entry here // The purpose for this hashmap is to detect duplication of trait implementations ( if any ) - trait_implementaions: HashMap<(Type, TraitId), Ident>, + trait_implementations: HashMap>, /// Map from ExprId (referring to a Function/Method call) to its corresponding TypeBindings, /// filled out during type checking from instantiated variables. Used during monomorphization @@ -193,6 +199,12 @@ impl TraitId { } } +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub struct TraitMethodId { + pub trait_id: TraitId, + pub method_index: usize, // index in Trait::methods +} + macro_rules! into_index { ($id_type:ty) => { impl From<$id_type> for Index { @@ -306,7 +318,7 @@ impl Default for NodeInterner { structs: HashMap::new(), type_aliases: Vec::new(), traits: HashMap::new(), - trait_implementaions: HashMap::new(), + trait_implementations: HashMap::new(), instantiation_bindings: HashMap::new(), field_indices: HashMap::new(), next_type_variable_id: 0, @@ -721,24 +733,16 @@ impl NodeInterner { } } - pub fn get_previous_trait_implementation(&self, key: &(Type, TraitId)) -> Option<&Ident> { - self.trait_implementaions.get(key) + pub fn get_trait_implementation(&self, key: &TraitImplKey) -> Option> { + self.trait_implementations.get(key).cloned() } - pub fn add_trait_implementaion( - &mut self, - key: &(Type, TraitId), - trait_definition_ident: &Ident, - methods: &UnresolvedFunctions, - ) -> Vec { - self.trait_implementaions.insert(key.clone(), trait_definition_ident.clone()); - methods - .functions - .iter() - .flat_map(|(_, func_id, _)| { - self.add_method(&key.0, self.function_name(func_id).to_owned(), *func_id) - }) - .collect::>() + pub fn add_trait_implementation(&mut self, key: &TraitImplKey, trait_impl: Shared) { + self.trait_implementations.insert(key.clone(), trait_impl.clone()); + + for func_id in &trait_impl.borrow().methods { + self.add_method(&key.typ, self.function_name(func_id).to_owned(), *func_id); + } } /// Search by name for a method on the given struct diff --git a/compiler/noirc_frontend/src/parser/mod.rs b/compiler/noirc_frontend/src/parser/mod.rs index 64f8c077648..efd85861235 100644 --- a/compiler/noirc_frontend/src/parser/mod.rs +++ b/compiler/noirc_frontend/src/parser/mod.rs @@ -17,8 +17,8 @@ use crate::token::{Keyword, Token}; use crate::{ast::ImportStatement, Expression, NoirStruct}; use crate::{ BlockExpression, ExpressionKind, ForExpression, Ident, IndexExpression, LetStatement, - MethodCallExpression, NoirFunction, NoirTrait, NoirTypeAlias, Path, PathKind, Pattern, - Recoverable, Statement, TraitImpl, TypeImpl, UnresolvedType, UseTree, + MethodCallExpression, NoirFunction, NoirTrait, NoirTraitImpl, NoirTypeAlias, Path, PathKind, + Pattern, Recoverable, Statement, TypeImpl, UnresolvedType, UseTree, }; use acvm::FieldElement; @@ -41,7 +41,7 @@ pub(crate) enum TopLevelStatement { Import(UseTree), Struct(NoirStruct), Trait(NoirTrait), - TraitImpl(TraitImpl), + TraitImpl(NoirTraitImpl), Impl(TypeImpl), TypeAlias(NoirTypeAlias), SubModule(SubModule), @@ -224,7 +224,7 @@ pub struct ParsedModule { pub functions: Vec, pub types: Vec, pub traits: Vec, - pub trait_impls: Vec, + pub trait_impls: Vec, pub impls: Vec, pub type_aliases: Vec, pub globals: Vec, @@ -258,7 +258,7 @@ impl ParsedModule { self.traits.push(noir_trait); } - fn push_trait_impl(&mut self, trait_impl: TraitImpl) { + fn push_trait_impl(&mut self, trait_impl: NoirTraitImpl) { self.trait_impls.push(trait_impl); } diff --git a/compiler/noirc_frontend/src/parser/parser.rs b/compiler/noirc_frontend/src/parser/parser.rs index 227aac8030e..a6452c91cb5 100644 --- a/compiler/noirc_frontend/src/parser/parser.rs +++ b/compiler/noirc_frontend/src/parser/parser.rs @@ -39,9 +39,9 @@ use crate::token::{Attribute, Attributes, Keyword, Token, TokenKind}; use crate::{ BinaryOp, BinaryOpKind, BlockExpression, ConstrainStatement, Distinctness, FunctionDefinition, FunctionReturnType, Ident, IfExpression, InfixExpression, LValue, Lambda, Literal, - NoirFunction, NoirStruct, NoirTrait, NoirTypeAlias, Path, PathKind, Pattern, Recoverable, - TraitBound, TraitConstraint, TraitImpl, TraitImplItem, TraitItem, TypeImpl, UnaryOp, - UnresolvedTypeExpression, UseTree, UseTreeKind, Visibility, + NoirFunction, NoirStruct, NoirTrait, NoirTraitImpl, NoirTypeAlias, Path, PathKind, Pattern, + Recoverable, TraitBound, TraitImplItem, TraitItem, TypeImpl, UnaryOp, + UnresolvedTraitConstraint, UnresolvedTypeExpression, UseTree, UseTreeKind, Visibility, }; use chumsky::prelude::*; @@ -459,7 +459,7 @@ fn validate_attributes( fn validate_where_clause( generics: &Vec, - where_clause: &Vec, + where_clause: &Vec, span: Span, emit: &mut dyn FnMut(ParserError), ) { @@ -540,7 +540,7 @@ fn trait_implementation() -> impl NoirParser { other_args; emit(ParserError::with_reason(ParserErrorReason::ExperimentalFeature("Traits"), span)); - TopLevelStatement::TraitImpl(TraitImpl { + TopLevelStatement::TraitImpl(NoirTraitImpl { impl_generics, trait_name, trait_generics, @@ -565,7 +565,7 @@ fn trait_implementation_body() -> impl NoirParser> { function.or(alias).repeated() } -fn where_clause() -> impl NoirParser> { +fn where_clause() -> impl NoirParser> { struct MultiTraitConstraint { typ: UnresolvedType, trait_bounds: Vec, @@ -583,11 +583,13 @@ fn where_clause() -> impl NoirParser> { .or_not() .map(|option| option.unwrap_or_default()) .map(|x: Vec| { - let mut result: Vec = Vec::new(); + let mut result: Vec = Vec::new(); for constraint in x { for bound in constraint.trait_bounds { - result - .push(TraitConstraint { typ: constraint.typ.clone(), trait_bound: bound }); + result.push(UnresolvedTraitConstraint { + typ: constraint.typ.clone(), + trait_bound: bound, + }); } } result @@ -599,9 +601,11 @@ fn trait_bounds() -> impl NoirParser> { } fn trait_bound() -> impl NoirParser { - ident() - .then(generic_type_args(parse_type())) - .map(|(trait_name, trait_generics)| TraitBound { trait_name, trait_generics }) + ident().then(generic_type_args(parse_type())).map(|(trait_name, trait_generics)| TraitBound { + trait_name, + trait_generics, + trait_id: None, + }) } fn block_expr<'a, P>(expr_parser: P) -> impl NoirParser + 'a From b8112dae493d13261e1f0eb8672fda19a458a5ee Mon Sep 17 00:00:00 2001 From: Alex Vitkov Date: Fri, 15 Sep 2023 15:55:48 +0300 Subject: [PATCH 7/7] fix: missing init field --- compiler/noirc_frontend/src/hir/type_check/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/noirc_frontend/src/hir/type_check/mod.rs b/compiler/noirc_frontend/src/hir/type_check/mod.rs index d690fe2458a..162622f0af0 100644 --- a/compiler/noirc_frontend/src/hir/type_check/mod.rs +++ b/compiler/noirc_frontend/src/hir/type_check/mod.rs @@ -274,6 +274,7 @@ mod test { return_distinctness: Distinctness::DuplicationAllowed, has_body: true, return_type: FunctionReturnType::Default(Span::default()), + trait_constraints: Vec::new(), }; interner.push_fn_meta(func_meta, func_id);