Skip to content

Commit

Permalink
Send method arguments with numerics to the second pass (#6700)
Browse files Browse the repository at this point in the history
## Description

This PR brings back encode/decode buffer ownership tests and closes
#6567.

The original issue was that an error in the CI file was hiding that
these tests were not compiling anymore.

IR generation now also tests the expression and the variant type match,
giving a better error than before.

## Checklist

- [x] I have linked to any relevant issues.
- [ ] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [x] I have added tests that prove my fix is effective or that my
feature works.
- [ ] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.
  • Loading branch information
xunilrj authored Nov 12, 2024
1 parent cbf0c62 commit ae9f172
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 50 deletions.
17 changes: 16 additions & 1 deletion sway-core/src/ir_generation/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3975,15 +3975,30 @@ impl<'eng> FnCompiler<'eng> {
if field_tys.len() != 1 && contents.is_some() {
// Insert the value too.
// Only store if the value does not diverge.
let contents_expr = contents.unwrap();
let contents_value = return_on_termination_or_extract!(
self.compile_expression_to_value(context, md_mgr, contents.unwrap())?
self.compile_expression_to_value(context, md_mgr, contents_expr)?
);
let contents_type = contents_value.get_type(context).ok_or_else(|| {
CompileError::Internal(
"Unable to get type for enum contents.",
enum_decl.span.clone(),
)
})?;

let variant_type = field_tys[1].get_field_type(context, tag as u64).unwrap();
if contents_type != variant_type {
return Err(CompileError::Internal(
format!(
"Expression type \"{}\" and Variant type \"{}\" do not match",
contents_type.as_string(context),
variant_type.as_string(context)
)
.leak(),
contents_expr.span.clone(),
));
}

let gep_val = self
.current_block
.append(context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,17 @@ pub(crate) fn type_check_method_application(
let arg_handler = Handler::default();
let arg_opt = ty::TyExpression::type_check(&arg_handler, ctx, arg).ok();

let needs_second_pass = arg_handler.has_errors();
let has_errors = arg_handler.has_errors();
let has_numerics = arg_opt
.as_ref()
.map(|x| {
x.return_type
.extract_inner_types(engines, IncludeSelf::Yes)
.iter()
.any(|x| matches!(&*engines.te().get(*x), TypeInfo::Numeric))
})
.unwrap_or_default();
let needs_second_pass = has_errors || has_numerics;

if index == 0 {
// We want to emit errors in the self parameter and ignore TraitConstraintNotSatisfied with Placeholder
Expand Down
47 changes: 23 additions & 24 deletions sway-lib-std/src/bytes.sw
Original file line number Diff line number Diff line change
Expand Up @@ -927,27 +927,26 @@ impl AbiDecode for Bytes {
}
}

// TODO: Uncomment when fixed. https://github.com/FuelLabs/sway/issues/6567
// #[test]
// fn ok_bytes_buffer_ownership() {
// let mut original_array = [1u8, 2u8, 3u8, 4u8];
// let slice = raw_slice::from_parts::<u8>(__addr_of(original_array), 4);

// // Check Bytes duplicates the original slice
// let mut bytes = Bytes::from(slice);
// bytes.set(0, 5);
// assert(original_array[0] == 1);

// // At this point, slice equals [5, 2, 3, 4]
// let encoded_slice = encode(bytes);

// // `Bytes` should duplicate the underlying buffer,
// // so when we write to it, it should not change
// // `encoded_slice`
// let mut bytes = abi_decode::<Bytes>(encoded_slice);
// bytes.set(0, 6);
// assert(bytes.get(0) == Some(6));

// let mut bytes = abi_decode::<Bytes>(encoded_slice);
// assert(bytes.get(0) == Some(5));
// }
#[test]
fn ok_bytes_buffer_ownership() {
let mut original_array = [1u8, 2u8, 3u8, 4u8];
let slice = raw_slice::from_parts::<u8>(__addr_of(original_array), 4);

// Check Bytes duplicates the original slice
let mut bytes = Bytes::from(slice);
bytes.set(0, 5);
assert(original_array[0] == 1);

// At this point, slice equals [5, 2, 3, 4]
let encoded_slice = encode(bytes);

// `Bytes` should duplicate the underlying buffer,
// so when we write to it, it should not change
// `encoded_slice`
let mut bytes = abi_decode::<Bytes>(encoded_slice);
bytes.set(0, 6);
assert(bytes.get(0) == Some(6));

let mut bytes = abi_decode::<Bytes>(encoded_slice);
assert(bytes.get(0) == Some(5));
}
47 changes: 23 additions & 24 deletions sway-lib-std/src/vec.sw
Original file line number Diff line number Diff line change
Expand Up @@ -705,27 +705,26 @@ impl<T> Iterator for VecIter<T> {
}
}

// TODO: Uncomment when fixed. https://github.com/FuelLabs/sway/issues/6567
// #[test]
// fn ok_vec_buffer_ownership() {
// let mut original_array = [1u8, 2u8, 3u8, 4u8];
// let slice = raw_slice::from_parts::<u8>(__addr_of(original_array), 4);

// // Check Vec duplicates the original slice
// let mut bytes = Vec::<u8>::from(slice);
// bytes.set(0, 5);
// assert(original_array[0] == 1);

// // At this point, slice equals [5, 2, 3, 4]
// let encoded_slice = encode(bytes);

// // `Vec<u8>` should duplicate the underlying buffer,
// // so when we write to it, it should not change
// // `encoded_slice`
// let mut bytes = abi_decode::<Vec<u8>>(encoded_slice);
// bytes.set(0, 6);
// assert(bytes.get(0) == Some(6));

// let mut bytes = abi_decode::<Vec<u8>>(encoded_slice);
// assert(bytes.get(0) == Some(5));
// }
#[test]
fn ok_vec_buffer_ownership() {
let mut original_array = [1u8, 2u8, 3u8, 4u8];
let slice = raw_slice::from_parts::<u8>(__addr_of(original_array), 4);

// Check Vec duplicates the original slice
let mut bytes = Vec::<u8>::from(slice);
bytes.set(0, 5);
assert(original_array[0] == 1);

// At this point, slice equals [5, 2, 3, 4]
let encoded_slice = encode(bytes);

// `Vec<u8>` should duplicate the underlying buffer,
// so when we write to it, it should not change
// `encoded_slice`
let mut bytes = abi_decode::<Vec<u8>>(encoded_slice);
bytes.set(0, 6);
assert(bytes.get(0) == Some(6));

let mut bytes = abi_decode::<Vec<u8>>(encoded_slice);
assert(bytes.get(0) == Some(5));
}

0 comments on commit ae9f172

Please sign in to comment.