From f871a48807e97bf17d392f27bb401fd8d36a7e24 Mon Sep 17 00:00:00 2001 From: IGI-111 Date: Tue, 25 Feb 2025 12:48:27 +0400 Subject: [PATCH 1/3] Extend `#[deprecated]` support (#6944) ## Description Add support for the `#[deprecated]` attribute to functions, enums, struct items, enum variants and propagate deprecation check exhaustively throughout expressions variants. Partially addresses #6942. Support for deprecating traits, abis and the methods thereof in their definitions is still missing, as well as scrutinees and storage fields. ## Checklist - [x] 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). - [x] 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. --- sway-core/src/language/ty/code_block.rs | 15 +- .../src/language/ty/expression/expression.rs | 215 ++++++++++++++++-- sway-lib-std/src/ecr.sw | 2 + sway-lib-std/src/vm/evm/ecr.sw | 1 + .../language/deprecated/src/main.sw | 41 +++- .../should_pass/language/deprecated/test.toml | 21 +- 6 files changed, 271 insertions(+), 24 deletions(-) diff --git a/sway-core/src/language/ty/code_block.rs b/sway-core/src/language/ty/code_block.rs index 77a841ff4bc..0284a72f6f7 100644 --- a/sway-core/src/language/ty/code_block.rs +++ b/sway-core/src/language/ty/code_block.rs @@ -1,6 +1,6 @@ use crate::{ decl_engine::*, engine_threading::*, language::ty::*, semantic_analysis::TypeCheckContext, - type_system::*, + transform::AllowDeprecatedState, type_system::*, }; use serde::{Deserialize, Serialize}; use std::hash::Hasher; @@ -13,6 +13,19 @@ pub struct TyCodeBlock { pub(crate) whole_block_span: Span, } +impl TyCodeBlock { + pub(crate) fn check_deprecated( + &self, + engines: &Engines, + handler: &Handler, + allow_deprecated: &mut AllowDeprecatedState, + ) { + for n in self.contents.iter() { + n.check_deprecated(engines, handler, allow_deprecated); + } + } +} + impl Default for TyCodeBlock { fn default() -> Self { Self { diff --git a/sway-core/src/language/ty/expression/expression.rs b/sway-core/src/language/ty/expression/expression.rs index f94902d2368..7929095e207 100644 --- a/sway-core/src/language/ty/expression/expression.rs +++ b/sway-core/src/language/ty/expression/expression.rs @@ -437,6 +437,81 @@ impl TyExpression { } match &self.expression { + TyExpressionVariant::Literal(..) => {} + TyExpressionVariant::FunctionApplication { + call_path, + fn_ref, + arguments, + .. + } => { + for (_, expr) in arguments.iter() { + expr.check_deprecated(engines, handler, allow_deprecated); + } + + let fn_ty = engines.de().get(fn_ref); + if let Some(TyDecl::ImplSelfOrTrait(t)) = &fn_ty.implementing_type { + let t = &engines.de().get(&t.decl_id).implementing_for; + if let TypeInfo::Struct(struct_id) = &*engines.te().get(t.type_id) { + let s = engines.de().get(struct_id); + emit_warning_if_deprecated( + &s.attributes, + &call_path.span(), + handler, + "deprecated struct", + allow_deprecated, + ); + } + } + + emit_warning_if_deprecated( + &fn_ty.attributes, + &call_path.span(), + handler, + "deprecated function", + allow_deprecated, + ); + } + TyExpressionVariant::LazyOperator { lhs, rhs, .. } => { + lhs.check_deprecated(engines, handler, allow_deprecated); + rhs.check_deprecated(engines, handler, allow_deprecated); + } + TyExpressionVariant::ConstantExpression { span, decl, .. } => { + emit_warning_if_deprecated( + &decl.attributes, + span, + handler, + "deprecated constant", + allow_deprecated, + ); + } + TyExpressionVariant::ConfigurableExpression { span, decl, .. } => { + emit_warning_if_deprecated( + &decl.attributes, + span, + handler, + "deprecated configurable", + allow_deprecated, + ); + } + TyExpressionVariant::VariableExpression { .. } => {} + TyExpressionVariant::Tuple { fields } => { + for e in fields.iter() { + e.check_deprecated(engines, handler, allow_deprecated); + } + } + TyExpressionVariant::ArrayExplicit { contents, .. } => { + for e in contents.iter() { + e.check_deprecated(engines, handler, allow_deprecated); + } + } + TyExpressionVariant::ArrayRepeat { value, length, .. } => { + value.check_deprecated(engines, handler, allow_deprecated); + length.check_deprecated(engines, handler, allow_deprecated); + } + TyExpressionVariant::ArrayIndex { prefix, index } => { + prefix.check_deprecated(engines, handler, allow_deprecated); + index.check_deprecated(engines, handler, allow_deprecated); + } TyExpressionVariant::StructExpression { struct_id, instantiation_span, @@ -451,26 +526,132 @@ impl TyExpression { allow_deprecated, ); } - TyExpressionVariant::FunctionApplication { - call_path, fn_ref, .. + TyExpressionVariant::CodeBlock(block) => { + block.check_deprecated(engines, handler, allow_deprecated); + } + TyExpressionVariant::FunctionParameter => {} + TyExpressionVariant::MatchExp { + desugared, + //scrutinees, + .. } => { - if let Some(TyDecl::ImplSelfOrTrait(t)) = - &engines.de().get(fn_ref).implementing_type - { - let t = &engines.de().get(&t.decl_id).implementing_for; - if let TypeInfo::Struct(struct_id) = &*engines.te().get(t.type_id) { - let s = engines.de().get(struct_id); - emit_warning_if_deprecated( - &s.attributes, - &call_path.span(), - handler, - "deprecated struct", - allow_deprecated, - ); - } + desugared.check_deprecated(engines, handler, allow_deprecated); + // TODO: check scrutinees if necessary + } + TyExpressionVariant::IfExp { + condition, + then, + r#else, + } => { + condition.check_deprecated(engines, handler, allow_deprecated); + then.check_deprecated(engines, handler, allow_deprecated); + if let Some(e) = r#else { + e.check_deprecated(engines, handler, allow_deprecated); } } - _ => {} + TyExpressionVariant::AsmExpression { .. } => {} + TyExpressionVariant::StructFieldAccess { + prefix, + field_to_access, + field_instantiation_span, + .. + } => { + prefix.check_deprecated(engines, handler, allow_deprecated); + emit_warning_if_deprecated( + &field_to_access.attributes, + field_instantiation_span, + handler, + "deprecated struct field", + allow_deprecated, + ); + } + TyExpressionVariant::TupleElemAccess { prefix, .. } => { + prefix.check_deprecated(engines, handler, allow_deprecated); + } + TyExpressionVariant::EnumInstantiation { + enum_ref, + tag, + contents, + variant_instantiation_span, + .. + } => { + let enum_ty = engines.de().get(enum_ref); + emit_warning_if_deprecated( + &enum_ty.attributes, + variant_instantiation_span, + handler, + "deprecated enum", + allow_deprecated, + ); + if let Some(variant_decl) = enum_ty.variants.get(*tag) { + emit_warning_if_deprecated( + &variant_decl.attributes, + variant_instantiation_span, + handler, + "deprecated enum variant", + allow_deprecated, + ); + } + if let Some(expr) = contents { + expr.check_deprecated(engines, handler, allow_deprecated); + } + } + TyExpressionVariant::AbiCast { address, .. } => { + // TODO: check abi name? + address.check_deprecated(engines, handler, allow_deprecated); + } + TyExpressionVariant::StorageAccess(access) => { + // TODO: check storage access? + if let Some(expr) = &access.key_expression { + expr.check_deprecated(engines, handler, allow_deprecated); + } + } + TyExpressionVariant::IntrinsicFunction(kind) => { + for arg in kind.arguments.iter() { + arg.check_deprecated(engines, handler, allow_deprecated); + } + } + TyExpressionVariant::AbiName(..) => {} + TyExpressionVariant::EnumTag { exp } => { + exp.check_deprecated(engines, handler, allow_deprecated); + } + TyExpressionVariant::UnsafeDowncast { + exp, + //variant, + .. + } => { + exp.check_deprecated(engines, handler, allow_deprecated); + // TODO: maybe check variant? + } + TyExpressionVariant::WhileLoop { condition, body } => { + condition.check_deprecated(engines, handler, allow_deprecated); + body.check_deprecated(engines, handler, allow_deprecated); + } + TyExpressionVariant::ForLoop { desugared } => { + desugared.check_deprecated(engines, handler, allow_deprecated); + } + TyExpressionVariant::Break => {} + TyExpressionVariant::Continue => {} + TyExpressionVariant::Reassignment(reass) => { + if let TyReassignmentTarget::Deref(expr) = &reass.lhs { + expr.check_deprecated(engines, handler, allow_deprecated); + } + reass + .rhs + .check_deprecated(engines, handler, allow_deprecated); + } + TyExpressionVariant::ImplicitReturn(expr) => { + expr.check_deprecated(engines, handler, allow_deprecated); + } + TyExpressionVariant::Return(expr) => { + expr.check_deprecated(engines, handler, allow_deprecated); + } + TyExpressionVariant::Ref(expr) => { + expr.check_deprecated(engines, handler, allow_deprecated); + } + TyExpressionVariant::Deref(expr) => { + expr.check_deprecated(engines, handler, allow_deprecated); + } } } diff --git a/sway-lib-std/src/ecr.sw b/sway-lib-std/src/ecr.sw index 33ac4fb9924..28f6ccf4560 100644 --- a/sway-lib-std/src/ecr.sw +++ b/sway-lib-std/src/ecr.sw @@ -217,6 +217,7 @@ pub fn ed_verify(public_key: b256, signature: B512, msg: Bytes) -> Result Result { let pub_key_result = ec_recover(signature, msg_hash); @@ -263,6 +264,7 @@ pub fn ec_recover_address(signature: B512, msg_hash: b256) -> Result Result { let pub_key_result = ec_recover_r1(signature, msg_hash); diff --git a/sway-lib-std/src/vm/evm/ecr.sw b/sway-lib-std/src/vm/evm/ecr.sw index 57f0565824b..f97b5f52428 100644 --- a/sway-lib-std/src/vm/evm/ecr.sw +++ b/sway-lib-std/src/vm/evm/ecr.sw @@ -36,6 +36,7 @@ use ::vm::evm::evm_address::EvmAddress; /// } /// ``` #[deprecated(note = "std:vm::evm:ecr has been replaced by std::crypto, and is no longer maintained")] +#[allow(deprecated)] pub fn ec_recover_evm_address( signature: B512, msg_hash: b256, diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/deprecated/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/deprecated/src/main.sw index a3dbe4e6b05..1c581d84ec0 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/deprecated/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/deprecated/src/main.sw @@ -1,15 +1,46 @@ -library; +script; #[deprecated] struct A { + #[deprecated] + a: u64, + b: u64, +} + +impl A { + #[deprecated] + fn fun(self) {} } #[deprecated] enum B { - A: () + A: (), + #[deprecated] + B: (), } -pub fn f() { - let _ = A {}; + +#[deprecated] +fn depr(_a: A) {} + +fn fun(_a: A) {} + +#[deprecated] +fn depr_b(_b: B) {} + +// TODO: support for traits, abis and their methods +pub fn main() { + let a = A { a: 0, b: 0 }; + let b = B::A; + depr(a); + depr(A { a: 0, b: 0 }); + depr_b(b); + depr_b(B::A); + fun(a); + fun(A { a: 0, b: 0 }); + let _ = a.a; + let _ = a.b; let _ = B::A; -} \ No newline at end of file + let _ = B::B; + a.fun(); +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/deprecated/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/deprecated/test.toml index 6d3bec6fe46..a32b777862b 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/deprecated/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/deprecated/test.toml @@ -1,4 +1,23 @@ category = "compile" -expected_warnings = 1 +expected_warnings = 20 +# check: $()deprecated struct field # check: $()deprecated struct +# check: $()deprecated enum +# check: $()deprecated enum +# check: $()deprecated enum variant +# check: $()deprecated struct +# check: $()deprecated enum +# check: $()deprecated function +# check: $()deprecated struct +# check: $()deprecated function +# check: $()deprecated function +# check: $()deprecated enum +# check: $()deprecated function +# check: $()deprecated struct +# check: $()deprecated struct field +# check: $()deprecated enum +# check: $()deprecated enum +# check: $()deprecated enum variant +# check: $()deprecated struct +# check: $()deprecated function From a879ffbbb1db024fa4a5f86b8bbf409b2bfc80bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ron=C4=8Devi=C4=87?= Date: Tue, 25 Feb 2025 10:59:51 +0100 Subject: [PATCH 2/3] Add `bldd` case to `Op::parse_opcode()` (#6957) ## Description The `bldd` opcode was not covered in the `Op::parse_opcode()` which resulted in `Unknown opcode: "bldd"` error. The remaining part of the `bldd` opcode integration chain is already implemented in #6254. ## 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) - [ ] 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. --- sway-core/src/asm_lang/mod.rs | 4 ++++ .../should_pass/ecall/ecall_basic/Forc.lock | 8 -------- .../should_pass/ecall/ecall_basic/test.toml | 1 - .../language/asm/instructions/bldd/Forc.lock | 3 +++ .../language/asm/instructions/bldd/Forc.toml | 6 ++++++ .../language/asm/instructions/bldd/src/main.sw | 10 ++++++++++ .../language/asm/instructions/bldd/test.toml | 1 + .../language/asm/instructions/ecall/Forc.lock | 3 +++ .../language/asm/instructions/ecall/Forc.toml | 6 ++++++ .../asm/instructions/ecall}/src/main.sw | 4 ++-- .../language/asm/instructions/ecall/test.toml | 1 + .../instructions/wqxx}/Forc.lock | 14 +++++++------- .../asm/instructions/wqxx}/Forc.toml | 5 ++--- .../instructions/wqxx}/src/main.sw | 0 .../instructions/wqxx}/test.toml | 0 .../language/asm_wqxx_instructions/Forc.toml | 8 -------- 16 files changed, 45 insertions(+), 29 deletions(-) delete mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/ecall/ecall_basic/Forc.lock delete mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/ecall/ecall_basic/test.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/bldd/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/bldd/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/bldd/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/bldd/test.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/ecall/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/ecall/Forc.toml rename test/src/e2e_vm_tests/test_programs/should_pass/{ecall/ecall_basic => language/asm/instructions/ecall}/src/main.sw (77%) create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/ecall/test.toml rename test/src/e2e_vm_tests/test_programs/should_pass/language/{asm_wqxx_instructions => asm/instructions/wqxx}/Forc.lock (52%) rename test/src/e2e_vm_tests/test_programs/should_pass/{ecall/ecall_basic => language/asm/instructions/wqxx}/Forc.toml (52%) rename test/src/e2e_vm_tests/test_programs/should_pass/language/{asm_wqxx_instructions => asm/instructions/wqxx}/src/main.sw (100%) rename test/src/e2e_vm_tests/test_programs/should_pass/language/{asm_wqxx_instructions => asm/instructions/wqxx}/test.toml (100%) delete mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/asm_wqxx_instructions/Forc.toml diff --git a/sway-core/src/asm_lang/mod.rs b/sway-core/src/asm_lang/mod.rs index aabea4edfc8..91feeb1264a 100644 --- a/sway-core/src/asm_lang/mod.rs +++ b/sway-core/src/asm_lang/mod.rs @@ -596,6 +596,10 @@ impl Op { let (r1, r2, r3, i0) = three_regs_imm_06(handler, args, immediate, whole_op_span)?; VirtualOp::LDC(r1, r2, r3, i0) } + "bldd" => { + let (r1, r2, r3, r4) = four_regs(handler, args, immediate, whole_op_span)?; + VirtualOp::BLDD(r1, r2, r3, r4) + } "log" => { let (r1, r2, r3, r4) = four_regs(handler, args, immediate, whole_op_span)?; VirtualOp::LOG(r1, r2, r3, r4) diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/ecall/ecall_basic/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/ecall/ecall_basic/Forc.lock deleted file mode 100644 index cd43bbf78d8..00000000000 --- a/test/src/e2e_vm_tests/test_programs/should_pass/ecall/ecall_basic/Forc.lock +++ /dev/null @@ -1,8 +0,0 @@ -[[package]] -name = "core" -source = "path+from-root-02C557D3012ABF18" - -[[package]] -name = "ecall_basic" -source = "member" -dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/ecall/ecall_basic/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/ecall/ecall_basic/test.toml deleted file mode 100644 index 0f3f6d7e866..00000000000 --- a/test/src/e2e_vm_tests/test_programs/should_pass/ecall/ecall_basic/test.toml +++ /dev/null @@ -1 +0,0 @@ -category = "unit_tests_pass" diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/bldd/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/bldd/Forc.lock new file mode 100644 index 00000000000..b7234531207 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/bldd/Forc.lock @@ -0,0 +1,3 @@ +[[package]] +name = "bldd" +source = "member" diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/bldd/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/bldd/Forc.toml new file mode 100644 index 00000000000..43b72c376c0 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/bldd/Forc.toml @@ -0,0 +1,6 @@ +[project] +authors = ["Fuel Labs "] +license = "Apache-2.0" +name = "bldd" +entry = "main.sw" +implicit-std = false \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/bldd/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/bldd/src/main.sw new file mode 100644 index 00000000000..6377b6e9929 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/bldd/src/main.sw @@ -0,0 +1,10 @@ +library; + +// Intentionally not using `b256::zero()` to avoid dependency to `core`. +const B256_ZERO: b256 = 0x0000000000000000000000000000000000000000000000000000000000000000; + +pub fn main() { + asm(r1: B256_ZERO, r2: B256_ZERO, r3: 42u64, r4: 21u64) { + bldd r1 r2 r3 r4; + } +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/bldd/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/bldd/test.toml new file mode 100644 index 00000000000..e816041d3f8 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/bldd/test.toml @@ -0,0 +1 @@ +category = "compile" diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/ecall/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/ecall/Forc.lock new file mode 100644 index 00000000000..c877dd0642d --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/ecall/Forc.lock @@ -0,0 +1,3 @@ +[[package]] +name = "ecall" +source = "member" diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/ecall/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/ecall/Forc.toml new file mode 100644 index 00000000000..2828da2b86f --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/ecall/Forc.toml @@ -0,0 +1,6 @@ +[project] +authors = ["Fuel Labs "] +license = "Apache-2.0" +name = "ecall" +entry = "main.sw" +implicit-std = false \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/ecall/ecall_basic/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/ecall/src/main.sw similarity index 77% rename from test/src/e2e_vm_tests/test_programs/should_pass/ecall/ecall_basic/src/main.sw rename to test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/ecall/src/main.sw index 8e5d877eaf5..a0c83888d98 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/ecall/ecall_basic/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/ecall/src/main.sw @@ -1,6 +1,6 @@ -script; +library; -fn main() { +pub fn main() { asm(r1: 1u64, r2: 2u32, r3: 3u32, r4: 4u32) { ecal r1 r2 r3 r4; } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/ecall/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/ecall/test.toml new file mode 100644 index 00000000000..e816041d3f8 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/ecall/test.toml @@ -0,0 +1 @@ +category = "compile" diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/asm_wqxx_instructions/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/wqxx/Forc.lock similarity index 52% rename from test/src/e2e_vm_tests/test_programs/should_pass/language/asm_wqxx_instructions/Forc.lock rename to test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/wqxx/Forc.lock index 3b576dee330..801eb46b57f 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/asm_wqxx_instructions/Forc.lock +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/wqxx/Forc.lock @@ -1,13 +1,13 @@ -[[package]] -name = "asm_wqxx_instructions" -source = "member" -dependencies = ["std"] - [[package]] name = "core" -source = "path+from-root-DEA77F133437397D" +source = "path+from-root-6CA79EAC12B0D10A" [[package]] name = "std" -source = "path+from-root-DEA77F133437397D" +source = "path+from-root-6CA79EAC12B0D10A" dependencies = ["core"] + +[[package]] +name = "wqxx" +source = "member" +dependencies = ["std"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/ecall/ecall_basic/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/wqxx/Forc.toml similarity index 52% rename from test/src/e2e_vm_tests/test_programs/should_pass/ecall/ecall_basic/Forc.toml rename to test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/wqxx/Forc.toml index 13c1b6e9982..f97c1eb9aa1 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/ecall/ecall_basic/Forc.toml +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/wqxx/Forc.toml @@ -1,9 +1,8 @@ [project] -name = "ecall_basic" authors = ["Fuel Labs "] entry = "main.sw" -implicit-std = false license = "Apache-2.0" +name = "wqxx" [dependencies] -core = { path = "../../../../../../../sway-lib-core" } +std = { path = "../../../../../../reduced_std_libs/sway-lib-std-assert" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/asm_wqxx_instructions/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/wqxx/src/main.sw similarity index 100% rename from test/src/e2e_vm_tests/test_programs/should_pass/language/asm_wqxx_instructions/src/main.sw rename to test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/wqxx/src/main.sw diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/asm_wqxx_instructions/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/wqxx/test.toml similarity index 100% rename from test/src/e2e_vm_tests/test_programs/should_pass/language/asm_wqxx_instructions/test.toml rename to test/src/e2e_vm_tests/test_programs/should_pass/language/asm/instructions/wqxx/test.toml diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/asm_wqxx_instructions/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/asm_wqxx_instructions/Forc.toml deleted file mode 100644 index c44f1f66715..00000000000 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/asm_wqxx_instructions/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "asm_wqxx_instructions" - -[dependencies] -std = { path = "../../../../reduced_std_libs/sway-lib-std-assert" } From a090937bef418fe42a8bc0991e944d09f7ad6ea8 Mon Sep 17 00:00:00 2001 From: SwayStar123 <46050679+SwayStar123@users.noreply.github.com> Date: Tue, 25 Feb 2025 19:26:11 +0530 Subject: [PATCH 3/3] Add as_u256 for U128 (#6951) ## Description Adds the conversion helper for U128 ## Checklist - [x] 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). - [ ] 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. --- sway-lib-std/src/u128.sw | 22 ++++++++++++ .../u128_inline_tests/src/main.sw | 36 +++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/sway-lib-std/src/u128.sw b/sway-lib-std/src/u128.sw index 8bb53376064..a7fe70523a8 100644 --- a/sway-lib-std/src/u128.sw +++ b/sway-lib-std/src/u128.sw @@ -299,6 +299,7 @@ impl U128 { } } + // TODO: Rename to `try_as_u64` to be consistent with all other downcasts /// Safely downcast to `u64` without loss of precision. /// /// # Additional Information @@ -333,6 +334,27 @@ impl U128 { } } + /// Upcasts a `U128` to a `u256`. + /// + /// # Returns + /// + /// * [u256] - The `u256` representation of the `U128` value. + /// + /// # Examples + /// + /// ```sway + /// use std::u128::U128; + /// + /// fn foo() { + /// let u128_value = U128::from(0u64); + /// let u256_value = u128_value.as_u256(); + /// } + pub fn as_u256(self) -> u256 { + asm(nums: (0, 0, self.upper, self.lower)) { + nums: u256 + } + } + /// The smallest value that can be represented by this integer type. /// /// # Returns diff --git a/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw b/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw index 584a1716ad4..4ace0c839f9 100644 --- a/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw +++ b/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw @@ -1188,3 +1188,39 @@ fn u128_unsafemath_log2() { set_flags(prior_flags); } + +#[test] +fn u128_as_u256() { + let mut vals = Vec::new(); + vals.push(0); + vals.push(1); + vals.push(2); + vals.push(u64::max() - 1); + vals.push(u64::max()); + + for val in vals.iter() { + // Ensure parity with u256::from(val) + let u128_val = U128::from(val); + let u256_val = u128_val.as_u256(); + assert(u256_val == u256::from(val)); + + // Ensure parity with asm u256 conversion + let asm_val = asm(nums: (0, 0, 0, val)) { + nums: u256 + }; + assert(u256_val == asm_val); + + for val2 in vals.iter() { + // Ensure parity with u256::from(0, 0, val, val2) + let u128_val = U128::from((val, val2)); + let u256_val = u128_val.as_u256(); + assert(u256_val == u256::from((0, 0, val, val2))); + + // Ensure parity with asm u256 conversion + let asm_val = asm(nums: (0, 0, val, val2)) { + nums: u256 + }; + assert(u256_val == asm_val); + } + } +} \ No newline at end of file