Skip to content

Commit

Permalink
Fix access to tuples in structs (FuelLabs#907)
Browse files Browse the repository at this point in the history
* fixing tuple access in structs

* improving a comment

Co-authored-by: Mohammad <[email protected]>
  • Loading branch information
mohammadfawaz and Mohammad authored Mar 9, 2022
1 parent 10a78cf commit 53ecab4
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 13 deletions.
16 changes: 12 additions & 4 deletions sway-core/src/asm_generation/expression/subfield.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ pub(crate) fn convert_subfield_to_asm(

// step 2
let offset_in_words = check!(
descriptor.offset_to_field_name(field_to_access_name, field_to_access_span),
descriptor.offset_to_field_name(field_to_access_name, field_to_access_span.clone()),
0,
warnings,
errors
Expand All @@ -145,16 +145,24 @@ pub(crate) fn convert_subfield_to_asm(
path: None,
};
// step 3
// if this is a copy type (primitives that fit in a word), copy it into the register.
// Otherwise, load the pointer to the field into the register
// if this type fits in a word, copy it into the register. Otherwise, load the pointer to the
// field into the register
let resolved_type_of_this_field = match resolve_type(*type_of_this_field, &span) {
Ok(o) => o,
Err(e) => {
errors.push(e.into());
return err(warnings, errors);
}
};
asm_buf.push(if resolved_type_of_this_field.is_copy_type() {

let size_of_type = resolved_type_of_this_field
.size_in_words(&field_to_access_span)
.unwrap_or_else(|e| {
errors.push(e);
0
});

asm_buf.push(if size_of_type <= 1 {
let offset_in_words = match VirtualImmediate12::new(offset_in_words, span.clone()) {
Ok(o) => o,
Err(e) => {
Expand Down
9 changes: 0 additions & 9 deletions sway-core/src/type_engine/type_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,15 +471,6 @@ impl TypeInfo {
}
}
}
pub(crate) fn is_copy_type(&self) -> bool {
match self {
TypeInfo::UnsignedInteger(_) | TypeInfo::Boolean | TypeInfo::Byte => true,
TypeInfo::Tuple(fields) => fields
.iter()
.all(|field_type| look_up_type_id(*field_type).is_copy_type()),
_ => false,
}
}

pub fn is_uninhabited(&self) -> bool {
match self {
Expand Down
1 change: 1 addition & 0 deletions test/src/e2e_vm_tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ pub fn run(filter_regex: Option<regex::Regex>) {
("new_allocator_test", ProgramState::Return(42)), // true
("inline_if_expr_const", ProgramState::Return(0)),
("method_on_empty_struct", ProgramState::Return(1)),
("tuple_in_struct", ProgramState::Return(1)),
];

let mut number_of_tests_run = positive_project_names.iter().fold(0, |acc, (name, res)| {
Expand Down
13 changes: 13 additions & 0 deletions test/src/e2e_vm_tests/test_programs/tuple_in_struct/Forc.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[[package]]
name = 'core'
source = 'git+http://github.com/FuelLabs/sway-lib-core?reference=master#c331ed20ebc9d646acec6b8ee8f408627ce3b573'
dependencies = []

[[package]]
name = 'std'
source = 'git+http://github.com/FuelLabs/sway-lib-std?reference=master#7081d2e1ac2401f22a0de0673e8a01535180ba3a'
dependencies = ['core git+http://github.com/FuelLabs/sway-lib-core?reference=master#c331ed20ebc9d646acec6b8ee8f408627ce3b573']

[[package]]
name = 'tuple_in_struct'
dependencies = ['std git+http://github.com/FuelLabs/sway-lib-std?reference=master#7081d2e1ac2401f22a0de0673e8a01535180ba3a']
8 changes: 8 additions & 0 deletions test/src/e2e_vm_tests/test_programs/tuple_in_struct/Forc.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[project]
author = "Fuel Labs <[email protected]>"
entry = "main.sw"
license = "Apache-2.0"
name = "tuple_in_struct"

[dependencies]
std = { git = "http://github.com/FuelLabs/sway-lib-std" }
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
55 changes: 55 additions & 0 deletions test/src/e2e_vm_tests/test_programs/tuple_in_struct/src/main.sw
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
script;
use std::chain::*;

struct W {
t5: u64,
t6: (u8, u8, (u64, u8), u16),
}

struct T {
t3: (u8, u8),
t4: u16
}

struct S {
t0: W,
t1: (u64, u64),
t2: T,
}

struct U {
u: u64
}

fn main() -> bool {
let s = S {
t0: W {
t5: 5,
t6: (6, 7, (8, 9), 10)
},
t1: (0, 1),
t2: T {
t3: (2, 3),
t4: 4
}
};

assert((s.t1).0 == 0);
assert((s.t1).1 == 1);
assert((s.t2.t3).0 == 2);
assert((s.t2.t3).1 == 3);
assert(s.t2.t4 == 4);
assert(((s.t0).t5) == 5);
assert(((s.t0).t6).0 == 6);
assert(((s.t0).t6).1 == 7);
assert((((s.t0).t6).2).0 == 8);
assert((((s.t0).t6).2).1 == 9);
assert(((s.t0).t6).3 == 10);

let u = U {
u: 22
};
assert(u.u == 22);

true
}

0 comments on commit 53ecab4

Please sign in to comment.