Skip to content

Commit

Permalink
Fix ge/le/neq implementation and improve supertraits (FuelLabs#1092)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
  • Loading branch information
sezna and Alexander Hansen authored Mar 30, 2022
1 parent 6143aa2 commit 2dd40aa
Showing 9 changed files with 78 additions and 39 deletions.
24 changes: 21 additions & 3 deletions sway-core/src/semantic_analysis/ast_node/mod.rs
Original file line number Diff line number Diff line change
@@ -409,14 +409,34 @@ 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 {
match namespace
.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(
55 changes: 21 additions & 34 deletions sway-lib-core/src/ops.sw
Original file line number Diff line number Diff line change
@@ -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 {}
5 changes: 3 additions & 2 deletions test/src/e2e_vm_tests/mod.rs
Original file line number Diff line number Diff line change
@@ -122,6 +122,7 @@ pub fn run(filter_regex: Option<regex::Regex>) {
"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<regex::Regex>) {
"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<regex::Regex>) {
"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),
Original file line number Diff line number Diff line change
@@ -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 {
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
out
target
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[[package]]
name = 'core'
dependencies = []

[[package]]
name = 'ge_test'
dependencies = ['std']

[[package]]
name = 'std'
dependencies = ['core']
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[project]
authors = ["Fuel Labs <[email protected]>"]
entry = "main.sw"
license = "Apache-2.0"
name = "ge_test"

[dependencies]
std = { path = "../../../../../../../sway-lib-std" }
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
script;
use std::assert::assert;

fn main() -> bool {

!(5 >= 10) && 5 >= 5 && 10 >= 10 && !(4 >= 5) && 10 >= 5

}

0 comments on commit 2dd40aa

Please sign in to comment.