From 253330df2e4fb1863d7826914cb3cc790e89bec9 Mon Sep 17 00:00:00 2001 From: Marcos Henrich Date: Wed, 4 Sep 2024 00:58:48 +0100 Subject: [PATCH 1/6] Fixes impl self duplicated missing error. (#6493) ## Description While inserting trait implementations into the trait map we now compare the implementing type_id without matching UnkownGenerics trait constraints. Matching the trait constraints was causing a missing error. Fixes #6381 ## Checklist - [ ] I have linked to any relevant issues. - [x] 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. - [x] 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. Co-authored-by: IGI-111 --- .../src/type_system/unify/unify_check.rs | 5 ++- .../impl_self_duplicated/Forc.lock | 8 ++++ .../impl_self_duplicated/Forc.toml | 9 ++++ .../impl_self_duplicated/src/main.sw | 42 +++++++++++++++++++ .../impl_self_duplicated/test.toml | 6 +++ 5 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/impl_self_duplicated/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/impl_self_duplicated/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/impl_self_duplicated/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/impl_self_duplicated/test.toml diff --git a/sway-core/src/type_system/unify/unify_check.rs b/sway-core/src/type_system/unify/unify_check.rs index 26a0777bdee..7479a4142ac 100644 --- a/sway-core/src/type_system/unify/unify_check.rs +++ b/sway-core/src/type_system/unify/unify_check.rs @@ -471,7 +471,10 @@ impl<'a> UnifyCheck<'a> { parent: _, is_from_type_parameter: _, }, - ) => rtc.eq(ltc, &PartialEqWithEnginesContext::new(self.engines)), + ) => { + matches!(self.mode, NonGenericConstraintSubset) + || rtc.eq(ltc, &PartialEqWithEnginesContext::new(self.engines)) + } // any type can be coerced into a generic, // except if the type already contains the generic diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/impl_self_duplicated/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_fail/impl_self_duplicated/Forc.lock new file mode 100644 index 00000000000..3cb45ccbaed --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/impl_self_duplicated/Forc.lock @@ -0,0 +1,8 @@ +[[package]] +name = "core" +source = "path+from-root-7EB1B3610F4F66A3" + +[[package]] +name = "impl_self_duplicated" +source = "member" +dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/impl_self_duplicated/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/impl_self_duplicated/Forc.toml new file mode 100644 index 00000000000..7bd047f83cf --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/impl_self_duplicated/Forc.toml @@ -0,0 +1,9 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +implicit-std = false +license = "Apache-2.0" +name = "impl_self_duplicated" + +[dependencies] +core = { path = "../../../../../../sway-lib-core" } diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/impl_self_duplicated/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/impl_self_duplicated/src/main.sw new file mode 100644 index 00000000000..b51479e89e7 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/impl_self_duplicated/src/main.sw @@ -0,0 +1,42 @@ +script; +trait Cat { + fn speak(self) -> u64; +} +trait Dog { + fn speak(self) -> u64; +} +struct S { + x: T, +} +impl S +where + T: Cat, +{ + fn foo(self) -> u64 { + self.x.speak() + 1 + } +} +impl S +where + T: Dog, +{ + fn foo(self) -> u64 { + self.x.speak() + 2 + } +} +impl Dog for u64 { + fn speak(self) -> u64 { + 2 + } +} +impl Cat for u64 { + fn speak(self) -> u64 { + 1 + } +} +fn main() -> u64 { + let s = S:: { x: 1 }; + s.foo(); + + 42 +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/impl_self_duplicated/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/impl_self_duplicated/test.toml new file mode 100644 index 00000000000..716219cfde9 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/impl_self_duplicated/test.toml @@ -0,0 +1,6 @@ +category = "fail" +validate_abi = false +expected_warnings = 3 + +# check: fn foo(self) -> u64 { +# nextln: $()Duplicate definitions for the method "foo" for type "S". From a81c42eb18827c644f46a6119054d4dacb500f92 Mon Sep 17 00:00:00 2001 From: Marcos Henrich Date: Wed, 4 Sep 2024 12:16:47 +0100 Subject: [PATCH 2/6] Adds function return type unification. (#6490) ## Description The function return type unification was missing, leading to generic functions not being resolved based on the return type. ## Checklist - [x] I have linked to any relevant issues. - [x] 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. - [x] 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. --------- Co-authored-by: Joshua Batty Co-authored-by: IGI-111 --- .../typed_expression/function_application.rs | 11 +++++++ .../bad_generic_annotation/test.toml | 6 ++++ .../shadowing_in_reexporting_module/test.toml | 2 +- .../recursive_type_unification/test.toml | 7 +++++ .../.gitignore | 2 ++ .../Forc.lock | 13 +++++++++ .../Forc.toml | 8 +++++ .../src/main.sw | 29 +++++++++++++++++++ .../test.toml | 4 +++ 9 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/.gitignore create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/test.toml diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/function_application.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/function_application.rs index a3f299027b9..e400e3b1470 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/function_application.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/function_application.rs @@ -61,6 +61,17 @@ pub(crate) fn instantiate_function_application( &function_decl.parameters, )?; + // unify function return type with current ctx.type_annotation(). + engines.te().unify_with_generic( + handler, + engines, + function_decl.return_type.type_id, + ctx.type_annotation(), + &call_path_binding.span(), + "Function return type does not match up with local type annotation.", + None, + ); + let mut function_return_type_id = function_decl.return_type.type_id; let function_ident: IdentUnique = function_decl.name.clone().into(); diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/bad_generic_annotation/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/bad_generic_annotation/test.toml index 2023da0cc3a..e65971dfc6d 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/bad_generic_annotation/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/bad_generic_annotation/test.toml @@ -1,5 +1,11 @@ category = "fail" +# check: let _g: u32 = three_generics(true, "foo", 10); +# nextln: $()Mismatched types. +# nextln: $()expected: u32 +# nextln: $()found: str. +# nextln: $()help: Function return type does not match up with local type annotation. + # check: let _g: u32 = three_generics(true, "foo", 10); # nextln: $()Mismatched types. # nextln: $()expected: u32 diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/shadowing_in_reexporting_module/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/shadowing_in_reexporting_module/test.toml index 9ba4d7f4a66..700594e5116 100755 --- a/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/shadowing_in_reexporting_module/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/shadowing_in_reexporting_module/test.toml @@ -188,4 +188,4 @@ category = "fail" #check: $()error #check: $()This path must return a value of type "u64" from function "items_2_trait_function", but it does not. -#check: $()Aborting due to 40 errors. +#check: $()Aborting due to 42 errors. diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_type_unification/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_type_unification/test.toml index 48b8108e7a9..a660e53c0ad 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_type_unification/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_type_unification/test.toml @@ -1,5 +1,12 @@ category = "fail" +# check: $()error +# check: $()MyOption::Some::(foo::(value)) +# nextln: $()Mismatched types. +# nextln: $()expected: V +# nextln: $()found: MyOption. +# nextln: $()Function return type does not match up with local type annotation. + # check: $()error # check: $()MyOption::Some::(foo::(value)) # nextln: $()Mismatched types. diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/.gitignore b/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/.gitignore new file mode 100644 index 00000000000..77d3844f58c --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/.gitignore @@ -0,0 +1,2 @@ +out +target diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/Forc.lock new file mode 100644 index 00000000000..8407bd5c37c --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/Forc.lock @@ -0,0 +1,13 @@ +[[package]] +name = "core" +source = "path+from-root-D73E65B1F4E48513" + +[[package]] +name = "function_return_type_unification" +source = "member" +dependencies = ["std"] + +[[package]] +name = "std" +source = "path+from-root-D73E65B1F4E48513" +dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/Forc.toml new file mode 100644 index 00000000000..96f4447a531 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/Forc.toml @@ -0,0 +1,8 @@ +[project] +name = "function_return_type_unification" +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" + +[dependencies] +std = { path = "../../../../reduced_std_libs/sway-lib-std-assert" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/src/main.sw new file mode 100644 index 00000000000..9d5c8d4d08c --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/src/main.sw @@ -0,0 +1,29 @@ +script; + +trait Build { + fn build() -> Self; +} + +impl Build for u32 { + fn build() -> Self { + 31 + } +} + +impl Build for u64 { + fn build() -> Self { + 63 + } +} + +fn produce() -> T +where T: Build, +{ + T::build() +} + +fn main() -> bool { + let _:u32 = produce(); + + true +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/test.toml new file mode 100644 index 00000000000..1591686ff87 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/test.toml @@ -0,0 +1,4 @@ +category = "run" +expected_result = { action = "return", value = 1 } +expected_result_new_encoding = { action = "return_data", value = "01" } +validate_abi = false From e220ecab1ec2663952791be4168034e96b916681 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ron=C4=8Devi=C4=87?= Date: Wed, 4 Sep 2024 19:56:27 +0200 Subject: [PATCH 3/6] Implement `__contract_ret` as diverging and `retd` as terminator (#6486) ## Description This PR implements the `__contract_ret` as a diverging (returning `!`) and accordingly the FuelVM `retd` instruction as being a terminator. This strict semantics is needed in the #6351 which introduces strict(er) verification of IR invariants. ## Checklist - [x] I have linked to any relevant issues. - [x] 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. --- .../test/data/standalone_contract/Forc.lock | 13 ++++++ forc-plugins/forc-client/tests/deploy.rs | 8 ++-- sway-core/src/ir_generation/compile.rs | 2 +- .../ast_node/expression/intrinsic_function.rs | 43 +++++++++++-------- sway-ir/src/block.rs | 13 ++++-- sway-ir/src/instruction.rs | 13 ++++-- sway-ir/src/value.rs | 10 +---- .../language/contract_ret_intrinsic/Forc.lock | 13 ++++++ .../language/contract_ret_intrinsic/Forc.toml | 9 ++++ .../json_abi_oracle.json | 25 +++++++++++ .../json_abi_oracle_new_encoding.json | 23 ++++++++++ .../contract_ret_intrinsic/src/main.sw | 34 +++++++++++++++ .../language/contract_ret_intrinsic/test.toml | 1 + .../language/slice/slice_contract/src/main.sw | 3 +- .../string_slice_contract/src/main.sw | 3 +- .../array_of_structs_caller/src/main.sw | 2 +- .../asset_ops_test/src/main.sw | 4 +- .../bal_opcode/src/main.sw | 2 +- .../call_abi_with_tuples/src/main.sw | 2 +- .../call_basic_storage/src/main.sw | 2 +- .../src/main.sw | 2 +- .../call_increment_contract/src/main.sw | 2 +- .../call_storage_enum/src/main.sw | 2 +- .../caller_auth_test/src/main.sw | 2 +- .../caller_context_test/src/main.sw | 2 +- .../nested_struct_args_caller/src/main.sw | 2 +- .../storage_access_caller/src/main.sw | 2 +- .../contract_multi_test/src/main.sw | 6 +-- 28 files changed, 187 insertions(+), 58 deletions(-) create mode 100644 forc-plugins/forc-client/test/data/standalone_contract/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/contract_ret_intrinsic/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/contract_ret_intrinsic/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/contract_ret_intrinsic/json_abi_oracle.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/contract_ret_intrinsic/json_abi_oracle_new_encoding.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/contract_ret_intrinsic/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/contract_ret_intrinsic/test.toml diff --git a/forc-plugins/forc-client/test/data/standalone_contract/Forc.lock b/forc-plugins/forc-client/test/data/standalone_contract/Forc.lock new file mode 100644 index 00000000000..7b517045569 --- /dev/null +++ b/forc-plugins/forc-client/test/data/standalone_contract/Forc.lock @@ -0,0 +1,13 @@ +[[package]] +name = "core" +source = "path+from-root-79BB3EA8498403DE" + +[[package]] +name = "standalone_contract" +source = "member" +dependencies = ["std"] + +[[package]] +name = "std" +source = "path+from-root-79BB3EA8498403DE" +dependencies = ["core"] diff --git a/forc-plugins/forc-client/tests/deploy.rs b/forc-plugins/forc-client/tests/deploy.rs index 2c0c29d3012..93faa96d40e 100644 --- a/forc-plugins/forc-client/tests/deploy.rs +++ b/forc-plugins/forc-client/tests/deploy.rs @@ -341,7 +341,7 @@ async fn test_simple_deploy() { node.kill().unwrap(); let expected = vec![DeployedContract { id: ContractId::from_str( - "ad0bba17e0838ef859abe2693d8a5e3bc4e7cfb901601e30f4dc34999fda6335", + "50fe882cbef5f3da6da82509a66b7e5e0a64a40d70164861c01c908a332198ae", ) .unwrap(), proxy: None, @@ -383,7 +383,7 @@ async fn test_deploy_submit_only() { node.kill().unwrap(); let expected = vec![DeployedContract { id: ContractId::from_str( - "ad0bba17e0838ef859abe2693d8a5e3bc4e7cfb901601e30f4dc34999fda6335", + "50fe882cbef5f3da6da82509a66b7e5e0a64a40d70164861c01c908a332198ae", ) .unwrap(), proxy: None, @@ -428,12 +428,12 @@ async fn test_deploy_fresh_proxy() { node.kill().unwrap(); let impl_contract = DeployedContract { id: ContractId::from_str( - "ad0bba17e0838ef859abe2693d8a5e3bc4e7cfb901601e30f4dc34999fda6335", + "50fe882cbef5f3da6da82509a66b7e5e0a64a40d70164861c01c908a332198ae", ) .unwrap(), proxy: Some( ContractId::from_str( - "f2d67efbd6038c85ddaffdcdc859770d8bd20eeec8e3909911f1446b2ec9f764", + "9c50c6837ba29508ad1b0fb01953892031218b5a08be73925ca5c0148e00a186", ) .unwrap(), ), diff --git a/sway-core/src/ir_generation/compile.rs b/sway-core/src/ir_generation/compile.rs index 135b398ca74..a0c2b10ca8e 100644 --- a/sway-core/src/ir_generation/compile.rs +++ b/sway-core/src/ir_generation/compile.rs @@ -635,7 +635,7 @@ fn compile_fn( // recent instruction was a RET. let already_returns = compiler .current_block - .is_terminated_by_ret_or_revert(context); + .is_terminated_by_return_or_revert(context); if !already_returns && (compiler.current_block.num_instructions(context) > 0 || compiler.current_block == compiler.function.get_entry_block(context) diff --git a/sway-core/src/semantic_analysis/ast_node/expression/intrinsic_function.rs b/sway-core/src/semantic_analysis/ast_node/expression/intrinsic_function.rs index 70c83d9b07a..c220ef33c1e 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/intrinsic_function.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/intrinsic_function.rs @@ -1855,14 +1855,7 @@ fn type_check_smo( ); let data = ty::TyExpression::type_check(handler, ctx.by_ref(), &arguments[1])?; - // Type check the third argument which is the output index, so it has to be a `u64`. - let mut ctx = ctx.by_ref().with_type_annotation(type_engine.insert( - engines, - TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), - None, - )); - - // Type check the fourth argument which is the amount of coins to send, so it has to be a `u64`. + // Type check the third argument which is the amount of coins to send, so it has to be a `u64`. let mut ctx = ctx.by_ref().with_type_annotation(type_engine.insert( engines, TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), @@ -1881,20 +1874,37 @@ fn type_check_smo( )) } -/// Signature: `__contract_call()` -/// Description: Calls another contract +/// Signature: `__contract_ret(ptr: raw_ptr, len: u64) -> !` +/// Description: Returns from contract. The returned data is located at the memory location `ptr` and has +/// the length of `len` bytes. /// Constraints: None. fn type_check_contract_ret( handler: &Handler, mut ctx: TypeCheckContext, - _kind: sway_ast::Intrinsic, + kind: sway_ast::Intrinsic, arguments: &[Expression], - _type_arguments: &[TypeArgument], - _span: Span, + type_arguments: &[TypeArgument], + span: Span, ) -> Result<(ty::TyIntrinsicFunctionKind, TypeId), ErrorEmitted> { let type_engine = ctx.engines.te(); let engines = ctx.engines(); + if arguments.len() != 2 { + return Err(handler.emit_err(CompileError::IntrinsicIncorrectNumArgs { + name: kind.to_string(), + expected: 2, + span, + })); + } + + if !type_arguments.is_empty() { + return Err(handler.emit_err(CompileError::IntrinsicIncorrectNumTArgs { + name: kind.to_string(), + expected: 0, + span, + })); + } + let arguments: Vec = arguments .iter() .map(|x| { @@ -1906,17 +1916,14 @@ fn type_check_contract_ret( }) .collect::, _>>()?; - let t = ctx - .engines - .te() - .insert(ctx.engines, TypeInfo::Tuple(vec![]), None); + let t = ctx.engines.te().insert(ctx.engines, TypeInfo::Never, None); Ok(( ty::TyIntrinsicFunctionKind { kind: Intrinsic::ContractRet, arguments, type_arguments: vec![], - span: Span::dummy(), + span, }, t, )) diff --git a/sway-ir/src/block.rs b/sway-ir/src/block.rs index deea1096d16..fb56b644059 100644 --- a/sway-ir/src/block.rs +++ b/sway-ir/src/block.rs @@ -369,14 +369,21 @@ impl Block { } } - /// Return whether this block is already terminated specifically by a Ret instruction. - pub fn is_terminated_by_ret_or_revert(&self, context: &Context) -> bool { + /// Return whether this block is already terminated by non-branching instructions, + /// means with instructions that cause either revert, or local or context returns. + /// Those instructions are: [InstOp::Ret], [FuelVmInstruction::Retd], + /// [FuelVmInstruction::JmpMem], and [FuelVmInstruction::Revert]). + pub fn is_terminated_by_return_or_revert(&self, context: &Context) -> bool { self.get_terminator(context).map_or(false, |i| { matches!( i, Instruction { op: InstOp::Ret(..) - | InstOp::FuelVm(FuelVmInstruction::Revert(..) | FuelVmInstruction::JmpMem), + | InstOp::FuelVm( + FuelVmInstruction::Revert(..) + | FuelVmInstruction::JmpMem + | FuelVmInstruction::Retd { .. } + ), .. } ) diff --git a/sway-ir/src/instruction.rs b/sway-ir/src/instruction.rs index d0fe6e6a5f4..1db5a4663ed 100644 --- a/sway-ir/src/instruction.rs +++ b/sway-ir/src/instruction.rs @@ -284,7 +284,6 @@ impl InstOp { InstOp::FuelVm(FuelVmInstruction::Log { .. }) => Some(Type::get_unit(context)), InstOp::FuelVm(FuelVmInstruction::ReadRegister(_)) => Some(Type::get_uint64(context)), InstOp::FuelVm(FuelVmInstruction::Smo { .. }) => Some(Type::get_unit(context)), - InstOp::FuelVm(FuelVmInstruction::Retd { .. }) => None, // Load needs to strip the pointer from the source type. InstOp::Load(ptr_val) => match &context.values[ptr_val.0].value { @@ -310,7 +309,11 @@ impl InstOp { // These are all terminators which don't return, essentially. No type. InstOp::Branch(_) | InstOp::ConditionalBranch { .. } - | InstOp::FuelVm(FuelVmInstruction::Revert(..) | FuelVmInstruction::JmpMem) + | InstOp::FuelVm( + FuelVmInstruction::Revert(..) + | FuelVmInstruction::JmpMem + | FuelVmInstruction::Retd { .. }, + ) | InstOp::Ret(..) => None, // No-op is also no-type. @@ -692,7 +695,11 @@ impl InstOp { InstOp::Branch(_) | InstOp::ConditionalBranch { .. } | InstOp::Ret(..) - | InstOp::FuelVm(FuelVmInstruction::Revert(..) | FuelVmInstruction::JmpMem) + | InstOp::FuelVm( + FuelVmInstruction::Revert(..) + | FuelVmInstruction::JmpMem + | FuelVmInstruction::Retd { .. } + ) ) } } diff --git a/sway-ir/src/value.rs b/sway-ir/src/value.rs index c7b7af6b6af..42324aca351 100644 --- a/sway-ir/src/value.rs +++ b/sway-ir/src/value.rs @@ -12,7 +12,7 @@ use crate::{ block::BlockArgument, constant::Constant, context::Context, - instruction::{FuelVmInstruction, InstOp}, + instruction::InstOp, irtype::Type, metadata::{combine, MetadataIndex}, pretty::DebugWithContext, @@ -102,13 +102,7 @@ impl Value { /// and is either a branch or return. pub fn is_terminator(&self, context: &Context) -> bool { match &context.values[self.0].value { - ValueDatum::Instruction(Instruction { op, .. }) => matches!( - op, - InstOp::Branch(_) - | InstOp::ConditionalBranch { .. } - | InstOp::Ret(_, _) - | InstOp::FuelVm(FuelVmInstruction::Revert(_) | FuelVmInstruction::JmpMem) - ), + ValueDatum::Instruction(Instruction { op, .. }) => op.is_terminator(), ValueDatum::Argument(..) | ValueDatum::Constant(..) => false, } } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/contract_ret_intrinsic/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/contract_ret_intrinsic/Forc.lock new file mode 100644 index 00000000000..b5acd0aa565 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/contract_ret_intrinsic/Forc.lock @@ -0,0 +1,13 @@ +[[package]] +name = "contract_ret_intrinsic" +source = "member" +dependencies = ["std"] + +[[package]] +name = "core" +source = "path+from-root-793618C6A3B48D0B" + +[[package]] +name = "std" +source = "path+from-root-793618C6A3B48D0B" +dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/contract_ret_intrinsic/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/contract_ret_intrinsic/Forc.toml new file mode 100644 index 00000000000..45d67307b35 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/contract_ret_intrinsic/Forc.toml @@ -0,0 +1,9 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "contract_ret_intrinsic" +implicit-std = false + +[dependencies] +std = { path = "../../../../reduced_std_libs/sway-lib-std-assert" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/contract_ret_intrinsic/json_abi_oracle.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/contract_ret_intrinsic/json_abi_oracle.json new file mode 100644 index 00000000000..ad50b55d54c --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/contract_ret_intrinsic/json_abi_oracle.json @@ -0,0 +1,25 @@ +{ + "configurables": [], + "functions": [ + { + "attributes": null, + "inputs": [], + "name": "main", + "output": { + "name": "", + "type": 0, + "typeArguments": null + } + } + ], + "loggedTypes": [], + "messagesTypes": [], + "types": [ + { + "components": null, + "type": "u64", + "typeId": 0, + "typeParameters": null + } + ] +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/contract_ret_intrinsic/json_abi_oracle_new_encoding.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/contract_ret_intrinsic/json_abi_oracle_new_encoding.json new file mode 100644 index 00000000000..05b0f04b2d3 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/contract_ret_intrinsic/json_abi_oracle_new_encoding.json @@ -0,0 +1,23 @@ +{ + "concreteTypes": [ + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "type": "u64" + } + ], + "configurables": [], + "encodingVersion": "1", + "functions": [ + { + "attributes": null, + "inputs": [], + "name": "main", + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "loggedTypes": [], + "messagesTypes": [], + "metadataTypes": [], + "programType": "script", + "specVersion": "1" +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/contract_ret_intrinsic/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/contract_ret_intrinsic/src/main.sw new file mode 100644 index 00000000000..6db6e3ed434 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/contract_ret_intrinsic/src/main.sw @@ -0,0 +1,34 @@ +contract; + +abi Abi { + fn return_via_contract_ret(x: u8) -> u64; +} + +impl Abi for Contract { + fn return_via_contract_ret(x: u8) -> u64 { + match x { + 1 => { + let ret: raw_slice = encode::(100); + __contract_ret(ret.ptr(), ret.len::()); + __revert(100); + }, + 2 => { + let ret: raw_slice = encode::(200); + __contract_ret(ret.ptr(), ret.len::()); + __revert(200); + }, + _ => __revert(0xaaa), + } + } +} + +#[test] +fn test() { + let caller = abi(Abi, CONTRACT_ID); + + let res = caller.return_via_contract_ret(1); + assert_eq(100, res); + + let res = caller.return_via_contract_ret(2); + assert_eq(200, res); +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/contract_ret_intrinsic/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/contract_ret_intrinsic/test.toml new file mode 100644 index 00000000000..f1958c1b086 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/contract_ret_intrinsic/test.toml @@ -0,0 +1 @@ +category = "unit_tests_pass" \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/slice/slice_contract/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/slice/slice_contract/src/main.sw index fd5bdad8837..c86ce974d88 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/slice/slice_contract/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/slice/slice_contract/src/main.sw @@ -12,8 +12,7 @@ impl MyContract for Contract { #[test] fn test_success() { - let contract_id = 0x4269c55d899c258109d170019aa45b1fd3acf6eb8c50e6139887a07ea6df1ae7; // AUTO-CONTRACT-ID . - let caller = abi(MyContract, contract_id); + let caller = abi(MyContract, CONTRACT_ID); let data = 1u64; let slice = raw_slice::from_parts::(__addr_of(&data), 1); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/string_slice/string_slice_contract/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/string_slice/string_slice_contract/src/main.sw index bcce12c6b0f..70cb24b5ef9 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/string_slice/string_slice_contract/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/string_slice/string_slice_contract/src/main.sw @@ -12,8 +12,7 @@ impl MyContract for Contract { #[test] fn test_success() { - let contract_id = 0x573a7901ce5a722d0b80a4ad49296f8e6a23e4f6282555a561ed5118e5890ec2; // AUTO-CONTRACT-ID . - let caller = abi(MyContract, contract_id); + let caller = abi(MyContract, CONTRACT_ID); let result = caller.test_function("a"); assert(result == "a") } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/array_of_structs_caller/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/array_of_structs_caller/src/main.sw index 31d2cbaf57d..7537a1e5881 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/array_of_structs_caller/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/array_of_structs_caller/src/main.sw @@ -6,7 +6,7 @@ use std::hash::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0x14ed3cd06c2947248f69d54bfa681fe40d26267be84df7e19e253622b7921bbe; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0xb7fd078d247144fb0b1505caf58ba37e1cb7a44495e135e8626fec02790b0ad4; // AUTO-CONTRACT-ID ../../test_contracts/array_of_structs_contract --release +const CONTRACT_ID = 0xf9f1fec713b977865880637fc24e58cda9e69f6e711ed8e5efe7de9ce51c88ec; // AUTO-CONTRACT-ID ../../test_contracts/array_of_structs_contract --release fn main() -> u64 { let addr = abi(TestContract, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/asset_ops_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/asset_ops_test/src/main.sw index 2edbe09c4af..02567676e67 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/asset_ops_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/asset_ops_test/src/main.sw @@ -9,12 +9,12 @@ use test_fuel_coin_abi::*; #[cfg(experimental_new_encoding = false)] const FUEL_COIN_CONTRACT_ID = 0xec2277ebe007ade87e3d797c3b1e070dcd542d5ef8f038b471f262ef9cebc87c; #[cfg(experimental_new_encoding = true)] -const FUEL_COIN_CONTRACT_ID = 0xf5d8dc006c7686b126c6a8d4e8aa5ec53e73f23c367d2427f930cb3783c4dbb2; +const FUEL_COIN_CONTRACT_ID = 0xf8c7b4d09f9964ab4c437ac7f5cbd6dbad7e1f218fce452c5807aac3c67afa6f; #[cfg(experimental_new_encoding = false)] const BALANCE_CONTRACT_ID = 0xf6cd545152ac83225e8e7df2efb5c6fa6e37bc9b9e977b5ea8103d28668925df; #[cfg(experimental_new_encoding = true)] -const BALANCE_CONTRACT_ID = 0x51088b17e33a9fbbcac387cd3e462571dfce54e340579d7130c5b6fe08793ea9; // AUTO-CONTRACT-ID ../../test_contracts/balance_test_contract --release +const BALANCE_CONTRACT_ID = 0xccf637b5b0071861f3074fcf963ef2339dab5d306d919b4c7e65024a7fbc64e6; // AUTO-CONTRACT-ID ../../test_contracts/balance_test_contract --release fn main() -> bool { let default_gas = 1_000_000_000_000; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/bal_opcode/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/bal_opcode/src/main.sw index 79c9b83161e..a739f0d408c 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/bal_opcode/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/bal_opcode/src/main.sw @@ -5,7 +5,7 @@ use balance_test_abi::BalanceTest; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0xf6cd545152ac83225e8e7df2efb5c6fa6e37bc9b9e977b5ea8103d28668925df; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x51088b17e33a9fbbcac387cd3e462571dfce54e340579d7130c5b6fe08793ea9; // AUTO-CONTRACT-ID ../../test_contracts/balance_test_contract --release +const CONTRACT_ID = 0xccf637b5b0071861f3074fcf963ef2339dab5d306d919b4c7e65024a7fbc64e6; // AUTO-CONTRACT-ID ../../test_contracts/balance_test_contract --release fn main() -> bool { let balance_test_contract = abi(BalanceTest, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_abi_with_tuples/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_abi_with_tuples/src/main.sw index 08ec336099c..57633b2de20 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_abi_with_tuples/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_abi_with_tuples/src/main.sw @@ -6,7 +6,7 @@ use abi_with_tuples::{MyContract, Location, Person}; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0xfdc14550c8aee742cd556d0ab7f378b7be0d3b1e6e086c097352e94590d4ed02; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x95a6752ed4ad94a442f54a90edcda5ff722889f6640c5ecc5dbde676443bad06; // AUTO-CONTRACT-ID ../../test_contracts/abi_with_tuples_contract --release +const CONTRACT_ID = 0x0328999650df8c33503c894fd6ac49b0299c9d64147feb69daa1606521dbe86e; // AUTO-CONTRACT-ID ../../test_contracts/abi_with_tuples_contract --release fn main() -> bool { let the_abi = abi(MyContract, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_basic_storage/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_basic_storage/src/main.sw index 142397cef20..4e2144117af 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_basic_storage/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_basic_storage/src/main.sw @@ -4,7 +4,7 @@ use basic_storage_abi::{BasicStorage, Quad}; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0x94db39f409a31b9f2ebcadeea44378e419208c20de90f5d8e1e33dc1523754cb; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0xa4ade9ba5b85a85758300bee7a0ea1b506d5f967e6e183ad6b09513b3925e59d; // AUTO-CONTRACT-ID ../../test_contracts/basic_storage --release +const CONTRACT_ID = 0x23afacfc8eaa13d36c3f2f4d764b66e53d284e4cd31477e8bd72b4ccc411022b; // AUTO-CONTRACT-ID ../../test_contracts/basic_storage --release fn main() -> u64 { let addr = abi(BasicStorage, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_contract_with_type_aliases/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_contract_with_type_aliases/src/main.sw index 275aa4be2b4..aacf8538eba 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_contract_with_type_aliases/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_contract_with_type_aliases/src/main.sw @@ -5,7 +5,7 @@ use contract_with_type_aliases_abi::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0x0cbeb6efe3104b460be769bdc4ea101ebf16ccc16f2d7b667ec3e1c7f5ce35b5; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x1a3297b8864ade29d4f35e2d9a81ccb9cbe9520d82554100fde724d5c2dcc468; // AUTO-CONTRACT-ID ../../test_contracts/contract_with_type_aliases --release +const CONTRACT_ID = 0xfffcb364f01ce902477fa73720ae48bfb8bc735447f75d55d441a76943a27a65; // AUTO-CONTRACT-ID ../../test_contracts/contract_with_type_aliases --release fn main() { let caller = abi(MyContract, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_increment_contract/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_increment_contract/src/main.sw index ec1ae9dd8e0..85deb2bb2ba 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_increment_contract/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_increment_contract/src/main.sw @@ -6,7 +6,7 @@ use dynamic_contract_call::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0xd1b4047af7ef111c023ab71069e01dc2abfde487c0a0ce1268e4f447e6c6e4c2; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x1ea00e7ace6ea3cc3928a4bd4eb6121da9c13dcc62351ee9c3cc33daf1244797; // AUTO-CONTRACT-ID ../../test_contracts/increment_contract --release +const CONTRACT_ID = 0x5229470a8bb907a909aba79325a347bd8849a8aceb9c8116e3d1c73ea4977b6d; // AUTO-CONTRACT-ID ../../test_contracts/increment_contract --release fn main() -> bool { let the_abi = abi(Incrementor, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_storage_enum/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_storage_enum/src/main.sw index d9e4eac9539..ac6240cfd81 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_storage_enum/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_storage_enum/src/main.sw @@ -5,7 +5,7 @@ use storage_enum_abi::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0xc601d11767195485a6654d566c67774134668863d8c797a8c69e8778fb1f89e9; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0xb362dfb21211b3ffad920cb6a200f3aa413066057229b6d64e0867a121ae2a52; // AUTO-CONTRACT-ID ../../test_contracts/storage_enum_contract --release +const CONTRACT_ID = 0x4bb9cb0a4b3df7981e702609cbce4b684b3d9c21e474e9988825f48fae81b06d; // AUTO-CONTRACT-ID ../../test_contracts/storage_enum_contract --release fn main() -> u64 { let caller = abi(StorageEnum, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_auth_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_auth_test/src/main.sw index 8b8bed75d36..6b47bf9d3a1 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_auth_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_auth_test/src/main.sw @@ -5,7 +5,7 @@ use auth_testing_abi::AuthTesting; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0xc2eec20491b53aab7232cbd27c31d15417b4e9daf0b89c74cc242ef1295f681f; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x17078468cc937c3653ad0d2df73255aae6fc95934d4765897f3950773cb32199; // AUTO-CONTRACT-ID ../../test_contracts/auth_testing_contract --release +const CONTRACT_ID = 0xbbd538c6fc4f6a805b4e178529e1460453aee648b5e49949bdfc8a12a585e7d2; // AUTO-CONTRACT-ID ../../test_contracts/auth_testing_contract --release // should be false in the case of a script fn main() -> bool { diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_context_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_context_test/src/main.sw index 798830b12ad..8da2675ccda 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_context_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_context_test/src/main.sw @@ -6,7 +6,7 @@ use context_testing_abi::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0x6054c11cda000f5990373a4d61929396165be4dfdd61d5b7bd26da60ab0d8577; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x250ab6ffd6a0412382833377802e0728a8c63adb43d62442aadff5daae0fbdc9; // AUTO-CONTRACT-ID ../../test_contracts/context_testing_contract --release +const CONTRACT_ID = 0x7821bf368390972d4892e1f382fd954fea5b567e533eed6fac0f173800647945; // AUTO-CONTRACT-ID ../../test_contracts/context_testing_contract --release fn main() -> bool { let gas: u64 = u64::max(); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/nested_struct_args_caller/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/nested_struct_args_caller/src/main.sw index a062c2b4cc5..ed163d5076d 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/nested_struct_args_caller/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/nested_struct_args_caller/src/main.sw @@ -5,7 +5,7 @@ use nested_struct_args_abi::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0xe63d33a1b3a6903808b379f6a41a72fa8a370e8b76626775e7d9d2f9c4c5da40; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x0eb746cc637d63dc62a9b3154b455cdb2017da824bb8c7b7b80bfe9783e1c494; // AUTO-CONTRACT-ID ../../test_contracts/nested_struct_args_contract --release +const CONTRACT_ID = 0x90fdb746b560d271261d8fab6eba6a4381f173432b7fa8c93e2765c38bca508b; // AUTO-CONTRACT-ID ../../test_contracts/nested_struct_args_contract --release fn main() -> bool { let caller = abi(NestedStructArgs, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/storage_access_caller/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/storage_access_caller/src/main.sw index 54ba110acca..eb9d9d24411 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/storage_access_caller/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/storage_access_caller/src/main.sw @@ -6,7 +6,7 @@ use std::hash::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0x3bc28acd66d327b8c1b9624c1fabfc07e9ffa1b5d71c2832c3bfaaf8f4b805e9; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x5a4e8650faa5f2d17aa9d7edcbe9c561c11e74fe1879bbb7b4c1a6950096fb53; // AUTO-CONTRACT-ID ../../test_contracts/storage_access_contract --release +const CONTRACT_ID = 0x3da675876942326fd4c66b079216742f75e5f15681271a5db54a9cf19a813b22; // AUTO-CONTRACT-ID ../../test_contracts/storage_access_contract --release fn main() -> bool { let caller = abi(StorageAccess, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/workspace_test/contract_multi_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/workspace_test/contract_multi_test/src/main.sw index c0e3a1b9067..61e416f17bd 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/workspace_test/contract_multi_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/workspace_test/contract_multi_test/src/main.sw @@ -17,16 +17,14 @@ fn test_foo() { #[test(should_revert)] fn test_fail() { - let contract_id = 0xad0bba17e0838ef859abe2693d8a5e3bc4e7cfb901601e30f4dc34999fda6335; // AUTO-CONTRACT-ID . - let caller = abi(MyContract, contract_id); + let caller = abi(MyContract, CONTRACT_ID); let result = caller.test_function {}(); assert(result == false) } #[test] fn test_success() { - let contract_id = 0xad0bba17e0838ef859abe2693d8a5e3bc4e7cfb901601e30f4dc34999fda6335; // AUTO-CONTRACT-ID . - let caller = abi(MyContract, contract_id); + let caller = abi(MyContract, CONTRACT_ID); let result = caller.test_function {}(); assert(result == true) } From cd95cdccbc121f8b52f7b7a8b043fb1b52de0fa2 Mon Sep 17 00:00:00 2001 From: Marcos Henrich Date: Thu, 5 Sep 2024 01:58:58 +0100 Subject: [PATCH 4/6] Fixes ABI alias metadata types. (#6494) ## Description Before this push, using an alias in a contract would produce an ABI with two distinct metadata types for tuples: one for `(_,_)` and another for `(u64,u64)`. With this change, aliases are bypassed and we only produce metadata for the string type of the inner alias type. If alias is `(u64, u64)` we will produce a metadatatype for `(_,_)`. Fixes #6488 ## Checklist - [x] I have linked to any relevant issues. - [x] 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. - [x] 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. --------- Co-authored-by: IGI-111 --- sway-core/src/abi_generation/abi_str.rs | 6 +- .../json_abi_oracle_new_encoding.json | 2 +- .../test_contracts/abi_with_alias/Forc.lock | 8 +++ .../test_contracts/abi_with_alias/Forc.toml | 9 +++ .../abi_with_alias/json_abi_oracle.json | 63 +++++++++++++++++++ .../json_abi_oracle_new_encoding.json | 63 +++++++++++++++++++ .../test_contracts/abi_with_alias/src/main.sw | 15 +++++ .../test_contracts/abi_with_alias/test.toml | 3 + 8 files changed, 166 insertions(+), 3 deletions(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/abi_with_alias/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/abi_with_alias/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/abi_with_alias/json_abi_oracle.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/abi_with_alias/json_abi_oracle_new_encoding.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/abi_with_alias/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/abi_with_alias/test.toml diff --git a/sway-core/src/abi_generation/abi_str.rs b/sway-core/src/abi_generation/abi_str.rs index 339a9453f81..2972c9cee0e 100644 --- a/sway-core/src/abi_generation/abi_str.rs +++ b/sway-core/src/abi_generation/abi_str.rs @@ -28,10 +28,12 @@ impl TypeId { &*type_engine.get(resolved_type_id), ) { (TypeInfo::Custom { .. }, TypeInfo::Struct { .. }) - | (TypeInfo::Custom { .. }, TypeInfo::Enum { .. }) - | (TypeInfo::Custom { .. }, TypeInfo::Alias { .. }) => type_engine + | (TypeInfo::Custom { .. }, TypeInfo::Enum { .. }) => type_engine .get(resolved_type_id) .abi_str(ctx, engines, true), + (_, TypeInfo::Alias { ty, .. }) => { + ty.type_id.get_abi_type_str(ctx, engines, ty.type_id) + } (TypeInfo::Tuple(fields), TypeInfo::Tuple(resolved_fields)) => { assert_eq!(fields.len(), resolved_fields.len()); let field_strs = resolved_fields diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_generics/json_abi_oracle_new_encoding.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_generics/json_abi_oracle_new_encoding.json index 6d485af4964..64d80ab9878 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_generics/json_abi_oracle_new_encoding.json +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_generics/json_abi_oracle_new_encoding.json @@ -52,7 +52,7 @@ } ], "metadataTypeId": 0, - "type": "(struct TwoGenerics, struct OneGeneric)" + "type": "(_, _)" }, { "metadataTypeId": 1, diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/abi_with_alias/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/abi_with_alias/Forc.lock new file mode 100644 index 00000000000..e85a8258d1c --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/abi_with_alias/Forc.lock @@ -0,0 +1,8 @@ +[[package]] +name = "abi_with_alias" +source = "member" +dependencies = ["core"] + +[[package]] +name = "core" +source = "path+from-root-DE4DCECD674C309C" diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/abi_with_alias/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/abi_with_alias/Forc.toml new file mode 100644 index 00000000000..402ce909bea --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/abi_with_alias/Forc.toml @@ -0,0 +1,9 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +implicit-std = false +license = "Apache-2.0" +name = "abi_with_alias" + +[dependencies] +core = { path = "../../../../../../../sway-lib-core" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/abi_with_alias/json_abi_oracle.json b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/abi_with_alias/json_abi_oracle.json new file mode 100644 index 00000000000..acc54cf39b3 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/abi_with_alias/json_abi_oracle.json @@ -0,0 +1,63 @@ +{ + "concreteTypes": [ + { + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "type": "()" + }, + { + "concreteTypeId": "41bd1a98f0a59642d8f824c805b798a5f268d1f7d05808eb05c4189c493f1be0", + "metadataTypeId": 0, + "type": "(u64, u64)" + } + ], + "configurables": [], + "encodingVersion": "1", + "functions": [ + { + "attributes": null, + "inputs": [ + { + "concreteTypeId": "41bd1a98f0a59642d8f824c805b798a5f268d1f7d05808eb05c4189c493f1be0", + "name": "arg1" + } + ], + "name": "aliased_tuple", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": null, + "inputs": [ + { + "concreteTypeId": "41bd1a98f0a59642d8f824c805b798a5f268d1f7d05808eb05c4189c493f1be0", + "name": "_arg1" + } + ], + "name": "tuple", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ], + "loggedTypes": [], + "messagesTypes": [], + "metadataTypes": [ + { + "components": [ + { + "name": "__tuple_element", + "typeId": 1 + }, + { + "name": "__tuple_element", + "typeId": 1 + } + ], + "metadataTypeId": 0, + "type": "(_, _)" + }, + { + "metadataTypeId": 1, + "type": "u64" + } + ], + "programType": "contract", + "specVersion": "1" +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/abi_with_alias/json_abi_oracle_new_encoding.json b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/abi_with_alias/json_abi_oracle_new_encoding.json new file mode 100644 index 00000000000..acc54cf39b3 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/abi_with_alias/json_abi_oracle_new_encoding.json @@ -0,0 +1,63 @@ +{ + "concreteTypes": [ + { + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "type": "()" + }, + { + "concreteTypeId": "41bd1a98f0a59642d8f824c805b798a5f268d1f7d05808eb05c4189c493f1be0", + "metadataTypeId": 0, + "type": "(u64, u64)" + } + ], + "configurables": [], + "encodingVersion": "1", + "functions": [ + { + "attributes": null, + "inputs": [ + { + "concreteTypeId": "41bd1a98f0a59642d8f824c805b798a5f268d1f7d05808eb05c4189c493f1be0", + "name": "arg1" + } + ], + "name": "aliased_tuple", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": null, + "inputs": [ + { + "concreteTypeId": "41bd1a98f0a59642d8f824c805b798a5f268d1f7d05808eb05c4189c493f1be0", + "name": "_arg1" + } + ], + "name": "tuple", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ], + "loggedTypes": [], + "messagesTypes": [], + "metadataTypes": [ + { + "components": [ + { + "name": "__tuple_element", + "typeId": 1 + }, + { + "name": "__tuple_element", + "typeId": 1 + } + ], + "metadataTypeId": 0, + "type": "(_, _)" + }, + { + "metadataTypeId": 1, + "type": "u64" + } + ], + "programType": "contract", + "specVersion": "1" +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/abi_with_alias/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/abi_with_alias/src/main.sw new file mode 100644 index 00000000000..c75439d8e82 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/abi_with_alias/src/main.sw @@ -0,0 +1,15 @@ +contract; + +type AliasedTuple = (u64, u64); + +abi MyContract { + fn tuple(arg1: (u64, u64)); // Inline + fn aliased_tuple(arg1: AliasedTuple); // Alias +} + +impl MyContract for Contract { + fn tuple(_arg1: (u64, u64)) { + } + fn aliased_tuple(arg1: AliasedTuple) { + } +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/abi_with_alias/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/abi_with_alias/test.toml new file mode 100644 index 00000000000..2bad8b530a0 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/abi_with_alias/test.toml @@ -0,0 +1,3 @@ +category = "compile" +validate_abi = true +expected_warnings = 1 From de242ad1e4d4cc2de98848a29c137cb8d36bc70c Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite Date: Thu, 5 Sep 2024 02:22:11 +0100 Subject: [PATCH 5/6] Test for contract address being a complex expression (#6495) ## Description This PR improves tests for https://github.com/FuelLabs/sway/pull/6490. Now we have one contract test where the contract address comes from a complex expression. ## 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. --- .../array_of_structs_caller/src/main.sw | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/array_of_structs_caller/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/array_of_structs_caller/src/main.sw index 7537a1e5881..aba7556d410 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/array_of_structs_caller/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/array_of_structs_caller/src/main.sw @@ -8,8 +8,13 @@ const CONTRACT_ID = 0x14ed3cd06c2947248f69d54bfa681fe40d26267be84df7e19e253622b7 #[cfg(experimental_new_encoding = true)] const CONTRACT_ID = 0xf9f1fec713b977865880637fc24e58cda9e69f6e711ed8e5efe7de9ce51c88ec; // AUTO-CONTRACT-ID ../../test_contracts/array_of_structs_contract --release +fn get_address() -> Option { + Some(CONTRACT_ID.into()) +} + fn main() -> u64 { - let addr = abi(TestContract, CONTRACT_ID); + // Test address being a complex expression + let addr = abi(TestContract, get_address().unwrap().into()); let input = [Wrapper { id: Id { From 8959f118f4c076502a73c9aeaa59d9b730571514 Mon Sep 17 00:00:00 2001 From: GearedPaladin <98220490+GearedPaladin@users.noreply.github.com> Date: Thu, 5 Sep 2024 11:39:23 +0530 Subject: [PATCH 6/6] Add missing docs to primitive_conversions library in standard library (#5627) ## Description ## Checklist - [ ] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] 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. --------- Co-authored-by: Sophie Dankel <47993817+sdankel@users.noreply.github.com> Co-authored-by: IGI-111 Co-authored-by: Cameron Carstens --- sway-lib-std/src/primitive_conversions/str.sw | 14 ++++ sway-lib-std/src/primitive_conversions/u16.sw | 22 +++++++ sway-lib-std/src/primitive_conversions/u32.sw | 44 +++++++++++++ sway-lib-std/src/primitive_conversions/u64.sw | 66 +++++++++++++++++++ 4 files changed, 146 insertions(+) diff --git a/sway-lib-std/src/primitive_conversions/str.sw b/sway-lib-std/src/primitive_conversions/str.sw index 27f75b41d92..4ace1dd03a6 100644 --- a/sway-lib-std/src/primitive_conversions/str.sw +++ b/sway-lib-std/src/primitive_conversions/str.sw @@ -3,6 +3,20 @@ library; use ::option::Option::{self, *}; impl str { + /// Attempts to convert the string slice into a string array. + /// + /// # Returns + /// + /// * [Option] - `Some(str_array)` if the lengths of the `S` str_array type and the string slice's lengths match. Else `None`. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let string_slice = "abcd"; + /// let string_array: str[4] = a.try_as_str_array().unwrap(); + /// } + /// ``` pub fn try_as_str_array(self) -> Option { __assert_is_str_array::(); let str_size = __size_of_str_array::(); diff --git a/sway-lib-std/src/primitive_conversions/u16.sw b/sway-lib-std/src/primitive_conversions/u16.sw index bced8a770a5..5a032306332 100644 --- a/sway-lib-std/src/primitive_conversions/u16.sw +++ b/sway-lib-std/src/primitive_conversions/u16.sw @@ -5,6 +5,28 @@ use ::option::Option::{self, *}; use ::u128::U128; impl u16 { + /// Attempts to convert the u16 value into a u8 value. + /// + /// # Additional Information + /// + /// The max value a u8 can represent is 255. + /// + /// # Returns + /// + /// [Option] - `Some(u8)` if the u16 is less than or equal to the max u8 value. Else `None`. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let val = 255_u16.try_as_u8(); + /// assert(val == Some(255_u8)); + /// + /// // Conversion fails as value is above the max a u8 can represent. + /// let val2 = 256_u16.try_as_u8(); + /// assert(val == None); + /// } + /// ``` pub fn try_as_u8(self) -> Option { if self <= u8::max().as_u16() { Some(asm(input: self) { diff --git a/sway-lib-std/src/primitive_conversions/u32.sw b/sway-lib-std/src/primitive_conversions/u32.sw index ca5a0722680..8ffa2ca2605 100644 --- a/sway-lib-std/src/primitive_conversions/u32.sw +++ b/sway-lib-std/src/primitive_conversions/u32.sw @@ -5,6 +5,28 @@ use ::option::Option::{self, *}; use ::u128::U128; impl u32 { + /// Attempts to convert the u32 value into a u8 value. + /// + /// # Additional Information + /// + /// The max value a u8 can represent is 255. + /// + /// # Returns + /// + /// [Option] - `Some(u8)` if the u32 is less than or equal to the max u8 value. Else `None`. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let val = 255_u32.try_as_u8(); + /// assert(val == Some(255_u8)); + /// + /// // Conversion fails as value is above the max a u8 can represent. + /// let val2 = 256_u32.try_as_u8(); + /// assert(val == None); + /// } + /// ``` pub fn try_as_u8(self) -> Option { if self <= u8::max().as_u32() { Some(asm(input: self) { @@ -15,6 +37,28 @@ impl u32 { } } + /// Attempts to convert the u32 value into a u16 value. + /// + /// # Additional Information + /// + /// The max value a u16 can represent is 65_535. + /// + /// # Returns + /// + /// [Option] - `Some(u16)` if the u32 is less than or equal to the max u16 value. Else `None`. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let val = 65_535_u32.try_as_u16(); + /// assert(val == Some(65_535_u16)); + /// + /// // Conversion fails as value is above the max a u16 can represent. + /// let val2 = 65_536_u32.try_as_u16(); + /// assert(val == None); + /// } + /// ``` pub fn try_as_u16(self) -> Option { if self <= u16::max().as_u32() { Some(asm(input: self) { diff --git a/sway-lib-std/src/primitive_conversions/u64.sw b/sway-lib-std/src/primitive_conversions/u64.sw index b373bb85ae9..92267638a1d 100644 --- a/sway-lib-std/src/primitive_conversions/u64.sw +++ b/sway-lib-std/src/primitive_conversions/u64.sw @@ -5,6 +5,28 @@ use ::option::Option::{self, *}; use ::u128::U128; impl u64 { + /// Attempts to convert the u64 value into a u8 value. + /// + /// # Additional Information + /// + /// The max value a u8 can represent is 255. + /// + /// # Returns + /// + /// [Option] - `Some(u8)` if the u64 is less than or equal to the max u8 value. Else `None`. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let val = 255_u64.try_as_u8(); + /// assert(val == Some(255_u8)); + /// + /// // Conversion fails as value is above the max a u8 can represent. + /// let val2 = 256_u64.try_as_u8(); + /// assert(val == None); + /// } + /// ``` pub fn try_as_u8(self) -> Option { if self <= u8::max().as_u64() { Some(asm(input: self) { @@ -15,6 +37,28 @@ impl u64 { } } + /// Attempts to convert the u64 value into a u16 value. + /// + /// # Additional Information + /// + /// The max value a u16 can represent is 65_535. + /// + /// # Returns + /// + /// [Option] - `Some(u16)` if the u64 is less than or equal to the max u16 value. Else `None`. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let val = 65_535_u64.try_as_u16(); + /// assert(val == Some(65_535_u16)); + /// + /// // Conversion fails as value is above the max a u16 can represent. + /// let val2 = 65_536_u64.try_as_u16(); + /// assert(val == None); + /// } + /// ``` pub fn try_as_u16(self) -> Option { if self <= u16::max().as_u64() { Some(asm(input: self) { @@ -25,6 +69,28 @@ impl u64 { } } + /// Attempts to convert the u64 value into a u32 value. + /// + /// # Additional Information + /// + /// The max value a u32 can represent is 4_294_967_295. + /// + /// # Returns + /// + /// [Option] - `Some(u32)` if the u64 is less than or equal to the max u32 value. Else `None`. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let val = 4_294_967_295_u64.try_as_u32(); + /// assert(val == Some(4_294_967_295_u32)); + /// + /// // Conversion fails as value is above the max a u32 can represent. + /// let val2 = 4_294_967_296_u64.try_as_u32(); + /// assert(val == None); + /// } + /// ``` pub fn try_as_u32(self) -> Option { if self <= u32::max().as_u64() { Some(asm(input: self) {