From 2dd40aa63b9f01f7d352f62fbd3231f038bff24a Mon Sep 17 00:00:00 2001 From: Alex Hansen Date: Wed, 30 Mar 2022 05:46:47 +0400 Subject: [PATCH] Fix ge/le/neq implementation and improve supertraits (#1092) * Fix ge/le/neq implementation and improve supertraits * Fix warning; add breadcrumbs * Fix fmt * fix test case in supertraits * update toml file * update lockfile Co-authored-by: Alexander Hansen --- .../src/semantic_analysis/ast_node/mod.rs | 24 +++++++- sway-lib-core/src/ops.sw | 55 +++++++------------ test/src/e2e_vm_tests/mod.rs | 5 +- .../language/supertraits/src/main.sw | 3 + .../should_pass/stdlib/ge_test/.gitignore | 2 + .../should_pass/stdlib/ge_test/Forc.lock | 11 ++++ .../should_pass/stdlib/ge_test/Forc.toml | 8 +++ .../stdlib/ge_test/json_abi_oracle.json | 1 + .../should_pass/stdlib/ge_test/src/main.sw | 8 +++ 9 files changed, 78 insertions(+), 39 deletions(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/ge_test/.gitignore create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/ge_test/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/ge_test/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/ge_test/json_abi_oracle.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/ge_test/src/main.sw diff --git a/sway-core/src/semantic_analysis/ast_node/mod.rs b/sway-core/src/semantic_analysis/ast_node/mod.rs index 734340703ad..cefedb33196 100644 --- a/sway-core/src/semantic_analysis/ast_node/mod.rs +++ b/sway-core/src/semantic_analysis/ast_node/mod.rs @@ -409,6 +409,7 @@ impl TypedAstNode { errors ); + let trait_namespace = create_new_scope(namespace); // Error checking. Make sure that each supertrait exists and that none // of the supertraits are actually an ABI declaration for supertrait in &supertraits { @@ -416,7 +417,26 @@ impl TypedAstNode { .get_call_path(&supertrait.name) .ok(&mut warnings, &mut errors) { - Some(TypedDeclaration::TraitDeclaration(_)) => (), + Some(TypedDeclaration::TraitDeclaration( + TypedTraitDeclaration { + ref interface_surface, + .. + }, + )) => { + // insert trait implementations for all of the supertraits + trait_namespace.insert_trait_implementation( + supertrait.name.clone(), + TypeInfo::SelfType, + interface_surface + .iter() + .map(|x| x.to_dummy_func(Mode::NonAbi)) + .collect(), + ); + // TODO: use `_methods` to insert dummy funcs for those + // methods into the namespace here + // will need to implement something for converting + // non-type-checked functions into dummy functions + } Some(TypedDeclaration::AbiDeclaration(_)) => { errors.push(CompileError::AbiAsSupertrait { span: name.span().clone(), @@ -428,8 +448,6 @@ impl TypedAstNode { }), } } - - let trait_namespace = create_new_scope(namespace); // insert placeholder functions representing the interface surface // to allow methods to use those functions trait_namespace.insert_trait_implementation( diff --git a/sway-lib-core/src/ops.sw b/sway-lib-core/src/ops.sw index aeae37e9bdc..91767cd6044 100644 --- a/sway-lib-core/src/ops.sw +++ b/sway-lib-core/src/ops.sw @@ -267,6 +267,22 @@ impl Shiftable for u8 { pub trait Eq { fn eq(self, other: Self) -> bool; +} { + fn neq(self, other: Self) -> bool { + asm(r1: self.eq(other), r2) { + eq r2 r1 zero; + r2: bool + } + } +} + +trait OrdEq: Ord + Eq { } { + fn ge(self, other: Self) -> bool { + self.gt(other) || self.eq(other) + } + fn le(self, other: Self) -> bool { + self.lt(other) || self.eq(other) + } } impl Eq for bool { @@ -328,40 +344,6 @@ impl Eq for b256 { pub trait Ord { fn gt(self, other: Self) -> bool; fn lt(self, other: Self) -> bool; -} { - fn le(self, other: Self) -> bool { - asm(r1: self, r2: other, r3, r4) { - gt r3 r1 r2; - not r4 r3; - - r4: bool - } - } - fn ge(self, other: Self) -> bool { - asm(r1: self, r2: other, r3, r4) { - lt r3 r1 r2; - not r4 r3; - - r4: bool - } - } - fn neq(self, other: Self) -> bool { - // TODO unary operator negation - - // Fix this ugly block which uses assembly rather than - // importing and utilizing an eq method - let is_equal: bool = asm(r1: self, r2: other, r3) { - eq r3 r1 r2; - - r3: bool - }; - - if is_equal { - false - } else { - true - } - } } impl Ord for u64 { @@ -460,3 +442,8 @@ impl u64 { } } } + +impl OrdEq for u64 {} +impl OrdEq for u32 {} +impl OrdEq for u16 {} +impl OrdEq for u8 {} diff --git a/test/src/e2e_vm_tests/mod.rs b/test/src/e2e_vm_tests/mod.rs index 2f5d5d3a0a9..9a6d8dff334 100644 --- a/test/src/e2e_vm_tests/mod.rs +++ b/test/src/e2e_vm_tests/mod.rs @@ -122,6 +122,7 @@ pub fn run(filter_regex: Option) { "should_pass/stdlib/b512_struct_alignment", ProgramState::Return(1), ), // true + ("should_pass/stdlib/ge_test", ProgramState::Return(1)), // true ( "should_pass/language/generic_structs", ProgramState::Return(1), @@ -139,7 +140,7 @@ pub fn run(filter_regex: Option) { "should_pass/stdlib/ec_recover_test", ProgramState::Return(1), ), // true - ("should_pass/stdlib/address_test", ProgramState::Return(1)), // true + ("should_pass/stdlib/address_test", ProgramState::Return(1)), // true ( "should_pass/language/generic_struct", ProgramState::Return(1), @@ -148,7 +149,7 @@ pub fn run(filter_regex: Option) { "should_pass/language/zero_field_types", ProgramState::Return(10), ), // true - ("should_pass/stdlib/assert_test", ProgramState::Return(1)), // true + ("should_pass/stdlib/assert_test", ProgramState::Return(1)), // true ( "should_pass/language/match_expressions", ProgramState::Return(42), diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/supertraits/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/supertraits/src/main.sw index 7061372b885..4d2b3b620b4 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/supertraits/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/supertraits/src/main.sw @@ -22,6 +22,9 @@ trait B: A { fn mul_g(self, x: u64) -> u64 { self.g() * x } + fn test_inheritance(self) { + self.f(); + } } trait C: B { diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/ge_test/.gitignore b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/ge_test/.gitignore new file mode 100644 index 00000000000..77d3844f58c --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/ge_test/.gitignore @@ -0,0 +1,2 @@ +out +target diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/ge_test/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/ge_test/Forc.lock new file mode 100644 index 00000000000..f1bdeeb2f02 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/ge_test/Forc.lock @@ -0,0 +1,11 @@ +[[package]] +name = 'core' +dependencies = [] + +[[package]] +name = 'ge_test' +dependencies = ['std'] + +[[package]] +name = 'std' +dependencies = ['core'] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/ge_test/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/ge_test/Forc.toml new file mode 100644 index 00000000000..7daa387a5eb --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/ge_test/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "ge_test" + +[dependencies] +std = { path = "../../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/ge_test/json_abi_oracle.json b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/ge_test/json_abi_oracle.json new file mode 100644 index 00000000000..0637a088a01 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/ge_test/json_abi_oracle.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/ge_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/ge_test/src/main.sw new file mode 100644 index 00000000000..5ecb4fc968c --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/ge_test/src/main.sw @@ -0,0 +1,8 @@ +script; +use std::assert::assert; + +fn main() -> bool { + + !(5 >= 10) && 5 >= 5 && 10 >= 10 && !(4 >= 5) && 10 >= 5 + +}