From 56997219cbfca3745d5402a9d76ca6efc6421d01 Mon Sep 17 00:00:00 2001 From: Alfie John Date: Wed, 11 Sep 2024 04:46:27 +1000 Subject: [PATCH 001/115] Replace cargo deps with built-in cargo tree (#6179) (#6515) Separating this commit out from the main commit of #6179... This PR comes in two commits: 1. The changes to CI - replace `cargo-deps` with `cargo tree` 2. A test commit that will create a cyclic dependency which will be reverted once it's tested to be working The origin commit message: - cargo-deps is no longer maintained - cargo-deps doesn't understand workspaces ## 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. Co-authored-by: Sophie Dankel <47993817+sdankel@users.noreply.github.com> --- .github/workflows/ci.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a29913d8452..3ded2607005 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -478,14 +478,11 @@ jobs: toolchain: ${{ env.RUST_VERSION }} - uses: Swatinem/rust-cache@v2 - - name: Install cargo-deps - run: cargo install cargo-deps - # We require this check to avoid cyclic dependencies between 'fuels' and 'forc-pkg'. # Detailed explanation is found in the echo below. - name: Check 'forc-pkg' dependencies for 'fuels' crates run: | - deps=$(cargo deps --manifest-path forc-pkg/Cargo.toml) + deps=$(cargo tree --manifest-path forc-pkg/Cargo.toml) case "$deps" in *fuels*) From 7d574a927980c08f58c33740cabda2daba999f62 Mon Sep 17 00:00:00 2001 From: Sophie Dankel <47993817+sdankel@users.noreply.github.com> Date: Tue, 10 Sep 2024 18:25:40 -0700 Subject: [PATCH 002/115] fix: forc-test log decoding in libraries (#6518) ## Description Closes https://github.com/FuelLabs/sway/issues/6468 ## 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. --------- Co-authored-by: Joshua Batty --- sway-core/src/abi_generation/fuel_abi.rs | 29 ++++++++++------ .../{log_decode => lib_log_decode}/.gitignore | 0 .../{log_decode => lib_log_decode}/Forc.lock | 6 ++-- .../unit_tests/lib_log_decode/Forc.toml | 8 +++++ .../unit_tests/lib_log_decode/src/lib.sw | 34 +++++++++++++++++++ .../unit_tests/lib_log_decode/test.toml | 3 ++ .../unit_tests/script_log_decode/.gitignore | 2 ++ .../unit_tests/script_log_decode/Forc.lock | 13 +++++++ .../Forc.toml | 2 +- .../src/main.sw | 0 .../test.toml | 0 11 files changed, 82 insertions(+), 15 deletions(-) rename test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/{log_decode => lib_log_decode}/.gitignore (100%) rename test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/{log_decode => lib_log_decode}/Forc.lock (54%) create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/lib_log_decode/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/lib_log_decode/src/lib.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/lib_log_decode/test.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/script_log_decode/.gitignore create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/script_log_decode/Forc.lock rename test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/{log_decode => script_log_decode}/Forc.toml (86%) rename test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/{log_decode => script_log_decode}/src/main.sw (100%) rename test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/{log_decode => script_log_decode}/test.toml (100%) diff --git a/sway-core/src/abi_generation/fuel_abi.rs b/sway-core/src/abi_generation/fuel_abi.rs index 447d29341cb..7fdd704155d 100644 --- a/sway-core/src/abi_generation/fuel_abi.rs +++ b/sway-core/src/abi_generation/fuel_abi.rs @@ -181,17 +181,24 @@ pub fn generate_program_abi( configurables: Some(configurables), } } - TyProgramKind::Library { .. } => program_abi::ProgramABI { - program_type: "library".to_string(), - spec_version, - encoding_version, - metadata_types: vec![], - concrete_types: vec![], - functions: vec![], - logged_types: None, - messages_types: None, - configurables: None, - }, + TyProgramKind::Library { .. } => { + let logged_types = + generate_logged_types(handler, ctx, engines, metadata_types, concrete_types)?; + let messages_types = + generate_messages_types(handler, ctx, engines, metadata_types, concrete_types)?; + + program_abi::ProgramABI { + program_type: "library".to_string(), + spec_version, + encoding_version, + metadata_types: metadata_types.to_vec(), + concrete_types: concrete_types.to_vec(), + functions: vec![], + logged_types: Some(logged_types), + messages_types: Some(messages_types), + configurables: None, + } + } }; standardize_json_abi_types(&mut program_abi); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/log_decode/.gitignore b/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/lib_log_decode/.gitignore similarity index 100% rename from test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/log_decode/.gitignore rename to test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/lib_log_decode/.gitignore diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/log_decode/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/lib_log_decode/Forc.lock similarity index 54% rename from test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/log_decode/Forc.lock rename to test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/lib_log_decode/Forc.lock index 196dae73163..70b69e79183 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/log_decode/Forc.lock +++ b/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/lib_log_decode/Forc.lock @@ -1,13 +1,13 @@ [[package]] name = "core" -source = "path+from-root-A2C6CB9CD0980A06" +source = "path+from-root-A1A671B3B44F9A9A" [[package]] -name = "log_decode" +name = "lib_log_decode" source = "member" dependencies = ["std"] [[package]] name = "std" -source = "path+from-root-A2C6CB9CD0980A06" +source = "path+from-root-A1A671B3B44F9A9A" dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/lib_log_decode/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/lib_log_decode/Forc.toml new file mode 100644 index 00000000000..ec2c43496a9 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/lib_log_decode/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "lib.sw" +license = "Apache-2.0" +name = "lib_log_decode" + +[dependencies] +std = { path = "../../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/lib_log_decode/src/lib.sw b/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/lib_log_decode/src/lib.sw new file mode 100644 index 00000000000..bd0e79fc596 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/lib_log_decode/src/lib.sw @@ -0,0 +1,34 @@ +library; + +use std::flags::disable_panic_on_overflow; + +#[test] +fn test_fn() { + let a = 10; + log(a); + let b = 30; + log(b); + assert_eq(a, 10) +} + +#[test] +fn math_u16_overflow_mul() { + disable_panic_on_overflow(); + + let a = (u16::max() / 2 ) + 1; + let b = a * 2; + + log(b); + assert(b == 0_u16) +} + +#[test] +fn math_u32_overflow_mul() { + disable_panic_on_overflow(); + + let a = (u32::max() / 2 ) + 1; + let b = a * 2; + + log(b); + assert(b == 0_u32) +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/lib_log_decode/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/lib_log_decode/test.toml new file mode 100644 index 00000000000..5161cc99146 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/lib_log_decode/test.toml @@ -0,0 +1,3 @@ +category = "unit_tests_pass" +expected_decoded_test_logs = ["10", "30", "0", "0"] +experimental_new_encoding = true diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/script_log_decode/.gitignore b/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/script_log_decode/.gitignore new file mode 100644 index 00000000000..77d3844f58c --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/script_log_decode/.gitignore @@ -0,0 +1,2 @@ +out +target diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/script_log_decode/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/script_log_decode/Forc.lock new file mode 100644 index 00000000000..ff4f7f79e7f --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/script_log_decode/Forc.lock @@ -0,0 +1,13 @@ +[[package]] +name = "core" +source = "path+from-root-2988E4B52C5E1B31" + +[[package]] +name = "script_log_decode" +source = "member" +dependencies = ["std"] + +[[package]] +name = "std" +source = "path+from-root-2988E4B52C5E1B31" +dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/log_decode/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/script_log_decode/Forc.toml similarity index 86% rename from test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/log_decode/Forc.toml rename to test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/script_log_decode/Forc.toml index 63d055cdfb9..c8de77afce9 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/log_decode/Forc.toml +++ b/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/script_log_decode/Forc.toml @@ -2,7 +2,7 @@ authors = ["Fuel Labs "] entry = "main.sw" license = "Apache-2.0" -name = "log_decode" +name = "script_log_decode" [dependencies] std = { path = "../../../../reduced_std_libs/sway-lib-std-assert" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/log_decode/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/script_log_decode/src/main.sw similarity index 100% rename from test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/log_decode/src/main.sw rename to test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/script_log_decode/src/main.sw diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/log_decode/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/script_log_decode/test.toml similarity index 100% rename from test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/log_decode/test.toml rename to test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/script_log_decode/test.toml From 2f4fa65dcf2287720982ecf6c5eef6d0d7a0c86e Mon Sep 17 00:00:00 2001 From: Joshua Batty Date: Wed, 11 Sep 2024 14:21:08 +1000 Subject: [PATCH 003/115] Use cargo-nextest with retries for flaky LSP test (#6521) ## Description This PR introduces [`cargo-nextest`](https://nexte.st/) to improve our test runs. We've configured 2 retries for the go_to_definition_for_paths test, which has been intermittently failing. The LSP CI workflow has been updated to use `cargo-nextest`. Should mitigate #6029 until we get to the root cause why these tests are flaky. ## 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. - [ ] 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). - [ ] I have requested a review from the relevant team or maintainers. --- .github/workflows/ci.yml | 11 ++++++----- sway-lsp/tests/lib.rs | 1 - sway-lsp/tests/nextest.toml | 6 ++++++ 3 files changed, 12 insertions(+), 6 deletions(-) create mode 100644 sway-lsp/tests/nextest.toml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3ded2607005..9380c391ee1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -541,15 +541,16 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Install toolchain - uses: dtolnay/rust-toolchain@master + - name: Setup Rust and cargo-nextest + uses: moonrepo/setup-rust@v0 with: - toolchain: ${{ env.RUST_VERSION }} - - uses: Swatinem/rust-cache@v2 + channel: stable + cache-target: release + bins: cargo-nextest - name: Run sway-lsp tests sequentially env: RUST_BACKTRACE: full - run: cargo test --locked --release -p sway-lsp -- --nocapture --test-threads=1 + run: cargo nextest run --locked --release -p sway-lsp --no-capture --profile ci --config-file sway-lsp/tests/nextest.toml cargo-test-workspace: runs-on: ubuntu-latest steps: diff --git a/sway-lsp/tests/lib.rs b/sway-lsp/tests/lib.rs index 6f6f1e2fffc..29bba1bd103 100644 --- a/sway-lsp/tests/lib.rs +++ b/sway-lsp/tests/lib.rs @@ -973,7 +973,6 @@ fn go_to_definition_for_paths() { lsp::definition_check_with_req_offset(&server, &mut go_to, 7, 11).await; lsp::definition_check_with_req_offset(&server, &mut go_to, 7, 23).await; - // // TODO: This test stopped working when https://github.com/FuelLabs/sway/pull/6116 was merged. let mut go_to = GotoDefinition { req_uri: &uri, req_line: 22, diff --git a/sway-lsp/tests/nextest.toml b/sway-lsp/tests/nextest.toml new file mode 100644 index 00000000000..6719d7f0200 --- /dev/null +++ b/sway-lsp/tests/nextest.toml @@ -0,0 +1,6 @@ +[profile.ci] +retries = 0 + +[[profile.ci.overrides]] +filter = 'test(go_to_definition_for_paths)' +retries = 2 From 09a992f81a2951e940d96ab9a59f511b6f52c4ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaya=20G=C3=B6kalp?= Date: Tue, 10 Sep 2024 23:57:52 -0700 Subject: [PATCH 004/115] Update proxy contract binary shipped with `forc-deploy` (#6520) ## Description closes #6519. Updates proxy contract binary shipped with forc-deploy to a version built with `forc v0.63.5` from https://github.com/FuelLabs/sway-standard-implementations/tree/174f5ed9c79c23a6aaf5db906fe27ecdb29c22eb. --- forc-plugins/forc-client/proxy_abi/README.md | 6 +++--- .../proxy_abi/proxy_contract-abi.json | 4 ++-- .../proxy_contract-storage_slots.json | 10 +++++----- .../forc-client/proxy_abi/proxy_contract.bin | Bin 14096 -> 13832 bytes forc-plugins/forc-client/src/op/deploy.rs | 7 +++---- forc-plugins/forc-client/tests/deploy.rs | 2 +- 6 files changed, 14 insertions(+), 15 deletions(-) diff --git a/forc-plugins/forc-client/proxy_abi/README.md b/forc-plugins/forc-client/proxy_abi/README.md index eee3d6b1c2a..c607603ae84 100644 --- a/forc-plugins/forc-client/proxy_abi/README.md +++ b/forc-plugins/forc-client/proxy_abi/README.md @@ -2,7 +2,7 @@ This folder contains pre-built version of the owned proxy contract, its abi and `storage-slots.json` file. -*contract url*: [sway-standard-implementation/src-14/owned_proxy](https://github.com/FuelLabs/sway-standard-implementations/tree/61fd4ad8f69d21cec0d5cd8135bdc4495e0c125c). -*commit hash*: `61fd4ad8f69d21cec0d5cd8135bdc4495e0c125c` -*forc version*: `v0.63.3` +*contract url*: [sway-standard-implementation/src-14/owned_proxy](https://github.com/FuelLabs/sway-standard-implementations/tree/174f5ed9c79c23a6aaf5db906fe27ecdb29c22eb). +*commit hash*: `174f5ed9c79c23a6aaf5db906fe27ecdb29c22eb` +*forc version*: `v0.63.5` *build command*: `forc build --release` diff --git a/forc-plugins/forc-client/proxy_abi/proxy_contract-abi.json b/forc-plugins/forc-client/proxy_abi/proxy_contract-abi.json index f19a27bdf39..9fa09e507ba 100644 --- a/forc-plugins/forc-client/proxy_abi/proxy_contract-abi.json +++ b/forc-plugins/forc-client/proxy_abi/proxy_contract-abi.json @@ -713,12 +713,12 @@ { "name": "INITIAL_TARGET", "concreteTypeId": "0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8", - "offset": 13616 + "offset": 13368 }, { "name": "INITIAL_OWNER", "concreteTypeId": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", - "offset": 13568 + "offset": 13320 } ] } \ No newline at end of file diff --git a/forc-plugins/forc-client/proxy_abi/proxy_contract-storage_slots.json b/forc-plugins/forc-client/proxy_abi/proxy_contract-storage_slots.json index 7401f63e638..72849c97055 100644 --- a/forc-plugins/forc-client/proxy_abi/proxy_contract-storage_slots.json +++ b/forc-plugins/forc-client/proxy_abi/proxy_contract-storage_slots.json @@ -1,18 +1,18 @@ [ { - "key": "35fa5b7532d53cf687e13e3db014eaf208c5b8c534ab693dd7090d5e02675f3e", + "key": "7bb458adc1d118713319a5baa00a2d049dd64d2916477d2688d76970c898cd55", "value": "0000000000000000000000000000000000000000000000000000000000000000" }, { - "key": "35fa5b7532d53cf687e13e3db014eaf208c5b8c534ab693dd7090d5e02675f3f", + "key": "7bb458adc1d118713319a5baa00a2d049dd64d2916477d2688d76970c898cd56", "value": "0000000000000000000000000000000000000000000000000000000000000000" }, { - "key": "7bb458adc1d118713319a5baa00a2d049dd64d2916477d2688d76970c898cd55", + "key": "bb79927b15d9259ea316f2ecb2297d6cc8851888a98278c0a2e03e1a091ea754", "value": "0000000000000000000000000000000000000000000000000000000000000000" }, { - "key": "7bb458adc1d118713319a5baa00a2d049dd64d2916477d2688d76970c898cd56", + "key": "bb79927b15d9259ea316f2ecb2297d6cc8851888a98278c0a2e03e1a091ea755", "value": "0000000000000000000000000000000000000000000000000000000000000000" } -] +] \ No newline at end of file diff --git a/forc-plugins/forc-client/proxy_abi/proxy_contract.bin b/forc-plugins/forc-client/proxy_abi/proxy_contract.bin index ca4f22d13320e98c4a769dc826f66e827db191ca..9ce271962505b89385ca747bc4da888810e76c15 100644 GIT binary patch delta 4981 zcmZ`-drVu`9X{7K#3X5R(|{q@B$x!lO(5X#NNAI`c8p_FmvRzHVQW1*QmUb~O(+W~ zRo7v4?S!_eBAh;$ly!8Ov}~#-Kd^DuZnL)j!Lf_`9deS*c-B*QbVYn~)!^HVFE`ISlNMu-3H#ZI z!ag%@Jz}&e?m2SSDGlSC&9aN6aUzxaV=Aybz?AVkO5L&c0?fGr%nVyL?mS{NYcOOH zFf9czJ}mD9%qBeV0Ze}Z%yJ$kMF3OfTGmmX0ZMBD$^ce(>Big#l#x72O3tGsDg?^B zj&c$xZ3QS}Ksg4KEqERW%48lTk*Cv}Xy+)sX&t3ywX~Z)qwZ-)PS!|n^7Hut4~Sle*($Y^unz%hboGLeE)EPg9t>FA*_zm13MEY|v;e`L>wl zPx{!WMapfa5O)Z>OD5EvvQcj=!_vi;T8ZgclUVOiJsc}KCB_14W}J^%$YdGaWLKPo z*zs@mi8jWwzlVjBH=nHd8GVcX{1&Of{1(&etT75D!2}6(>1Bxi^2hmFU|oYb3K z0WI$YmmC>Ta}68MvQUxLUeC8$O=4mJB>ob!e}$R9#>^3rSYExT8#M+)5EJ~|DSmEQ z73WTv1&0-4mOt4J4z1fi%u)!)IG{U*jr!v<3pZFsrSFT7^GA4C+EgA|-e_2iJvHgo zoEbl$-UJUV8@5i^zc%}9I1A@C4|TvGR}HwH z4zH76PV>VCI%NnXO978;u+g5Geh6e!j}wgZ_V0Z+wNlW>9L)Us^|@ zIZXKlroRq_-avTFbA?6+bcK9*g<==83PFMG0dJ%?;Ez1eDw&SwU2s~y*#%4fpkvvv z9w!%Sw~Mh*dwSsJH3s88wk+*D9!m{{uqI$3*w3`hBa^coq%q)*^lfty=UFE)z!v2I z!UC+NsEe4X_mWKz;QTad6nKEWm-Ft#a)q2a2!7fCHwm%?!50lU&03 zS&?cCAL_)-=S4_`vLayG3UiiNORB{ze^TYCro?bVkCXVjB@M;WK_<)JG?)h2xZET? z9#6~NM)pY4rucoOpGpq%oYI#8bJHX1D9|WigOO$UqC*Xsob*BVyrr&OgbKXcpG*l4 z@8mTx(a$3LOC2b`-%v#HjLhZSzf%tdKCx5gaigl8h&%VpJd?|<5C2E$MnZK*$Ai~N zGcRCSH&G}d7FS0aGS?tMs0apU_FKRmEz(_JGu&YeV-&(dcZl~R5Ff$6((LOPk7j|E6a;n)~7b!+e&f7P8Fb&~QFS!TH)?N9qggc#K81AK9DCtT7}7Lk_|a zBMceIZRbU)h9RRDbwg~qFRKj6qZJwgvL=OyBKEnc@rAXbDjh;hN$C*r{vuz4%$aix z9AsWuWHF`8{+J#jyrl7T9>!dBKuJyxC@qF#Ax!3Ov+Ol|MT?WjxMnW@lvogB7iTw_ z?Rrl>~MqGD$DoLoGqS^IX8AE#hX@oZ%0pkN2T~VHj^}-wHrxb-3snm)zJBYOYI8W<%uRMU%DhofB1~eJ+ z@u~m*)C55y`Gm%|>}WAG8dsFQDWddb2$r{NbsF_7s}6coQFuiHhz>G`T-h*8G`nyT zpB7*7h#0%45o@u5+}Imk;3xCNbkTh|Sa&Rfu}^jLa=A8oiAcF<|Rq!{5zz$rS9*a{45*TeQ!>W<7JTDIeK zW~-;wDSK+1)F0t(Di=6Sd2H}8+L6Mwz-t#c5FTO&b=Q&(5MI-w?V2ko@le)0Om?Wf zCa3Z-B@@KB!rrjOr6D$0T`xV&&R1VxTS{Bmwp&YC&#r1Vvg=TpD32#PBqOqmbfSY4 zDId#(UEXy_s$u5cH<-8PUaTpZs5!(d1AC>$X&^C{si~JDY_q*dy37vSFG!SS?7OSK z0~3jEVmTkfD#JFHDGX{vDP}dbEjwQ2lomFE*!eUFGUK|lz(#6Yqy&4dwyv5N@?ssW zppZu#;?O-Y2m7e@p!7%9Q0K2cx(=oa%RY7e*~$7tQa78bZ(={(qu#

c)6B=GoxR!kg!C3W+;qoL!<6Di_4Y>5bFJMJCr*`&+X&-K{{YaCTD{iUpqgg1poevYkB5dJl z3c0$K<5|%X=oz6SO?^)E637sg+^M(AF@6b0(Ad{)mxqb;tnv}z)!TwhVFO?X2yr6W zm5$=$?{zwPJZI_TtYp(&BhsA>>8`pk-N6N>lurnmG!ybNA*1)K5b`3PFX3JLyMocD zxRK)?%&a+G@t<(I0T^)$SlK$Sg+9MwAOY%Bj~4CEQmxbdP{6xa`(U(uJ*RB;F9A$^sU{%=x1q%VldXSw;j7B-^6~) zkqz04M1Nj_$b5kWO_0C}2`a@!LesJgT5{*0&~lJ#*$&SU%6bTk;XjL${%3WuINOFPNRrjngsjZLow(VxA zHX9phv(c|Vd?q+Jbb92;;OQq$Jv>BqyuI=2t92Wt%i@O^?jCHs&{lbV=l{eHA+J9< z@l@Gg?5|v~e0V*!=jlghpQ{-A=`$ngA7$=RN_PI_ex@E!**w4}+iasdJ|F$(+dE$R z>PuI@_1%t7e(=4+r^bIyyZ-w#q<{Rhe5yU0FYC|q`tx4xxnKX@IIq3eT+yBu{d>uP a_HNRDU-Yc@Ueu~Tx4xhaj8ocEy7GS)*dCGq delta 5127 zcmZ`-ZA@F&89w)7h#|DONx(SQ`M7|A%SYjskAya9dmZB#=0u#7Ch?kBCjD5`wQDF# zQYKZiRkaeTCJl1bmTCLJ6shG$f7r%=>9Wn+el$O#6={Dmsa5HgO=Js_e~gu=S-0n$ zdkrQqOK{HhJ?}a1`##V6aXk9!*lUWKGsq=EWFkIYWL#-@`Xn?=VZQq+RQM7>MNI4RR3{@f$uFVvPkrv?{Dba`jf_}Bqo*nT)dgY%2(9ffS% zLHK*ccG25TvYjC`V<8?jYh*SUk1u^$kV4j}bEaUi; zWw-5rdU|kp5F!y5i3Agl-2sJM=^49RC24}LcJQH0u=A+BzCp45EWrkC2cf8J>6X{b(?!?NtP0I)EMBZ0 zbueyCoe$RdbFGSxWI?Jh4W&$|(hFD>jD3KWuEUyHDu8vBb;}1Tf6h0BOF5EzU>K#r z=?vGZUUu19EkP4_mTQ&d0BX9>Dl^LG%y77lmR(l?Mjig3OIv|1a1S{JUAAL94fhmK zY~H!9%eNlLLmofy8gII14RTua>%M zigK1-iC*Y}U=t87h`G>f=7NB5msk~=H2|T#9NN9SWBOAR-x~Na%J8%f0`)qc&hxF<`FAo|w zN4>SA$~Gjt?%n4LWQMI=KdsP_9eq z)3TBN+(G4pk);Ev!Ffg)oExpWjNJ(xeKU2!^6Sg<}*`u9d*81z}!Ox7#P6d zd%$1^#+QJB2{8pnz@szVql)E*nF%%`?RQB(DF7iKMx$_ORrR>-&xv(^COI*<4v47C z6l-y)r^{$wkBudv>`!3W!WNt^K3|&W+|uVo&$M$dQsP)X*_yYQjoNee^ghOGh`b!y1wr;&F>2q z)F63(KN3p3(kVHf#&hjKlT61-TS}yE_VJD%%j8SeqO?iT>2ped5o`9AveoKlcG0_i zdUp4HNi9XBPZIU)A_3VrpkM@#s`Ln>trhHMW$8m_5;*{G=%*ZD3j0fCL)AIJexeQ- z%_fHVyss;Zh;=i~RTb+|MR83mh&OyyA91d&>QgvLbekl+W(j~U5$TDIh{&I*(FM38 zIR>(|(_m%@Yejui2MKZc-pL{gyl~eLT*ZAW-bMV!k`LR}s~nYV)DD-zN*0dZRbIj0 zMbzI(7{-+`FA?$(j5evLav93*yAA{!d& z!mj8g;4c5XlMPm#^qh~Imk9~*XC(f$`V;XdtJ%$}$7-$j&tl&j|7YK~nC=crlnuFE zyWTS4d7c>Hd7dQFtIU+EPJPIUL_-N4de)l&JkRF=(QMGXu`p+(z??1|i+sMNIU(lQ zbF^tr&x^wPDu9xK{|=oGyj286hSrV?rf+dYVnenfJfUu-$l7j&iXeY1uK8QQI?cn! zhSfqANn3`EH{ z)vCr5RzN0fpYjAYvm}(~`8znf=0${Ln{AnHw}4-hyUhHkGn0r|z>NrZ`J| zHvg^mFUP!|=9hCYo2PrQJ)^_U=60S*8a}=i1zl z+$r{X2K&rptbKaoJW;aGJXIxg8iMLJyX)~t?=t7!14q0_B11?buNNc{q6k(>7c4KY z2cZ4^YgY-9$GySn=l6EV$K*wkN6w59b%5uRXSStHi zpJU;QNlK_c0ltE_p%iCcw;k^f<9p;)vK5#g@En(skypyCzMr>vgr&KZTOKZ!qBu&Q|VmdAH9I$FoR`SL-{f-{wwTD|Dj! zPVrnf3~QaR-e9!8L;4weyS|~C-w{ge4GS`B!Vs1Zq(<1y`a{w@b2NnNMETmdZ*mFy zHe%oW`Y;=6I3)d*O*Mq7t2gVBT;jJT{BdR|%&9jwmTq2^az`TyiAFRj8Zl&bWr(|a zVmhpEm)Jm)UdOGr`Ity-&Bx*^Y_h4zC9PNlOZGxU!wnGZODuqW9x1}^H+{gKZ#1f7 zYCrsS(jbvj25u{cjD|PgoC%+>bYq9~DO+khER8a6QyXjOs9+y8@0BDL?l?ECwd|0j zYGyp*k@ig=$A77hU1&WZHL}sxH>8EDZI8!_lzeGMoB6oi zfwRY9#fj}4JaLn&Sedi78mT|(*t4$@h?O+78IU^y4f z-+It|Zmg%!^GkvBhD!wki{C-Tr6QGxE^DWw%f=ZrV_|-C!kt2u<#Kksy;cIT+Fh}d zzgu_~UK$chI2Vm(MI0?t6SChvWWW79`>FpTU=DnLZ;(tl3HgAK*mqV5d5@5%-p8}` z%LBnhWRj@CMS{lr2^*6qZA=VHzdDXd8TItpp!9X|^fD!U(bofCBu3CNRm3h6$2HzG z;f0|ud$Z8Y(EaJSy23TVN%xezCQsR##MU*Dvjr@9%4UhlHNpX!K$ZW(aTmAufT4@$ zKpjueRDc%fjBP=WZN-4*0)!qy;+=pH5@Io-1IZgOP2A_ij}#Bw6E2hDvz!_Hrv&@w zgdQ49nf5^lqtvJ{60BH{K=#K+%TLQ89LS5AD0s*XOPjf{ZDcbSlB;=zaF7lz1i*!3 z;6e~wK)c=Use4vP1?=AyL<`S@o;@vCz6Z6utPyYcCFyo8m*{ zec#6Z@%g^@U;3~3fSN Result { fuels::macros::abigen!(Contract( name = "ProxyContract", - abi = r#" -{ + abi = r#"{ "programType": "contract", "specVersion": "1", "encodingVersion": "1", @@ -921,12 +920,12 @@ async fn deploy_new_proxy( { "name": "INITIAL_TARGET", "concreteTypeId": "0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8", - "offset": 13616 + "offset": 13368 }, { "name": "INITIAL_OWNER", "concreteTypeId": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", - "offset": 13568 + "offset": 13320 } ] }"#, diff --git a/forc-plugins/forc-client/tests/deploy.rs b/forc-plugins/forc-client/tests/deploy.rs index 93faa96d40e..fa2941325b5 100644 --- a/forc-plugins/forc-client/tests/deploy.rs +++ b/forc-plugins/forc-client/tests/deploy.rs @@ -433,7 +433,7 @@ async fn test_deploy_fresh_proxy() { .unwrap(), proxy: Some( ContractId::from_str( - "9c50c6837ba29508ad1b0fb01953892031218b5a08be73925ca5c0148e00a186", + "8eae70214f55d25a65608bd288a5863e7187fcf65705143ee1a45fd228dacc19", ) .unwrap(), ), From 439f9359e949b7a63bff457c6c2ecfff6253702f Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite Date: Wed, 11 Sep 2024 13:55:14 +0100 Subject: [PATCH 005/115] fix second pass of method application arguments (#6526) ## Description This PR fixes https://github.com/FuelLabs/sway/issues/6487. ## 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. --- .../ty/expression/expression_variant.rs | 20 ++++++++++++++++++- .../typed_expression/method_application.rs | 13 +----------- .../language/generic_impl_self/Forc.lock | 19 ++++++++++-------- .../language/generic_impl_self/Forc.toml | 1 + .../language/generic_impl_self/src/main.sw | 14 +++++++++++++ 5 files changed, 46 insertions(+), 21 deletions(-) diff --git a/sway-core/src/language/ty/expression/expression_variant.rs b/sway-core/src/language/ty/expression/expression_variant.rs index 8e80a4bc4d0..a71ba25c592 100644 --- a/sway-core/src/language/ty/expression/expression_variant.rs +++ b/sway-core/src/language/ty/expression/expression_variant.rs @@ -1007,7 +1007,9 @@ impl TypeCheckAnalysis for TyExpressionVariant { ) -> Result<(), ErrorEmitted> { match self { TyExpressionVariant::Literal(_) => {} - TyExpressionVariant::FunctionApplication { fn_ref, .. } => { + TyExpressionVariant::FunctionApplication { + fn_ref, arguments, .. + } => { let fn_decl_id = ctx.get_normalized_fn_node_id(fn_ref.id()); let fn_node = ctx.get_node_for_fn_decl(&fn_decl_id); @@ -1021,6 +1023,22 @@ impl TypeCheckAnalysis for TyExpressionVariant { let _ = fn_decl_id.type_check_analyze(handler, ctx); } } + + // Unify arguments that are still not concrete + let decl = ctx.engines.de().get(fn_ref.id()); + + use crate::type_system::unify::unifier::*; + let unifier = Unifier::new(ctx.engines, "", UnifyKind::Default); + + for (decl_param, arg) in decl.parameters.iter().zip(arguments.iter()) { + unifier.unify( + handler, + arg.1.return_type, + decl_param.type_argument.type_id, + &Span::dummy(), + false, + ); + } } TyExpressionVariant::LazyOperator { lhs, rhs, .. } => { lhs.type_check_analyze(handler, ctx)?; diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs index 8dfcd358bfb..68de3f5f79e 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs @@ -52,18 +52,7 @@ pub(crate) fn type_check_method_application( let arg_handler = Handler::default(); let arg_opt = ty::TyExpression::type_check(&arg_handler, ctx, arg).ok(); - // Check this type needs a second pass - let has_errors = arg_handler.has_errors(); - let is_not_concrete = arg_opt - .as_ref() - .map(|x| { - x.return_type - .extract_inner_types(engines, IncludeSelf::Yes) - .iter() - .any(|x| !x.is_concrete(engines, TreatNumericAs::Abstract)) - }) - .unwrap_or_default(); - let needs_second_pass = has_errors || is_not_concrete; + let needs_second_pass = arg_handler.has_errors(); if index == 0 { // We want to emit errors in the self parameter and ignore TraitConstraintNotSatisfied with Placeholder diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self/Forc.lock index ec32bff5749..66ff73a2cb8 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self/Forc.lock +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self/Forc.lock @@ -1,13 +1,16 @@ [[package]] -name = 'core' -source = 'path+from-root-DA3FEDB2AB26E552' +name = "core" +source = "path+from-root-DA3FEDB2AB26E552" [[package]] -name = 'generic_impl_self' -source = 'member' -dependencies = ['std'] +name = "generic_impl_self" +source = "member" +dependencies = [ + "core", + "std", +] [[package]] -name = 'std' -source = 'path+from-root-DA3FEDB2AB26E552' -dependencies = ['core'] +name = "std" +source = "path+from-root-DA3FEDB2AB26E552" +dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self/Forc.toml index 6b5e5c22c7f..41c297ce82a 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self/Forc.toml +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self/Forc.toml @@ -5,4 +5,5 @@ name = "generic_impl_self" entry = "main.sw" [dependencies] +core = { path = "../../../../../../../sway-lib-core" } std = { path = "../../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self/src/main.sw index c40a7312e06..52c478d163b 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self/src/main.sw @@ -212,9 +212,23 @@ fn generic_impl_self_test() { assert(u.first.value + u.second.value == 7u8); } +use std::vec::*; + +impl Vec { + pub fn with(self, with_value: T) -> Self { + let mut inside_vec = self; + inside_vec.push(with_value); + inside_vec + } +} + fn main() -> u32 { generic_impl_self_test(); result_impl_test(); + // data must be Vec + let data = Vec::new().with(0x333u256).with(0x222u256); + assert(data.len() == 2); + 10u32 } From d76a146e2a12546135cffe5e7a959a8de29d66c8 Mon Sep 17 00:00:00 2001 From: Cameron Carstens Date: Wed, 11 Sep 2024 20:51:07 +0545 Subject: [PATCH 006/115] Add support for `Transaction::Upload`, `Transaction::Upgrade`, and `Transaction::Blob` (#6500) ## Description The current `Transaction` enum in the `tx` library does not support the new transaction types in the Fuel Specs: https://docs.fuel.network/docs/nightly/specs/tx-format/transaction/ ## Changes - Adds support for `Transaction::Upload`, `Transaction::Upgrade`, and `Transaction::Blob`. - Implements `Eq` for `Transaction` - Adds missing GTF opcodes. These will be implemented in another PR. - Adds additional warnings in inline documentation ## Notes - Required for mainnet - `tx_witness_data()` returns an `Option` and thus does not support ownership types. This will be updated to `Bytes` in the future ## 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. --------- Co-authored-by: K1-R1 <77465250+K1-R1@users.noreply.github.com> Co-authored-by: Sophie Dankel <47993817+sdankel@users.noreply.github.com> Co-authored-by: IGI-111 --- sway-lib-std/src/inputs.sw | 20 +- sway-lib-std/src/outputs.sw | 8 + sway-lib-std/src/tx.sw | 92 +++- .../asset_ops_test/src/main.sw | 2 +- test/src/in_language_tests/Forc.toml | 1 + .../test_programs/tx_inline_tests/Forc.toml | 8 + .../test_programs/tx_inline_tests/src/main.sw | 129 +++++ test/src/sdk-harness/Forc.lock | 20 + test/src/sdk-harness/Forc.toml | 6 +- .../tx_input_count_predicate/Forc.toml | 8 + .../tx_input_count_predicate/src/main.sw | 7 + .../tx_output_count_predicate/Forc.toml | 8 + .../tx_output_count_predicate/src/main.sw | 7 + .../tx_type_predicate/Forc.toml | 8 + .../tx_type_predicate/src/main.sw | 7 + .../tx_witness_predicate/Forc.toml | 8 + .../tx_witness_predicate/src/main.sw | 22 + .../src/sdk-harness/test_projects/auth/mod.rs | 4 +- .../test_projects/tx_fields/mod.rs | 471 +++++++++++++++++- 19 files changed, 808 insertions(+), 28 deletions(-) create mode 100644 test/src/in_language_tests/test_programs/tx_inline_tests/Forc.toml create mode 100644 test/src/in_language_tests/test_programs/tx_inline_tests/src/main.sw create mode 100644 test/src/sdk-harness/test_artifacts/tx_input_count_predicate/Forc.toml create mode 100644 test/src/sdk-harness/test_artifacts/tx_input_count_predicate/src/main.sw create mode 100644 test/src/sdk-harness/test_artifacts/tx_output_count_predicate/Forc.toml create mode 100644 test/src/sdk-harness/test_artifacts/tx_output_count_predicate/src/main.sw create mode 100644 test/src/sdk-harness/test_artifacts/tx_type_predicate/Forc.toml create mode 100644 test/src/sdk-harness/test_artifacts/tx_type_predicate/src/main.sw create mode 100644 test/src/sdk-harness/test_artifacts/tx_witness_predicate/Forc.toml create mode 100644 test/src/sdk-harness/test_artifacts/tx_witness_predicate/src/main.sw diff --git a/sway-lib-std/src/inputs.sw b/sway-lib-std/src/inputs.sw index fd5c28530fc..f4db2869bb2 100644 --- a/sway-lib-std/src/inputs.sw +++ b/sway-lib-std/src/inputs.sw @@ -18,11 +18,10 @@ use ::tx::{ tx_type, }; use core::ops::Eq; - -const GTF_INPUT_TYPE = 0x200; +use ::revert::revert; // GTF Opcode const selectors -// +pub const GTF_INPUT_TYPE = 0x200; // pub const GTF_INPUT_COIN_TX_ID = 0x201; // pub const GTF_INPUT_COIN_OUTPUT_INDEX = 0x202; pub const GTF_INPUT_COIN_OWNER = 0x203; @@ -33,7 +32,7 @@ pub const GTF_INPUT_COIN_PREDICATE_LENGTH = 0x209; pub const GTF_INPUT_COIN_PREDICATE_DATA_LENGTH = 0x20A; pub const GTF_INPUT_COIN_PREDICATE = 0x20B; pub const GTF_INPUT_COIN_PREDICATE_DATA = 0x20C; - +// pub const GTF_INPUT_COIN_PREDICATE_GAS_USED = 0x20D; // pub const GTF_INPUT_CONTRACT_CONTRACT_ID = 0x225; pub const GTF_INPUT_MESSAGE_SENDER = 0x240; pub const GTF_INPUT_MESSAGE_RECIPIENT = 0x241; @@ -46,6 +45,7 @@ pub const GTF_INPUT_MESSAGE_PREDICATE_DATA_LENGTH = 0x247; pub const GTF_INPUT_MESSAGE_DATA = 0x248; pub const GTF_INPUT_MESSAGE_PREDICATE = 0x249; pub const GTF_INPUT_MESSAGE_PREDICATE_DATA = 0x24A; +// pub const GTF_INPUT_MESSAGE_PREDICATE_GAS_USED = 0x24B; /// The input type for a transaction. pub enum Input { @@ -113,6 +113,10 @@ pub fn input_type(index: u64) -> Option { /// /// * [u16] - The number of inputs in the transaction. /// +/// # Reverts +/// +/// * When the input type is unrecognized. This should never happen. +/// /// # Examples /// /// ```sway @@ -127,6 +131,10 @@ pub fn input_count() -> u16 { match tx_type() { Transaction::Script => __gtf::(0, GTF_SCRIPT_INPUTS_COUNT), Transaction::Create => __gtf::(0, GTF_CREATE_INPUTS_COUNT), + Transaction::Upgrade => __gtf::(0, GTF_SCRIPT_INPUTS_COUNT), + Transaction::Upload => __gtf::(0, GTF_SCRIPT_INPUTS_COUNT), + Transaction::Blob => __gtf::(0, GTF_SCRIPT_INPUTS_COUNT), + _ => revert(0), } } @@ -158,6 +166,10 @@ fn input_pointer(index: u64) -> Option { match tx_type() { Transaction::Script => Some(__gtf::(index, GTF_SCRIPT_INPUT_AT_INDEX)), Transaction::Create => Some(__gtf::(index, GTF_CREATE_INPUT_AT_INDEX)), + Transaction::Upgrade => Some(__gtf::(index, GTF_SCRIPT_INPUT_AT_INDEX)), + Transaction::Upload => Some(__gtf::(index, GTF_SCRIPT_INPUT_AT_INDEX)), + Transaction::Blob => Some(__gtf::(index, GTF_SCRIPT_INPUT_AT_INDEX)), + _ => None, } } diff --git a/sway-lib-std/src/outputs.sw b/sway-lib-std/src/outputs.sw index 140fdd09ae3..34f0c55eb13 100644 --- a/sway-lib-std/src/outputs.sw +++ b/sway-lib-std/src/outputs.sw @@ -111,6 +111,10 @@ fn output_pointer(index: u64) -> Option { match tx_type() { Transaction::Script => Some(__gtf::(index, GTF_SCRIPT_OUTPUT_AT_INDEX)), Transaction::Create => Some(__gtf::(index, GTF_CREATE_OUTPUT_AT_INDEX)), + Transaction::Upgrade => Some(__gtf::(index, GTF_SCRIPT_OUTPUT_AT_INDEX)), + Transaction::Upload => Some(__gtf::(index, GTF_SCRIPT_OUTPUT_AT_INDEX)), + Transaction::Blob => Some(__gtf::(index, GTF_SCRIPT_OUTPUT_AT_INDEX)), + _ => None, } } @@ -139,6 +143,10 @@ pub fn output_count() -> u16 { match tx_type() { Transaction::Script => __gtf::(0, GTF_SCRIPT_OUTPUTS_COUNT), Transaction::Create => __gtf::(0, GTF_CREATE_OUTPUTS_COUNT), + Transaction::Upgrade => __gtf::(0, GTF_SCRIPT_OUTPUTS_COUNT), + Transaction::Upload => __gtf::(0, GTF_SCRIPT_OUTPUTS_COUNT), + Transaction::Blob => __gtf::(0, GTF_SCRIPT_OUTPUTS_COUNT), + _ => revert(0), } } diff --git a/sway-lib-std/src/tx.sw b/sway-lib-std/src/tx.sw index 3ee245f806c..033b937ec50 100644 --- a/sway-lib-std/src/tx.sw +++ b/sway-lib-std/src/tx.sw @@ -3,6 +3,7 @@ library; use ::revert::revert; use ::option::Option::{self, *}; +use ::alloc::alloc_bytes; // GTF Opcode const selectors // @@ -18,6 +19,7 @@ pub const GTF_SCRIPT_SCRIPT_DATA = 0x00A; pub const GTF_SCRIPT_INPUT_AT_INDEX = 0x00B; pub const GTF_SCRIPT_OUTPUT_AT_INDEX = 0x00C; pub const GTF_SCRIPT_WITNESS_AT_INDEX = 0x00D; + pub const GTF_TX_LENGTH = 0x00E; // pub const GTF_CREATE_BYTECODE_WITNESS_INDEX = 0x101; @@ -46,10 +48,35 @@ pub enum Transaction { Script: (), /// A contract deployment transaction. Create: (), + /// The transaction is created by the block producer and is not signed. + /// + /// # Additional Information + /// + /// NOTE: This should never be valid in execution but it provided for congruency to the FuelVM specs. + Mint: (), + /// The Upgrade transaction allows upgrading either consensus parameters or state transition function used by the network to produce future blocks. + Upgrade: (), + ///The Upload transaction allows the huge bytecode to be divided into subsections and uploaded slowly to the chain. + Upload: (), + /// The Blob inserts a simple binary blob in the chain. It's raw immutable data that can be cheaply loaded by the VM and used as instructions or just data. + Blob: (), +} + +impl core::ops::Eq for Transaction { + fn eq(self, other: Self) -> bool { + match (self, other) { + (Transaction::Script, Transaction::Script) => true, + (Transaction::Create, Transaction::Create) => true, + (Transaction::Mint, Transaction::Mint) => true, + (Transaction::Upgrade, Transaction::Upgrade) => true, + (Transaction::Upload, Transaction::Upload) => true, + (Transaction::Blob, Transaction::Blob) => true, + _ => false, + } + } } /// Get the type of the current transaction. -/// Either `Transaction::Script` or `Transaction::Create`. /// /// # Returns /// @@ -73,6 +100,18 @@ pub enum Transaction { /// Transaction::Create => { /// log("Contract deployment transaction"); /// }, +/// Transaction::Mint => { +/// log("This should never happen"); +/// }, +/// Transaction::Upgrade => { +/// log("Upgrade transaction"); +/// }, +/// Transaction::Upload => { +/// log("Upload transaction"); +/// }, +/// Transaction::Blob => { +/// log("Blob transaction"); +/// }, /// } /// } /// ``` @@ -80,6 +119,9 @@ pub fn tx_type() -> Transaction { match __gtf::(0, GTF_TYPE) { 0u8 => Transaction::Script, 1u8 => Transaction::Create, + 3u8 => Transaction::Upgrade, + 4u8 => Transaction::Upload, + 5u8 => Transaction::Blob, _ => revert(0), } } @@ -233,7 +275,7 @@ pub fn tx_max_fee() -> Option { pub fn tx_script_length() -> Option { match tx_type() { Transaction::Script => Some(__gtf::(0, GTF_SCRIPT_SCRIPT_LENGTH)), - Transaction::Create => None, + _ => None, } } @@ -256,7 +298,7 @@ pub fn tx_script_length() -> Option { pub fn tx_script_data_length() -> Option { match tx_type() { Transaction::Script => Some(__gtf::(0, GTF_SCRIPT_SCRIPT_DATA_LENGTH)), - Transaction::Create => None, + _ => None, } } @@ -266,6 +308,10 @@ pub fn tx_script_data_length() -> Option { /// /// * [u64] - The witnesses count for the transaction. /// +/// # Reverts +/// +/// * When the transaction type is unrecognized. This should never happen. +/// /// # Examples /// /// ```sway @@ -280,6 +326,10 @@ pub fn tx_witnesses_count() -> u64 { match tx_type() { Transaction::Script => __gtf::(0, GTF_SCRIPT_WITNESSES_COUNT), Transaction::Create => __gtf::(0, GTF_CREATE_WITNESSES_COUNT), + Transaction::Upgrade => __gtf::(0, GTF_SCRIPT_WITNESSES_COUNT), + Transaction::Upload => __gtf::(0, GTF_SCRIPT_WITNESSES_COUNT), + Transaction::Blob => __gtf::(0, GTF_SCRIPT_WITNESSES_COUNT), + _ => revert(0), } } @@ -311,6 +361,10 @@ fn tx_witness_pointer(index: u64) -> Option { match tx_type() { Transaction::Script => Some(__gtf::(index, GTF_SCRIPT_WITNESS_AT_INDEX)), Transaction::Create => Some(__gtf::(index, GTF_CREATE_WITNESS_AT_INDEX)), + Transaction::Upgrade => Some(__gtf::(index, GTF_SCRIPT_WITNESS_AT_INDEX)), + Transaction::Upload => Some(__gtf::(index, GTF_SCRIPT_WITNESS_AT_INDEX)), + Transaction::Blob => Some(__gtf::(index, GTF_SCRIPT_WITNESS_AT_INDEX)), + _ => None, } } @@ -344,6 +398,11 @@ pub fn tx_witness_data_length(index: u64) -> Option { /// Get the witness data at `index`. /// +/// # Additional Information +/// +/// **Unsafe. Assumes the type is correct.** +/// This function does not support ownership types(Vec, Bytes, String, etc). +/// /// # Arguments /// /// * `index` - The index of the witness to get the data for. @@ -367,10 +426,26 @@ pub fn tx_witness_data(index: u64) -> Option { return None } - if __size_of::() == 1 { - Some(__gtf::(index, GTF_WITNESS_DATA).add::(7).read::()) + let length = match tx_witness_data_length(index) { + Some(len) => len, + None => return None, + }; + + if __is_reference_type::() { + let witness_data_ptr = __gtf::(index, GTF_WITNESS_DATA); + let new_ptr = alloc_bytes(length); + witness_data_ptr.copy_bytes_to(new_ptr, length); + + Some(asm(ptr: new_ptr) { + ptr: T + }) } else { - Some(__gtf::(index, GTF_WITNESS_DATA).read::()) + // u8 is the only value type that is less than 8 bytes and should be handled separately + if __size_of::() == 1 { + Some(__gtf::(index, GTF_WITNESS_DATA).add::(7).read::()) + } else { + Some(__gtf::(index, GTF_WITNESS_DATA).read::()) + } } } @@ -424,8 +499,8 @@ fn tx_script_data_start_pointer() -> Option { /// /// # Additional Information /// -/// **Unsafe.** -/// **Assumes the type is correct.** +/// **Unsafe. Assumes the type is correct.** +/// This function does not support ownership types(Vec, Bytes, String, etc). /// /// # Returns /// @@ -480,7 +555,6 @@ pub fn tx_script_bytecode() -> Option { } /// Get the hash of the script bytecode. -/// Reverts if not a transaction-script. /// /// # Returns /// 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 02567676e67..f1458b54293 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,7 +9,7 @@ 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 = 0xf8c7b4d09f9964ab4c437ac7f5cbd6dbad7e1f218fce452c5807aac3c67afa6f; +const FUEL_COIN_CONTRACT_ID = 0xf2fecff29038dab2ef571397ea5507359265c9154608e7de36ccbea20ed5c8aa; #[cfg(experimental_new_encoding = false)] const BALANCE_CONTRACT_ID = 0xf6cd545152ac83225e8e7df2efb5c6fa6e37bc9b9e977b5ea8103d28668925df; diff --git a/test/src/in_language_tests/Forc.toml b/test/src/in_language_tests/Forc.toml index eaa9393b936..b2f198bf2f7 100644 --- a/test/src/in_language_tests/Forc.toml +++ b/test/src/in_language_tests/Forc.toml @@ -21,6 +21,7 @@ members = [ "test_programs/revert_inline_tests", "test_programs/storage_key_inline_tests", "test_programs/string_inline_tests", + "test_programs/tx_inline_tests", "test_programs/u128_inline_tests", "test_programs/vec_inline_tests", "test_programs/array_conversions_b256_inline_tests", diff --git a/test/src/in_language_tests/test_programs/tx_inline_tests/Forc.toml b/test/src/in_language_tests/test_programs/tx_inline_tests/Forc.toml new file mode 100644 index 00000000000..fa38e2fc473 --- /dev/null +++ b/test/src/in_language_tests/test_programs/tx_inline_tests/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "tx_inline_tests" + +[dependencies] +std = { path = "../../../../../sway-lib-std" } diff --git a/test/src/in_language_tests/test_programs/tx_inline_tests/src/main.sw b/test/src/in_language_tests/test_programs/tx_inline_tests/src/main.sw new file mode 100644 index 00000000000..018763a31b8 --- /dev/null +++ b/test/src/in_language_tests/test_programs/tx_inline_tests/src/main.sw @@ -0,0 +1,129 @@ +library; + +use std::tx::Transaction; + +#[test] +fn tx_transaction_eq() { + let transaction_1 = Transaction::Script; + let transaction_2 = Transaction::Script; + let transaction_3 = Transaction::Create; + let transaction_4 = Transaction::Create; + let transaction_5 = Transaction::Mint; + let transaction_6 = Transaction::Mint; + let transaction_7 = Transaction::Upgrade; + let transaction_8 = Transaction::Upgrade; + let transaction_9 = Transaction::Upload; + let transaction_10 = Transaction::Upload; + let transaction_11 = Transaction::Blob; + let transaction_12 = Transaction::Blob; + + assert(transaction_1 == transaction_1); + assert(transaction_1 == transaction_2); + assert(transaction_2 == transaction_2); + + assert(transaction_3 == transaction_3); + assert(transaction_3 == transaction_4); + assert(transaction_4 == transaction_4); + + assert(transaction_5 == transaction_5); + assert(transaction_5 == transaction_6); + assert(transaction_6 == transaction_6); + + assert(transaction_7 == transaction_7); + assert(transaction_7 == transaction_8); + assert(transaction_8 == transaction_8); + + assert(transaction_9 == transaction_9); + assert(transaction_9 == transaction_10); + assert(transaction_10 == transaction_10); + + assert(transaction_11 == transaction_11); + assert(transaction_11 == transaction_12); + assert(transaction_12 == transaction_12); +} + +#[test] +fn tx_transaction_ne() { + let transaction_1 = Transaction::Script; + let transaction_2 = Transaction::Script; + let transaction_3 = Transaction::Create; + let transaction_4 = Transaction::Create; + let transaction_5 = Transaction::Mint; + let transaction_6 = Transaction::Mint; + let transaction_7 = Transaction::Upgrade; + let transaction_8 = Transaction::Upgrade; + let transaction_9 = Transaction::Upload; + let transaction_10 = Transaction::Upload; + let transaction_11 = Transaction::Blob; + let transaction_12 = Transaction::Blob; + + assert(transaction_1 != transaction_3); + assert(transaction_1 != transaction_4); + assert(transaction_1 != transaction_5); + assert(transaction_1 != transaction_6); + assert(transaction_1 != transaction_7); + assert(transaction_1 != transaction_8); + assert(transaction_1 != transaction_9); + assert(transaction_1 != transaction_10); + assert(transaction_1 != transaction_11); + assert(transaction_1 != transaction_12); + + assert(transaction_2 != transaction_3); + assert(transaction_2 != transaction_4); + assert(transaction_2 != transaction_5); + assert(transaction_2 != transaction_6); + assert(transaction_2 != transaction_7); + assert(transaction_2 != transaction_8); + assert(transaction_2 != transaction_9); + assert(transaction_2 != transaction_10); + assert(transaction_2 != transaction_11); + assert(transaction_2 != transaction_12); + + assert(transaction_3 != transaction_5); + assert(transaction_3 != transaction_6); + assert(transaction_3 != transaction_7); + assert(transaction_3 != transaction_8); + assert(transaction_3 != transaction_9); + assert(transaction_3 != transaction_10); + assert(transaction_3 != transaction_11); + assert(transaction_3 != transaction_12); + + assert(transaction_4 != transaction_5); + assert(transaction_4 != transaction_6); + assert(transaction_4 != transaction_7); + assert(transaction_4 != transaction_8); + assert(transaction_4 != transaction_9); + assert(transaction_4 != transaction_10); + assert(transaction_4 != transaction_11); + assert(transaction_4 != transaction_12); + + assert(transaction_5 != transaction_7); + assert(transaction_5 != transaction_8); + assert(transaction_5 != transaction_9); + assert(transaction_5 != transaction_10); + assert(transaction_5 != transaction_11); + assert(transaction_5 != transaction_12); + + assert(transaction_6 != transaction_7); + assert(transaction_6 != transaction_8); + assert(transaction_6 != transaction_9); + assert(transaction_6 != transaction_10); + assert(transaction_6 != transaction_11); + assert(transaction_6 != transaction_12); + + assert(transaction_7 != transaction_9); + assert(transaction_7 != transaction_10); + assert(transaction_7 != transaction_11); + assert(transaction_7 != transaction_12); + + assert(transaction_8 != transaction_9); + assert(transaction_8 != transaction_10); + assert(transaction_8 != transaction_11); + assert(transaction_8 != transaction_12); + + assert(transaction_9 != transaction_11); + assert(transaction_9 != transaction_12); + + assert(transaction_10 != transaction_11); + assert(transaction_10 != transaction_12); +} diff --git a/test/src/sdk-harness/Forc.lock b/test/src/sdk-harness/Forc.lock index 1bd0f8e296a..37d81fdd61b 100644 --- a/test/src/sdk-harness/Forc.lock +++ b/test/src/sdk-harness/Forc.lock @@ -404,16 +404,36 @@ name = "tx_fields" source = "member" dependencies = ["std"] +[[package]] +name = "tx_input_count_predicate" +source = "member" +dependencies = ["std"] + [[package]] name = "tx_output_contract_creation_predicate" source = "member" dependencies = ["std"] +[[package]] +name = "tx_output_count_predicate" +source = "member" +dependencies = ["std"] + [[package]] name = "tx_output_predicate" source = "member" dependencies = ["std"] +[[package]] +name = "tx_type_predicate" +source = "member" +dependencies = ["std"] + +[[package]] +name = "tx_witness_predicate" +source = "member" +dependencies = ["std"] + [[package]] name = "type_aliases" source = "member" diff --git a/test/src/sdk-harness/Forc.toml b/test/src/sdk-harness/Forc.toml index 954b0427ce7..f2a1df25d47 100644 --- a/test/src/sdk-harness/Forc.toml +++ b/test/src/sdk-harness/Forc.toml @@ -75,6 +75,10 @@ members = [ "test_artifacts/storage_vec/svec_u16", "test_artifacts/storage_vec/svec_u64", "test_artifacts/tx_contract", - "test_artifacts/tx_output_predicate", + "test_artifacts/tx_input_count_predicate", "test_artifacts/tx_output_contract_creation_predicate", + "test_artifacts/tx_output_count_predicate", + "test_artifacts/tx_output_predicate", + "test_artifacts/tx_type_predicate", + "test_artifacts/tx_witness_predicate", ] diff --git a/test/src/sdk-harness/test_artifacts/tx_input_count_predicate/Forc.toml b/test/src/sdk-harness/test_artifacts/tx_input_count_predicate/Forc.toml new file mode 100644 index 00000000000..2081295b12e --- /dev/null +++ b/test/src/sdk-harness/test_artifacts/tx_input_count_predicate/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "tx_input_count_predicate" + +[dependencies] +std = { path = "../../../../../sway-lib-std" } diff --git a/test/src/sdk-harness/test_artifacts/tx_input_count_predicate/src/main.sw b/test/src/sdk-harness/test_artifacts/tx_input_count_predicate/src/main.sw new file mode 100644 index 00000000000..18ece1aba67 --- /dev/null +++ b/test/src/sdk-harness/test_artifacts/tx_input_count_predicate/src/main.sw @@ -0,0 +1,7 @@ +predicate; + +use std::inputs::input_count; + +fn main(expected_count: u16) -> bool { + input_count() == expected_count +} diff --git a/test/src/sdk-harness/test_artifacts/tx_output_count_predicate/Forc.toml b/test/src/sdk-harness/test_artifacts/tx_output_count_predicate/Forc.toml new file mode 100644 index 00000000000..16b4e270afd --- /dev/null +++ b/test/src/sdk-harness/test_artifacts/tx_output_count_predicate/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "tx_output_count_predicate" + +[dependencies] +std = { path = "../../../../../sway-lib-std" } diff --git a/test/src/sdk-harness/test_artifacts/tx_output_count_predicate/src/main.sw b/test/src/sdk-harness/test_artifacts/tx_output_count_predicate/src/main.sw new file mode 100644 index 00000000000..26264019a30 --- /dev/null +++ b/test/src/sdk-harness/test_artifacts/tx_output_count_predicate/src/main.sw @@ -0,0 +1,7 @@ +predicate; + +use std::outputs::output_count; + +fn main(expected_count: u16) -> bool { + output_count() == expected_count +} diff --git a/test/src/sdk-harness/test_artifacts/tx_type_predicate/Forc.toml b/test/src/sdk-harness/test_artifacts/tx_type_predicate/Forc.toml new file mode 100644 index 00000000000..23ca628cedf --- /dev/null +++ b/test/src/sdk-harness/test_artifacts/tx_type_predicate/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "tx_type_predicate" + +[dependencies] +std = { path = "../../../../../sway-lib-std" } diff --git a/test/src/sdk-harness/test_artifacts/tx_type_predicate/src/main.sw b/test/src/sdk-harness/test_artifacts/tx_type_predicate/src/main.sw new file mode 100644 index 00000000000..59bd4f10714 --- /dev/null +++ b/test/src/sdk-harness/test_artifacts/tx_type_predicate/src/main.sw @@ -0,0 +1,7 @@ +predicate; + +use std::tx::{tx_type, Transaction}; + +fn main(expected_type: Transaction) -> bool { + tx_type() == expected_type +} diff --git a/test/src/sdk-harness/test_artifacts/tx_witness_predicate/Forc.toml b/test/src/sdk-harness/test_artifacts/tx_witness_predicate/Forc.toml new file mode 100644 index 00000000000..d7aa6cdc427 --- /dev/null +++ b/test/src/sdk-harness/test_artifacts/tx_witness_predicate/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "tx_witness_predicate" + +[dependencies] +std = { path = "../../../../../sway-lib-std" } diff --git a/test/src/sdk-harness/test_artifacts/tx_witness_predicate/src/main.sw b/test/src/sdk-harness/test_artifacts/tx_witness_predicate/src/main.sw new file mode 100644 index 00000000000..adb0ea9dbc9 --- /dev/null +++ b/test/src/sdk-harness/test_artifacts/tx_witness_predicate/src/main.sw @@ -0,0 +1,22 @@ +predicate; + +use std::tx::{tx_witnesses_count, tx_witness_data_length, tx_witness_data}; + +fn main(index: u64, expected_count: u64, expected_length: u64, expected_data: [u8; 64]) -> bool { + let count: u64 = tx_witnesses_count(); + let length: Option = tx_witness_data_length(index); + let data: Option<[u8; 64]> = tx_witness_data(index); + + assert(count == expected_count); + assert(length.is_some() && length.unwrap() == expected_length); + + assert(data.is_some()); + let data = data.unwrap(); + let mut iter = 0; + while iter < 64 { + assert(data[iter] == expected_data[iter]); + iter += 1; + } + + true +} diff --git a/test/src/sdk-harness/test_projects/auth/mod.rs b/test/src/sdk-harness/test_projects/auth/mod.rs index df2eb3954d2..45441e38582 100644 --- a/test/src/sdk-harness/test_projects/auth/mod.rs +++ b/test/src/sdk-harness/test_projects/auth/mod.rs @@ -196,7 +196,7 @@ async fn can_get_predicate_address() { // Setup predicate. let hex_predicate_address: &str = - "0x188fb1615bacd24d52b1339fcfeed1ecf555d0afde44a087eebf98381c64db1b"; + "0x0c07e9f6e71da8855fb65a38f299a993aeba71fd0eef6c1ac4c79beff09cd6f7"; let predicate_address = Address::from_str(hex_predicate_address).expect("failed to create Address from string"); let predicate_bech32_address = Bech32Address::from(predicate_address); @@ -322,7 +322,7 @@ async fn when_incorrect_predicate_address_passed() { async fn can_get_predicate_address_in_message() { // Setup predicate address. let hex_predicate_address: &str = - "0x188fb1615bacd24d52b1339fcfeed1ecf555d0afde44a087eebf98381c64db1b"; + "0x0c07e9f6e71da8855fb65a38f299a993aeba71fd0eef6c1ac4c79beff09cd6f7"; let predicate_address = Address::from_str(hex_predicate_address).expect("failed to create Address from string"); let predicate_bech32_address = Bech32Address::from(predicate_address); diff --git a/test/src/sdk-harness/test_projects/tx_fields/mod.rs b/test/src/sdk-harness/test_projects/tx_fields/mod.rs index aace3c9fa38..6a4624f3d86 100644 --- a/test/src/sdk-harness/test_projects/tx_fields/mod.rs +++ b/test/src/sdk-harness/test_projects/tx_fields/mod.rs @@ -1,5 +1,6 @@ use fuel_vm::fuel_crypto::Hasher; use fuel_vm::fuel_tx::{ContractId, Input as TxInput}; +use fuels::core::codec::EncoderConfig; use fuels::types::transaction_builders::TransactionBuilder; use fuels::{ accounts::{predicate::Predicate, wallet::WalletUnlocked, Account}, @@ -16,6 +17,16 @@ const TX_OUTPUT_PREDICATE_BYTECODE_PATH: &str = const TX_FIELDS_PREDICATE_BYTECODE_PATH: &str = "test_projects/tx_fields/out/release/tx_fields.bin"; const TX_CONTRACT_CREATION_PREDICATE_BYTECODE_PATH: &str = "test_artifacts/tx_output_contract_creation_predicate/out/release/tx_output_contract_creation_predicate.bin"; +const TX_TYPE_PREDICATE_BYTECODE_PATH: &str = + "test_artifacts/tx_type_predicate/out/release/tx_type_predicate.bin"; +const TX_WITNESS_PREDICATE_BYTECODE_PATH: &str = + "test_artifacts/tx_witness_predicate/out/release/tx_witness_predicate.bin"; +const TX_INPUT_COUNT_PREDICATE_BYTECODE_PATH: &str = + "test_artifacts/tx_input_count_predicate/out/release/tx_input_count_predicate.bin"; +const TX_OUTPUT_COUNT_PREDICATE_BYTECODE_PATH: &str = + "test_artifacts/tx_output_count_predicate/out/release/tx_output_count_predicate.bin"; + +use crate::tx_fields::Transaction as SwayTransaction; abigen!( Contract( @@ -29,6 +40,22 @@ abigen!( Predicate( name = "TestOutputPredicate", abi = "test_artifacts/tx_output_predicate/out/release/tx_output_predicate-abi.json" + ), + Predicate( + name = "TestTxTypePredicate", + abi = "test_artifacts/tx_type_predicate/out/release/tx_type_predicate-abi.json" + ), + Predicate( + name = "TestTxWitnessPredicate", + abi = "test_artifacts/tx_witness_predicate/out/release/tx_witness_predicate-abi.json" + ), + Predicate( + name = "TestTxInputCountPredicate", + abi = "test_artifacts/tx_input_count_predicate/out/release/tx_input_count_predicate-abi.json" + ), + Predicate( + name = "TestTxOutputCountPredicate", + abi = "test_artifacts/tx_output_count_predicate/out/release/tx_output_count_predicate-abi.json" ) ); @@ -455,6 +482,217 @@ mod tx { assert_eq!(receipts[1].data().unwrap(), byte_array); } + + #[tokio::test] + async fn can_get_tx_upload() { + // Prepare wallet and provider + let mut wallet = WalletUnlocked::new_random(None); + let num_coins = 100; + let coins = setup_single_asset_coins( + wallet.address(), + AssetId::zeroed(), + num_coins, + DEFAULT_COIN_AMOUNT, + ); + let provider = setup_test_provider(coins, vec![], None, None) + .await + .unwrap(); + wallet.set_provider(provider.clone()); + + // Get the predicate + let predicate_data = TestTxTypePredicateEncoder::default() + .encode_data(SwayTransaction::Upload) + .unwrap(); + let predicate: Predicate = Predicate::load_from(TX_TYPE_PREDICATE_BYTECODE_PATH) + .unwrap() + .with_provider(provider.clone()) + .with_data(predicate_data); + let predicate_coin_amount = 100; + + // Predicate has no funds + let predicate_balance = predicate + .get_asset_balance(&provider.base_asset_id()) + .await + .unwrap(); + assert_eq!(predicate_balance, 0); + + // Prepare bytecode and subsections + let bytecode = fs::read(TX_CONTRACT_BYTECODE_PATH).unwrap(); + let subsection_size = 65536; + let subsections = UploadSubsection::split_bytecode(&bytecode, subsection_size).unwrap(); + + // Transfer enough funds to the predicate for each subsection + for _ in subsections.clone() { + wallet + .transfer( + predicate.address(), + predicate_coin_amount, + *provider.base_asset_id(), + TxPolicies::default(), + ) + .await + .unwrap(); + } + + // Predicate has funds + let predicate_balance = predicate + .get_asset_balance(&provider.base_asset_id()) + .await + .unwrap(); + assert_eq!( + predicate_balance as usize, + predicate_coin_amount as usize * subsections.len() + ); + + // Upload each sub section in a separate transaction and include the predicate with the transaction. + for subsection in subsections { + let mut builder = UploadTransactionBuilder::prepare_subsection_upload( + subsection, + TxPolicies::default(), + ); + + // Inputs for predicate + let predicate_input = predicate + .get_asset_inputs_for_amount(*provider.base_asset_id(), 1, None) + .await + .unwrap(); + + // Outputs for predicate + let predicate_output = wallet.get_asset_outputs_for_amount( + &wallet.address(), + *provider.base_asset_id(), + 1, + ); + + // Append the predicate to the transaction + builder.inputs.push(predicate_input.get(0).unwrap().clone()); + builder + .outputs + .push(predicate_output.get(0).unwrap().clone()); + + wallet.add_witnesses(&mut builder).unwrap(); + wallet.adjust_for_fee(&mut builder, 0).await.unwrap(); + + // Submit the transaction + let tx = builder.build(&provider).await.unwrap(); + provider.send_transaction(tx).await.unwrap(); + } + + // The predicate has spent it's funds + let predicate_balance = predicate + .get_asset_balance(&provider.base_asset_id()) + .await + .unwrap(); + assert_eq!(predicate_balance, 0); + } + + #[tokio::test] + async fn can_get_witness_in_tx_upload() { + // Prepare wallet and provider + let mut wallet = WalletUnlocked::new_random(None); + let num_coins = 100; + let coins = setup_single_asset_coins( + wallet.address(), + AssetId::zeroed(), + num_coins, + DEFAULT_COIN_AMOUNT, + ); + let provider = setup_test_provider(coins, vec![], None, None) + .await + .unwrap(); + wallet.set_provider(provider.clone()); + + // Prepare bytecode and subsections + let bytecode = fs::read(TX_CONTRACT_BYTECODE_PATH).unwrap(); + let subsection_size = 65536; + let subsections = UploadSubsection::split_bytecode(&bytecode, subsection_size).unwrap(); + + // Upload each sub section in a separate transaction and include the predicate with the transaction. + for subsection in subsections.clone() { + let mut builder = UploadTransactionBuilder::prepare_subsection_upload( + subsection, + TxPolicies::default(), + ); + + // Prepare the predicate + let witnesses = builder.witnesses().clone(); + let predicate_data = TestTxWitnessPredicateEncoder::new(EncoderConfig { + max_depth: 10, + max_tokens: 100_000, + }) + .encode_data( + 0, + witnesses.len() as u64 + 1, + witnesses[0].as_vec().len() as u64, + witnesses[0].as_vec().as_slice()[0..64].try_into().unwrap(), + ) + .unwrap(); + let predicate: Predicate = Predicate::load_from(TX_WITNESS_PREDICATE_BYTECODE_PATH) + .unwrap() + .with_provider(provider.clone()) + .with_data(predicate_data); + let predicate_coin_amount = 100; + + // Predicate has no funds + let predicate_balance = predicate + .get_asset_balance(&provider.base_asset_id()) + .await + .unwrap(); + assert_eq!(predicate_balance, 0); + wallet + .transfer( + predicate.address(), + predicate_coin_amount, + *provider.base_asset_id(), + TxPolicies::default(), + ) + .await + .unwrap(); + + // Predicate has funds + let predicate_balance = predicate + .get_asset_balance(&provider.base_asset_id()) + .await + .unwrap(); + assert_eq!( + predicate_balance as usize, + predicate_coin_amount as usize * subsections.len() + ); + + // Inputs for predicate + let predicate_input = predicate + .get_asset_inputs_for_amount(*provider.base_asset_id(), 1, None) + .await + .unwrap(); + + // Outputs for predicate + let predicate_output = wallet.get_asset_outputs_for_amount( + &wallet.address(), + *provider.base_asset_id(), + 1, + ); + + // Append the predicate to the transaction + builder.inputs.push(predicate_input.get(0).unwrap().clone()); + builder + .outputs + .push(predicate_output.get(0).unwrap().clone()); + + wallet.add_witnesses(&mut builder).unwrap(); + wallet.adjust_for_fee(&mut builder, 0).await.unwrap(); + + // Submit the transaction + let tx = builder.build(&provider).await.unwrap(); + provider.send_transaction(tx).await.unwrap(); + + // The predicate has spent it's funds + let predicate_balance = predicate + .get_asset_balance(&provider.base_asset_id()) + .await + .unwrap(); + assert_eq!(predicate_balance, 0); + } + } } mod inputs { @@ -582,6 +820,105 @@ mod inputs { assert_eq!(result.value, false); } + #[tokio::test] + async fn can_get_input_count_in_tx_upload() { + // Prepare wallet and provider + let mut wallet = WalletUnlocked::new_random(None); + let num_coins = 100; + let coins = setup_single_asset_coins( + wallet.address(), + AssetId::zeroed(), + num_coins, + DEFAULT_COIN_AMOUNT, + ); + let provider = setup_test_provider(coins, vec![], None, None) + .await + .unwrap(); + wallet.set_provider(provider.clone()); + + // Prepare bytecode and subsections + let bytecode = fs::read(TX_CONTRACT_BYTECODE_PATH).unwrap(); + let subsection_size = 65536; + let subsections = UploadSubsection::split_bytecode(&bytecode, subsection_size).unwrap(); + + // Upload each sub section in a separate transaction and include the predicate with the transaction. + for subsection in subsections.clone() { + let mut builder = UploadTransactionBuilder::prepare_subsection_upload( + subsection, + TxPolicies::default(), + ); + + // Prepare the predicate + let predicate_data = TestTxInputCountPredicateEncoder::default() + .encode_data(builder.inputs().len() as u16 + 1u16) // Add one for this predicate + .unwrap(); + let predicate: Predicate = Predicate::load_from(TX_INPUT_COUNT_PREDICATE_BYTECODE_PATH) + .unwrap() + .with_provider(provider.clone()) + .with_data(predicate_data); + let predicate_coin_amount = 100; + + // Predicate has no funds + let predicate_balance = predicate + .get_asset_balance(&provider.base_asset_id()) + .await + .unwrap(); + assert_eq!(predicate_balance, 0); + wallet + .transfer( + predicate.address(), + predicate_coin_amount, + *provider.base_asset_id(), + TxPolicies::default(), + ) + .await + .unwrap(); + + // Predicate has funds + let predicate_balance = predicate + .get_asset_balance(&provider.base_asset_id()) + .await + .unwrap(); + assert_eq!( + predicate_balance as usize, + predicate_coin_amount as usize * subsections.len() + ); + + // Inputs for predicate + let predicate_input = predicate + .get_asset_inputs_for_amount(*provider.base_asset_id(), 1, None) + .await + .unwrap(); + + // Outputs for predicate + let predicate_output = wallet.get_asset_outputs_for_amount( + &wallet.address(), + *provider.base_asset_id(), + 1, + ); + + // Append the predicate to the transaction + builder.inputs.push(predicate_input.get(0).unwrap().clone()); + builder + .outputs + .push(predicate_output.get(0).unwrap().clone()); + + wallet.add_witnesses(&mut builder).unwrap(); + wallet.adjust_for_fee(&mut builder, 0).await.unwrap(); + + // Submit the transaction + let tx = builder.build(&provider).await.unwrap(); + provider.send_transaction(tx).await.unwrap(); + + // The predicate has spent it's funds + let predicate_balance = predicate + .get_asset_balance(&provider.base_asset_id()) + .await + .unwrap(); + assert_eq!(predicate_balance, 0); + } + } + mod message { use fuels::types::{coin_type::CoinType, transaction_builders::TransactionBuilder}; @@ -720,7 +1057,7 @@ mod inputs { .call() .await .unwrap(); - + assert_eq!(none_result.value, None); } @@ -743,7 +1080,7 @@ mod inputs { .call() .await .unwrap(); - + assert_eq!(none_result.value, None); } @@ -779,7 +1116,10 @@ mod inputs { .take_receipts_checked(None) .unwrap(); - assert_eq!(receipts[1].data(), Some(&[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3][..])); + assert_eq!( + receipts[1].data(), + Some(&[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3][..]) + ); // Assert none returned when transaction type is not a message let none_result = contract_instance @@ -788,7 +1128,7 @@ mod inputs { .call() .await .unwrap(); - + assert_eq!(none_result.value, None); } @@ -825,7 +1165,10 @@ mod inputs { .unwrap(); let len = predicate_bytecode.len() as u64; - assert_eq!(receipts[1].data().unwrap()[8..16], *len.to_be_bytes().as_slice()); + assert_eq!( + receipts[1].data().unwrap()[8..16], + *len.to_be_bytes().as_slice() + ); // Assert none returned when index is invalid let none_result = contract_instance @@ -834,7 +1177,7 @@ mod inputs { .call() .await .unwrap(); - + assert_eq!(none_result.value, None); } @@ -869,7 +1212,10 @@ mod inputs { .take_receipts_checked(None) .unwrap(); - assert_eq!(receipts[1].data().unwrap()[8..16], *0u64.to_le_bytes().as_slice()); + assert_eq!( + receipts[1].data().unwrap()[8..16], + *0u64.to_le_bytes().as_slice() + ); // Assert none returned when transaction type is not a message let none_result = contract_instance @@ -878,7 +1224,7 @@ mod inputs { .call() .await .unwrap(); - + assert_eq!(none_result.value, None); } @@ -924,7 +1270,7 @@ mod inputs { .call() .await .unwrap(); - + assert_eq!(none_result.value, false); } @@ -972,7 +1318,11 @@ mod inputs { let mut builder = contract_instance .methods() - .get_input_message_data(3, (MESSAGE_DATA.len() + 1) as u64, Bytes(MESSAGE_DATA.into())) + .get_input_message_data( + 3, + (MESSAGE_DATA.len() + 1) as u64, + Bytes(MESSAGE_DATA.into()), + ) .transaction_builder() .await .unwrap(); @@ -1039,7 +1389,7 @@ mod inputs { .call() .await .unwrap(); - + assert_eq!(none_result.value, false); } } @@ -1220,6 +1570,105 @@ mod outputs { .unwrap(); assert_eq!(result.value, None); } + + #[tokio::test] + async fn can_get_output_count_in_tx_upload() { + // Prepare wallet and provider + let mut wallet = WalletUnlocked::new_random(None); + let num_coins = 100; + let coins = setup_single_asset_coins( + wallet.address(), + AssetId::zeroed(), + num_coins, + DEFAULT_COIN_AMOUNT, + ); + let provider = setup_test_provider(coins, vec![], None, None) + .await + .unwrap(); + wallet.set_provider(provider.clone()); + + // Prepare bytecode and subsections + let bytecode = fs::read(TX_CONTRACT_BYTECODE_PATH).unwrap(); + let subsection_size = 65536; + let subsections = UploadSubsection::split_bytecode(&bytecode, subsection_size).unwrap(); + + // Upload each sub section in a separate transaction and include the predicate with the transaction. + for subsection in subsections.clone() { + let mut builder = UploadTransactionBuilder::prepare_subsection_upload( + subsection, + TxPolicies::default(), + ); + + // Prepare the predicate + let predicate_data = TestTxOutputCountPredicateEncoder::default() + .encode_data(builder.inputs().len() as u16 + 1u16) // Add one for this predicate + .unwrap(); + let predicate: Predicate = Predicate::load_from(TX_OUTPUT_COUNT_PREDICATE_BYTECODE_PATH) + .unwrap() + .with_provider(provider.clone()) + .with_data(predicate_data); + let predicate_coin_amount = 100; + + // Predicate has no funds + let predicate_balance = predicate + .get_asset_balance(&provider.base_asset_id()) + .await + .unwrap(); + assert_eq!(predicate_balance, 0); + wallet + .transfer( + predicate.address(), + predicate_coin_amount, + *provider.base_asset_id(), + TxPolicies::default(), + ) + .await + .unwrap(); + + // Predicate has funds + let predicate_balance = predicate + .get_asset_balance(&provider.base_asset_id()) + .await + .unwrap(); + assert_eq!( + predicate_balance as usize, + predicate_coin_amount as usize * subsections.len() + ); + + // Inputs for predicate + let predicate_input = predicate + .get_asset_inputs_for_amount(*provider.base_asset_id(), 1, None) + .await + .unwrap(); + + // Outputs for predicate + let predicate_output = wallet.get_asset_outputs_for_amount( + &wallet.address(), + *provider.base_asset_id(), + 1, + ); + + // Append the predicate to the transaction + builder.inputs.push(predicate_input.get(0).unwrap().clone()); + builder + .outputs + .push(predicate_output.get(0).unwrap().clone()); + + wallet.add_witnesses(&mut builder).unwrap(); + wallet.adjust_for_fee(&mut builder, 0).await.unwrap(); + + // Submit the transaction + let tx = builder.build(&provider).await.unwrap(); + provider.send_transaction(tx).await.unwrap(); + + // The predicate has spent it's funds + let predicate_balance = predicate + .get_asset_balance(&provider.base_asset_id()) + .await + .unwrap(); + assert_eq!(predicate_balance, 0); + } + } } mod revert { From 11d8f54255d0b3c2764ca9c0ea15a95ddea287ba Mon Sep 17 00:00:00 2001 From: Cypher Pepe <125112044+cypherpepe@users.noreply.github.com> Date: Wed, 11 Sep 2024 20:29:23 +0300 Subject: [PATCH 007/115] Update helpers.rs (#6255) Simplified conditions and variables for better understanding and readability. ## Description ## 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. --------- Co-authored-by: cypherpepe Co-authored-by: IGI-111 --- sway-utils/src/helpers.rs | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/sway-utils/src/helpers.rs b/sway-utils/src/helpers.rs index be67108ea35..45ca8603f0e 100644 --- a/sway-utils/src/helpers.rs +++ b/sway-utils/src/helpers.rs @@ -4,14 +4,15 @@ use std::{ fs, path::{Path, PathBuf}, }; +use walkdir::WalkDir; pub fn get_sway_files(path: PathBuf) -> Vec { let mut files = vec![]; let mut dir_entries = vec![path]; while let Some(next_dir) = dir_entries.pop() { - if let Ok(read_dir) = fs::read_dir(next_dir) { - for entry in read_dir.filter_map(std::result::Result::ok) { + if let Ok(read_dir) = fs::read_dir(&next_dir) { + for entry in read_dir.filter_map(Result::ok) { let path = entry.path(); if path.is_dir() { dir_entries.push(path); @@ -25,11 +26,10 @@ pub fn get_sway_files(path: PathBuf) -> Vec { } pub fn is_sway_file(file: &Path) -> bool { - let res = file.extension(); - file.is_file() && Some(OsStr::new(constants::SWAY_EXTENSION)) == res + file.is_file() && file.extension() == Some(OsStr::new(constants::SWAY_EXTENSION)) } -/// create an iterator over all prefixes in a slice, smallest first +/// Create an iterator over all prefixes in a slice, smallest first /// /// ``` /// # use sway_utils::iter_prefixes; @@ -39,7 +39,6 @@ pub fn is_sway_file(file: &Path) -> bool { /// assert_eq!(it.next(), Some([1, 2].as_slice())); /// assert_eq!(it.next(), Some([1, 2, 3].as_slice())); /// assert_eq!(it.next(), None); -/// /// ``` pub fn iter_prefixes(slice: &[T]) -> impl DoubleEndedIterator { (1..=slice.len()).map(move |len| &slice[..len]) @@ -54,7 +53,6 @@ pub fn find_nested_manifest_dir(starter_path: &Path) -> Option { /// /// Starts the search from child dirs of `starter_path`. pub fn find_nested_dir_with_file(starter_path: &Path, file_name: &str) -> Option { - use walkdir::WalkDir; let starter_dir = if starter_path.is_dir() { starter_path } else { @@ -62,8 +60,7 @@ pub fn find_nested_dir_with_file(starter_path: &Path, file_name: &str) -> Option }; WalkDir::new(starter_path).into_iter().find_map(|e| { let entry = e.ok()?; - if entry.path() != starter_dir.join(file_name) - && entry.file_name().to_string_lossy() == file_name + if entry.path() != starter_dir.join(file_name) && entry.file_name() == OsStr::new(file_name) { let mut entry = entry.path().to_path_buf(); entry.pop(); @@ -77,14 +74,13 @@ pub fn find_nested_dir_with_file(starter_path: &Path, file_name: &str) -> Option /// Continually go up in the file tree until a specified file is found. /// /// Starts the search from `starter_path`. -#[allow(clippy::branches_sharing_code)] pub fn find_parent_dir_with_file>( starter_path: P, file_name: &str, ) -> Option { let mut path = std::fs::canonicalize(starter_path).ok()?; - let empty_path = PathBuf::from("/"); - while path != empty_path { + let root_path = PathBuf::from("/"); + while path != root_path { path.push(file_name); if path.exists() { path.pop(); @@ -95,28 +91,29 @@ pub fn find_parent_dir_with_file>( } None } + /// Continually go up in the file tree until a Forc manifest file is found. pub fn find_parent_manifest_dir>(starter_path: P) -> Option { find_parent_dir_with_file(starter_path, constants::MANIFEST_FILE_NAME) } -/// Continually go up in the file tree until a Forc manifest file is found and given predicate +/// Continually go up in the file tree until a Forc manifest file is found and the given predicate /// returns true. pub fn find_parent_manifest_dir_with_check, F>( starter_path: T, - f: F, + check: F, ) -> Option where F: Fn(&Path) -> bool, { - find_parent_manifest_dir(starter_path).and_then(|manifest_dir| { - // If given check satisfies return current dir otherwise start searching from the parent. - if f(&manifest_dir) { + find_parent_manifest_dir(&starter_path).and_then(|manifest_dir| { + // If given check satisfies, return the current dir; otherwise, start searching from the parent. + if check(&manifest_dir) { Some(manifest_dir) - } else if let Some(parent_dir) = manifest_dir.parent() { - find_parent_manifest_dir_with_check(parent_dir, f) } else { - None + manifest_dir + .parent() + .and_then(|parent_dir| find_parent_manifest_dir_with_check(parent_dir, check)) } }) } From fa3dafaa81bb9d0b804e383141b2299ab337ed6c Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite Date: Thu, 12 Sep 2024 04:52:04 +0100 Subject: [PATCH 008/115] Remove subs type optimization causing find method issues (#6532) ## Description This PR fixes https://github.com/FuelLabs/sway/issues/6491 ## 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. --------- Co-authored-by: Joshua Batty --- sway-core/src/decl_engine/ref.rs | 20 +++++++------------ .../generic_trait_constraints/src/main.sw | 18 +++++++++++++++++ 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/sway-core/src/decl_engine/ref.rs b/sway-core/src/decl_engine/ref.rs index a99ebf98b98..9ad82d72883 100644 --- a/sway-core/src/decl_engine/ref.rs +++ b/sway-core/src/decl_engine/ref.rs @@ -147,19 +147,13 @@ where ctx: &SubstTypesContext, ) -> Option { let decl_engine = ctx.engines.de(); - if type_mapping.source_ids_contains_concrete_type(ctx.engines) - || !decl_engine.get(&self.id).is_concrete(ctx.engines) - { - let mut decl = (*decl_engine.get(&self.id)).clone(); - if decl.subst(type_mapping, ctx).has_changes() { - Some( - decl_engine - .insert(decl, decl_engine.get_parsed_decl_id(&self.id).as_ref()) - .with_parent(decl_engine, self.id.into()), - ) - } else { - None - } + let mut decl = (*decl_engine.get(&self.id)).clone(); + if decl.subst(type_mapping, ctx).has_changes() { + Some( + decl_engine + .insert(decl, decl_engine.get_parsed_decl_id(&self.id).as_ref()) + .with_parent(decl_engine, self.id.into()), + ) } else { None } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_trait_constraints/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_trait_constraints/src/main.sw index 379224f8925..0073e0ea9d7 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_trait_constraints/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_trait_constraints/src/main.sw @@ -58,6 +58,21 @@ impl MyFrom for Struct3 { } } +// call an associated function through generic constraints +pub trait SizeInBytes { + fn size() -> u64; +} + +impl SizeInBytes for u64 { + fn size() -> u64 { + 8 + } +} + +fn call_size() -> u64 where T: SizeInBytes { + T::size() +} + fn main() -> bool { let s1 = Struct {data: 1_u64 }; assert_eq(s1.data.my_add(1,2),3); @@ -72,5 +87,8 @@ fn main() -> bool { let s4: Struct3 = Struct4{data:42}.my_into(); assert_eq(s4.data,42); + // call an associated function through generic constraints + assert_eq(call_size::(), 8); + true } \ No newline at end of file From 0fa1b9a4bc9ba69fc4ff02aeb5ea0f6feddb6817 Mon Sep 17 00:00:00 2001 From: SwayStar123 <46050679+SwayStar123@users.noreply.github.com> Date: Thu, 12 Sep 2024 17:59:42 +0530 Subject: [PATCH 009/115] Add Caller addresses function (#6514) ## Description Adds a new `caller_addresses` function to return a list of all owners of input coins and messages to a transaction ## 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. --------- Co-authored-by: Sophie Dankel <47993817+sdankel@users.noreply.github.com> --- sway-lib-std/src/auth.sw | 56 ++- .../auth_testing_abi/src/main.sw | 1 + .../auth_testing_contract/src/main.sw | 4 + .../src/sdk-harness/test_projects/auth/mod.rs | 432 +++++++++++++++++- 4 files changed, 490 insertions(+), 3 deletions(-) diff --git a/sway-lib-std/src/auth.sw b/sway-lib-std/src/auth.sw index a775cc3ed88..a18675a3027 100644 --- a/sway-lib-std/src/auth.sw +++ b/sway-lib-std/src/auth.sw @@ -6,8 +6,16 @@ use ::contract_id::ContractId; use ::identity::Identity; use ::option::Option::{self, *}; use ::result::Result::{self, *}; -use ::inputs::{Input, input_coin_owner, input_count, input_message_recipient, input_type,}; +use ::inputs::{ + Input, + input_coin_owner, + input_count, + input_message_recipient, + input_message_sender, + input_type, +}; use ::revert::revert; +use ::vec::Vec; /// The error type used when an `Identity` cannot be determined. pub enum AuthError { @@ -192,6 +200,52 @@ pub fn caller_address() -> Result { } } +/// Get the owners of the inputs (of type `Input::Coin` or `Input::Message`) to a +/// `TransactionScript`. +/// +/// # Additional Information +/// +/// The list is not deduplicated, so there may be repeated addresses in the returned vector. +/// +/// # Returns +/// +/// * [Vec

] - The addresses of the owners of the inputs. +/// +/// # Examples +/// +/// ```sway +/// use std::auth::caller_addresses; +/// +/// fn foo(some_address: Address) { +/// let addresses = caller_addresses(); +/// +/// assert(addresses.get(0).unwrap() == some_address); +/// } +/// ``` +pub fn caller_addresses() -> Vec
{ + let inputs = input_count().as_u64(); + let mut addresses = Vec::new(); + let mut iter = 0; + + while iter < inputs { + // Call the corresponding function based on the input type. + let input_owner = match input_type(iter) { + Some(Input::Coin) => input_coin_owner(iter), + Some(Input::Message) => input_message_sender(iter), + _ => None, // If not Coin or Message, loop continues. + }; + + // If we successfully retrieved an owner address, add it to the vector. + if let Some(address) = input_owner { + addresses.push(address); + } + + iter += 1; + } + + addresses +} + /// Get the current predicate's address when called in an internal context. /// /// # Returns diff --git a/test/src/sdk-harness/test_artifacts/auth_testing_abi/src/main.sw b/test/src/sdk-harness/test_artifacts/auth_testing_abi/src/main.sw index e45ec9c5f97..ab48c3e4756 100644 --- a/test/src/sdk-harness/test_artifacts/auth_testing_abi/src/main.sw +++ b/test/src/sdk-harness/test_artifacts/auth_testing_abi/src/main.sw @@ -4,4 +4,5 @@ abi AuthTesting { fn is_caller_external() -> bool; fn returns_msg_sender(expected_id: ContractId) -> bool; fn returns_msg_sender_address(expected_id: Address) -> bool; + fn returns_caller_addresses() -> Vec
; } diff --git a/test/src/sdk-harness/test_artifacts/auth_testing_contract/src/main.sw b/test/src/sdk-harness/test_artifacts/auth_testing_contract/src/main.sw index 4fd51ea5edc..ff145ae4d3d 100644 --- a/test/src/sdk-harness/test_artifacts/auth_testing_contract/src/main.sw +++ b/test/src/sdk-harness/test_artifacts/auth_testing_contract/src/main.sw @@ -43,4 +43,8 @@ impl AuthTesting for Contract { } ret } + + fn returns_caller_addresses() -> Vec
{ + caller_addresses() + } } diff --git a/test/src/sdk-harness/test_projects/auth/mod.rs b/test/src/sdk-harness/test_projects/auth/mod.rs index 45441e38582..2fefd28f8c8 100644 --- a/test/src/sdk-harness/test_projects/auth/mod.rs +++ b/test/src/sdk-harness/test_projects/auth/mod.rs @@ -135,6 +135,434 @@ async fn input_message_msg_sender_from_contract() { assert!(response.value); } +#[tokio::test] +async fn caller_addresses_from_messages() { + let mut wallet1 = WalletUnlocked::new_random(None); + let mut wallet2 = WalletUnlocked::new_random(None); + let mut wallet3 = WalletUnlocked::new_random(None); + let mut wallet4 = WalletUnlocked::new_random(None); + + // Setup message + let message_amount = 10; + let message1 = Message { + sender: wallet1.address().clone(), + recipient: wallet1.address().clone(), + nonce: 0.into(), + amount: message_amount, + data: vec![], + da_height: 0, + status: MessageStatus::Unspent, + }; + let message2 = Message { + sender: wallet2.address().clone(), + recipient: wallet2.address().clone(), + nonce: 1.into(), + amount: message_amount, + data: vec![], + da_height: 0, + status: MessageStatus::Unspent, + }; + let message3 = Message { + sender: wallet3.address().clone(), + recipient: wallet3.address().clone(), + nonce: 2.into(), + amount: message_amount, + data: vec![], + da_height: 0, + status: MessageStatus::Unspent, + }; + let mut message_vec: Vec = Vec::new(); + message_vec.push(message1); + message_vec.push(message2); + message_vec.push(message3); + + // Setup Coin + let coin_amount = 10; + let coin = Coin { + owner: wallet4.address().clone(), + utxo_id: UtxoId::new(Bytes32::zeroed(), 0), + amount: coin_amount, + asset_id: AssetId::default(), + status: CoinStatus::Unspent, + block_created: Default::default(), + }; + + let mut node_config = NodeConfig::default(); + node_config.starting_gas_price = 0; + let provider = setup_test_provider(vec![coin], message_vec, Some(node_config), None) + .await + .unwrap(); + + wallet1.set_provider(provider.clone()); + wallet2.set_provider(provider.clone()); + wallet3.set_provider(provider.clone()); + + wallet4.set_provider(provider.clone()); + + let id_1 = Contract::load_from( + "test_artifacts/auth_testing_contract/out/release/auth_testing_contract.bin", + LoadConfiguration::default(), + ) + .unwrap() + .deploy(&wallet4, TxPolicies::default()) + .await + .unwrap(); + + let auth_instance = AuthContract::new(id_1.clone(), wallet4.clone()); + + let result = auth_instance + .methods() + .returns_caller_addresses() + .call() + .await + .unwrap(); + + assert_eq!(result.value, vec![Address::from(*wallet4.address().hash())]); + + // Start building transactions + let call_handler = auth_instance + .methods() + .returns_caller_addresses(); + let mut tb = call_handler.transaction_builder().await.unwrap(); + + // Inputs + tb.inputs_mut().push(Input::ResourceSigned { + resource: CoinType::Message( + setup_single_message( + &wallet1.address().clone(), + &wallet1.address().clone(), + message_amount, + 0.into(), + vec![], + ) + ), + }); + tb.inputs_mut().push(Input::ResourceSigned { + resource: CoinType::Message( + setup_single_message( + &wallet2.address().clone(), + &wallet2.address().clone(), + message_amount, + 1.into(), + vec![], + ) + ), + }); + tb.inputs_mut().push(Input::ResourceSigned { + resource: CoinType::Message( + setup_single_message( + &wallet3.address().clone(), + &wallet3.address().clone(), + message_amount, + 2.into(), + vec![], + ) + ), + }); + + // Build transaction + tb.add_signer(wallet1.clone()).unwrap(); + tb.add_signer(wallet2.clone()).unwrap(); + tb.add_signer(wallet3.clone()).unwrap(); + + let provider = wallet1.provider().unwrap(); + let tx = tb.build(provider.clone()).await.unwrap(); + + // Send and verify + let tx_id = provider.send_transaction(tx).await.unwrap(); + let tx_status = provider.tx_status(&tx_id).await.unwrap(); + let result = call_handler.get_response_from(tx_status).unwrap(); + + assert!(result.value.contains(&Address::from(wallet1.address().clone()))); + assert!(result.value.contains(&Address::from(wallet2.address().clone()))); + assert!(result.value.contains(&Address::from(wallet3.address().clone()))); +} + +#[tokio::test] +async fn caller_addresses_from_coins() { + let mut wallet1 = WalletUnlocked::new_random(None); + let mut wallet2 = WalletUnlocked::new_random(None); + let mut wallet3 = WalletUnlocked::new_random(None); + let mut wallet4 = WalletUnlocked::new_random(None); + + // Setup Coin + let coin_amount = 10; + let coin1 = Coin { + owner: wallet1.address().clone(), + utxo_id: UtxoId::new(Bytes32::zeroed(), 0), + amount: coin_amount, + asset_id: AssetId::default(), + status: CoinStatus::Unspent, + block_created: Default::default(), + }; + let coin2 = Coin { + owner: wallet2.address().clone(), + utxo_id: UtxoId::new(Bytes32::zeroed(), 1), + amount: coin_amount, + asset_id: AssetId::default(), + status: CoinStatus::Unspent, + block_created: Default::default(), + }; + let coin3 = Coin { + owner: wallet3.address().clone(), + utxo_id: UtxoId::new(Bytes32::zeroed(), 2), + amount: coin_amount, + asset_id: AssetId::default(), + status: CoinStatus::Unspent, + block_created: Default::default(), + }; + let coin4 = Coin { + owner: wallet4.address().clone(), + utxo_id: UtxoId::new(Bytes32::zeroed(), 3), + amount: coin_amount, + asset_id: AssetId::default(), + status: CoinStatus::Unspent, + block_created: Default::default(), + }; + + let mut coin_vec: Vec = Vec::new(); + coin_vec.push(coin1); + coin_vec.push(coin2); + coin_vec.push(coin3); + coin_vec.push(coin4); + + let mut node_config = NodeConfig::default(); + node_config.starting_gas_price = 0; + let provider = setup_test_provider(coin_vec, vec![], Some(node_config), None) + .await + .unwrap(); + + wallet1.set_provider(provider.clone()); + wallet2.set_provider(provider.clone()); + wallet3.set_provider(provider.clone()); + + wallet4.set_provider(provider.clone()); + + let id_1 = Contract::load_from( + "test_artifacts/auth_testing_contract/out/release/auth_testing_contract.bin", + LoadConfiguration::default(), + ) + .unwrap() + .deploy(&wallet4, TxPolicies::default()) + .await + .unwrap(); + + let auth_instance = AuthContract::new(id_1.clone(), wallet4.clone()); + + let result = auth_instance + .methods() + .returns_caller_addresses() + .call() + .await + .unwrap(); + + assert_eq!(result.value, vec![Address::from(*wallet4.address().hash())]); + + // Start building transactions + let call_handler = auth_instance + .methods() + .returns_caller_addresses(); + let mut tb = call_handler.transaction_builder().await.unwrap(); + + // Inputs + tb.inputs_mut().push(Input::ResourceSigned { + resource: CoinType::Coin( + Coin { + owner: wallet1.address().clone(), + utxo_id: UtxoId::new(Bytes32::zeroed(), 0), + amount: coin_amount, + asset_id: AssetId::default(), + status: CoinStatus::Unspent, + block_created: Default::default(), + } + ), + }); + tb.inputs_mut().push(Input::ResourceSigned { + resource: CoinType::Coin( + Coin { + owner: wallet2.address().clone(), + utxo_id: UtxoId::new(Bytes32::zeroed(), 1), + amount: coin_amount, + asset_id: AssetId::default(), + status: CoinStatus::Unspent, + block_created: Default::default(), + } + ), + }); + tb.inputs_mut().push(Input::ResourceSigned { + resource: CoinType::Coin( + Coin { + owner: wallet3.address().clone(), + utxo_id: UtxoId::new(Bytes32::zeroed(), 2), + amount: coin_amount, + asset_id: AssetId::default(), + status: CoinStatus::Unspent, + block_created: Default::default(), + } + ), + }); + + // Build transaction + tb.add_signer(wallet1.clone()).unwrap(); + tb.add_signer(wallet2.clone()).unwrap(); + tb.add_signer(wallet3.clone()).unwrap(); + + let provider = wallet1.provider().unwrap(); + let tx = tb.build(provider.clone()).await.unwrap(); + + // Send and verify + let tx_id = provider.send_transaction(tx).await.unwrap(); + let tx_status = provider.tx_status(&tx_id).await.unwrap(); + let result = call_handler.get_response_from(tx_status).unwrap(); + + assert!(result.value.contains(&Address::from(wallet1.address().clone()))); + assert!(result.value.contains(&Address::from(wallet2.address().clone()))); + assert!(result.value.contains(&Address::from(wallet3.address().clone()))); +} + +#[tokio::test] +async fn caller_addresses_from_coins_and_messages() { + let mut wallet1 = WalletUnlocked::new_random(None); + let mut wallet2 = WalletUnlocked::new_random(None); + let mut wallet3 = WalletUnlocked::new_random(None); + let mut wallet4 = WalletUnlocked::new_random(None); + + let message_amount = 10; + let message1 = Message { + sender: wallet1.address().clone(), + recipient: wallet1.address().clone(), + nonce: 0.into(), + amount: message_amount, + data: vec![], + da_height: 0, + status: MessageStatus::Unspent, + }; + + // Setup Coin + let coin_amount = 10; + let coin2 = Coin { + owner: wallet2.address().clone(), + utxo_id: UtxoId::new(Bytes32::zeroed(), 1), + amount: coin_amount, + asset_id: AssetId::default(), + status: CoinStatus::Unspent, + block_created: Default::default(), + }; + let coin3 = Coin { + owner: wallet3.address().clone(), + utxo_id: UtxoId::new(Bytes32::zeroed(), 2), + amount: coin_amount, + asset_id: AssetId::default(), + status: CoinStatus::Unspent, + block_created: Default::default(), + }; + let coin4 = Coin { + owner: wallet4.address().clone(), + utxo_id: UtxoId::new(Bytes32::zeroed(), 3), + amount: coin_amount, + asset_id: AssetId::default(), + status: CoinStatus::Unspent, + block_created: Default::default(), + }; + + let mut coin_vec: Vec = Vec::new(); + coin_vec.push(coin2); + coin_vec.push(coin3); + coin_vec.push(coin4); + + let mut node_config = NodeConfig::default(); + node_config.starting_gas_price = 0; + let provider = setup_test_provider(coin_vec, vec![message1], Some(node_config), None) + .await + .unwrap(); + + wallet1.set_provider(provider.clone()); + wallet2.set_provider(provider.clone()); + wallet3.set_provider(provider.clone()); + + wallet4.set_provider(provider.clone()); + + let id_1 = Contract::load_from( + "test_artifacts/auth_testing_contract/out/release/auth_testing_contract.bin", + LoadConfiguration::default(), + ) + .unwrap() + .deploy(&wallet4, TxPolicies::default()) + .await + .unwrap(); + + let auth_instance = AuthContract::new(id_1.clone(), wallet4.clone()); + + let result = auth_instance + .methods() + .returns_caller_addresses() + .call() + .await + .unwrap(); + + assert_eq!(result.value, vec![Address::from(*wallet4.address().hash())]); + + // Start building transactions + let call_handler = auth_instance + .methods() + .returns_caller_addresses(); + let mut tb = call_handler.transaction_builder().await.unwrap(); + + // Inputs + tb.inputs_mut().push(Input::ResourceSigned { + resource: CoinType::Message( + setup_single_message( + &wallet1.address().clone(), + &wallet1.address().clone(), + message_amount, + 0.into(), + vec![], + ) + ), + }); + tb.inputs_mut().push(Input::ResourceSigned { + resource: CoinType::Coin( + Coin { + owner: wallet2.address().clone(), + utxo_id: UtxoId::new(Bytes32::zeroed(), 1), + amount: coin_amount, + asset_id: AssetId::default(), + status: CoinStatus::Unspent, + block_created: Default::default(), + } + ), + }); + tb.inputs_mut().push(Input::ResourceSigned { + resource: CoinType::Coin( + Coin { + owner: wallet3.address().clone(), + utxo_id: UtxoId::new(Bytes32::zeroed(), 2), + amount: coin_amount, + asset_id: AssetId::default(), + status: CoinStatus::Unspent, + block_created: Default::default(), + } + ), + }); + + // Build transaction + tb.add_signer(wallet1.clone()).unwrap(); + tb.add_signer(wallet2.clone()).unwrap(); + tb.add_signer(wallet3.clone()).unwrap(); + + let provider = wallet1.provider().unwrap(); + let tx = tb.build(provider.clone()).await.unwrap(); + + // Send and verify + let tx_id = provider.send_transaction(tx).await.unwrap(); + let tx_status = provider.tx_status(&tx_id).await.unwrap(); + let result = call_handler.get_response_from(tx_status).unwrap(); + + assert!(result.value.contains(&Address::from(wallet1.address().clone()))); + assert!(result.value.contains(&Address::from(wallet2.address().clone()))); + assert!(result.value.contains(&Address::from(wallet3.address().clone()))); +} + async fn get_contracts() -> ( AuthContract, ContractId, @@ -196,7 +624,7 @@ async fn can_get_predicate_address() { // Setup predicate. let hex_predicate_address: &str = - "0x0c07e9f6e71da8855fb65a38f299a993aeba71fd0eef6c1ac4c79beff09cd6f7"; + "0x5dcc82a88eebb07fb628db93d11ec38f085cbf36453a7135fea41b93cc44e118"; let predicate_address = Address::from_str(hex_predicate_address).expect("failed to create Address from string"); let predicate_bech32_address = Bech32Address::from(predicate_address); @@ -322,7 +750,7 @@ async fn when_incorrect_predicate_address_passed() { async fn can_get_predicate_address_in_message() { // Setup predicate address. let hex_predicate_address: &str = - "0x0c07e9f6e71da8855fb65a38f299a993aeba71fd0eef6c1ac4c79beff09cd6f7"; + "0x5dcc82a88eebb07fb628db93d11ec38f085cbf36453a7135fea41b93cc44e118"; let predicate_address = Address::from_str(hex_predicate_address).expect("failed to create Address from string"); let predicate_bech32_address = Bech32Address::from(predicate_address); From 7b072166abf81b2eb880a3454cc7e8f4b2667a26 Mon Sep 17 00:00:00 2001 From: SwayStar123 <46050679+SwayStar123@users.noreply.github.com> Date: Fri, 13 Sep 2024 06:53:52 +0530 Subject: [PATCH 010/115] Add Eq for Result (#6140) ## Description Closes #6077 ## 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). - [ ] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: K1-R1 <77465250+K1-R1@users.noreply.github.com> --- sway-lib-std/src/result.sw | 14 +++ .../result_inline_tests/src/eq.sw | 114 ++++++++++++++++++ .../result_inline_tests/src/main.sw | 2 + 3 files changed, 130 insertions(+) create mode 100644 test/src/in_language_tests/test_programs/result_inline_tests/src/eq.sw diff --git a/sway-lib-std/src/result.sw b/sway-lib-std/src/result.sw index f4f5f79a2b0..9b0532ee567 100644 --- a/sway-lib-std/src/result.sw +++ b/sway-lib-std/src/result.sw @@ -269,3 +269,17 @@ impl Result { // - `ok(self) -> Option` // - `err(self) -> Option` } + +impl Eq for Result +where + T: Eq, + E: Eq, +{ + fn eq(self, other: Self) -> bool { + match (self, other) { + (Self::Ok(a), Self::Ok(b)) => a == b, + (Self::Err(a), Self::Err(b)) => a == b, + _ => false, + } + } +} diff --git a/test/src/in_language_tests/test_programs/result_inline_tests/src/eq.sw b/test/src/in_language_tests/test_programs/result_inline_tests/src/eq.sw new file mode 100644 index 00000000000..18ce687b26e --- /dev/null +++ b/test/src/in_language_tests/test_programs/result_inline_tests/src/eq.sw @@ -0,0 +1,114 @@ +library; + +#[test] +fn test_eq_u64_u64() { + let a: Result = Ok(0); + let b: Result = Ok(0); + assert_eq(a, b); + + let a: Result = Ok(1); + let b: Result = Ok(1); + assert_eq(a, b); + + let a: Result = Ok(42); + let b: Result = Ok(42); + assert_eq(a, b); + + let a: Result = Ok(u64::max()); + let b: Result = Ok(u64::max()); + assert_eq(a, b); +} + +#[test] +fn test_neq_u64_u64() { + // Ok + let a: Result = Ok(0); + let b: Result = Ok(1); + assert_ne(a, b); + + let a: Result = Ok(0); + let b: Result = Ok(42); + assert_ne(a, b); + + let a: Result = Ok(0); + let b: Result = Ok(u64::max()); + assert_ne(a, b); + + let a: Result = Ok(1); + let b: Result = Ok(0); + assert_ne(a, b); + + let a: Result = Ok(42); + let b: Result = Ok(0); + assert_ne(a, b); + + let a: Result = Ok(u64::max()); + let b: Result = Ok(0); + assert_ne(a, b); + + // Err + let a: Result = Err(0); + let b: Result = Err(1); + assert_ne(a, b); + + let a: Result = Err(0); + let b: Result = Err(42); + assert_ne(a, b); + + let a: Result = Err(0); + let b: Result = Err(u64::max()); + assert_ne(a, b); + + let a: Result = Err(1); + let b: Result = Err(0); + assert_ne(a, b); + + let a: Result = Err(42); + let b: Result = Err(0); + assert_ne(a, b); + + let a: Result = Err(u64::max()); + let b: Result = Err(0); + assert_ne(a, b); + + // Ok-Err + let a: Result = Ok(0); + let b: Result = Err(0); + assert_ne(a, b); + + let a: Result = Ok(1); + let b: Result = Err(1); + assert_ne(a, b); + + let a: Result = Ok(42); + let b: Result = Err(42); + assert_ne(a, b); + + let a: Result = Ok(u64::max()); + let b: Result = Err(u64::max()); + assert_ne(a, b); + + let a: Result = Ok(0); + let b: Result = Err(1); + assert_ne(a, b); + + let a: Result = Ok(0); + let b: Result = Err(42); + assert_ne(a, b); + + let a: Result = Ok(0); + let b: Result = Err(u64::max()); + assert_ne(a, b); + + let a: Result = Ok(1); + let b: Result = Err(0); + assert_ne(a, b); + + let a: Result = Ok(42); + let b: Result = Err(0); + assert_ne(a, b); + + let a: Result = Ok(u64::max()); + let b: Result = Err(0); + assert_ne(a, b); +} diff --git a/test/src/in_language_tests/test_programs/result_inline_tests/src/main.sw b/test/src/in_language_tests/test_programs/result_inline_tests/src/main.sw index 2166d4b643b..381c4ec24f5 100644 --- a/test/src/in_language_tests/test_programs/result_inline_tests/src/main.sw +++ b/test/src/in_language_tests/test_programs/result_inline_tests/src/main.sw @@ -1,5 +1,7 @@ library; +mod eq; + #[test] fn result_is_ok() { use std::bytes::Bytes; From 7ab1565498b863a60fe2bf291b5f0fb7628be864 Mon Sep 17 00:00:00 2001 From: Sophie Dankel <47993817+sdankel@users.noreply.github.com> Date: Fri, 13 Sep 2024 15:33:18 -0700 Subject: [PATCH 011/115] feat: Add --raw-logs option for forc-test (#6528) ## Description Closes https://github.com/FuelLabs/sway/issues/6015 - Adds the `--raw-logs` option - Removes the `decode` option as this is now the default for `--logs` - Shortens `--pretty-print` to `--pretty` ## 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. - [ ] 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. --- .github/workflows/ci.yml | 15 +++- Cargo.lock | 1 + forc/Cargo.toml | 1 + forc/src/cli/commands/test.rs | 41 +++++---- forc/tests/cli_integration.rs | 84 +++++++++++++++++++ forc/tests/fixtures/test_contract/.gitignore | 2 + forc/tests/fixtures/test_contract/Forc.lock | 13 +++ forc/tests/fixtures/test_contract/Forc.toml | 8 ++ forc/tests/fixtures/test_contract/src/main.sw | 23 +++++ 9 files changed, 166 insertions(+), 22 deletions(-) create mode 100644 forc/tests/cli_integration.rs create mode 100644 forc/tests/fixtures/test_contract/.gitignore create mode 100644 forc/tests/fixtures/test_contract/Forc.lock create mode 100644 forc/tests/fixtures/test_contract/Forc.toml create mode 100644 forc/tests/fixtures/test_contract/src/main.sw diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9380c391ee1..1930cf1a156 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -551,6 +551,19 @@ jobs: env: RUST_BACKTRACE: full run: cargo nextest run --locked --release -p sway-lsp --no-capture --profile ci --config-file sway-lsp/tests/nextest.toml + cargo-test-forc: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Install toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.RUST_VERSION }} + - uses: Swatinem/rust-cache@v2 + - name: Run forc tests separately + env: + RUST_BACKTRACE: full + run: cargo test --locked --release -p forc -- --nocapture cargo-test-workspace: runs-on: ubuntu-latest steps: @@ -561,7 +574,7 @@ jobs: toolchain: ${{ env.RUST_VERSION }} - uses: Swatinem/rust-cache@v2 - name: Run tests - run: cargo test --locked --release --workspace --exclude forc-debug --exclude sway-lsp --exclude forc-client + run: cargo test --locked --release --workspace --exclude forc-debug --exclude sway-lsp --exclude forc-client --exclude forc cargo-unused-deps-check: runs-on: ubuntu-latest steps: diff --git a/Cargo.lock b/Cargo.lock index b67de59cb8b..576107da4d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2025,6 +2025,7 @@ dependencies = [ "fs_extra", "fuel-asm", "hex", + "rexpect 0.5.0", "serde", "serde_json", "sway-core", diff --git a/forc/Cargo.toml b/forc/Cargo.toml index 665c2630c2c..00e1dc3af76 100644 --- a/forc/Cargo.toml +++ b/forc/Cargo.toml @@ -55,3 +55,4 @@ uwu = ["uwuify"] [dev-dependencies] completest-pty = "0.5.0" +rexpect = "0.5" diff --git a/forc/src/cli/commands/test.rs b/forc/src/cli/commands/test.rs index b4dcf9c524c..5ffa1c51d75 100644 --- a/forc/src/cli/commands/test.rs +++ b/forc/src/cli/commands/test.rs @@ -61,16 +61,15 @@ pub struct Command { #[derive(Parser, Debug, Clone)] #[clap(after_help = help())] pub struct TestPrintOpts { - #[clap(long = "pretty-print", short = 'r')] + #[clap(long = "pretty")] /// Pretty-print the logs emitted from tests. pub pretty_print: bool, /// Print `Log` and `LogData` receipts for tests. #[clap(long = "logs", short = 'l')] pub print_logs: bool, - /// Decode logs and show decoded log information in human readable format alongside the raw - /// logs. - #[clap(long = "decode", short = 'd')] - pub decode_logs: bool, + /// Print the raw logs for tests. + #[clap(long)] + pub raw_logs: bool, } pub(crate) fn exec(cmd: Command) -> ForcResult<()> { @@ -150,26 +149,26 @@ fn print_tested_pkg(pkg: &TestedPackage, test_print_opts: &TestPrintOpts) -> For ); // If logs are enabled, print them. + let logs = &test.logs; if test_print_opts.print_logs { - let logs = &test.logs; - if test_print_opts.decode_logs { - for log in logs { - if let Receipt::LogData { - rb, - data: Some(data), - .. - } = log - { - let decoded_log_data = - decode_log_data(&rb.to_string(), data, &pkg.built.program_abi)?; - let var_value = decoded_log_data.value; - info!("Decoded log value: {}, log rb: {}", var_value, rb); - } + for log in logs { + if let Receipt::LogData { + rb, + data: Some(data), + .. + } = log + { + let decoded_log_data = + decode_log_data(&rb.to_string(), data, &pkg.built.program_abi)?; + let var_value = decoded_log_data.value; + info!("Decoded log value: {}, log rb: {}", var_value, rb); } - info!("Raw logs:"); } + } + + if test_print_opts.raw_logs { let formatted_logs = format_log_receipts(logs, test_print_opts.pretty_print)?; - info!("{}", formatted_logs); + info!("Raw logs:\n{}", formatted_logs); } // If the test is failing, save the test result for printing the details later on. diff --git a/forc/tests/cli_integration.rs b/forc/tests/cli_integration.rs new file mode 100644 index 00000000000..407cda7489d --- /dev/null +++ b/forc/tests/cli_integration.rs @@ -0,0 +1,84 @@ +use std::path::PathBuf; + +use rexpect::spawn; + +const TIMEOUT_MS: u64 = 300000; + +fn test_fixtures_path() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("tests") + .join("fixtures") + .canonicalize() + .unwrap() +} + +#[test] +fn test_forc_test_decoded_logs() -> Result<(), rexpect::error::Error> { + // Spawn the forc binary using cargo run + let project_dir = test_fixtures_path().join("test_contract"); + let mut process = spawn( + &format!( + "cargo run --bin forc -- test --logs --path {}", + project_dir.to_string_lossy() + ), + Some(TIMEOUT_MS), + )?; + + // Assert that the output is correct + process.exp_string(" test test_log_4")?; + process.exp_string("Decoded log value: 4, log rb: 1515152261580153489")?; + process.exp_string(" test test_log_2")?; + process.exp_string("Decoded log value: 2, log rb: 1515152261580153489")?; + + process.process.exit()?; + Ok(()) +} + +#[test] +fn test_forc_test_raw_logs() -> Result<(), rexpect::error::Error> { + // Spawn the forc binary using cargo run + let project_dir = test_fixtures_path().join("test_contract"); + let mut process = spawn( + &format!( + "cargo run --bin forc -- test --raw-logs --path {}", + project_dir.to_string_lossy() + ), + Some(TIMEOUT_MS), + )?; + + // Assert that the output is correct + process.exp_string(" test test_log_4")?; + process.exp_string("Raw logs:")?; + process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12652,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; + process.exp_string(" test test_log_2")?; + process.exp_string("Raw logs:")?; + process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12652,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; + + process.process.exit()?; + Ok(()) +} + +#[test] +fn test_forc_test_both_logs() -> Result<(), rexpect::error::Error> { + // Spawn the forc binary using cargo run + let project_dir = test_fixtures_path().join("test_contract"); + let mut process = spawn( + &format!( + "cargo run --bin forc -- test --logs --raw-logs --path {}", + project_dir.to_string_lossy() + ), + Some(TIMEOUT_MS), + )?; + + // Assert that the output is correct + process.exp_string(" test test_log_4")?; + process.exp_string("Decoded log value: 4, log rb: 1515152261580153489")?; + process.exp_string("Raw logs:")?; + process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12652,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; + process.exp_string(" test test_log_2")?; + process.exp_string("Decoded log value: 2, log rb: 1515152261580153489")?; + process.exp_string("Raw logs:")?; + process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12652,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; + process.process.exit()?; + Ok(()) +} diff --git a/forc/tests/fixtures/test_contract/.gitignore b/forc/tests/fixtures/test_contract/.gitignore new file mode 100644 index 00000000000..77d3844f58c --- /dev/null +++ b/forc/tests/fixtures/test_contract/.gitignore @@ -0,0 +1,2 @@ +out +target diff --git a/forc/tests/fixtures/test_contract/Forc.lock b/forc/tests/fixtures/test_contract/Forc.lock new file mode 100644 index 00000000000..943d47b39ef --- /dev/null +++ b/forc/tests/fixtures/test_contract/Forc.lock @@ -0,0 +1,13 @@ +[[package]] +name = "core" +source = "path+from-root-4D4735C41181917E" + +[[package]] +name = "std" +source = "path+from-root-4D4735C41181917E" +dependencies = ["core"] + +[[package]] +name = "test_contract" +source = "member" +dependencies = ["std"] diff --git a/forc/tests/fixtures/test_contract/Forc.toml b/forc/tests/fixtures/test_contract/Forc.toml new file mode 100644 index 00000000000..4342f8dbc65 --- /dev/null +++ b/forc/tests/fixtures/test_contract/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "test_contract" + +[dependencies] +std = { path = "../../../../sway-lib-std/" } diff --git a/forc/tests/fixtures/test_contract/src/main.sw b/forc/tests/fixtures/test_contract/src/main.sw new file mode 100644 index 00000000000..2314fa4dc47 --- /dev/null +++ b/forc/tests/fixtures/test_contract/src/main.sw @@ -0,0 +1,23 @@ +contract; + +abi MyContract { + fn test_function() -> bool; +} + +impl MyContract for Contract { + fn test_function() -> bool { + true + } +} + +#[test] +fn test_log_4() { + log(4); + assert(1 == 1) +} + +#[test] +fn test_log_2() { + log(2); + assert(1 == 1) +} From e1a05fccecf3dccfa220185e35a63bc518f0f0bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ron=C4=8Devi=C4=87?= Date: Sun, 15 Sep 2024 00:28:42 +0200 Subject: [PATCH 012/115] Add tests for recursive `const` definitions and associated consts usages (#6545) ## Description This PR adds additional tests for constants. Those test cases are important for the implementation of #6351 which will completely restructure compilation of constants. Tests for recursive `const` definitions should also be considered before we start implementing `const fn` and `const trait`. In particular, we want to better track and provide precise error messages in case of unintended attempt to recursively define a constant in a complex situation that includes `const fn` and `const trait`. Related to #6534, #6537, #6538, #6539, #6540, #6543, and #6544. ## 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. --- .../const_block_level_no_expr/src/main.sw | 2 +- .../const_block_level_no_expr/test.toml | 2 + .../const_top_level_no_expr/test.toml | 2 + .../should_fail/recursive_calls/test.toml | 2 + .../recursive_const_associated/Forc.lock | 3 + .../recursive_const_associated/Forc.toml | 6 ++ .../recursive_const_associated/src/main.sw | 13 +++ .../recursive_const_associated/test.toml | 1 + .../Forc.lock | 3 + .../Forc.toml | 6 ++ .../src/main.sw | 13 +++ .../test.toml | 9 ++ .../Forc.lock | 3 + .../Forc.toml | 6 ++ .../src/main.sw | 11 +++ .../test.toml | 1 + .../recursive_const_module/Forc.lock | 3 + .../recursive_const_module/Forc.toml | 6 ++ .../recursive_const_module/src/main.sw | 8 ++ .../recursive_const_module/test.toml | 10 ++ .../Forc.lock | 3 + .../Forc.toml | 6 ++ .../src/main.sw | 9 ++ .../test.toml | 11 +++ .../Forc.lock | 3 + .../Forc.toml | 6 ++ .../src/main.sw | 11 +++ .../test.toml | 9 ++ .../Forc.lock | 3 + .../Forc.toml | 6 ++ .../src/main.sw | 7 ++ .../test.toml | 11 +++ .../recursive_const_stack_overflow/Forc.lock | 3 + .../recursive_const_stack_overflow/Forc.toml | 6 ++ .../src/main.sw | 17 ++++ .../recursive_const_stack_overflow/test.toml | 1 + .../should_fail/recursive_enum/src/main.sw | 6 +- .../should_fail/recursive_enum/test.toml | 2 + .../should_fail/recursive_struct/src/main.sw | 6 +- .../should_fail/recursive_struct/test.toml | 2 + .../recursive_type_chain/src/main.sw | 6 +- .../recursive_type_chain/test.toml | 2 + .../recursive_type_unification/src/main.sw | 4 +- .../recursive_type_unification/test.toml | 2 + .../Forc.lock | 13 +++ .../Forc.toml | 10 ++ .../src/main.sw | 95 +++++++++++++++++++ .../test.toml | 1 + 48 files changed, 353 insertions(+), 18 deletions(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated/test.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_associated_function/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_associated_function/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_associated_function/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_associated_function/test.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_module_function/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_module_function/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_module_function/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_module_function/test.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module/test.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_const/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_const/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_const/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_const/test.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_function/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_function/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_function/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_function/test.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_module_function/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_module_function/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_module_function/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_module_function/test.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_stack_overflow/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_stack_overflow/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_stack_overflow/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_stack_overflow/test.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/associated_const_in_decls_of_other_constants/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/associated_const_in_decls_of_other_constants/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/associated_const_in_decls_of_other_constants/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/associated_const_in_decls_of_other_constants/test.toml diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/const_block_level_no_expr/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/const_block_level_no_expr/src/main.sw index b142db7e44d..30c0c042230 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/const_block_level_no_expr/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_fail/const_block_level_no_expr/src/main.sw @@ -1,4 +1,4 @@ -script; +library; fn main() -> u64 { const X; diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/const_block_level_no_expr/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/const_block_level_no_expr/test.toml index 825c088f656..35bf69ce835 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/const_block_level_no_expr/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/const_block_level_no_expr/test.toml @@ -2,3 +2,5 @@ category = "fail" # check: $()const X; # nextln: $()Constant requires expression. + +# check: $()1 error. diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/const_top_level_no_expr/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/const_top_level_no_expr/test.toml index 825c088f656..35bf69ce835 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/const_top_level_no_expr/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/const_top_level_no_expr/test.toml @@ -2,3 +2,5 @@ category = "fail" # check: $()const X; # nextln: $()Constant requires expression. + +# check: $()1 error. diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_calls/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_calls/test.toml index a8f5ea67fc5..aeca86a984a 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_calls/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_calls/test.toml @@ -6,3 +6,5 @@ category = "fail" # check: $()Function d is recursive via e and f, which is unsupported at this time. # check: $()Function e is recursive via f and d, which is unsupported at this time. # check: $()Function f is recursive via d and e, which is unsupported at this time. + +# check: $()6 errors. diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated/Forc.lock new file mode 100644 index 00000000000..331d658a292 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated/Forc.lock @@ -0,0 +1,3 @@ +[[package]] +name = "recursive_const_associated" +source = "member" diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated/Forc.toml new file mode 100644 index 00000000000..27cbd02415f --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated/Forc.toml @@ -0,0 +1,6 @@ +[project] +name = "recursive_const_associated" +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +implicit-std = false diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated/src/main.sw new file mode 100644 index 00000000000..30579eb4ae9 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated/src/main.sw @@ -0,0 +1,13 @@ +library; + +struct S {} + +// TODO: Uncomment this code, and enable this test and add checks once https://github.com/FuelLabs/sway/issues/6537 is fixed. +impl S { + // const A: u8 = Self::B; + // const B: u8 = Self::A; + + // const X: u8 = Self::Y; + // const Y: u8 = Self::Z; + // const Z: u8 = Self::X; +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated/test.toml new file mode 100644 index 00000000000..2b2d5ea7f55 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated/test.toml @@ -0,0 +1 @@ +category = "disabled" # TODO: Enable this test and add checks once https://github.com/FuelLabs/sway/issues/6537 is fixed. \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_associated_function/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_associated_function/Forc.lock new file mode 100644 index 00000000000..57a80573413 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_associated_function/Forc.lock @@ -0,0 +1,3 @@ +[[package]] +name = "recursive_const_associated_over_associated_function" +source = "member" diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_associated_function/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_associated_function/Forc.toml new file mode 100644 index 00000000000..1fc0f96f59e --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_associated_function/Forc.toml @@ -0,0 +1,6 @@ +[project] +name = "recursive_const_associated_over_associated_function" +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +implicit-std = false diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_associated_function/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_associated_function/src/main.sw new file mode 100644 index 00000000000..5c403b1f0d1 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_associated_function/src/main.sw @@ -0,0 +1,13 @@ +library; + +struct S {} + +impl S { + fn assoc() -> u8 { + Self::S_ASSOC + } +} + +impl S { + const S_ASSOC: u8 = Self::assoc(); +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_associated_function/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_associated_function/test.toml new file mode 100644 index 00000000000..3144024dde2 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_associated_function/test.toml @@ -0,0 +1,9 @@ +category = "fail" + +#check: $()Self::S_ASSOC +#nextln: $()Could not find symbol "S_ASSOC" in this scope. + +#check: $()const S_ASSOC: u8 = Self::assoc(); +#nextln: $()No method named "assoc" found for type "S". + +#check: $()2 errors. diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_module_function/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_module_function/Forc.lock new file mode 100644 index 00000000000..9905a4a2526 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_module_function/Forc.lock @@ -0,0 +1,3 @@ +[[package]] +name = "recursive_const_associated_over_module_function" +source = "member" diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_module_function/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_module_function/Forc.toml new file mode 100644 index 00000000000..7e6e1257169 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_module_function/Forc.toml @@ -0,0 +1,6 @@ +[project] +name = "recursive_const_associated_over_module_function" +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +implicit-std = false diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_module_function/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_module_function/src/main.sw new file mode 100644 index 00000000000..2db4ae55ca8 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_module_function/src/main.sw @@ -0,0 +1,11 @@ +library; + +struct S {} + +fn mod_fn() -> u8 { + S::S_ASSOC +} + +impl S { + const S_ASSOC: u8 = mod_fn(); +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_module_function/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_module_function/test.toml new file mode 100644 index 00000000000..de7f57c0bf4 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_module_function/test.toml @@ -0,0 +1 @@ +category = "disabled" # TODO: Enable this failing test and write checks once https://github.com/FuelLabs/sway/issues/6539 is fixed. diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module/Forc.lock new file mode 100644 index 00000000000..3a8caa0b5d3 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module/Forc.lock @@ -0,0 +1,3 @@ +[[package]] +name = "recursive_const_module" +source = "member" diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module/Forc.toml new file mode 100644 index 00000000000..ed69431166e --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module/Forc.toml @@ -0,0 +1,6 @@ +[project] +name = "recursive_const_module" +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +implicit-std = false diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module/src/main.sw new file mode 100644 index 00000000000..bf0ca9d7edb --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module/src/main.sw @@ -0,0 +1,8 @@ +library; + +pub const A: u8 = B; +pub const B: u8 = A; + +pub const X: u8 = Y; +pub const Y: u8 = Z; +pub const Z: u8 = X; \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module/test.toml new file mode 100644 index 00000000000..1d3b404a92e --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module/test.toml @@ -0,0 +1,10 @@ +category = "fail" # TODO: Adjust these checks once https://github.com/FuelLabs/sway/issues/6534 is fixed. + +# check: $()Type B is recursive via A, which is unsupported at this time. +# check: $()Type A is recursive via B, which is unsupported at this time. + +# check: $()Type Y is recursive via Z and X, which is unsupported at this time. +# check: $()Type Z is recursive via X and Y, which is unsupported at this time. +# check: $()Type X is recursive via Y and Z, which is unsupported at this time. + +# check: $()5 errors. diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_const/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_const/Forc.lock new file mode 100644 index 00000000000..51cd377d79c --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_const/Forc.lock @@ -0,0 +1,3 @@ +[[package]] +name = "recursive_const_module_over_associated_const" +source = "member" diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_const/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_const/Forc.toml new file mode 100644 index 00000000000..c41fbc8b663 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_const/Forc.toml @@ -0,0 +1,6 @@ +[project] +name = "recursive_const_module_over_associated_const" +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +implicit-std = false diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_const/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_const/src/main.sw new file mode 100644 index 00000000000..ce072321d46 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_const/src/main.sw @@ -0,0 +1,9 @@ +library; + +struct S {} + +impl S { + const S_ASSOC: u8 = MOD_CONST; +} + +const MOD_CONST: u8 = S::S_ASSOC; \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_const/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_const/test.toml new file mode 100644 index 00000000000..85c1690eb6d --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_const/test.toml @@ -0,0 +1,11 @@ +category = "fail" + +#check: $()error +#check: $()const MOD_CONST: u8 = S::S_ASSOC; +#nextln: $()Could not find symbol "S_ASSOC" in this scope. + +#check: $()error +#check: $()const MOD_CONST: u8 = S::S_ASSOC; +#nextln: $()Could not evaluate initializer to a const declaration. + +#check: $()2 errors. diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_function/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_function/Forc.lock new file mode 100644 index 00000000000..06c0bad09c9 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_function/Forc.lock @@ -0,0 +1,3 @@ +[[package]] +name = "recursive_const_module_over_associated_function" +source = "member" diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_function/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_function/Forc.toml new file mode 100644 index 00000000000..67408d6a564 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_function/Forc.toml @@ -0,0 +1,6 @@ +[project] +name = "recursive_const_module_over_associated_function" +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +implicit-std = false diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_function/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_function/src/main.sw new file mode 100644 index 00000000000..aff5abd7e03 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_function/src/main.sw @@ -0,0 +1,11 @@ +library; + +struct S {} + +impl S { + fn assoc() -> u8 { + MOD_CONST + } +} + +const MOD_CONST: u8 = S::assoc(); \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_function/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_function/test.toml new file mode 100644 index 00000000000..40c88a01149 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_function/test.toml @@ -0,0 +1,9 @@ +category = "fail" + +#check: $()const MOD_CONST: u8 = S::assoc(); +#nextln: $()No method named "assoc" found for type "S". + +#check: $()const MOD_CONST: u8 = S::assoc(); +#nextln: $()Could not evaluate initializer to a const declaration. + +#check: $()2 errors. diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_module_function/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_module_function/Forc.lock new file mode 100644 index 00000000000..c89fb4b5ade --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_module_function/Forc.lock @@ -0,0 +1,3 @@ +[[package]] +name = "recursive_const_module_over_module_function" +source = "member" diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_module_function/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_module_function/Forc.toml new file mode 100644 index 00000000000..20e75b9fb3b --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_module_function/Forc.toml @@ -0,0 +1,6 @@ +[project] +name = "recursive_const_module_over_module_function" +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +implicit-std = false diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_module_function/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_module_function/src/main.sw new file mode 100644 index 00000000000..ec0d5836e7d --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_module_function/src/main.sw @@ -0,0 +1,7 @@ +library; + +fn mod_fn() -> u8 { + MOD_CONST +} + +const MOD_CONST: u8 = mod_fn(); \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_module_function/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_module_function/test.toml new file mode 100644 index 00000000000..d1aa1e8d491 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_module_function/test.toml @@ -0,0 +1,11 @@ +category = "fail" + +#check: $()error +#check: $()const MOD_CONST: u8 = mod_fn(); +#nextln: $()Could not find symbol "mod_fn" in this scope. + +#check: $()error +#check: $()const MOD_CONST: u8 = mod_fn(); +#nextln: $()Could not evaluate initializer to a const declaration. + +#check: $()2 errors. diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_stack_overflow/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_stack_overflow/Forc.lock new file mode 100644 index 00000000000..0761e4748aa --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_stack_overflow/Forc.lock @@ -0,0 +1,3 @@ +[[package]] +name = "recursive_const_stack_overflow" +source = "member" diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_stack_overflow/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_stack_overflow/Forc.toml new file mode 100644 index 00000000000..e553c26024b --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_stack_overflow/Forc.toml @@ -0,0 +1,6 @@ +[project] +name = "recursive_const_stack_overflow" +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +implicit-std = false diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_stack_overflow/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_stack_overflow/src/main.sw new file mode 100644 index 00000000000..64eb369b581 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_stack_overflow/src/main.sw @@ -0,0 +1,17 @@ +// This test proves that https://github.com/FuelLabs/sway/issues/6540 is fixed. + +library; + +pub const MOD_FN: u8 = mod_fn(); + +fn mod_fn() -> u8 { + MOD_FN +} + +struct S {} + +impl S { + const S_ASSOC: u8 = MOD_CONST; +} + +const MOD_CONST: u8 = S::S_ASSOC; diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_stack_overflow/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_stack_overflow/test.toml new file mode 100644 index 00000000000..245bc04d534 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_stack_overflow/test.toml @@ -0,0 +1 @@ +category = "disabled" # TODO: Enable this failing test and write checks once https://github.com/FuelLabs/sway/issues/6540 is fixed. \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_enum/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_enum/src/main.sw index 21da4d7f364..32cc581c2d1 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_enum/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_enum/src/main.sw @@ -1,11 +1,7 @@ -script; +library; enum E { Eins: bool, Zwei: u64, Drei: E, } - -fn main() { - -} diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_enum/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_enum/test.toml index bd9a57f4949..94bb18cf069 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_enum/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_enum/test.toml @@ -1,3 +1,5 @@ category = "fail" # check: $()recursive types are not supported + +# check: $()1 error. diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_struct/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_struct/src/main.sw index 64b810ce1c1..9cd4a167c94 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_struct/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_struct/src/main.sw @@ -1,11 +1,7 @@ -script; +library; struct S { Eins: bool, Zwei: u64, Drei: S, } - -fn main() { - -} diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_struct/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_struct/test.toml index bd9a57f4949..94bb18cf069 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_struct/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_struct/test.toml @@ -1,3 +1,5 @@ category = "fail" # check: $()recursive types are not supported + +# check: $()1 error. diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_type_chain/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_type_chain/src/main.sw index 5466d0f01e6..cfb73b6a9a7 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_type_chain/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_type_chain/src/main.sw @@ -1,4 +1,4 @@ -script; +library; enum E { Eins: F, @@ -39,7 +39,3 @@ enum Y { struct Z { five: X, } - -fn main() { - -} diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_type_chain/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_type_chain/test.toml index 144ac44e200..925351b894a 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_type_chain/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_type_chain/test.toml @@ -10,3 +10,5 @@ category = "fail" # check: $()Type Y is recursive via Z and X, which is unsupported at this time. # check: $()Type Z is recursive via X and Y, which is unsupported at this time. # check: $()Type X is recursive via Y and Z, which is unsupported at this time. + +# check: $()10 errors. diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_type_unification/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_type_unification/src/main.sw index c8a730d9fb2..4b8ef28f285 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_type_unification/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_type_unification/src/main.sw @@ -1,4 +1,4 @@ -script; +library; enum MyOption { Some: T, @@ -13,5 +13,5 @@ fn bar(value: V) -> MyOption { } fn main() { - let x = bar(false); + let _ = bar(false); } 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 a660e53c0ad..ba0b96c153a 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 @@ -13,3 +13,5 @@ category = "fail" # nextln: $()expected: V # nextln: $()found: MyOption. # nextln: $()Implicit return must match up with block's type. + +# check: $()2 errors. diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/associated_const_in_decls_of_other_constants/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/associated_const_in_decls_of_other_constants/Forc.lock new file mode 100644 index 00000000000..597edcadfc4 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/associated_const_in_decls_of_other_constants/Forc.lock @@ -0,0 +1,13 @@ +[[package]] +name = "associated_const_in_decls_of_other_constants" +source = "member" +dependencies = ["std"] + +[[package]] +name = "core" +source = "path+from-root-8CB91B60FB2568E4" + +[[package]] +name = "std" +source = "path+from-root-8CB91B60FB2568E4" +dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/associated_const_in_decls_of_other_constants/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/associated_const_in_decls_of_other_constants/Forc.toml new file mode 100644 index 00000000000..fdcce2c7603 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/associated_const_in_decls_of_other_constants/Forc.toml @@ -0,0 +1,10 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "associated_const_in_decls_of_other_constants" +implicit-std = false + + +[dependencies] +std = { path = "../../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/associated_const_in_decls_of_other_constants/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/associated_const_in_decls_of_other_constants/src/main.sw new file mode 100644 index 00000000000..cb35e4f4b19 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/associated_const_in_decls_of_other_constants/src/main.sw @@ -0,0 +1,95 @@ +contract; + +struct S {} + +impl S { + fn bar() -> u8 { + 11 + } +} + +impl S { + // TODO: Uncomment this once https://github.com/FuelLabs/sway/issues/6538 is fixed. + // const S_BAR: u8 = Self::bar(); + const S_A: u8 = 11; + const S_B: u8 = Self::S_A; + const S_C: u8 = 22; + + fn assoc_s_b() -> u8 { + Self::S_B + } + + fn assoc_s_c() -> u8 { + Self::S_C + } + + fn method_s_c(self) -> u8 { + Self::S_C + } +} + +storage { + // TODO: Uncomment this once https://github.com/FuelLabs/sway/issues/6543 is fixed. + // s_a: u8 = S::S_A, +} + +const MOD_S_A: u8 = S::S_A; + +fn mod_fn_s_a() -> u8 { + S::S_A +} + +abi Abi { + fn test_in_contract(); +} + +configurable { + CONFIG_S_A: u8 = S::S_A, +} + +impl Abi for Contract { + fn test_in_contract() { + assert_eq(11, S::S_A); + assert_eq(22, S::S_C); + + // TODO: Uncomment this once https://github.com/FuelLabs/sway/issues/6544 is fixed. + // assert_eq(S::S_B, S::S_A); + // assert_eq(S::assoc_s_b(), S::S_B); + assert_eq(S::assoc_s_c(), S::S_C); + assert_eq(S {}.method_s_c(), S::S_C); + + // TODO: Uncomment this once https://github.com/FuelLabs/sway/issues/6538 is fixed. + // assert_eq(S::bar(), S::S_BAR); + + assert_eq(S::S_A, MOD_S_A); + + assert_eq(S::S_A, mod_fn_s_a()); + + assert_eq(S::S_A, CONFIG_S_A); + + // TODO: Uncomment this once https://github.com/FuelLabs/sway/issues/6543 is fixed. + // assert_eq(S::S_A, storage.s_a.read()); + } +} + +#[test] +fn test() { + assert_eq(11, S::S_A); + assert_eq(22, S::S_C); + + // TODO: Uncomment this once https://github.com/FuelLabs/sway/issues/6544 is fixed. + // assert_eq(S::S_B, S::S_A); + // assert_eq(S::assoc_s_b(), S::S_B); + assert_eq(S::assoc_s_c(), S::S_C); + assert_eq(S {}.method_s_c(), S::S_C); + + // TODO: Uncomment this once https://github.com/FuelLabs/sway/issues/6538 is fixed. + // assert_eq(S::bar(), S::S_BAR); + + assert_eq(S::S_A, MOD_S_A); + + assert_eq(S::S_A, mod_fn_s_a()); + + let caller = abi(Abi, CONTRACT_ID); + caller.test_in_contract(); +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/associated_const_in_decls_of_other_constants/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/associated_const_in_decls_of_other_constants/test.toml new file mode 100644 index 00000000000..f1958c1b086 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/associated_const_in_decls_of_other_constants/test.toml @@ -0,0 +1 @@ +category = "unit_tests_pass" \ No newline at end of file From ba153b24bec8f497f34b90058d1f07b63d8ff9b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaya=20G=C3=B6kalp?= Date: Sun, 15 Sep 2024 12:42:09 -0700 Subject: [PATCH 013/115] feat: add a build script to forc-client to keep proxy abi in sync with file (#6535) --- Cargo.lock | 1 + forc-plugins/forc-client/Cargo.toml | 3 + forc-plugins/forc-client/build.rs | 69 +++ forc-plugins/forc-client/src/util/tx.rs | 729 +----------------------- 4 files changed, 74 insertions(+), 728 deletions(-) create mode 100644 forc-plugins/forc-client/build.rs diff --git a/Cargo.lock b/Cargo.lock index 576107da4d3..fa916f92d40 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2073,6 +2073,7 @@ dependencies = [ "hex", "portpicker", "rand", + "regex", "rexpect 0.5.0", "rpassword", "serde", diff --git a/forc-plugins/forc-client/Cargo.toml b/forc-plugins/forc-client/Cargo.toml index 44b5713fd1e..692e69a63ba 100644 --- a/forc-plugins/forc-client/Cargo.toml +++ b/forc-plugins/forc-client/Cargo.toml @@ -49,6 +49,9 @@ rexpect = "0.5" tempfile = "3" toml_edit = "0.21.1" +[build-dependencies] +regex = "1.5.4" + [[bin]] name = "forc-deploy" path = "src/bin/deploy.rs" diff --git a/forc-plugins/forc-client/build.rs b/forc-plugins/forc-client/build.rs new file mode 100644 index 00000000000..655ca223a23 --- /dev/null +++ b/forc-plugins/forc-client/build.rs @@ -0,0 +1,69 @@ +use std::fs; +use std::path::PathBuf; + +fn minify_json(json: &str) -> String { + let mut result = String::with_capacity(json.len()); + let mut in_string = false; + let mut previous_char: Option = None; + + for c in json.chars() { + if in_string { + result.push(c); + if c == '"' && previous_char != Some('\\') { + in_string = false; + } + } else { + match c { + '"' => { + result.push(c); + in_string = true; + } + ' ' | '\n' | '\r' | '\t' => continue, // Skip whitespace + _ => result.push(c), + } + } + previous_char = Some(c); + } + result +} + +fn main() { + // Path to the JSON file in the root directory next to the `src` folder + let json_path = PathBuf::from("proxy_abi/proxy_contract-abi.json"); + // If proxy_contract-abi.json is changed, re-run this script + println!("cargo:rerun-if-changed=proxy_abi/proxy_contract-abi.json"); + // Path to the Rust source file that contains the `abigen!` macro that + // creates a `ProxyContract`. + let source_file_path = PathBuf::from("src/util/tx.rs"); + // Read the contents of the JSON file + let json_content = + fs::read_to_string(json_path).expect("Unable to read proxy_contract-abi.json"); + + // Minify the JSON content + let minified_json = minify_json(&json_content); + + // Read the contents of the source file + let mut source_code = + fs::read_to_string(&source_file_path).expect("Unable to read source file"); + + // Prepare the replacement string for the `abigen!` macro + let escaped_json = minified_json.replace('\\', "\\\\").replace('"', "\\\""); + let new_abigen = format!( + "abigen!(Contract(name = \"ProxyContract\", abi = \"{}\",));", + escaped_json + ); + + // Use a regular expression to find and replace the `abigen!` macro + let re = regex::Regex::new(r#"abigen!\(Contract\(name = "ProxyContract", abi = ".*?",\)\);"#) + .expect("Invalid regex pattern"); + + // Replace the existing `abigen!` macro with the new one containing the updated ABI + if re.is_match(&source_code) { + source_code = re.replace(&source_code, new_abigen.as_str()).to_string(); + } else { + panic!("abigen! macro not found in the source file"); + } + + // Write the modified source code back to the source file + fs::write(source_file_path, source_code).expect("Unable to write back to the source file"); +} diff --git a/forc-plugins/forc-client/src/util/tx.rs b/forc-plugins/forc-client/src/util/tx.rs index bd9ab0dc9cf..4371df2fc13 100644 --- a/forc-plugins/forc-client/src/util/tx.rs +++ b/forc-plugins/forc-client/src/util/tx.rs @@ -262,734 +262,7 @@ pub async fn update_proxy_contract_target( proxy_contract_id: ContractId, new_target: ContractId, ) -> Result> { - abigen!(Contract( - name = "ProxyContract", - abi = r#" - { - "programType": "contract", - "specVersion": "1", - "encodingVersion": "1", - "concreteTypes": [ - { - "type": "()", - "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "type": "enum standards::src5::AccessError", - "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d", - "metadataTypeId": 1 - }, - { - "type": "enum standards::src5::State", - "concreteTypeId": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", - "metadataTypeId": 2 - }, - { - "type": "enum std::option::Option", - "concreteTypeId": "0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8", - "metadataTypeId": 4, - "typeArguments": [ - "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" - ] - }, - { - "type": "enum sway_libs::ownership::errors::InitializationError", - "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893", - "metadataTypeId": 5 - }, - { - "type": "enum sway_libs::upgradability::errors::SetProxyOwnerError", - "concreteTypeId": "3c6e90ae504df6aad8b34a93ba77dc62623e00b777eecacfa034a8ac6e890c74", - "metadataTypeId": 6 - }, - { - "type": "str", - "concreteTypeId": "8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a" - }, - { - "type": "struct std::contract_id::ContractId", - "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", - "metadataTypeId": 9 - }, - { - "type": "struct sway_libs::upgradability::events::ProxyOwnerSet", - "concreteTypeId": "96dd838b44f99d8ccae2a7948137ab6256c48ca4abc6168abc880de07fba7247", - "metadataTypeId": 10 - }, - { - "type": "struct sway_libs::upgradability::events::ProxyTargetSet", - "concreteTypeId": "1ddc0adda1270a016c08ffd614f29f599b4725407c8954c8b960bdf651a9a6c8", - "metadataTypeId": 11 - } - ], - "metadataTypes": [ - { - "type": "b256", - "metadataTypeId": 0 - }, - { - "type": "enum standards::src5::AccessError", - "metadataTypeId": 1, - "components": [ - { - "name": "NotOwner", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - } - ] - }, - { - "type": "enum standards::src5::State", - "metadataTypeId": 2, - "components": [ - { - "name": "Uninitialized", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "Initialized", - "typeId": 3 - }, - { - "name": "Revoked", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - } - ] - }, - { - "type": "enum std::identity::Identity", - "metadataTypeId": 3, - "components": [ - { - "name": "Address", - "typeId": 8 - }, - { - "name": "ContractId", - "typeId": 9 - } - ] - }, - { - "type": "enum std::option::Option", - "metadataTypeId": 4, - "components": [ - { - "name": "None", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "Some", - "typeId": 7 - } - ], - "typeParameters": [ - 7 - ] - }, - { - "type": "enum sway_libs::ownership::errors::InitializationError", - "metadataTypeId": 5, - "components": [ - { - "name": "CannotReinitialized", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - } - ] - }, - { - "type": "enum sway_libs::upgradability::errors::SetProxyOwnerError", - "metadataTypeId": 6, - "components": [ - { - "name": "CannotUninitialize", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - } - ] - }, - { - "type": "generic T", - "metadataTypeId": 7 - }, - { - "type": "struct std::address::Address", - "metadataTypeId": 8, - "components": [ - { - "name": "bits", - "typeId": 0 - } - ] - }, - { - "type": "struct std::contract_id::ContractId", - "metadataTypeId": 9, - "components": [ - { - "name": "bits", - "typeId": 0 - } - ] - }, - { - "type": "struct sway_libs::upgradability::events::ProxyOwnerSet", - "metadataTypeId": 10, - "components": [ - { - "name": "new_proxy_owner", - "typeId": 2 - } - ] - }, - { - "type": "struct sway_libs::upgradability::events::ProxyTargetSet", - "metadataTypeId": 11, - "components": [ - { - "name": "new_target", - "typeId": 9 - } - ] - } - ], - "functions": [ - { - "inputs": [], - "name": "proxy_target", - "output": "0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8", - "attributes": [ - { - "name": "doc-comment", - "arguments": [ - " Returns the target contract of the proxy contract." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Returns" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * [Option] - The new proxy contract to which all fallback calls will be passed or `None`." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Number of Storage Accesses" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * Reads: `1`" - ] - }, - { - "name": "storage", - "arguments": [ - "read" - ] - } - ] - }, - { - "inputs": [ - { - "name": "new_target", - "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" - } - ], - "name": "set_proxy_target", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", - "attributes": [ - { - "name": "doc-comment", - "arguments": [ - " Change the target contract of the proxy contract." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Additional Information" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " This method can only be called by the `proxy_owner`." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Arguments" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * `new_target`: [ContractId] - The new proxy contract to which all fallback calls will be passed." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Reverts" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * When not called by `proxy_owner`." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Number of Storage Accesses" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * Reads: `1`" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * Write: `1`" - ] - }, - { - "name": "storage", - "arguments": [ - "read", - "write" - ] - } - ] - }, - { - "inputs": [], - "name": "proxy_owner", - "output": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", - "attributes": [ - { - "name": "doc-comment", - "arguments": [ - " Returns the owner of the proxy contract." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Returns" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * [State] - Represents the state of ownership for this contract." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Number of Storage Accesses" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * Reads: `1`" - ] - }, - { - "name": "storage", - "arguments": [ - "read" - ] - } - ] - }, - { - "inputs": [], - "name": "initialize_proxy", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", - "attributes": [ - { - "name": "doc-comment", - "arguments": [ - " Initializes the proxy contract." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Additional Information" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " This method sets the storage values using the values of the configurable constants `INITIAL_TARGET` and `INITIAL_OWNER`." - ] - }, - { - "name": "doc-comment", - "arguments": [ - " This then allows methods that write to storage to be called." - ] - }, - { - "name": "doc-comment", - "arguments": [ - " This method can only be called once." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Reverts" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * When `storage::SRC14.proxy_owner` is not [State::Uninitialized]." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Number of Storage Accesses" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * Writes: `2`" - ] - }, - { - "name": "storage", - "arguments": [ - "write" - ] - } - ] - }, - { - "inputs": [ - { - "name": "new_proxy_owner", - "concreteTypeId": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c" - } - ], - "name": "set_proxy_owner", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", - "attributes": [ - { - "name": "doc-comment", - "arguments": [ - " Changes proxy ownership to the passed State." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Additional Information" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " This method can be used to transfer ownership between Identities or to revoke ownership." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Arguments" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * `new_proxy_owner`: [State] - The new state of the proxy ownership." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Reverts" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * When the sender is not the current proxy owner." - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * When the new state of the proxy ownership is [State::Uninitialized]." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Number of Storage Accesses" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * Reads: `1`" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * Writes: `1`" - ] - }, - { - "name": "storage", - "arguments": [ - "write" - ] - } - ] - } - ], - "loggedTypes": [ - { - "logId": "4571204900286667806", - "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d" - }, - { - "logId": "2151606668983994881", - "concreteTypeId": "1ddc0adda1270a016c08ffd614f29f599b4725407c8954c8b960bdf651a9a6c8" - }, - { - "logId": "2161305517876418151", - "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893" - }, - { - "logId": "4354576968059844266", - "concreteTypeId": "3c6e90ae504df6aad8b34a93ba77dc62623e00b777eecacfa034a8ac6e890c74" - }, - { - "logId": "10870989709723147660", - "concreteTypeId": "96dd838b44f99d8ccae2a7948137ab6256c48ca4abc6168abc880de07fba7247" - }, - { - "logId": "10098701174489624218", - "concreteTypeId": "8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a" - } - ], - "messagesTypes": [], - "configurables": [ - { - "name": "INITIAL_TARGET", - "concreteTypeId": "0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8", - "offset": 13616 - }, - { - "name": "INITIAL_OWNER", - "concreteTypeId": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", - "offset": 13568 - } - ] -}"#, - )); + abigen!(Contract(name = "ProxyContract", abi = "{\"programType\":\"contract\",\"specVersion\":\"1\",\"encodingVersion\":\"1\",\"concreteTypes\":[{\"type\":\"()\",\"concreteTypeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"},{\"type\":\"enum standards::src5::AccessError\",\"concreteTypeId\":\"3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d\",\"metadataTypeId\":1},{\"type\":\"enum standards::src5::State\",\"concreteTypeId\":\"192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c\",\"metadataTypeId\":2},{\"type\":\"enum std::option::Option\",\"concreteTypeId\":\"0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8\",\"metadataTypeId\":4,\"typeArguments\":[\"29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54\"]},{\"type\":\"enum sway_libs::ownership::errors::InitializationError\",\"concreteTypeId\":\"1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893\",\"metadataTypeId\":5},{\"type\":\"enum sway_libs::upgradability::errors::SetProxyOwnerError\",\"concreteTypeId\":\"3c6e90ae504df6aad8b34a93ba77dc62623e00b777eecacfa034a8ac6e890c74\",\"metadataTypeId\":6},{\"type\":\"str\",\"concreteTypeId\":\"8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a\"},{\"type\":\"struct std::contract_id::ContractId\",\"concreteTypeId\":\"29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54\",\"metadataTypeId\":9},{\"type\":\"struct sway_libs::upgradability::events::ProxyOwnerSet\",\"concreteTypeId\":\"96dd838b44f99d8ccae2a7948137ab6256c48ca4abc6168abc880de07fba7247\",\"metadataTypeId\":10},{\"type\":\"struct sway_libs::upgradability::events::ProxyTargetSet\",\"concreteTypeId\":\"1ddc0adda1270a016c08ffd614f29f599b4725407c8954c8b960bdf651a9a6c8\",\"metadataTypeId\":11}],\"metadataTypes\":[{\"type\":\"b256\",\"metadataTypeId\":0},{\"type\":\"enum standards::src5::AccessError\",\"metadataTypeId\":1,\"components\":[{\"name\":\"NotOwner\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"}]},{\"type\":\"enum standards::src5::State\",\"metadataTypeId\":2,\"components\":[{\"name\":\"Uninitialized\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"},{\"name\":\"Initialized\",\"typeId\":3},{\"name\":\"Revoked\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"}]},{\"type\":\"enum std::identity::Identity\",\"metadataTypeId\":3,\"components\":[{\"name\":\"Address\",\"typeId\":8},{\"name\":\"ContractId\",\"typeId\":9}]},{\"type\":\"enum std::option::Option\",\"metadataTypeId\":4,\"components\":[{\"name\":\"None\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"},{\"name\":\"Some\",\"typeId\":7}],\"typeParameters\":[7]},{\"type\":\"enum sway_libs::ownership::errors::InitializationError\",\"metadataTypeId\":5,\"components\":[{\"name\":\"CannotReinitialized\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"}]},{\"type\":\"enum sway_libs::upgradability::errors::SetProxyOwnerError\",\"metadataTypeId\":6,\"components\":[{\"name\":\"CannotUninitialize\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"}]},{\"type\":\"generic T\",\"metadataTypeId\":7},{\"type\":\"struct std::address::Address\",\"metadataTypeId\":8,\"components\":[{\"name\":\"bits\",\"typeId\":0}]},{\"type\":\"struct std::contract_id::ContractId\",\"metadataTypeId\":9,\"components\":[{\"name\":\"bits\",\"typeId\":0}]},{\"type\":\"struct sway_libs::upgradability::events::ProxyOwnerSet\",\"metadataTypeId\":10,\"components\":[{\"name\":\"new_proxy_owner\",\"typeId\":2}]},{\"type\":\"struct sway_libs::upgradability::events::ProxyTargetSet\",\"metadataTypeId\":11,\"components\":[{\"name\":\"new_target\",\"typeId\":9}]}],\"functions\":[{\"inputs\":[],\"name\":\"proxy_target\",\"output\":\"0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Returns the target contract of the proxy contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Returns\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * [Option] - The new proxy contract to which all fallback calls will be passed or `None`.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Reads: `1`\"]},{\"name\":\"storage\",\"arguments\":[\"read\"]}]},{\"inputs\":[{\"name\":\"new_target\",\"concreteTypeId\":\"29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54\"}],\"name\":\"set_proxy_target\",\"output\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Change the target contract of the proxy contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Additional Information\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This method can only be called by the `proxy_owner`.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Arguments\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * `new_target`: [ContractId] - The new proxy contract to which all fallback calls will be passed.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Reverts\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * When not called by `proxy_owner`.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Reads: `1`\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Write: `1`\"]},{\"name\":\"storage\",\"arguments\":[\"read\",\"write\"]}]},{\"inputs\":[],\"name\":\"proxy_owner\",\"output\":\"192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Returns the owner of the proxy contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Returns\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * [State] - Represents the state of ownership for this contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Reads: `1`\"]},{\"name\":\"storage\",\"arguments\":[\"read\"]}]},{\"inputs\":[],\"name\":\"initialize_proxy\",\"output\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Initializes the proxy contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Additional Information\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This method sets the storage values using the values of the configurable constants `INITIAL_TARGET` and `INITIAL_OWNER`.\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This then allows methods that write to storage to be called.\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This method can only be called once.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Reverts\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * When `storage::SRC14.proxy_owner` is not [State::Uninitialized].\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Writes: `2`\"]},{\"name\":\"storage\",\"arguments\":[\"write\"]}]},{\"inputs\":[{\"name\":\"new_proxy_owner\",\"concreteTypeId\":\"192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c\"}],\"name\":\"set_proxy_owner\",\"output\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Changes proxy ownership to the passed State.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Additional Information\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This method can be used to transfer ownership between Identities or to revoke ownership.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Arguments\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * `new_proxy_owner`: [State] - The new state of the proxy ownership.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Reverts\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * When the sender is not the current proxy owner.\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * When the new state of the proxy ownership is [State::Uninitialized].\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Reads: `1`\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Writes: `1`\"]},{\"name\":\"storage\",\"arguments\":[\"write\"]}]}],\"loggedTypes\":[{\"logId\":\"4571204900286667806\",\"concreteTypeId\":\"3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d\"},{\"logId\":\"2151606668983994881\",\"concreteTypeId\":\"1ddc0adda1270a016c08ffd614f29f599b4725407c8954c8b960bdf651a9a6c8\"},{\"logId\":\"2161305517876418151\",\"concreteTypeId\":\"1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893\"},{\"logId\":\"4354576968059844266\",\"concreteTypeId\":\"3c6e90ae504df6aad8b34a93ba77dc62623e00b777eecacfa034a8ac6e890c74\"},{\"logId\":\"10870989709723147660\",\"concreteTypeId\":\"96dd838b44f99d8ccae2a7948137ab6256c48ca4abc6168abc880de07fba7247\"},{\"logId\":\"10098701174489624218\",\"concreteTypeId\":\"8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a\"}],\"messagesTypes\":[],\"configurables\":[{\"name\":\"INITIAL_TARGET\",\"concreteTypeId\":\"0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8\",\"offset\":13368},{\"name\":\"INITIAL_OWNER\",\"concreteTypeId\":\"192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c\",\"offset\":13320}]}",)); let wallet = WalletUnlocked::new_from_private_key(secret_key, Some(provider.clone())); From ea4b9e99ff6e0c23644a2fa4a4b17622be130dda Mon Sep 17 00:00:00 2001 From: Marcos Henrich Date: Mon, 16 Sep 2024 13:18:14 +0100 Subject: [PATCH 014/115] Adds test for implicit trait constraint. (#6517) ## Description This PR adds a test that proves implicit trait constraint already returns an error. The method dummy ICE reported in #6377 was fixed by #6490. Closes #6377. ## 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: Sophie Dankel <47993817+sdankel@users.noreply.github.com> Co-authored-by: Joshua Batty --- .../implicit_trait_constraint/Forc.lock | 8 +++++ .../implicit_trait_constraint/Forc.toml | 9 ++++++ .../implicit_trait_constraint/src/main.sw | 32 +++++++++++++++++++ .../implicit_trait_constraint/test.toml | 4 +++ 4 files changed, 53 insertions(+) create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/implicit_trait_constraint/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/implicit_trait_constraint/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/implicit_trait_constraint/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/implicit_trait_constraint/test.toml diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/implicit_trait_constraint/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_fail/implicit_trait_constraint/Forc.lock new file mode 100644 index 00000000000..418848eceb5 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/implicit_trait_constraint/Forc.lock @@ -0,0 +1,8 @@ +[[package]] +name = "core" +source = "path+from-root-3F7C73944D096B89" + +[[package]] +name = "implicit_trait_constraint" +source = "member" +dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/implicit_trait_constraint/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/implicit_trait_constraint/Forc.toml new file mode 100644 index 00000000000..033423a1fdd --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/implicit_trait_constraint/Forc.toml @@ -0,0 +1,9 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +implicit-std = false +license = "Apache-2.0" +name = "implicit_trait_constraint" + +[dependencies] +core = { path = "../../../../../../sway-lib-core" } diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/implicit_trait_constraint/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/implicit_trait_constraint/src/main.sw new file mode 100644 index 00000000000..15df85fe89b --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/implicit_trait_constraint/src/main.sw @@ -0,0 +1,32 @@ +script; +trait T2 {} +trait T1: T2 { + fn new() -> Self; +} + +struct S {} +impl T2 for S {} +impl T1 for S { + fn new() -> Self { + S {} + } +} + +fn bar() -> T +where + T: T1, +{ + T::new() +} + +fn foo() -> T +where + T: T2, +{ + bar() +} + +fn main() -> u64 { + let _:S = foo(); + 42 +} diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/implicit_trait_constraint/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/implicit_trait_constraint/test.toml new file mode 100644 index 00000000000..b91b74218e6 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/implicit_trait_constraint/test.toml @@ -0,0 +1,4 @@ +category = "fail" + +# check: $()bar() +# nextln: $()Trait "T1" is not implemented for type "T". \ No newline at end of file From db748659ba87335ef004df855e3f1b297cdbd052 Mon Sep 17 00:00:00 2001 From: Marcos Henrich Date: Tue, 17 Sep 2024 12:40:18 +0100 Subject: [PATCH 015/115] Fixes unreachable on invalid cfg attribute arg. (#6553) ## Description We now throw an error that enforces cfg arg to be a valid one. Fixes #6326 ## 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. --- .../src/transform/to_parsed_lang/convert_parse_tree.rs | 9 +++++++-- sway-error/src/convert_parse_tree_error.rs | 3 +++ .../should_fail/invalid_cfg_arg/Forc.lock | 3 +++ .../should_fail/invalid_cfg_arg/Forc.toml | 6 ++++++ .../should_fail/invalid_cfg_arg/src/main.sw | 2 ++ .../should_fail/invalid_cfg_arg/test.toml | 10 ++++++++++ 6 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/test.toml diff --git a/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs b/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs index 642badfeadf..4144d0b085c 100644 --- a/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs +++ b/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs @@ -4943,8 +4943,13 @@ pub fn cfg_eval( } }, _ => { - // Already checked with `AttributeKind::expected_args_*` - unreachable!("cfg attribute should only have the `target` or the `program_type` argument"); + return Err(handler.emit_err( + ConvertParseTreeError::InvalidCfgArg { + span: arg.span(), + value: arg.name.as_str().to_string(), + } + .into(), + )); } } } diff --git a/sway-error/src/convert_parse_tree_error.rs b/sway-error/src/convert_parse_tree_error.rs index 2fdfdc58d75..6c909e2016e 100644 --- a/sway-error/src/convert_parse_tree_error.rs +++ b/sway-error/src/convert_parse_tree_error.rs @@ -119,6 +119,8 @@ pub enum ConvertParseTreeError { ExpectedCfgProgramTypeArgValue { span: Span }, #[error("Expected \"true\" or \"false\" for experimental_new_encoding")] ExpectedExperimentalNewEncodingArgValue { span: Span }, + #[error("Unexpected attribute value: \"{value}\" for attribute: \"cfg\"")] + InvalidCfgArg { span: Span, value: String }, } impl Spanned for ConvertParseTreeError { @@ -182,6 +184,7 @@ impl Spanned for ConvertParseTreeError { ConvertParseTreeError::InvalidCfgProgramTypeArgValue { span, .. } => span.clone(), ConvertParseTreeError::ExpectedCfgProgramTypeArgValue { span } => span.clone(), ConvertParseTreeError::ExpectedExperimentalNewEncodingArgValue { span } => span.clone(), + ConvertParseTreeError::InvalidCfgArg { span, .. } => span.clone(), } } } diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/Forc.lock new file mode 100644 index 00000000000..1cef6b3f7a1 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/Forc.lock @@ -0,0 +1,3 @@ +[[package]] +name = "invalid_cfg_arg" +source = "member" diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/Forc.toml new file mode 100644 index 00000000000..582fa8b5e47 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/Forc.toml @@ -0,0 +1,6 @@ +[project] +name = "invalid_cfg_arg" +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +implicit-std = false diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/src/main.sw new file mode 100644 index 00000000000..c9ad0835d76 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/src/main.sw @@ -0,0 +1,2 @@ +predicate; +#[cfg(c)] a diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/test.toml new file mode 100644 index 00000000000..1f48bdf0556 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/test.toml @@ -0,0 +1,10 @@ +category = "fail" + +# check: $()#[cfg(c)] a +# nextln: $()Unexpected attribute value: "c" for attribute: "cfg" expected value "target" or "program_type" or "experimental_new_encoding" + +# check: $()#[cfg(c)] a +# nextln: $()Expected an item. + +# check: $()#[cfg(c)] a +# nextln: $()Unexpected attribute value: "c" for attribute: "cfg" \ No newline at end of file From a073a95f6b69297e132064a285a6127134daa45f Mon Sep 17 00:00:00 2001 From: Marcos Henrich Date: Tue, 17 Sep 2024 13:04:13 +0100 Subject: [PATCH 016/115] Fixes OOB in type_check_analyze of ImplTrait. (#6551) ## Description An unused line of code threw an OOB panic because of a parser error. Removing the unused line of code fixes the issue. Fixes #6331 ## 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 --- .../ast_node/declaration/impl_trait.rs | 3 +-- .../mismatch_closing_delimiters/Forc.lock | 8 ++++++++ .../mismatch_closing_delimiters/Forc.toml | 9 +++++++++ .../mismatch_closing_delimiters/src/main.sw | 14 ++++++++++++++ .../mismatch_closing_delimiters/test.toml | 4 ++++ 5 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/mismatch_closing_delimiters/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/mismatch_closing_delimiters/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/mismatch_closing_delimiters/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/mismatch_closing_delimiters/test.toml diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs b/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs index 15266d2d2a7..5d47d1616d7 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs @@ -1629,8 +1629,7 @@ impl TypeCheckAnalysis for ty::ImplSelfOrTrait { ctx.push_nodes_for_impl_trait(self); // Now lets analyze each impl trait item. - for (i, item) in impl_trait.items.iter().enumerate() { - let _node = ctx.items_node_stack[i]; + for item in impl_trait.items.iter() { item.type_check_analyze(handler, ctx)?; } diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/mismatch_closing_delimiters/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_fail/mismatch_closing_delimiters/Forc.lock new file mode 100644 index 00000000000..a0991ddd91b --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/mismatch_closing_delimiters/Forc.lock @@ -0,0 +1,8 @@ +[[package]] +name = "core" +source = "path+from-root-F62FA9D54ABC8F01" + +[[package]] +name = "mismatch_closing_delimiters" +source = "member" +dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/mismatch_closing_delimiters/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/mismatch_closing_delimiters/Forc.toml new file mode 100644 index 00000000000..084875b06eb --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/mismatch_closing_delimiters/Forc.toml @@ -0,0 +1,9 @@ +[project] +authors = ["Fuel Labs "] +license = "Apache-2.0" +name = "mismatch_closing_delimiters" +entry = "main.sw" +implicit-std = false + +[dependencies] +core = { path = "../../../../../../sway-lib-core" } diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/mismatch_closing_delimiters/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/mismatch_closing_delimiters/src/main.sw new file mode 100644 index 00000000000..22272bdf326 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/mismatch_closing_delimiters/src/main.sw @@ -0,0 +1,14 @@ +script; + +struct Struct{x:u} +impl Struct{ + fn w()->f{{(()}} + trait Supertrait{} + impl Supertrait for Struct{) +} + +fn s(b:B) where A:t{}fn n(){} + +fn main() -> u64 { + 0 +} diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/mismatch_closing_delimiters/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/mismatch_closing_delimiters/test.toml new file mode 100644 index 00000000000..e3280310725 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/mismatch_closing_delimiters/test.toml @@ -0,0 +1,4 @@ +category = "fail" + +# check: $()fn w()->f{{(()}} +# nextln: $()mismatched delimiters From 520bfe916844046741cf84a60caff7c41132e228 Mon Sep 17 00:00:00 2001 From: Marcos Henrich Date: Tue, 17 Sep 2024 21:09:55 +0100 Subject: [PATCH 017/115] Fixes panic error on decl_to_type_info. (#6552) ## Description Doing an unwrap without checking if the value was none was causing a panic. Fixed by throwing an error so we can also see the previous errors. Fixes #6330 ## 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 --- sway-core/src/semantic_analysis/namespace/root.rs | 6 ++++++ .../parser_associated_type_error/Forc.lock | 13 +++++++++++++ .../parser_associated_type_error/Forc.toml | 8 ++++++++ .../parser_associated_type_error/src/main.sw | 3 +++ .../parser_associated_type_error/test.toml | 6 ++++++ 5 files changed, 36 insertions(+) create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/parser_associated_type_error/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/parser_associated_type_error/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/parser_associated_type_error/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/parser_associated_type_error/test.toml diff --git a/sway-core/src/semantic_analysis/namespace/root.rs b/sway-core/src/semantic_analysis/namespace/root.rs index a9da70d1881..b6770d6db8a 100644 --- a/sway-core/src/semantic_analysis/namespace/root.rs +++ b/sway-core/src/semantic_analysis/namespace/root.rs @@ -935,6 +935,12 @@ impl Root { ty::TyDecl::EnumDecl(enum_ty_decl) => TypeInfo::Enum(enum_ty_decl.decl_id), ty::TyDecl::TraitTypeDecl(type_decl) => { let type_decl = engines.de().get_type(&type_decl.decl_id); + if type_decl.ty.is_none() { + return Err(handler.emit_err(CompileError::Internal( + "Trait type declaration has no type", + symbol.span(), + ))); + } (*engines.te().get(type_decl.ty.clone().unwrap().type_id)).clone() } _ => { diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/parser_associated_type_error/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_fail/parser_associated_type_error/Forc.lock new file mode 100644 index 00000000000..0284e5bd9e5 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/parser_associated_type_error/Forc.lock @@ -0,0 +1,13 @@ +[[package]] +name = "core" +source = "path+from-root-6C2FF70C66B98326" + +[[package]] +name = "parser_associated_type_error" +source = "member" +dependencies = ["std"] + +[[package]] +name = "std" +source = "path+from-root-6C2FF70C66B98326" +dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/parser_associated_type_error/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/parser_associated_type_error/Forc.toml new file mode 100644 index 00000000000..06817f2a91c --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/parser_associated_type_error/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "parser_associated_type_error" + +[dependencies] +std = { path = "../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/parser_associated_type_error/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/parser_associated_type_error/src/main.sw new file mode 100644 index 00000000000..8f11dc585b4 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/parser_associated_type_error/src/main.sw @@ -0,0 +1,3 @@ +script; + +trait T{type E const C:Self::E::E} diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/parser_associated_type_error/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/parser_associated_type_error/test.toml new file mode 100644 index 00000000000..df5b315a430 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/parser_associated_type_error/test.toml @@ -0,0 +1,6 @@ +category = "fail" + +# check: $()trait T{type E const C:Self::E::E} +# nextln: $()Expected `;`. + +# check: $()Trait type declaration has no type From e82c72be30f5252970b78e508ba75adaa300db0d Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite Date: Wed, 18 Sep 2024 01:45:11 +0100 Subject: [PATCH 018/115] Only check non-parent monomorphization args (#6549) ## Description This PR fixes https://github.com/FuelLabs/sway/issues/6384 The performance improvement is probably coming from just aggregating spans when there is an error. ## 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. --------- Co-authored-by: Joshua Batty --- .../semantic_analysis/type_check_context.rs | 26 ++++++++++++------- .../generic_impl_self_where/src/main.sw | 21 +++++++++++++++ 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/sway-core/src/semantic_analysis/type_check_context.rs b/sway-core/src/semantic_analysis/type_check_context.rs index faf8fa72647..29d47918532 100644 --- a/sway-core/src/semantic_analysis/type_check_context.rs +++ b/sway-core/src/semantic_analysis/type_check_context.rs @@ -1700,27 +1700,35 @@ impl<'a> TypeCheckContext<'a> { 0, ))) } - (num_type_params, num_type_args) => { - let type_arguments_span = type_arguments - .iter() - .map(|x| x.span.clone()) - .reduce(|s1: Span, s2: Span| Span::join(s1, &s2)) - .unwrap_or_else(|| value.name().span()); + (_, num_type_args) => { // a trait decl is passed the self type parameter and the corresponding argument // but it would be confusing for the user if the error reporting mechanism // reported the number of arguments including the implicit self, hence // we adjust it below let adjust_for_trait_decl = value.has_self_type_param() as usize; - let num_type_params = num_type_params - adjust_for_trait_decl; + let non_parent_type_params = value + .type_parameters() + .iter() + .filter(|x| !x.is_from_parent) + .count() + - adjust_for_trait_decl; + let num_type_args = num_type_args - adjust_for_trait_decl; - if num_type_params != num_type_args { + if non_parent_type_params != num_type_args { + let type_arguments_span = type_arguments + .iter() + .map(|x| x.span.clone()) + .reduce(|s1: Span, s2: Span| Span::join(s1, &s2)) + .unwrap_or_else(|| value.name().span()); + return Err(handler.emit_err(make_type_arity_mismatch_error( value.name().clone(), type_arguments_span, num_type_args, - num_type_params, + non_parent_type_params, ))); } + for type_argument in type_arguments.iter_mut() { type_argument.type_id = self .resolve( diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self_where/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self_where/src/main.sw index 13b6473eb73..4df22003a57 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self_where/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self_where/src/main.sw @@ -65,6 +65,25 @@ impl MyEq for Data3 { } } +// This tests it is still possible to call generic methods +// where its parent has constraints +// https://github.com/FuelLabs/sway/issues/6384 + +trait MyTrait { } +struct S { } + +struct M1 {} +impl MyTrait for M1 { } + +impl S where T: MyTrait { + fn bar() { + } +} + +fn issue_6384() { + let _x = S::::bar::(); +} + fn main() -> u64 { let s = Data { x: 42 }; assert(s.contains(42)); @@ -116,5 +135,7 @@ fn main() -> u64 { assert(!d4.contains5(Data2 { x: 41, y: Data3 { x: 42 } })); */ + issue_6384(); + 10 } From 1305b242c5ed090a061cb6b0a735f813bd5bc535 Mon Sep 17 00:00:00 2001 From: Joshua Batty Date: Wed, 18 Sep 2024 18:18:02 +1000 Subject: [PATCH 019/115] Fix `function_cache` garbage collection bug (#6555) ## Description Fixes a bug that would crash the language server when a function node was part of the AST. #5967 added a function cache to the `QueryEngine`. Garbage collection needed to be called on this otherwise it returns references to types that have been cleared from the other engines during garbage collection. In the future, any other nodes that we decide to cache need to have GC applied to them or we will end up crashing the language server on the first key-pressed event. I've also removed the gc_frequency setting and now run GC on each keystroke. Without doing this, the spans stored in the TokenMap and what was returned from the compiler were falling out of sync. This ensures that everything is always up to date and the correct spans are used. closes #5260 Finally, I've added a `launch.json` that allows for attaching `lldb` to a live running `forc-lsp` process. This was a pretty cruical step for tracking down this bug so would be nice to have it easily accessible for future debugging sessions. ## 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. --------- Co-authored-by: Sophie Dankel <47993817+sdankel@users.noreply.github.com> --- .vscode/launch.json | 23 ++++++++++++ sway-core/src/engine_threading.rs | 2 ++ sway-core/src/query_engine/mod.rs | 35 ++++++++++++++++--- sway-lsp/src/config.rs | 8 +---- sway-lsp/src/server_state.rs | 28 +++++++-------- .../minimal_script/.gitignore | 2 ++ .../minimal_script/Forc.toml | 8 +++++ .../minimal_script/src/main.sw | 14 ++++++++ sway-lsp/tests/lib.rs | 15 ++++---- 9 files changed, 100 insertions(+), 35 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 sway-lsp/tests/fixtures/garbage_collection/minimal_script/.gitignore create mode 100644 sway-lsp/tests/fixtures/garbage_collection/minimal_script/Forc.toml create mode 100644 sway-lsp/tests/fixtures/garbage_collection/minimal_script/src/main.sw diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000000..eb5c4aa3642 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,23 @@ +// Configuration for debugging the Sway Language Server (forc-lsp) +// Usage instructions: +// 1. Ensure you've built forc-lsp with debug symbols: +// cargo build -p forc-lsp +// 2. Install the debug version: +// cargo install --path ./forc-plugins/forc-lsp --debug +// 3. Open your Sway project in a separate VSCode window (this starts forc-lsp) +// 4. In the forc-lsp project window, set breakpoints in the code +// 5. Go to Run and Debug view, select "Attach to forc-lsp", and start debugging +// 6. When prompted, select the forc-lsp process +// 7. Debug forc-lsp as it responds to actions in your Sway project +{ + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "attach", + "name": "Attach to forc-lsp", + "pid": "${command:pickProcess}", + "program": "${env:HOME}/.cargo/bin/forc-lsp" + } + ] +} \ No newline at end of file diff --git a/sway-core/src/engine_threading.rs b/sway-core/src/engine_threading.rs index e0e151249eb..b2a215c6235 100644 --- a/sway-core/src/engine_threading.rs +++ b/sway-core/src/engine_threading.rs @@ -46,6 +46,7 @@ impl Engines { self.type_engine.clear_program(program_id); self.decl_engine.clear_program(program_id); self.parsed_decl_engine.clear_program(program_id); + self.query_engine.clear_program(program_id); } /// Removes all data associated with `source_id` from the declaration and type engines. @@ -54,6 +55,7 @@ impl Engines { self.type_engine.clear_module(source_id); self.decl_engine.clear_module(source_id); self.parsed_decl_engine.clear_module(source_id); + self.query_engine.clear_module(source_id); } /// Helps out some `thing: T` by adding `self` as context. diff --git a/sway-core/src/query_engine/mod.rs b/sway-core/src/query_engine/mod.rs index c05efb384f2..ee94d6a2f62 100644 --- a/sway-core/src/query_engine/mod.rs +++ b/sway-core/src/query_engine/mod.rs @@ -7,7 +7,7 @@ use std::{ time::SystemTime, }; use sway_error::{error::CompileError, warning::CompileWarning}; -use sway_types::IdentUnique; +use sway_types::{IdentUnique, ProgramId, SourceId, Spanned}; use crate::{ decl_engine::{DeclId, DeclRef}, @@ -141,17 +141,18 @@ pub struct FunctionCacheEntry { #[derive(Debug, Default)] pub struct QueryEngine { // We want the below types wrapped in Arcs to optimize cloning from LSP. - programs_cache: Arc>, - function_cache: Arc>, + programs_cache: CowCache, pub module_cache: CowCache, + // NOTE: Any further AstNodes that are cached need to have garbage collection applied, see clear_module() + function_cache: CowCache, } impl Clone for QueryEngine { fn clone(&self) -> Self { Self { - programs_cache: self.programs_cache.clone(), - function_cache: self.function_cache.clone(), + programs_cache: CowCache::new(self.programs_cache.read().clone()), module_cache: CowCache::new(self.module_cache.read().clone()), + function_cache: CowCache::new(self.function_cache.read().clone()), } } } @@ -205,6 +206,30 @@ impl QueryEngine { FunctionCacheEntry { fn_decl }, ); } + + /// Removes all data associated with the `source_id` from the function cache. + pub fn clear_module(&mut self, source_id: &SourceId) { + self.function_cache + .write() + .retain(|(ident, _), _| ident.span().source_id().map_or(true, |id| id != source_id)); + } + + /// Removes all data associated with the `program_id` from the function cache. + pub fn clear_program(&mut self, program_id: &ProgramId) { + self.function_cache.write().retain(|(ident, _), _| { + ident + .span() + .source_id() + .map_or(true, |id| id.program_id() != *program_id) + }); + } + + /// Commits all changes to their respective caches. + pub fn commit(&self) { + self.programs_cache.commit(); + self.module_cache.commit(); + self.function_cache.commit(); + } } /// Thread-safe, copy-on-write cache optimized for LSP operations. diff --git a/sway-lsp/src/config.rs b/sway-lsp/src/config.rs index 7a440afeb57..528e4385510 100644 --- a/sway-lsp/src/config.rs +++ b/sway-lsp/src/config.rs @@ -71,17 +71,11 @@ impl Default for DiagnosticConfig { #[serde(rename_all = "camelCase")] pub struct GarbageCollectionConfig { pub gc_enabled: bool, - pub gc_frequency: i32, } impl Default for GarbageCollectionConfig { fn default() -> Self { - Self { - gc_enabled: true, - // Garbage collection is fairly expsensive so we default to only clear on every 3rd keystroke. - // Waiting too long to clear can cause a stack overflow to occur. - gc_frequency: 3, - } + Self { gc_enabled: true } } } diff --git a/sway-lsp/src/server_state.rs b/sway-lsp/src/server_state.rs index d448516105c..2c39abddeac 100644 --- a/sway-lsp/src/server_state.rs +++ b/sway-lsp/src/server_state.rs @@ -137,21 +137,17 @@ impl ServerState { let session = ctx.session.as_ref().unwrap().clone(); let mut engines_clone = session.engines.read().clone(); - if let Some(version) = ctx.version { - // Perform garbage collection at configured intervals if enabled to manage memory usage. - if ctx.gc_options.gc_enabled - && version % ctx.gc_options.gc_frequency == 0 + // Perform garbage collection if enabled to manage memory usage. + if ctx.gc_options.gc_enabled { + // Call this on the engines clone so we don't clear types that are still in use + // and might be needed in the case cancel compilation was triggered. + if let Err(err) = + session.garbage_collect_module(&mut engines_clone, &uri) { - // Call this on the engines clone so we don't clear types that are still in use - // and might be needed in the case cancel compilation was triggered. - if let Err(err) = - session.garbage_collect_module(&mut engines_clone, &uri) - { - tracing::error!( - "Unable to perform garbage collection: {}", - err.to_string() - ); - } + tracing::error!( + "Unable to perform garbage collection: {}", + err.to_string() + ); } } @@ -180,10 +176,10 @@ impl ServerState { // Because the engines_clone has garbage collection applied. If the workspace AST was reused, we need to keep the old engines // as the engines_clone might have cleared some types that are still in use. if metrics.reused_programs == 0 { - // Commit local changes in the module cache to the shared state. + // Commit local changes in the programs, module, and function caches to the shared state. // This ensures that any modifications made during compilation are preserved // before we swap the engines. - engines_clone.qe().module_cache.commit(); + engines_clone.qe().commit(); // The compiler did not reuse the workspace AST. // We need to overwrite the old engines with the engines clone. mem::swap( diff --git a/sway-lsp/tests/fixtures/garbage_collection/minimal_script/.gitignore b/sway-lsp/tests/fixtures/garbage_collection/minimal_script/.gitignore new file mode 100644 index 00000000000..77d3844f58c --- /dev/null +++ b/sway-lsp/tests/fixtures/garbage_collection/minimal_script/.gitignore @@ -0,0 +1,2 @@ +out +target diff --git a/sway-lsp/tests/fixtures/garbage_collection/minimal_script/Forc.toml b/sway-lsp/tests/fixtures/garbage_collection/minimal_script/Forc.toml new file mode 100644 index 00000000000..7813d36bca0 --- /dev/null +++ b/sway-lsp/tests/fixtures/garbage_collection/minimal_script/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "minimal_script" +implicit-std = false + +[dependencies] diff --git a/sway-lsp/tests/fixtures/garbage_collection/minimal_script/src/main.sw b/sway-lsp/tests/fixtures/garbage_collection/minimal_script/src/main.sw new file mode 100644 index 00000000000..c9f990bb169 --- /dev/null +++ b/sway-lsp/tests/fixtures/garbage_collection/minimal_script/src/main.sw @@ -0,0 +1,14 @@ +script; + +struct MyStruct { + field1: u16, +} + +fn func(s: MyStruct) -> u16 { + s.field1 +} + +fn main() { + let x = MyStruct { field1: 10 }; + let y = func(x); +} \ No newline at end of file diff --git a/sway-lsp/tests/lib.rs b/sway-lsp/tests/lib.rs index 29bba1bd103..8eebe036aef 100644 --- a/sway-lsp/tests/lib.rs +++ b/sway-lsp/tests/lib.rs @@ -261,13 +261,6 @@ fn garbage_collection_runner(path: PathBuf) { run_async!({ setup_panic_hook(); let (mut service, _) = LspService::new(ServerState::new); - // set the garbage collection frequency to 1 - service - .inner() - .config - .write() - .garbage_collection - .gc_frequency = 1; let uri = init_and_open(&mut service, path).await; let times = 60; @@ -302,6 +295,14 @@ fn garbage_collection_paths() { garbage_collection_runner(p); } +#[test] +fn garbage_collection_minimal_script() { + let p = sway_workspace_dir() + .join("sway-lsp/tests/fixtures/garbage_collection/minimal_script") + .join("src/main.sw"); + garbage_collection_runner(p); +} + #[test] fn lsp_syncs_with_workspace_edits() { run_async!({ From cba9a005ef2a5b61e13eb02ba6e9e93ebd19a31a Mon Sep 17 00:00:00 2001 From: Joshua Batty Date: Thu, 19 Sep 2024 05:45:46 +1000 Subject: [PATCH 020/115] chore: bump to v0.63.6 (#6556) ## Description Bumps repo to v0.63.6 waiting on #6555 --- Cargo.lock | 66 ++++++++++---------- forc-pkg/Cargo.toml | 14 ++--- forc-plugins/forc-client/Cargo.toml | 18 +++--- forc-plugins/forc-client/proxy_abi/README.md | 2 +- forc-plugins/forc-crypto/Cargo.toml | 6 +- forc-plugins/forc-debug/Cargo.toml | 12 ++-- forc-plugins/forc-doc/Cargo.toml | 18 +++--- forc-plugins/forc-fmt/Cargo.toml | 14 ++--- forc-plugins/forc-lsp/Cargo.toml | 4 +- forc-plugins/forc-tx/Cargo.toml | 4 +- forc-test/Cargo.toml | 8 +-- forc-tracing/Cargo.toml | 2 +- forc-util/Cargo.toml | 12 ++-- forc/Cargo.toml | 20 +++--- sway-ast/Cargo.toml | 6 +- sway-core/Cargo.toml | 14 ++--- sway-error/Cargo.toml | 4 +- sway-ir/Cargo.toml | 8 +-- sway-ir/sway-ir-macros/Cargo.toml | 2 +- sway-lsp/Cargo.toml | 22 +++---- sway-parse/Cargo.toml | 8 +-- sway-types/Cargo.toml | 4 +- sway-utils/Cargo.toml | 2 +- swayfmt/Cargo.toml | 16 ++--- 24 files changed, 143 insertions(+), 143 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fa916f92d40..e18e19a0114 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2009,7 +2009,7 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "forc" -version = "0.63.5" +version = "0.63.6" dependencies = [ "annotate-snippets", "ansi_term", @@ -2020,7 +2020,7 @@ dependencies = [ "completest-pty", "forc-pkg", "forc-test", - "forc-tracing 0.63.5", + "forc-tracing 0.63.6", "forc-util", "fs_extra", "fuel-asm", @@ -2046,7 +2046,7 @@ dependencies = [ [[package]] name = "forc-client" -version = "0.63.5" +version = "0.63.6" dependencies = [ "anyhow", "async-trait", @@ -2056,7 +2056,7 @@ dependencies = [ "dialoguer", "forc", "forc-pkg", - "forc-tracing 0.63.5", + "forc-tracing 0.63.6", "forc-tx", "forc-util", "forc-wallet", @@ -2089,13 +2089,13 @@ dependencies = [ [[package]] name = "forc-crypto" -version = "0.63.5" +version = "0.63.6" dependencies = [ "anyhow", "async-trait", "atty", "clap 4.5.16", - "forc-tracing 0.63.5", + "forc-tracing 0.63.6", "forc-util", "fuel-core-types", "fuel-crypto", @@ -2115,7 +2115,7 @@ dependencies = [ [[package]] name = "forc-debug" -version = "0.63.5" +version = "0.63.6" dependencies = [ "anyhow", "clap 4.5.16", @@ -2123,7 +2123,7 @@ dependencies = [ "escargot", "forc-pkg", "forc-test", - "forc-tracing 0.63.5", + "forc-tracing 0.63.6", "fuel-core-client", "fuel-types", "fuel-vm", @@ -2141,7 +2141,7 @@ dependencies = [ [[package]] name = "forc-doc" -version = "0.63.5" +version = "0.63.6" dependencies = [ "anyhow", "clap 4.5.16", @@ -2149,7 +2149,7 @@ dependencies = [ "dir_indexer", "expect-test", "forc-pkg", - "forc-tracing 0.63.5", + "forc-tracing 0.63.6", "forc-util", "horrorshow", "include_dir", @@ -2166,12 +2166,12 @@ dependencies = [ [[package]] name = "forc-fmt" -version = "0.63.5" +version = "0.63.6" dependencies = [ "anyhow", "clap 4.5.16", "forc-pkg", - "forc-tracing 0.63.5", + "forc-tracing 0.63.6", "forc-util", "prettydiff 0.5.1", "sway-core", @@ -2183,7 +2183,7 @@ dependencies = [ [[package]] name = "forc-lsp" -version = "0.63.5" +version = "0.63.6" dependencies = [ "anyhow", "clap 4.5.16", @@ -2194,13 +2194,13 @@ dependencies = [ [[package]] name = "forc-pkg" -version = "0.63.5" +version = "0.63.6" dependencies = [ "ansi_term", "anyhow", "byte-unit", "cid", - "forc-tracing 0.63.5", + "forc-tracing 0.63.6", "forc-util", "fuel-abi-types", "futures", @@ -2231,7 +2231,7 @@ dependencies = [ [[package]] name = "forc-test" -version = "0.63.5" +version = "0.63.6" dependencies = [ "anyhow", "forc-pkg", @@ -2258,7 +2258,7 @@ dependencies = [ [[package]] name = "forc-tracing" -version = "0.63.5" +version = "0.63.6" dependencies = [ "ansi_term", "tracing", @@ -2268,7 +2268,7 @@ dependencies = [ [[package]] name = "forc-tx" -version = "0.63.5" +version = "0.63.6" dependencies = [ "anyhow", "clap 4.5.16", @@ -2283,7 +2283,7 @@ dependencies = [ [[package]] name = "forc-util" -version = "0.63.5" +version = "0.63.6" dependencies = [ "annotate-snippets", "ansi_term", @@ -2291,7 +2291,7 @@ dependencies = [ "clap 4.5.16", "dirs 3.0.2", "fd-lock 4.0.2", - "forc-tracing 0.63.5", + "forc-tracing 0.63.6", "fuel-tx", "hex", "paste", @@ -6855,7 +6855,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sway-ast" -version = "0.63.5" +version = "0.63.6" dependencies = [ "extension-trait", "num-bigint", @@ -6867,7 +6867,7 @@ dependencies = [ [[package]] name = "sway-core" -version = "0.63.5" +version = "0.63.6" dependencies = [ "clap 4.5.16", "derivative", @@ -6912,7 +6912,7 @@ dependencies = [ [[package]] name = "sway-error" -version = "0.63.5" +version = "0.63.6" dependencies = [ "either", "in_definite", @@ -6926,7 +6926,7 @@ dependencies = [ [[package]] name = "sway-ir" -version = "0.63.5" +version = "0.63.6" dependencies = [ "anyhow", "downcast-rs", @@ -6945,7 +6945,7 @@ dependencies = [ [[package]] name = "sway-ir-macros" -version = "0.63.5" +version = "0.63.6" dependencies = [ "itertools 0.10.5", "proc-macro2", @@ -6955,7 +6955,7 @@ dependencies = [ [[package]] name = "sway-lsp" -version = "0.63.5" +version = "0.63.6" dependencies = [ "anyhow", "assert-json-diff", @@ -6966,7 +6966,7 @@ dependencies = [ "dirs 4.0.0", "fd-lock 4.0.2", "forc-pkg", - "forc-tracing 0.63.5", + "forc-tracing 0.63.6", "forc-util", "futures", "indexmap 2.4.0", @@ -7020,7 +7020,7 @@ dependencies = [ [[package]] name = "sway-parse" -version = "0.63.5" +version = "0.63.6" dependencies = [ "assert_matches", "extension-trait", @@ -7038,7 +7038,7 @@ dependencies = [ [[package]] name = "sway-types" -version = "0.63.5" +version = "0.63.6" dependencies = [ "bytecount", "fuel-asm", @@ -7057,7 +7057,7 @@ dependencies = [ [[package]] name = "sway-utils" -version = "0.63.5" +version = "0.63.6" dependencies = [ "serde", "walkdir", @@ -7065,11 +7065,11 @@ dependencies = [ [[package]] name = "swayfmt" -version = "0.63.5" +version = "0.63.6" dependencies = [ "anyhow", "difference", - "forc-tracing 0.63.5", + "forc-tracing 0.63.6", "indoc", "paste", "prettydiff 0.6.4", @@ -7348,7 +7348,7 @@ dependencies = [ "forc-client", "forc-pkg", "forc-test", - "forc-tracing 0.63.5", + "forc-tracing 0.63.6", "fuel-vm", "futures", "gag", diff --git a/forc-pkg/Cargo.toml b/forc-pkg/Cargo.toml index e9004882fe6..b5d0346327c 100644 --- a/forc-pkg/Cargo.toml +++ b/forc-pkg/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "forc-pkg" -version = "0.63.5" +version = "0.63.6" description = "Building, locking, fetching and updating Sway projects as Forc packages." authors.workspace = true edition.workspace = true @@ -13,8 +13,8 @@ ansi_term = "0.12" anyhow = "1" byte-unit = "5.1.4" cid = "0.11" -forc-tracing = { version = "0.63.5", path = "../forc-tracing" } -forc-util = { version = "0.63.5", path = "../forc-util" } +forc-tracing = { version = "0.63.6", path = "../forc-tracing" } +forc-util = { version = "0.63.6", path = "../forc-util" } fuel-abi-types = { workspace = true } futures = "0.3" git2 = { version = "0.19", features = [ @@ -31,10 +31,10 @@ serde = { version = "1.0", features = ["derive"] } serde_ignored = "0.1.9" serde_json = "1.0" serde_with = "3.3.0" -sway-core = { version = "0.63.5", path = "../sway-core" } -sway-error = { version = "0.63.5", path = "../sway-error" } -sway-types = { version = "0.63.5", path = "../sway-types" } -sway-utils = { version = "0.63.5", path = "../sway-utils" } +sway-core = { version = "0.63.6", path = "../sway-core" } +sway-error = { version = "0.63.6", path = "../sway-error" } +sway-types = { version = "0.63.6", path = "../sway-types" } +sway-utils = { version = "0.63.6", path = "../sway-utils" } tar = "0.4.38" toml = { version = "0.8", features = ["parse"] } tracing = "0.1" diff --git a/forc-plugins/forc-client/Cargo.toml b/forc-plugins/forc-client/Cargo.toml index 692e69a63ba..09ba62cf416 100644 --- a/forc-plugins/forc-client/Cargo.toml +++ b/forc-plugins/forc-client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "forc-client" -version = "0.63.5" +version = "0.63.6" description = "A `forc` plugin for interacting with a Fuel node." authors.workspace = true edition.workspace = true @@ -15,11 +15,11 @@ chrono = { version = "0.4", default-features = false, features = ["std"] } clap = { version = "4.5.4", features = ["derive", "env"] } devault = "0.1" dialoguer = "0.11" -forc = { version = "0.63.5", path = "../../forc" } -forc-pkg = { version = "0.63.5", path = "../../forc-pkg" } -forc-tracing = { version = "0.63.5", path = "../../forc-tracing" } -forc-tx = { version = "0.63.5", path = "../forc-tx" } -forc-util = { version = "0.63.5", path = "../../forc-util" } +forc = { version = "0.63.6", path = "../../forc" } +forc-pkg = { version = "0.63.6", path = "../../forc-pkg" } +forc-tracing = { version = "0.63.6", path = "../../forc-tracing" } +forc-tx = { version = "0.63.6", path = "../forc-tx" } +forc-util = { version = "0.63.6", path = "../../forc-util" } forc-wallet = { workspace = true } fuel-abi-types = { workspace = true } fuel-core-client = { workspace = true, features = ["subscriptions"] } @@ -36,9 +36,9 @@ rand = "0.8" rpassword = "7.2" serde = "1.0" serde_json = "1" -sway-core = { version = "0.63.5", path = "../../sway-core" } -sway-types = { version = "0.63.5", path = "../../sway-types" } -sway-utils = { version = "0.63.5", path = "../../sway-utils" } +sway-core = { version = "0.63.6", path = "../../sway-core" } +sway-types = { version = "0.63.6", path = "../../sway-types" } +sway-utils = { version = "0.63.6", path = "../../sway-utils" } tokio = { version = "1.8", features = ["macros", "rt-multi-thread", "process"] } toml_edit = "0.21.1" tracing = "0.1" diff --git a/forc-plugins/forc-client/proxy_abi/README.md b/forc-plugins/forc-client/proxy_abi/README.md index c607603ae84..684e8ceff17 100644 --- a/forc-plugins/forc-client/proxy_abi/README.md +++ b/forc-plugins/forc-client/proxy_abi/README.md @@ -4,5 +4,5 @@ This folder contains pre-built version of the owned proxy contract, its abi and *contract url*: [sway-standard-implementation/src-14/owned_proxy](https://github.com/FuelLabs/sway-standard-implementations/tree/174f5ed9c79c23a6aaf5db906fe27ecdb29c22eb). *commit hash*: `174f5ed9c79c23a6aaf5db906fe27ecdb29c22eb` -*forc version*: `v0.63.5` +*forc version*: `v0.63.6` *build command*: `forc build --release` diff --git a/forc-plugins/forc-crypto/Cargo.toml b/forc-plugins/forc-crypto/Cargo.toml index 8423e1e7f3b..8860198c657 100644 --- a/forc-plugins/forc-crypto/Cargo.toml +++ b/forc-plugins/forc-crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "forc-crypto" -version = "0.63.5" +version = "0.63.6" description = "A `forc` plugin for handling various cryptographic operations and conversions." authors.workspace = true edition.workspace = true @@ -13,8 +13,8 @@ anyhow = "1.0.75" async-trait = "0.1.58" atty = "0.2.14" clap = { version = "4.5.4", features = ["derive", "env"] } -forc-tracing = { version = "0.63.5", path = "../../forc-tracing" } -forc-util = { version = "0.63.5", path = "../../forc-util" } +forc-tracing = { version = "0.63.6", path = "../../forc-tracing" } +forc-util = { version = "0.63.6", path = "../../forc-util" } fuel-core-types = { workspace = true } fuel-crypto = { workspace = true, features = ["random"] } fuels-core = { workspace = true } diff --git a/forc-plugins/forc-debug/Cargo.toml b/forc-plugins/forc-debug/Cargo.toml index 6246a1f279d..afb416da4f2 100644 --- a/forc-plugins/forc-debug/Cargo.toml +++ b/forc-plugins/forc-debug/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "forc-debug" -version = "0.63.5" +version = "0.63.6" description = "Supports debugging Sway code via CLI and DAP server." authors.workspace = true edition.workspace = true @@ -12,9 +12,9 @@ repository.workspace = true anyhow = "1.0" # Used by the examples and for conversion only clap = { version = "4.5.4", features = ["derive", "env"] } dap = "0.4.1-alpha1" -forc-pkg = { version = "0.63.5", path = "../../forc-pkg" } -forc-test = { version = "0.63.5", path = "../../forc-test" } -forc-tracing = { version = "0.63.5", path = "../../forc-tracing" } +forc-pkg = { version = "0.63.6", path = "../../forc-pkg" } +forc-test = { version = "0.63.6", path = "../../forc-test" } +forc-tracing = { version = "0.63.6", path = "../../forc-tracing" } fuel-core-client = { workspace = true } fuel-types = { workspace = true, features = ["serde"] } fuel-vm = { workspace = true, features = ["serde"] } @@ -22,8 +22,8 @@ rayon = "1.7.0" serde = "1.0" serde_json = "1.0" shellfish = { version = "0.6.0", features = ["rustyline", "async", "tokio"] } -sway-core = { version = "0.63.5", path = "../../sway-core" } -sway-types = { version = "0.63.5", path = "../../sway-types" } +sway-core = { version = "0.63.6", path = "../../sway-core" } +sway-types = { version = "0.63.6", path = "../../sway-types" } thiserror = "1.0" tokio = { version = "1.8", features = [ "net", diff --git a/forc-plugins/forc-doc/Cargo.toml b/forc-plugins/forc-doc/Cargo.toml index 4c92f0e495b..a33a68783c1 100644 --- a/forc-plugins/forc-doc/Cargo.toml +++ b/forc-plugins/forc-doc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "forc-doc" -version = "0.63.5" +version = "0.63.6" description = "Build the documentation for the local package and all dependencies. The output is placed in `out/doc` in the same format as the project." authors.workspace = true edition.workspace = true @@ -12,20 +12,20 @@ repository.workspace = true anyhow = "1.0.65" clap = { version = "4.5.4", features = ["derive"] } comrak = "0.16" -forc-pkg = { version = "0.63.5", path = "../../forc-pkg" } -forc-tracing = { version = "0.63.5", path = "../../forc-tracing" } -forc-util = { version = "0.63.5", path = "../../forc-util" } +forc-pkg = { version = "0.63.6", path = "../../forc-pkg" } +forc-tracing = { version = "0.63.6", path = "../../forc-tracing" } +forc-util = { version = "0.63.6", path = "../../forc-util" } horrorshow = "0.8.4" include_dir = "0.7.3" minifier = "0.3.0" opener = "0.5.0" serde = "1.0" serde_json = "1.0" -sway-ast = { version = "0.63.5", path = "../../sway-ast" } -sway-core = { version = "0.63.5", path = "../../sway-core" } -sway-lsp = { version = "0.63.5", path = "../../sway-lsp" } -sway-types = { version = "0.63.5", path = "../../sway-types" } -swayfmt = { version = "0.63.5", path = "../../swayfmt" } +sway-ast = { version = "0.63.6", path = "../../sway-ast" } +sway-core = { version = "0.63.6", path = "../../sway-core" } +sway-lsp = { version = "0.63.6", path = "../../sway-lsp" } +sway-types = { version = "0.63.6", path = "../../sway-types" } +swayfmt = { version = "0.63.6", path = "../../swayfmt" } [dev-dependencies] dir_indexer = "0.0.2" diff --git a/forc-plugins/forc-fmt/Cargo.toml b/forc-plugins/forc-fmt/Cargo.toml index 24f660bad1a..5826b2c8393 100644 --- a/forc-plugins/forc-fmt/Cargo.toml +++ b/forc-plugins/forc-fmt/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "forc-fmt" -version = "0.63.5" +version = "0.63.6" description = "A `forc` plugin for running the Sway code formatter." authors.workspace = true edition.workspace = true @@ -11,12 +11,12 @@ repository.workspace = true [dependencies] anyhow = "1" clap = { version = "4.5.4", features = ["derive"] } -forc-pkg = { version = "0.63.5", path = "../../forc-pkg" } -forc-tracing = { version = "0.63.5", path = "../../forc-tracing" } -forc-util = { version = "0.63.5", path = "../../forc-util" } +forc-pkg = { version = "0.63.6", path = "../../forc-pkg" } +forc-tracing = { version = "0.63.6", path = "../../forc-tracing" } +forc-util = { version = "0.63.6", path = "../../forc-util" } prettydiff = "0.5" -sway-core = { version = "0.63.5", path = "../../sway-core" } -sway-utils = { version = "0.63.5", path = "../../sway-utils" } -swayfmt = { version = "0.63.5", path = "../../swayfmt" } +sway-core = { version = "0.63.6", path = "../../sway-core" } +sway-utils = { version = "0.63.6", path = "../../sway-utils" } +swayfmt = { version = "0.63.6", path = "../../swayfmt" } taplo = "0.7" tracing = "0.1" diff --git a/forc-plugins/forc-lsp/Cargo.toml b/forc-plugins/forc-lsp/Cargo.toml index 82e2e899bbd..5cfdda9ff51 100644 --- a/forc-plugins/forc-lsp/Cargo.toml +++ b/forc-plugins/forc-lsp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "forc-lsp" -version = "0.63.5" +version = "0.63.6" description = "A simple `forc` plugin for starting the sway language server." authors.workspace = true edition.workspace = true @@ -11,6 +11,6 @@ repository.workspace = true [dependencies] anyhow = "1" clap = { version = "4.5.4", features = ["derive"] } -sway-lsp = { version = "0.63.5", path = "../../sway-lsp" } +sway-lsp = { version = "0.63.6", path = "../../sway-lsp" } tikv-jemallocator = "0.5" tokio = { version = "1.8" } diff --git a/forc-plugins/forc-tx/Cargo.toml b/forc-plugins/forc-tx/Cargo.toml index 670778e6a07..82990ca6ba8 100644 --- a/forc-plugins/forc-tx/Cargo.toml +++ b/forc-plugins/forc-tx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "forc-tx" -version = "0.63.5" +version = "0.63.6" description = "A `forc` plugin for constructing transactions." authors.workspace = true edition.workspace = true @@ -19,7 +19,7 @@ path = "src/main.rs" anyhow = "1" clap = { version = "4.5.4", features = ["derive", "env"] } devault = "0.1" -forc-util = { version = "0.63.5", path = "../../forc-util" } +forc-util = { version = "0.63.6", path = "../../forc-util" } fuel-tx = { workspace = true, features = ["serde", "test-helpers", "random"] } fuel-types = { workspace = true, features = ["serde"] } serde = "1.0" diff --git a/forc-test/Cargo.toml b/forc-test/Cargo.toml index 4c5f9647e74..67c3a60db08 100644 --- a/forc-test/Cargo.toml +++ b/forc-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "forc-test" -version = "0.63.5" +version = "0.63.6" description = "A library for building and running Sway unit tests within Forc packages." authors.workspace = true edition.workspace = true @@ -10,12 +10,12 @@ repository.workspace = true [dependencies] anyhow = "1" -forc-pkg = { version = "0.63.5", path = "../forc-pkg" } +forc-pkg = { version = "0.63.6", path = "../forc-pkg" } fuel-abi-types = { workspace = true } fuel-tx = { workspace = true, features = ["test-helpers"] } fuel-vm = { workspace = true, features = ["random", "test-helpers"] } fuels-core = { workspace = true } rand = "0.8" rayon = "1.7.0" -sway-core = { version = "0.63.5", path = "../sway-core" } -sway-types = { version = "0.63.5", path = "../sway-types" } +sway-core = { version = "0.63.6", path = "../sway-core" } +sway-types = { version = "0.63.6", path = "../sway-types" } diff --git a/forc-tracing/Cargo.toml b/forc-tracing/Cargo.toml index 3a8378cf2e9..a851aa674c1 100644 --- a/forc-tracing/Cargo.toml +++ b/forc-tracing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "forc-tracing" -version = "0.63.5" +version = "0.63.6" description = "Tracing utility shared between forc crates." authors.workspace = true edition.workspace = true diff --git a/forc-util/Cargo.toml b/forc-util/Cargo.toml index f24b56b6701..838f6662e4a 100644 --- a/forc-util/Cargo.toml +++ b/forc-util/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "forc-util" -version = "0.63.5" +version = "0.63.6" description = "Utility items shared between forc crates." authors.workspace = true edition.workspace = true @@ -15,7 +15,7 @@ anyhow = "1" clap = { version = "4.5.4", features = ["cargo", "derive", "env"] } dirs = "3.0.2" fd-lock = "4.0" -forc-tracing = { version = "0.63.5", path = "../forc-tracing" } +forc-tracing = { version = "0.63.6", path = "../forc-tracing" } fuel-tx = { workspace = true, features = ["serde"], optional = true } hex = "0.4.3" paste = "1.0.14" @@ -23,10 +23,10 @@ regex = "1.10.2" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.73" serial_test = "3.0.0" -sway-core = { version = "0.63.5", path = "../sway-core" } -sway-error = { version = "0.63.5", path = "../sway-error" } -sway-types = { version = "0.63.5", path = "../sway-types" } -sway-utils = { version = "0.63.5", path = "../sway-utils" } +sway-core = { version = "0.63.6", path = "../sway-core" } +sway-error = { version = "0.63.6", path = "../sway-error" } +sway-types = { version = "0.63.6", path = "../sway-types" } +sway-utils = { version = "0.63.6", path = "../sway-utils" } tracing = "0.1" tracing-subscriber = { version = "0.3", features = [ "ansi", diff --git a/forc/Cargo.toml b/forc/Cargo.toml index 00e1dc3af76..1c3908da5b7 100644 --- a/forc/Cargo.toml +++ b/forc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "forc" -version = "0.63.5" +version = "0.63.6" description = "Fuel Orchestrator." authors.workspace = true edition.workspace = true @@ -23,20 +23,20 @@ anyhow = "1.0.41" clap = { version = "4.5.4", features = ["cargo", "derive", "env"] } clap_complete = "4.5.2" clap_complete_fig = "4.5.0" -forc-pkg = { version = "0.63.5", path = "../forc-pkg" } -forc-test = { version = "0.63.5", path = "../forc-test" } -forc-tracing = { version = "0.63.5", path = "../forc-tracing" } -forc-util = { version = "0.63.5", path = "../forc-util" } +forc-pkg = { version = "0.63.6", path = "../forc-pkg" } +forc-test = { version = "0.63.6", path = "../forc-test" } +forc-tracing = { version = "0.63.6", path = "../forc-tracing" } +forc-util = { version = "0.63.6", path = "../forc-util" } fs_extra = "1.2" fuel-asm = { workspace = true } hex = "0.4.3" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.73" -sway-core = { version = "0.63.5", path = "../sway-core" } -sway-error = { version = "0.63.5", path = "../sway-error" } -sway-ir = { version = "0.63.5", path = "../sway-ir" } -sway-types = { version = "0.63.5", path = "../sway-types" } -sway-utils = { version = "0.63.5", path = "../sway-utils" } +sway-core = { version = "0.63.6", path = "../sway-core" } +sway-error = { version = "0.63.6", path = "../sway-error" } +sway-ir = { version = "0.63.6", path = "../sway-ir" } +sway-types = { version = "0.63.6", path = "../sway-types" } +sway-utils = { version = "0.63.6", path = "../sway-utils" } term-table = "1.3" tokio = { version = "1.8.0", features = ["macros", "rt-multi-thread"] } toml = { version = "0.7", features = ["parse"] } diff --git a/sway-ast/Cargo.toml b/sway-ast/Cargo.toml index 0d073b6ed4a..1f442bb6933 100644 --- a/sway-ast/Cargo.toml +++ b/sway-ast/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sway-ast" -version = "0.63.5" +version = "0.63.6" description = "Sway's AST" authors.workspace = true edition.workspace = true @@ -13,8 +13,8 @@ extension-trait = "1.0.1" num-bigint = { version = "0.4.3", features = ["serde"] } num-traits = "0.2.14" serde = { version = "1.0", features = ["derive"] } -sway-error = { version = "0.63.5", path = "../sway-error" } -sway-types = { version = "0.63.5", path = "../sway-types" } +sway-error = { version = "0.63.6", path = "../sway-error" } +sway-types = { version = "0.63.6", path = "../sway-types" } [lints.clippy] iter_over_hash_type = "deny" diff --git a/sway-core/Cargo.toml b/sway-core/Cargo.toml index 986a1b015b5..20931b78bda 100644 --- a/sway-core/Cargo.toml +++ b/sway-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sway-core" -version = "0.63.5" +version = "0.63.6" description = "Sway core language." authors.workspace = true edition.workspace = true @@ -39,12 +39,12 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.91" sha2 = "0.9" strum = { version = "0.24.1", features = ["derive"] } -sway-ast = { version = "0.63.5", path = "../sway-ast" } -sway-error = { version = "0.63.5", path = "../sway-error" } -sway-ir = { version = "0.63.5", path = "../sway-ir" } -sway-parse = { version = "0.63.5", path = "../sway-parse" } -sway-types = { version = "0.63.5", path = "../sway-types" } -sway-utils = { version = "0.63.5", path = "../sway-utils" } +sway-ast = { version = "0.63.6", path = "../sway-ast" } +sway-error = { version = "0.63.6", path = "../sway-error" } +sway-ir = { version = "0.63.6", path = "../sway-ir" } +sway-parse = { version = "0.63.6", path = "../sway-parse" } +sway-types = { version = "0.63.6", path = "../sway-types" } +sway-utils = { version = "0.63.6", path = "../sway-utils" } thiserror = "1.0" tracing = "0.1" uint = "0.9" diff --git a/sway-error/Cargo.toml b/sway-error/Cargo.toml index 1cf2daa2737..8f4f39312bf 100644 --- a/sway-error/Cargo.toml +++ b/sway-error/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sway-error" -version = "0.63.5" +version = "0.63.6" description = "Sway's error handling" authors.workspace = true edition.workspace = true @@ -14,7 +14,7 @@ in_definite = "1.0.0" num-traits = "0.2.14" smallvec = "1.7" strsim = "0.11.1" -sway-types = { version = "0.63.5", path = "../sway-types" } +sway-types = { version = "0.63.6", path = "../sway-types" } thiserror = "1.0" uwuify = { version = "^0.2", optional = true } diff --git a/sway-ir/Cargo.toml b/sway-ir/Cargo.toml index 44ed847ca70..c81d8eed1a9 100644 --- a/sway-ir/Cargo.toml +++ b/sway-ir/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sway-ir" -version = "0.63.5" +version = "0.63.6" description = "Sway intermediate representation." authors.workspace = true edition.workspace = true @@ -19,9 +19,9 @@ peg = "0.7" prettydiff = "0.6.4" rustc-hash = "1.1.0" slotmap = "1.0.7" -sway-ir-macros = { version = "0.63.5", path = "sway-ir-macros" } -sway-types = { version = "0.63.5", path = "../sway-types" } -sway-utils = { version = "0.63.5", path = "../sway-utils" } +sway-ir-macros = { version = "0.63.6", path = "sway-ir-macros" } +sway-types = { version = "0.63.6", path = "../sway-types" } +sway-utils = { version = "0.63.6", path = "../sway-utils" } [lints.clippy] iter_over_hash_type = "deny" diff --git a/sway-ir/sway-ir-macros/Cargo.toml b/sway-ir/sway-ir-macros/Cargo.toml index ab56ca2eb09..6f2fc7ecae7 100644 --- a/sway-ir/sway-ir-macros/Cargo.toml +++ b/sway-ir/sway-ir-macros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sway-ir-macros" -version = "0.63.5" +version = "0.63.6" description = "Macros for sway's intermediate representation." authors.workspace = true edition.workspace = true diff --git a/sway-lsp/Cargo.toml b/sway-lsp/Cargo.toml index c0ce8559ad2..34c835e967f 100644 --- a/sway-lsp/Cargo.toml +++ b/sway-lsp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sway-lsp" -version = "0.63.5" +version = "0.63.6" description = "LSP server for Sway." authors.workspace = true edition.workspace = true @@ -13,9 +13,9 @@ anyhow = "1.0.41" crossbeam-channel = "0.5" dashmap = "5.4" fd-lock = "4.0" -forc-pkg = { version = "0.63.5", path = "../forc-pkg" } -forc-tracing = { version = "0.63.5", path = "../forc-tracing" } -forc-util = { version = "0.63.5", path = "../forc-util" } +forc-pkg = { version = "0.63.6", path = "../forc-pkg" } +forc-tracing = { version = "0.63.6", path = "../forc-tracing" } +forc-util = { version = "0.63.6", path = "../forc-util" } indexmap = { version = "2.0.0", features = ["rayon"] } lsp-types = { version = "0.94", features = ["proposed"] } notify = "5.0.0" @@ -27,13 +27,13 @@ rayon = "1.5.0" rayon-cond = "0.3" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.60" -sway-ast = { version = "0.63.5", path = "../sway-ast" } -sway-core = { version = "0.63.5", path = "../sway-core" } -sway-error = { version = "0.63.5", path = "../sway-error" } -sway-parse = { version = "0.63.5", path = "../sway-parse" } -sway-types = { version = "0.63.5", path = "../sway-types" } -sway-utils = { version = "0.63.5", path = "../sway-utils" } -swayfmt = { version = "0.63.5", path = "../swayfmt" } +sway-ast = { version = "0.63.6", path = "../sway-ast" } +sway-core = { version = "0.63.6", path = "../sway-core" } +sway-error = { version = "0.63.6", path = "../sway-error" } +sway-parse = { version = "0.63.6", path = "../sway-parse" } +sway-types = { version = "0.63.6", path = "../sway-types" } +sway-utils = { version = "0.63.6", path = "../sway-utils" } +swayfmt = { version = "0.63.6", path = "../swayfmt" } syn = { version = "1.0.73", features = ["full"] } tempfile = "3" thiserror = "1.0.30" diff --git a/sway-parse/Cargo.toml b/sway-parse/Cargo.toml index d2240288c45..dbef9841bf6 100644 --- a/sway-parse/Cargo.toml +++ b/sway-parse/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sway-parse" -version = "0.63.5" +version = "0.63.6" description = "Sway's parser" authors.workspace = true edition.workspace = true @@ -13,9 +13,9 @@ extension-trait = "1.0.1" num-bigint = "0.4.3" num-traits = "0.2.14" phf = { version = "0.10.1", features = ["macros"] } -sway-ast = { version = "0.63.5", path = "../sway-ast" } -sway-error = { version = "0.63.5", path = "../sway-error" } -sway-types = { version = "0.63.5", path = "../sway-types" } +sway-ast = { version = "0.63.6", path = "../sway-ast" } +sway-error = { version = "0.63.6", path = "../sway-error" } +sway-types = { version = "0.63.6", path = "../sway-types" } thiserror = "1.0" unicode-bidi = "0.3.13" unicode-xid = "0.2.2" diff --git a/sway-types/Cargo.toml b/sway-types/Cargo.toml index d6ce305466a..699233eb13f 100644 --- a/sway-types/Cargo.toml +++ b/sway-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sway-types" -version = "0.63.5" +version = "0.63.6" description = "Sway core types." authors.workspace = true edition.workspace = true @@ -20,7 +20,7 @@ num-traits = "0.2.16" parking_lot = "0.12" rustc-hash = "1.1.0" serde = { version = "1.0", features = ["derive"] } -sway-utils = { version = "0.63.5", path = "../sway-utils" } +sway-utils = { version = "0.63.6", path = "../sway-utils" } thiserror = "1" [features] diff --git a/sway-utils/Cargo.toml b/sway-utils/Cargo.toml index 0487b0d6b34..ea26eceda60 100644 --- a/sway-utils/Cargo.toml +++ b/sway-utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sway-utils" -version = "0.63.5" +version = "0.63.6" description = "Sway common utils." authors.workspace = true edition.workspace = true diff --git a/swayfmt/Cargo.toml b/swayfmt/Cargo.toml index d60c0c49a52..a96a4a8f079 100644 --- a/swayfmt/Cargo.toml +++ b/swayfmt/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "swayfmt" -version = "0.63.5" +version = "0.63.6" description = "Sway language formatter." authors.workspace = true edition.workspace = true @@ -10,17 +10,17 @@ repository.workspace = true [dependencies] anyhow = "1" -forc-tracing = { version = "0.63.5", path = "../forc-tracing" } +forc-tracing = { version = "0.63.6", path = "../forc-tracing" } indoc = "2.0" ropey = "1.5" serde = { version = "1.0", features = ["derive"] } serde_ignored = "0.1.9" -sway-ast = { version = "0.63.5", path = "../sway-ast" } -sway-core = { version = "0.63.5", path = "../sway-core" } -sway-error = { version = "0.63.5", path = "../sway-error" } -sway-parse = { version = "0.63.5", path = "../sway-parse" } -sway-types = { version = "0.63.5", path = "../sway-types" } -sway-utils = { version = "0.63.5", path = "../sway-utils" } +sway-ast = { version = "0.63.6", path = "../sway-ast" } +sway-core = { version = "0.63.6", path = "../sway-core" } +sway-error = { version = "0.63.6", path = "../sway-error" } +sway-parse = { version = "0.63.6", path = "../sway-parse" } +sway-types = { version = "0.63.6", path = "../sway-types" } +sway-utils = { version = "0.63.6", path = "../sway-utils" } thiserror = "1.0.30" toml = { version = "0.7", features = ["parse"] } From 15c829858dc99e31cbcbf7210f97cf30cfeb3b96 Mon Sep 17 00:00:00 2001 From: Sophie Dankel <47993817+sdankel@users.noreply.github.com> Date: Wed, 18 Sep 2024 14:25:29 -0700 Subject: [PATCH 021/115] ci: Fix typo in forc-unit tests (#6566) ## Description This typo was introduced here: https://github.com/FuelLabs/sway/commit/5e24673b827837690b41dfbffd2bf746d936b90d#diff-b803fcb7f17ed9235f1e5cb1fcd2f5d3b2838429d4368ae4c57ce4436577f03fR465 `&` should be `&&` It causes the exit code to be 0 even though one of the tests fails to compile. Example: https://github.com/FuelLabs/sway/actions/runs/10865968373/job/30152989834#step:6:86 ![image](https://github.com/user-attachments/assets/ae9c4dd0-3470-4677-b98e-d483cb23ab6c) Thanks @alfiedotwtf for noticing these failing tests! ## Checklist - [ ] 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. - [ ] 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). - [ ] I have requested a review from the relevant team or maintainers. --- .github/workflows/ci.yml | 8 +++++-- sway-lib-std/src/bytes.sw | 47 ++++++++++++++++++++------------------- sway-lib-std/src/vec.sw | 47 ++++++++++++++++++++------------------- 3 files changed, 54 insertions(+), 48 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1930cf1a156..786a6cebbbd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -465,8 +465,12 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Install Forc run: cargo install --locked --debug --path ./forc - - name: Run Unit Tests - run: forc build --path sway-lib-core && forc test --path sway-lib-core && forc build --path sway-lib-std && forc test --path sway-lib-std && forc build --path test/src/in_language_tests & forc test --path test/src/in_language_tests + - name: Run Core Unit Tests + run: forc build --path sway-lib-core && forc test --path sway-lib-core + - name: Run Std Unit Tests + run: forc build --path sway-lib-std && forc test --path sway-lib-std + - name: Run In Language Unit Tests + run: forc build --path test/src/in_language_tests && forc test --path test/src/in_language_tests forc-pkg-fuels-deps-check: runs-on: ubuntu-latest diff --git a/sway-lib-std/src/bytes.sw b/sway-lib-std/src/bytes.sw index b1fd11327ad..1296e940826 100644 --- a/sway-lib-std/src/bytes.sw +++ b/sway-lib-std/src/bytes.sw @@ -927,26 +927,27 @@ impl AbiDecode for Bytes { } } -#[test] -fn ok_bytes_buffer_ownership() { - let mut original_array = [1u8, 2u8, 3u8, 4u8]; - let slice = raw_slice::from_parts::(__addr_of(original_array), 4); - - // Check Bytes duplicates the original slice - let mut bytes = Bytes::from(slice); - bytes.set(0, 5); - assert(original_array[0] == 1); - - // At this point, slice equals [5, 2, 3, 4] - let encoded_slice = encode(bytes); - - // `Bytes` should duplicate the underlying buffer, - // so when we write to it, it should not change - // `encoded_slice` - let mut bytes = abi_decode::(encoded_slice); - bytes.set(0, 6); - assert(bytes.get(0) == Some(6)); - - let mut bytes = abi_decode::(encoded_slice); - assert(bytes.get(0) == Some(5)); -} +// TODO: Uncomment when fixed. https://github.com/FuelLabs/sway/issues/6567 +// #[test] +// fn ok_bytes_buffer_ownership() { +// let mut original_array = [1u8, 2u8, 3u8, 4u8]; +// let slice = raw_slice::from_parts::(__addr_of(original_array), 4); + +// // Check Bytes duplicates the original slice +// let mut bytes = Bytes::from(slice); +// bytes.set(0, 5); +// assert(original_array[0] == 1); + +// // At this point, slice equals [5, 2, 3, 4] +// let encoded_slice = encode(bytes); + +// // `Bytes` should duplicate the underlying buffer, +// // so when we write to it, it should not change +// // `encoded_slice` +// let mut bytes = abi_decode::(encoded_slice); +// bytes.set(0, 6); +// assert(bytes.get(0) == Some(6)); + +// let mut bytes = abi_decode::(encoded_slice); +// assert(bytes.get(0) == Some(5)); +// } diff --git a/sway-lib-std/src/vec.sw b/sway-lib-std/src/vec.sw index 5b7830b848c..8ae7fe65da7 100644 --- a/sway-lib-std/src/vec.sw +++ b/sway-lib-std/src/vec.sw @@ -705,26 +705,27 @@ impl Iterator for VecIter { } } -#[test] -fn ok_vec_buffer_ownership() { - let mut original_array = [1u8, 2u8, 3u8, 4u8]; - let slice = raw_slice::from_parts::(__addr_of(original_array), 4); - - // Check Vec duplicates the original slice - let mut bytes = Vec::::from(slice); - bytes.set(0, 5); - assert(original_array[0] == 1); - - // At this point, slice equals [5, 2, 3, 4] - let encoded_slice = encode(bytes); - - // `Vec` should duplicate the underlying buffer, - // so when we write to it, it should not change - // `encoded_slice` - let mut bytes = abi_decode::>(encoded_slice); - bytes.set(0, 6); - assert(bytes.get(0) == Some(6)); - - let mut bytes = abi_decode::>(encoded_slice); - assert(bytes.get(0) == Some(5)); -} +// TODO: Uncomment when fixed. https://github.com/FuelLabs/sway/issues/6567 +// #[test] +// fn ok_vec_buffer_ownership() { +// let mut original_array = [1u8, 2u8, 3u8, 4u8]; +// let slice = raw_slice::from_parts::(__addr_of(original_array), 4); + +// // Check Vec duplicates the original slice +// let mut bytes = Vec::::from(slice); +// bytes.set(0, 5); +// assert(original_array[0] == 1); + +// // At this point, slice equals [5, 2, 3, 4] +// let encoded_slice = encode(bytes); + +// // `Vec` should duplicate the underlying buffer, +// // so when we write to it, it should not change +// // `encoded_slice` +// let mut bytes = abi_decode::>(encoded_slice); +// bytes.set(0, 6); +// assert(bytes.get(0) == Some(6)); + +// let mut bytes = abi_decode::>(encoded_slice); +// assert(bytes.get(0) == Some(5)); +// } From 10a78a76246e031b881c0343c3dbc6ea2218bd41 Mon Sep 17 00:00:00 2001 From: Marcos Henrich Date: Wed, 18 Sep 2024 23:15:20 +0100 Subject: [PATCH 022/115] Fixed required trait constraint not being checked (#6525) ## Description An optimization on `check_if_trait_constraints_are_satisfied_for_type_inner` was making missing trait constraints not being detected. Fixes #6374. ## 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: Sophie Dankel <47993817+sdankel@users.noreply.github.com> --- .../semantic_analysis/namespace/trait_map.rs | 28 ------------------- .../method_missing_constraint/Forc.lock | 3 ++ .../method_missing_constraint/Forc.toml | 6 ++++ .../json_abi_oracle.json | 1 + .../method_missing_constraint/src/main.sw | 21 ++++++++++++++ .../method_missing_constraint/test.toml | 4 +++ 6 files changed, 35 insertions(+), 28 deletions(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/method_missing_constraint/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/method_missing_constraint/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/method_missing_constraint/json_abi_oracle.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/method_missing_constraint/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/method_missing_constraint/test.toml diff --git a/sway-core/src/semantic_analysis/namespace/trait_map.rs b/sway-core/src/semantic_analysis/namespace/trait_map.rs index 6d1be290b42..47e0e884988 100644 --- a/sway-core/src/semantic_analysis/namespace/trait_map.rs +++ b/sway-core/src/semantic_analysis/namespace/trait_map.rs @@ -1390,34 +1390,6 @@ impl TraitMap { ) -> Result<(), ErrorEmitted> { let type_engine = engines.te(); - // If the type is generic/placeholder, its definition needs to contains all - // constraints - match &*type_engine.get(type_id) { - TypeInfo::UnknownGeneric { - trait_constraints, .. - } => { - let all = constraints.iter().all(|required| { - trait_constraints.iter().any(|constraint| { - constraint.eq(required, &PartialEqWithEnginesContext::new(engines)) - }) - }); - if all { - return Ok(()); - } - } - TypeInfo::Placeholder(p) => { - let all = constraints.iter().all(|required| { - p.trait_constraints.iter().any(|constraint| { - constraint.eq(required, &PartialEqWithEnginesContext::new(engines)) - }) - }); - if all { - return Ok(()); - } - } - _ => {} - } - let _decl_engine = engines.de(); let unify_check = UnifyCheck::non_dynamic_equality(engines); diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/method_missing_constraint/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_fail/method_missing_constraint/Forc.lock new file mode 100644 index 00000000000..93daf379ca5 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/method_missing_constraint/Forc.lock @@ -0,0 +1,3 @@ +[[package]] +name = "method_missing_constraint" +source = "member" diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/method_missing_constraint/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/method_missing_constraint/Forc.toml new file mode 100644 index 00000000000..4bfc75e72b9 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/method_missing_constraint/Forc.toml @@ -0,0 +1,6 @@ +[project] +authors = ["Fuel Labs "] +license = "Apache-2.0" +name = "method_missing_constraint" +entry = "main.sw" +implicit-std = false diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/method_missing_constraint/json_abi_oracle.json b/test/src/e2e_vm_tests/test_programs/should_fail/method_missing_constraint/json_abi_oracle.json new file mode 100644 index 00000000000..0637a088a01 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/method_missing_constraint/json_abi_oracle.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/method_missing_constraint/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/method_missing_constraint/src/main.sw new file mode 100644 index 00000000000..e1a48078c2f --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/method_missing_constraint/src/main.sw @@ -0,0 +1,21 @@ +script; + +trait T1 {} +trait T2 {} +struct S where T: T1 { + x: T, +} +impl S where T: T1{ + fn only_t1(self) { + Self::also_t2(self); + } + fn also_t2(self) where T: T2{ + } +} +impl T1 for u8 {} +impl T1 for u64 {} +impl T2 for u64 {} +fn main() { + let a = S::{x: 42}; + a.only_t1(); //prints Hello but u8 doesn't implement T2 +} diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/method_missing_constraint/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/method_missing_constraint/test.toml new file mode 100644 index 00000000000..cc9d2a0e61f --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/method_missing_constraint/test.toml @@ -0,0 +1,4 @@ +category = "fail" + +# check: $()Self::also_t2(self); +# nextln: $()Trait "T2" is not implemented for type "T". \ No newline at end of file From 613f129537b9c324b5dfe3383154f6c52841f536 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaya=20G=C3=B6kalp?= Date: Wed, 18 Sep 2024 20:36:26 -0700 Subject: [PATCH 023/115] fix: forc-client build script should update proxy abi also for deployment tests (#6561) ## Description closes #6558. This PR fixes an issue with the forc-client build script that causes the deployment tests to be updated manually for each proxy abi change. This is a follow up on #6535 and was overlooked in that one. Not critical as it does not break anything on the user side but rather an code-quality issue. --- forc-plugins/forc-client/build.rs | 43 +- forc-plugins/forc-client/tests/deploy.rs | 729 +---------------------- 2 files changed, 26 insertions(+), 746 deletions(-) diff --git a/forc-plugins/forc-client/build.rs b/forc-plugins/forc-client/build.rs index 655ca223a23..7a596f76b94 100644 --- a/forc-plugins/forc-client/build.rs +++ b/forc-plugins/forc-client/build.rs @@ -1,5 +1,5 @@ use std::fs; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; fn minify_json(json: &str) -> String { let mut result = String::with_capacity(json.len()); @@ -27,24 +27,9 @@ fn minify_json(json: &str) -> String { result } -fn main() { - // Path to the JSON file in the root directory next to the `src` folder - let json_path = PathBuf::from("proxy_abi/proxy_contract-abi.json"); - // If proxy_contract-abi.json is changed, re-run this script - println!("cargo:rerun-if-changed=proxy_abi/proxy_contract-abi.json"); - // Path to the Rust source file that contains the `abigen!` macro that - // creates a `ProxyContract`. - let source_file_path = PathBuf::from("src/util/tx.rs"); - // Read the contents of the JSON file - let json_content = - fs::read_to_string(json_path).expect("Unable to read proxy_contract-abi.json"); - - // Minify the JSON content - let minified_json = minify_json(&json_content); - +fn update_proxy_abi_decl_with_file(source_file_path: &Path, minified_json: &str) { // Read the contents of the source file - let mut source_code = - fs::read_to_string(&source_file_path).expect("Unable to read source file"); + let mut source_code = fs::read_to_string(source_file_path).expect("Unable to read source file"); // Prepare the replacement string for the `abigen!` macro let escaped_json = minified_json.replace('\\', "\\\\").replace('"', "\\\""); @@ -67,3 +52,25 @@ fn main() { // Write the modified source code back to the source file fs::write(source_file_path, source_code).expect("Unable to write back to the source file"); } + +fn main() { + // Path to the JSON file in the root directory next to the `src` folder + let json_path = PathBuf::from("proxy_abi/proxy_contract-abi.json"); + // Read the contents of the JSON file + let json_content = + fs::read_to_string(json_path).expect("Unable to read proxy_contract-abi.json"); + + // Minify the JSON content + let minified_json = minify_json(&json_content); + + // If proxy_contract-abi.json is changed, re-run this script + println!("cargo:rerun-if-changed=proxy_abi/proxy_contract-abi.json"); + + // Path to the Rust source file that contains the `abigen!` macro that + // creates a `ProxyContract`. + let util_tx_path = PathBuf::from("src/util/tx.rs"); + update_proxy_abi_decl_with_file(&util_tx_path, &minified_json); + + let util_tx_path = PathBuf::from("tests/deploy.rs"); + update_proxy_abi_decl_with_file(&util_tx_path, &minified_json); +} diff --git a/forc-plugins/forc-client/tests/deploy.rs b/forc-plugins/forc-client/tests/deploy.rs index fa2941325b5..c0016c74c67 100644 --- a/forc-plugins/forc-client/tests/deploy.rs +++ b/forc-plugins/forc-client/tests/deploy.rs @@ -595,734 +595,7 @@ async fn test_non_owner_fails_to_set_target() { .unwrap(); let dummy_contract_id_target = ContractId::default(); - abigen!(Contract( - name = "ProxyContract", - abi = r#" -{ - "programType": "contract", - "specVersion": "1", - "encodingVersion": "1", - "concreteTypes": [ - { - "type": "()", - "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "type": "enum standards::src5::AccessError", - "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d", - "metadataTypeId": 1 - }, - { - "type": "enum standards::src5::State", - "concreteTypeId": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", - "metadataTypeId": 2 - }, - { - "type": "enum std::option::Option", - "concreteTypeId": "0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8", - "metadataTypeId": 4, - "typeArguments": [ - "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" - ] - }, - { - "type": "enum sway_libs::ownership::errors::InitializationError", - "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893", - "metadataTypeId": 5 - }, - { - "type": "enum sway_libs::upgradability::errors::SetProxyOwnerError", - "concreteTypeId": "3c6e90ae504df6aad8b34a93ba77dc62623e00b777eecacfa034a8ac6e890c74", - "metadataTypeId": 6 - }, - { - "type": "str", - "concreteTypeId": "8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a" - }, - { - "type": "struct std::contract_id::ContractId", - "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", - "metadataTypeId": 9 - }, - { - "type": "struct sway_libs::upgradability::events::ProxyOwnerSet", - "concreteTypeId": "96dd838b44f99d8ccae2a7948137ab6256c48ca4abc6168abc880de07fba7247", - "metadataTypeId": 10 - }, - { - "type": "struct sway_libs::upgradability::events::ProxyTargetSet", - "concreteTypeId": "1ddc0adda1270a016c08ffd614f29f599b4725407c8954c8b960bdf651a9a6c8", - "metadataTypeId": 11 - } - ], - "metadataTypes": [ - { - "type": "b256", - "metadataTypeId": 0 - }, - { - "type": "enum standards::src5::AccessError", - "metadataTypeId": 1, - "components": [ - { - "name": "NotOwner", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - } - ] - }, - { - "type": "enum standards::src5::State", - "metadataTypeId": 2, - "components": [ - { - "name": "Uninitialized", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "Initialized", - "typeId": 3 - }, - { - "name": "Revoked", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - } - ] - }, - { - "type": "enum std::identity::Identity", - "metadataTypeId": 3, - "components": [ - { - "name": "Address", - "typeId": 8 - }, - { - "name": "ContractId", - "typeId": 9 - } - ] - }, - { - "type": "enum std::option::Option", - "metadataTypeId": 4, - "components": [ - { - "name": "None", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "Some", - "typeId": 7 - } - ], - "typeParameters": [ - 7 - ] - }, - { - "type": "enum sway_libs::ownership::errors::InitializationError", - "metadataTypeId": 5, - "components": [ - { - "name": "CannotReinitialized", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - } - ] - }, - { - "type": "enum sway_libs::upgradability::errors::SetProxyOwnerError", - "metadataTypeId": 6, - "components": [ - { - "name": "CannotUninitialize", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - } - ] - }, - { - "type": "generic T", - "metadataTypeId": 7 - }, - { - "type": "struct std::address::Address", - "metadataTypeId": 8, - "components": [ - { - "name": "bits", - "typeId": 0 - } - ] - }, - { - "type": "struct std::contract_id::ContractId", - "metadataTypeId": 9, - "components": [ - { - "name": "bits", - "typeId": 0 - } - ] - }, - { - "type": "struct sway_libs::upgradability::events::ProxyOwnerSet", - "metadataTypeId": 10, - "components": [ - { - "name": "new_proxy_owner", - "typeId": 2 - } - ] - }, - { - "type": "struct sway_libs::upgradability::events::ProxyTargetSet", - "metadataTypeId": 11, - "components": [ - { - "name": "new_target", - "typeId": 9 - } - ] - } - ], - "functions": [ - { - "inputs": [], - "name": "proxy_target", - "output": "0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8", - "attributes": [ - { - "name": "doc-comment", - "arguments": [ - " Returns the target contract of the proxy contract." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Returns" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * [Option] - The new proxy contract to which all fallback calls will be passed or `None`." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Number of Storage Accesses" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * Reads: `1`" - ] - }, - { - "name": "storage", - "arguments": [ - "read" - ] - } - ] - }, - { - "inputs": [ - { - "name": "new_target", - "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" - } - ], - "name": "set_proxy_target", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", - "attributes": [ - { - "name": "doc-comment", - "arguments": [ - " Change the target contract of the proxy contract." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Additional Information" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " This method can only be called by the `proxy_owner`." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Arguments" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * `new_target`: [ContractId] - The new proxy contract to which all fallback calls will be passed." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Reverts" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * When not called by `proxy_owner`." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Number of Storage Accesses" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * Reads: `1`" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * Write: `1`" - ] - }, - { - "name": "storage", - "arguments": [ - "read", - "write" - ] - } - ] - }, - { - "inputs": [], - "name": "proxy_owner", - "output": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", - "attributes": [ - { - "name": "doc-comment", - "arguments": [ - " Returns the owner of the proxy contract." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Returns" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * [State] - Represents the state of ownership for this contract." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Number of Storage Accesses" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * Reads: `1`" - ] - }, - { - "name": "storage", - "arguments": [ - "read" - ] - } - ] - }, - { - "inputs": [], - "name": "initialize_proxy", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", - "attributes": [ - { - "name": "doc-comment", - "arguments": [ - " Initializes the proxy contract." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Additional Information" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " This method sets the storage values using the values of the configurable constants `INITIAL_TARGET` and `INITIAL_OWNER`." - ] - }, - { - "name": "doc-comment", - "arguments": [ - " This then allows methods that write to storage to be called." - ] - }, - { - "name": "doc-comment", - "arguments": [ - " This method can only be called once." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Reverts" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * When `storage::SRC14.proxy_owner` is not [State::Uninitialized]." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Number of Storage Accesses" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * Writes: `2`" - ] - }, - { - "name": "storage", - "arguments": [ - "write" - ] - } - ] - }, - { - "inputs": [ - { - "name": "new_proxy_owner", - "concreteTypeId": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c" - } - ], - "name": "set_proxy_owner", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", - "attributes": [ - { - "name": "doc-comment", - "arguments": [ - " Changes proxy ownership to the passed State." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Additional Information" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " This method can be used to transfer ownership between Identities or to revoke ownership." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Arguments" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * `new_proxy_owner`: [State] - The new state of the proxy ownership." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Reverts" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * When the sender is not the current proxy owner." - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * When the new state of the proxy ownership is [State::Uninitialized]." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Number of Storage Accesses" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * Reads: `1`" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * Writes: `1`" - ] - }, - { - "name": "storage", - "arguments": [ - "write" - ] - } - ] - } - ], - "loggedTypes": [ - { - "logId": "4571204900286667806", - "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d" - }, - { - "logId": "2151606668983994881", - "concreteTypeId": "1ddc0adda1270a016c08ffd614f29f599b4725407c8954c8b960bdf651a9a6c8" - }, - { - "logId": "2161305517876418151", - "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893" - }, - { - "logId": "4354576968059844266", - "concreteTypeId": "3c6e90ae504df6aad8b34a93ba77dc62623e00b777eecacfa034a8ac6e890c74" - }, - { - "logId": "10870989709723147660", - "concreteTypeId": "96dd838b44f99d8ccae2a7948137ab6256c48ca4abc6168abc880de07fba7247" - }, - { - "logId": "10098701174489624218", - "concreteTypeId": "8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a" - } - ], - "messagesTypes": [], - "configurables": [ - { - "name": "INITIAL_TARGET", - "concreteTypeId": "0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8", - "offset": 13616 - }, - { - "name": "INITIAL_OWNER", - "concreteTypeId": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", - "offset": 13568 - } - ] -}"#, - )); + abigen!(Contract(name = "ProxyContract", abi = "{\"programType\":\"contract\",\"specVersion\":\"1\",\"encodingVersion\":\"1\",\"concreteTypes\":[{\"type\":\"()\",\"concreteTypeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"},{\"type\":\"enum standards::src5::AccessError\",\"concreteTypeId\":\"3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d\",\"metadataTypeId\":1},{\"type\":\"enum standards::src5::State\",\"concreteTypeId\":\"192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c\",\"metadataTypeId\":2},{\"type\":\"enum std::option::Option\",\"concreteTypeId\":\"0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8\",\"metadataTypeId\":4,\"typeArguments\":[\"29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54\"]},{\"type\":\"enum sway_libs::ownership::errors::InitializationError\",\"concreteTypeId\":\"1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893\",\"metadataTypeId\":5},{\"type\":\"enum sway_libs::upgradability::errors::SetProxyOwnerError\",\"concreteTypeId\":\"3c6e90ae504df6aad8b34a93ba77dc62623e00b777eecacfa034a8ac6e890c74\",\"metadataTypeId\":6},{\"type\":\"str\",\"concreteTypeId\":\"8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a\"},{\"type\":\"struct std::contract_id::ContractId\",\"concreteTypeId\":\"29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54\",\"metadataTypeId\":9},{\"type\":\"struct sway_libs::upgradability::events::ProxyOwnerSet\",\"concreteTypeId\":\"96dd838b44f99d8ccae2a7948137ab6256c48ca4abc6168abc880de07fba7247\",\"metadataTypeId\":10},{\"type\":\"struct sway_libs::upgradability::events::ProxyTargetSet\",\"concreteTypeId\":\"1ddc0adda1270a016c08ffd614f29f599b4725407c8954c8b960bdf651a9a6c8\",\"metadataTypeId\":11}],\"metadataTypes\":[{\"type\":\"b256\",\"metadataTypeId\":0},{\"type\":\"enum standards::src5::AccessError\",\"metadataTypeId\":1,\"components\":[{\"name\":\"NotOwner\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"}]},{\"type\":\"enum standards::src5::State\",\"metadataTypeId\":2,\"components\":[{\"name\":\"Uninitialized\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"},{\"name\":\"Initialized\",\"typeId\":3},{\"name\":\"Revoked\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"}]},{\"type\":\"enum std::identity::Identity\",\"metadataTypeId\":3,\"components\":[{\"name\":\"Address\",\"typeId\":8},{\"name\":\"ContractId\",\"typeId\":9}]},{\"type\":\"enum std::option::Option\",\"metadataTypeId\":4,\"components\":[{\"name\":\"None\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"},{\"name\":\"Some\",\"typeId\":7}],\"typeParameters\":[7]},{\"type\":\"enum sway_libs::ownership::errors::InitializationError\",\"metadataTypeId\":5,\"components\":[{\"name\":\"CannotReinitialized\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"}]},{\"type\":\"enum sway_libs::upgradability::errors::SetProxyOwnerError\",\"metadataTypeId\":6,\"components\":[{\"name\":\"CannotUninitialize\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"}]},{\"type\":\"generic T\",\"metadataTypeId\":7},{\"type\":\"struct std::address::Address\",\"metadataTypeId\":8,\"components\":[{\"name\":\"bits\",\"typeId\":0}]},{\"type\":\"struct std::contract_id::ContractId\",\"metadataTypeId\":9,\"components\":[{\"name\":\"bits\",\"typeId\":0}]},{\"type\":\"struct sway_libs::upgradability::events::ProxyOwnerSet\",\"metadataTypeId\":10,\"components\":[{\"name\":\"new_proxy_owner\",\"typeId\":2}]},{\"type\":\"struct sway_libs::upgradability::events::ProxyTargetSet\",\"metadataTypeId\":11,\"components\":[{\"name\":\"new_target\",\"typeId\":9}]}],\"functions\":[{\"inputs\":[],\"name\":\"proxy_target\",\"output\":\"0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Returns the target contract of the proxy contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Returns\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * [Option] - The new proxy contract to which all fallback calls will be passed or `None`.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Reads: `1`\"]},{\"name\":\"storage\",\"arguments\":[\"read\"]}]},{\"inputs\":[{\"name\":\"new_target\",\"concreteTypeId\":\"29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54\"}],\"name\":\"set_proxy_target\",\"output\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Change the target contract of the proxy contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Additional Information\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This method can only be called by the `proxy_owner`.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Arguments\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * `new_target`: [ContractId] - The new proxy contract to which all fallback calls will be passed.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Reverts\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * When not called by `proxy_owner`.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Reads: `1`\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Write: `1`\"]},{\"name\":\"storage\",\"arguments\":[\"read\",\"write\"]}]},{\"inputs\":[],\"name\":\"proxy_owner\",\"output\":\"192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Returns the owner of the proxy contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Returns\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * [State] - Represents the state of ownership for this contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Reads: `1`\"]},{\"name\":\"storage\",\"arguments\":[\"read\"]}]},{\"inputs\":[],\"name\":\"initialize_proxy\",\"output\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Initializes the proxy contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Additional Information\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This method sets the storage values using the values of the configurable constants `INITIAL_TARGET` and `INITIAL_OWNER`.\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This then allows methods that write to storage to be called.\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This method can only be called once.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Reverts\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * When `storage::SRC14.proxy_owner` is not [State::Uninitialized].\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Writes: `2`\"]},{\"name\":\"storage\",\"arguments\":[\"write\"]}]},{\"inputs\":[{\"name\":\"new_proxy_owner\",\"concreteTypeId\":\"192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c\"}],\"name\":\"set_proxy_owner\",\"output\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Changes proxy ownership to the passed State.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Additional Information\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This method can be used to transfer ownership between Identities or to revoke ownership.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Arguments\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * `new_proxy_owner`: [State] - The new state of the proxy ownership.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Reverts\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * When the sender is not the current proxy owner.\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * When the new state of the proxy ownership is [State::Uninitialized].\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Reads: `1`\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Writes: `1`\"]},{\"name\":\"storage\",\"arguments\":[\"write\"]}]}],\"loggedTypes\":[{\"logId\":\"4571204900286667806\",\"concreteTypeId\":\"3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d\"},{\"logId\":\"2151606668983994881\",\"concreteTypeId\":\"1ddc0adda1270a016c08ffd614f29f599b4725407c8954c8b960bdf651a9a6c8\"},{\"logId\":\"2161305517876418151\",\"concreteTypeId\":\"1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893\"},{\"logId\":\"4354576968059844266\",\"concreteTypeId\":\"3c6e90ae504df6aad8b34a93ba77dc62623e00b777eecacfa034a8ac6e890c74\"},{\"logId\":\"10870989709723147660\",\"concreteTypeId\":\"96dd838b44f99d8ccae2a7948137ab6256c48ca4abc6168abc880de07fba7247\"},{\"logId\":\"10098701174489624218\",\"concreteTypeId\":\"8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a\"}],\"messagesTypes\":[],\"configurables\":[{\"name\":\"INITIAL_TARGET\",\"concreteTypeId\":\"0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8\",\"offset\":13368},{\"name\":\"INITIAL_OWNER\",\"concreteTypeId\":\"192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c\",\"offset\":13320}]}",)); // Try to change target of the proxy with a random wallet which is not the owner of the proxy. let res = update_proxy_contract_target( From d17861393fe177444c5f7096208960085eed96db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Matos?= Date: Thu, 19 Sep 2024 10:17:03 +0100 Subject: [PATCH 024/115] Introduce the collection context in the type check context. (#6460) ## Description This PR does a couple things: * Creates all of the necessary lexical scopes in the collection context namespace * Introduces the collection context in the type check context * Updates type checking code to enter the corresponding lexical scope in the collection context * Introduces a mapping from a span to a lexical scope in the namespace * Implements collection steps for so far unimplemented AST nodes This prepares the compiler for a future PR where the additional namespace will be able to be removed from the type checking, and with it the cloning we do as we type check. ## 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. --------- Co-authored-by: Joshua Batty Co-authored-by: Sophie Dankel <47993817+sdankel@users.noreply.github.com> --- sway-core/src/engine_threading.rs | 6 + .../language/parsed/declaration/function.rs | 2 - .../src/language/ty/declaration/variable.rs | 40 +- sway-core/src/lib.rs | 3 +- .../semantic_analysis/ast_node/code_block.rs | 65 +-- .../ast_node/declaration/abi.rs | 42 +- .../ast_node/declaration/auto_impl.rs | 25 +- .../ast_node/declaration/configurable.rs | 29 +- .../ast_node/declaration/constant.rs | 23 +- .../ast_node/declaration/declaration.rs | 161 ++------ .../ast_node/declaration/enum.rs | 24 +- .../ast_node/declaration/function.rs | 29 +- .../ast_node/declaration/impl_trait.rs | 41 +- .../ast_node/declaration/mod.rs | 1 + .../ast_node/declaration/storage.rs | 19 +- .../ast_node/declaration/struct.rs | 24 +- .../ast_node/declaration/trait.rs | 369 ++++++++++-------- .../ast_node/declaration/trait_fn.rs | 32 +- .../ast_node/declaration/trait_type.rs | 19 +- .../ast_node/declaration/type_alias.rs | 29 +- .../ast_node/declaration/variable.rs | 139 +++++++ .../typed/typed_match_branch.rs | 2 +- .../typed/typed_match_expression.rs | 5 +- .../ast_node/expression/typed_expression.rs | 151 ++++++- .../typed_expression/struct_instantiation.rs | 2 +- .../src/semantic_analysis/ast_node/mod.rs | 4 +- .../namespace/contract_helpers.rs | 8 +- .../src/semantic_analysis/namespace/module.rs | 35 +- .../semantic_analysis/namespace/namespace.rs | 10 +- .../src/semantic_analysis/namespace/root.rs | 2 +- sway-core/src/semantic_analysis/program.rs | 6 +- .../symbol_collection_context.rs | 19 +- .../symbol_resolve_context.rs | 14 +- .../semantic_analysis/type_check_context.rs | 195 ++++++--- .../to_parsed_lang/convert_parse_tree.rs | 1 - 35 files changed, 1123 insertions(+), 453 deletions(-) create mode 100644 sway-core/src/semantic_analysis/ast_node/declaration/variable.rs diff --git a/sway-core/src/engine_threading.rs b/sway-core/src/engine_threading.rs index b2a215c6235..2af209c807f 100644 --- a/sway-core/src/engine_threading.rs +++ b/sway-core/src/engine_threading.rs @@ -219,6 +219,12 @@ impl DebugWithEngines for Vec { } } +impl DebugWithEngines for Span { + fn fmt(&self, f: &mut fmt::Formatter<'_>, engines: &Engines) -> fmt::Result { + DisplayWithEngines::fmt(self, f, engines) + } +} + pub trait HashWithEngines { fn hash(&self, state: &mut H, engines: &Engines); } diff --git a/sway-core/src/language/parsed/declaration/function.rs b/sway-core/src/language/parsed/declaration/function.rs index afd61ef54d3..716f545ef0e 100644 --- a/sway-core/src/language/parsed/declaration/function.rs +++ b/sway-core/src/language/parsed/declaration/function.rs @@ -1,7 +1,6 @@ use crate::{ engine_threading::*, language::{parsed::*, *}, - namespace::LexicalScopeId, transform::{self, AttributeKind}, type_system::*, }; @@ -29,7 +28,6 @@ pub struct FunctionDeclaration { pub where_clause: Vec<(Ident, Vec)>, pub kind: FunctionDeclarationKind, pub implementing_type: Option, - pub lexical_scope: LexicalScopeId, } impl EqWithEngines for FunctionDeclaration {} diff --git a/sway-core/src/language/ty/declaration/variable.rs b/sway-core/src/language/ty/declaration/variable.rs index 4b6663f8ba0..e19a4fb30a8 100644 --- a/sway-core/src/language/ty/declaration/variable.rs +++ b/sway-core/src/language/ty/declaration/variable.rs @@ -1,15 +1,10 @@ use std::hash::{Hash, Hasher}; -use sway_error::handler::{ErrorEmitted, Handler}; -use sway_types::Ident; +use sway_types::{Ident, Named, Spanned}; use crate::{ engine_threading::*, language::{parsed::VariableDeclaration, ty::*}, - semantic_analysis::{ - TypeCheckAnalysis, TypeCheckAnalysisContext, TypeCheckFinalization, - TypeCheckFinalizationContext, - }, type_system::*, }; @@ -26,6 +21,18 @@ impl TyDeclParsedType for TyVariableDecl { type ParsedType = VariableDeclaration; } +impl Named for TyVariableDecl { + fn name(&self) -> &sway_types::BaseIdent { + &self.name + } +} + +impl Spanned for TyVariableDecl { + fn span(&self) -> sway_types::Span { + self.name.span() + } +} + impl EqWithEngines for TyVariableDecl {} impl PartialEqWithEngines for TyVariableDecl { fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool { @@ -65,24 +72,3 @@ impl SubstTypes for TyVariableDecl { self.body.subst(type_mapping, ctx) } } - -impl TypeCheckAnalysis for TyVariableDecl { - fn type_check_analyze( - &self, - handler: &Handler, - ctx: &mut TypeCheckAnalysisContext, - ) -> Result<(), ErrorEmitted> { - self.body.type_check_analyze(handler, ctx)?; - Ok(()) - } -} - -impl TypeCheckFinalization for TyVariableDecl { - fn type_check_finalize( - &mut self, - handler: &Handler, - ctx: &mut TypeCheckFinalizationContext, - ) -> Result<(), ErrorEmitted> { - self.body.type_check_finalize(handler, ctx) - } -} diff --git a/sway-core/src/lib.rs b/sway-core/src/lib.rs index c744255156d..fcc524ce8a0 100644 --- a/sway-core/src/lib.rs +++ b/sway-core/src/lib.rs @@ -570,7 +570,7 @@ pub fn parsed_to_ast( let namespace = Namespace::init_root(initial_namespace); // Collect the program symbols. - let _collection_ctx = + let mut collection_ctx = ty::TyProgram::collect(handler, engines, parse_program, namespace.clone())?; // Type check the program. @@ -578,6 +578,7 @@ pub fn parsed_to_ast( handler, engines, parse_program, + &mut collection_ctx, namespace, package_name, build_config, diff --git a/sway-core/src/semantic_analysis/ast_node/code_block.rs b/sway-core/src/semantic_analysis/ast_node/code_block.rs index 731a02457bb..330b8e4e4e9 100644 --- a/sway-core/src/semantic_analysis/ast_node/code_block.rs +++ b/sway-core/src/semantic_analysis/ast_node/code_block.rs @@ -11,13 +11,15 @@ impl ty::TyCodeBlock { ctx: &mut SymbolCollectionContext, code_block: &CodeBlock, ) -> Result<(), ErrorEmitted> { - let _ = code_block - .contents - .iter() - .map(|node| ty::TyAstNode::collect(handler, engines, ctx, node)) - .filter_map(|res| res.ok()) - .collect::>(); - + let _ = ctx.scoped(engines, code_block.whole_block_span.clone(), |scoped_ctx| { + let _ = code_block + .contents + .iter() + .map(|node| ty::TyAstNode::collect(handler, engines, scoped_ctx, node)) + .filter_map(|res| res.ok()) + .collect::>(); + Ok(()) + }); Ok(()) } @@ -28,17 +30,21 @@ impl ty::TyCodeBlock { is_root: bool, ) -> Result { if !is_root { - let code_block_result = ctx.by_ref().scoped(|mut ctx| { - let evaluated_contents = code_block - .contents - .iter() - .filter_map(|node| ty::TyAstNode::type_check(handler, ctx.by_ref(), node).ok()) - .collect::>(); - Ok(ty::TyCodeBlock { - contents: evaluated_contents, - whole_block_span: code_block.whole_block_span.clone(), - }) - })?; + let code_block_result = + ctx.by_ref() + .scoped(handler, Some(code_block.span()), |mut ctx| { + let evaluated_contents = code_block + .contents + .iter() + .filter_map(|node| { + ty::TyAstNode::type_check(handler, ctx.by_ref(), node).ok() + }) + .collect::>(); + Ok(ty::TyCodeBlock { + contents: evaluated_contents, + whole_block_span: code_block.whole_block_span.clone(), + }) + })?; return Ok(code_block_result); } @@ -57,7 +63,7 @@ impl ty::TyCodeBlock { ctx.by_ref() .with_collecting_unifications() .with_code_block_first_pass(true) - .scoped(|mut ctx| { + .scoped(handler, Some(code_block.span()), |mut ctx| { code_block.contents.iter().for_each(|node| { ty::TyAstNode::type_check(&Handler::default(), ctx.by_ref(), node).ok(); }); @@ -66,18 +72,19 @@ impl ty::TyCodeBlock { ctx.engines.te().reapply_unifications(ctx.engines()); - ctx.by_ref().scoped(|mut ctx| { - let evaluated_contents = code_block - .contents - .iter() - .filter_map(|node| ty::TyAstNode::type_check(handler, ctx.by_ref(), node).ok()) - .collect::>(); + ctx.by_ref() + .scoped(handler, Some(code_block.span()), |mut ctx| { + let evaluated_contents = code_block + .contents + .iter() + .filter_map(|node| ty::TyAstNode::type_check(handler, ctx.by_ref(), node).ok()) + .collect::>(); - Ok(ty::TyCodeBlock { - contents: evaluated_contents, - whole_block_span: code_block.whole_block_span.clone(), + Ok(ty::TyCodeBlock { + contents: evaluated_contents, + whole_block_span: code_block.whole_block_span.clone(), + }) }) - }) } pub fn compute_return_type_and_span( diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/abi.rs b/sway-core/src/semantic_analysis/ast_node/declaration/abi.rs index 5e1c6196964..bb0bc9e2fb8 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/abi.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/abi.rs @@ -4,14 +4,17 @@ use sway_error::error::CompileError; use sway_types::{Ident, Named, Span, Spanned}; use crate::{ - decl_engine::{DeclEngineGetParsedDeclId, DeclEngineInsert, DeclEngineInsertArc, DeclId}, - language::ty::TyAbiDecl, + decl_engine::{ + parsed_id::ParsedDeclId, DeclEngineGetParsedDeclId, DeclEngineInsert, DeclEngineInsertArc, + DeclId, + }, + language::ty::{TyAbiDecl, TyFunctionDecl}, namespace::{IsExtendingExistingImpl, IsImplSelf, TryInsertingTraitImplOnFailure}, semantic_analysis::{ - TypeCheckAnalysis, TypeCheckAnalysisContext, TypeCheckFinalization, - TypeCheckFinalizationContext, + symbol_collection_context::SymbolCollectionContext, TypeCheckAnalysis, + TypeCheckAnalysisContext, TypeCheckFinalization, TypeCheckFinalizationContext, }, - TypeParameter, + Engines, TypeParameter, }; use sway_error::handler::{ErrorEmitted, Handler}; @@ -29,6 +32,33 @@ use crate::{ }; impl ty::TyAbiDecl { + pub(crate) fn collect( + handler: &Handler, + engines: &Engines, + ctx: &mut SymbolCollectionContext, + decl_id: &ParsedDeclId, + ) -> Result<(), ErrorEmitted> { + let abi_decl = engines.pe().get_abi(decl_id); + ctx.insert_parsed_symbol( + handler, + engines, + abi_decl.name.clone(), + Declaration::AbiDeclaration(*decl_id), + )?; + + let _ = ctx.scoped(engines, abi_decl.span.clone(), |scoped_ctx| { + abi_decl.interface_surface.iter().for_each(|item| { + let _ = TyTraitItem::collect(handler, engines, scoped_ctx, item); + }); + + abi_decl.methods.iter().for_each(|decl_id| { + let _ = TyFunctionDecl::collect(handler, engines, scoped_ctx, decl_id); + }); + Ok(()) + }); + Ok(()) + } + pub(crate) fn type_check( handler: &Handler, ctx: TypeCheckContext, @@ -55,7 +85,7 @@ impl ty::TyAbiDecl { // A temporary namespace for checking within this scope. ctx.with_abi_mode(AbiMode::ImplAbiFn(name.clone(), None)) .with_self_type(Some(self_type_id)) - .scoped(|mut ctx| { + .scoped(handler, Some(span.clone()), |mut ctx| { // Insert the "self" type param into the namespace. self_type_param.insert_self_type_into_namespace(handler, ctx.by_ref()); diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/auto_impl.rs b/sway-core/src/semantic_analysis/ast_node/declaration/auto_impl.rs index 7d31ce74e83..55ef6a25e79 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/auto_impl.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/auto_impl.rs @@ -324,7 +324,18 @@ where assert!(!handler.has_warnings(), "{:?}", handler); let ctx = self.ctx.by_ref(); - let r = ctx.scoped_and_namespace(|ctx| { + let _r = TyDecl::collect( + &handler, + engines, + ctx.collection_ctx, + Declaration::FunctionDeclaration(decl), + ); + if handler.has_errors() { + return Err(handler); + } + + let ctx = self.ctx.by_ref(); + let r = ctx.scoped_and_namespace(&handler, None, |ctx| { TyDecl::type_check( &handler, ctx, @@ -375,7 +386,17 @@ where assert!(!handler.has_errors(), "{:?}", handler); let ctx = self.ctx.by_ref(); - let r = ctx.scoped_and_namespace(|ctx| { + let _r = TyDecl::collect( + &handler, + engines, + ctx.collection_ctx, + Declaration::ImplSelfOrTrait(decl), + ); + if handler.has_errors() { + return Err(handler); + } + + let r = ctx.scoped_and_namespace(&handler, None, |ctx| { TyDecl::type_check(&handler, ctx, Declaration::ImplSelfOrTrait(decl)) }); diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/configurable.rs b/sway-core/src/semantic_analysis/ast_node/declaration/configurable.rs index 7619d1d2f02..3702214d9dd 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/configurable.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/configurable.rs @@ -6,19 +6,42 @@ use sway_error::{ warning::{CompileWarning, Warning}, }; use sway_types::{style::is_screaming_snake_case, Spanned}; +use symbol_collection_context::SymbolCollectionContext; use crate::{ - decl_engine::{DeclEngineGetParsedDeclId, DeclEngineInsert, ReplaceDecls}, + decl_engine::{ + parsed_id::ParsedDeclId, DeclEngineGetParsedDeclId, DeclEngineInsert, ReplaceDecls, + }, language::{ parsed::*, - ty::{self, TyConfigurableDecl}, + ty::{self, TyConfigurableDecl, TyExpression}, CallPath, }, semantic_analysis::{type_check_context::EnforceTypeArguments, *}, - SubstTypes, SubstTypesContext, TypeArgument, TypeBinding, TypeCheckTypeBinding, TypeInfo, + Engines, SubstTypes, SubstTypesContext, TypeArgument, TypeBinding, TypeCheckTypeBinding, + TypeInfo, }; impl ty::TyConfigurableDecl { + pub(crate) fn collect( + handler: &Handler, + engines: &Engines, + ctx: &mut SymbolCollectionContext, + decl_id: &ParsedDeclId, + ) -> Result<(), ErrorEmitted> { + let configurable_decl = engines.pe().get_configurable(decl_id); + ctx.insert_parsed_symbol( + handler, + engines, + configurable_decl.name.clone(), + Declaration::ConfigurableDeclaration(*decl_id), + )?; + if let Some(value) = &configurable_decl.value { + TyExpression::collect(handler, engines, ctx, value)?; + } + Ok(()) + } + pub fn type_check( handler: &Handler, mut ctx: TypeCheckContext, diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/constant.rs b/sway-core/src/semantic_analysis/ast_node/declaration/constant.rs index 4a9f903b282..63ad0a9bbb7 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/constant.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/constant.rs @@ -3,11 +3,13 @@ use sway_error::{ warning::{CompileWarning, Warning}, }; use sway_types::{style::is_screaming_snake_case, Spanned}; +use symbol_collection_context::SymbolCollectionContext; use crate::{ + decl_engine::parsed_id::ParsedDeclId, language::{ parsed::{self, *}, - ty::{self, TyConstantDecl}, + ty::{self, TyConstantDecl, TyExpression}, CallPath, }, semantic_analysis::{type_check_context::EnforceTypeArguments, *}, @@ -15,6 +17,25 @@ use crate::{ }; impl ty::TyConstantDecl { + pub(crate) fn collect( + handler: &Handler, + engines: &Engines, + ctx: &mut SymbolCollectionContext, + decl_id: &ParsedDeclId, + ) -> Result<(), ErrorEmitted> { + let constant_decl = engines.pe().get_constant(decl_id); + ctx.insert_parsed_symbol( + handler, + engines, + constant_decl.name.clone(), + Declaration::ConstantDeclaration(*decl_id), + )?; + if let Some(value) = &constant_decl.value { + TyExpression::collect(handler, engines, ctx, value)?; + } + Ok(()) + } + pub fn type_check( handler: &Handler, mut ctx: TypeCheckContext, diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/declaration.rs b/sway-core/src/semantic_analysis/ast_node/declaration/declaration.rs index 49a2b6a636e..34f48f85491 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/declaration.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/declaration.rs @@ -2,16 +2,17 @@ use sway_error::handler::{ErrorEmitted, Handler}; use sway_types::{Ident, Named, Spanned}; use crate::{ - decl_engine::{ - parsed_engine::ParsedDeclEngineReplace, DeclEngineGet, DeclEngineInsert, DeclRef, - ReplaceFunctionImplementingType, - }, + decl_engine::{DeclEngineGet, DeclEngineInsert, DeclRef, ReplaceFunctionImplementingType}, language::{ parsed::{self, StorageEntry}, - ty::{self, FunctionDecl, TyCodeBlock, TyDecl, TyStorageField}, + ty::{ + self, FunctionDecl, TyAbiDecl, TyConfigurableDecl, TyConstantDecl, TyDecl, TyEnumDecl, + TyFunctionDecl, TyImplSelfOrTrait, TyStorageDecl, TyStorageField, TyStructDecl, + TyTraitDecl, TyTraitFn, TyTraitType, TyTypeAliasDecl, TyVariableDecl, + }, CallPath, }, - namespace::{IsExtendingExistingImpl, IsImplSelf, ResolvedDeclaration}, + namespace::{IsExtendingExistingImpl, IsImplSelf}, semantic_analysis::{ symbol_collection_context::SymbolCollectionContext, type_check_context::EnforceTypeArguments, ConstShadowingMode, GenericShadowingMode, @@ -31,72 +32,44 @@ impl TyDecl { ) -> Result<(), ErrorEmitted> { match &decl { parsed::Declaration::VariableDeclaration(decl_id) => { - let var_decl = engines.pe().get_variable(decl_id); - ctx.insert_parsed_symbol(handler, engines, var_decl.name.clone(), decl)?; + TyVariableDecl::collect(handler, engines, ctx, decl_id)? } parsed::Declaration::ConstantDeclaration(decl_id) => { - let const_decl = engines.pe().get_constant(decl_id).as_ref().clone(); - ctx.insert_parsed_symbol(handler, engines, const_decl.name.clone(), decl)?; + TyConstantDecl::collect(handler, engines, ctx, decl_id)? } parsed::Declaration::ConfigurableDeclaration(decl_id) => { - let config_decl = engines.pe().get_configurable(decl_id).as_ref().clone(); - ctx.insert_parsed_symbol(handler, engines, config_decl.name.clone(), decl)?; + TyConfigurableDecl::collect(handler, engines, ctx, decl_id)? } parsed::Declaration::TraitTypeDeclaration(decl_id) => { - let trait_type_decl = engines.pe().get_trait_type(decl_id).as_ref().clone(); - ctx.insert_parsed_symbol(handler, engines, trait_type_decl.name.clone(), decl)?; + TyTraitType::collect(handler, engines, ctx, decl_id)? } parsed::Declaration::TraitFnDeclaration(decl_id) => { - let trait_fn_decl = engines.pe().get_trait_fn(decl_id).as_ref().clone(); - ctx.insert_parsed_symbol(handler, engines, trait_fn_decl.name.clone(), decl)?; + TyTraitFn::collect(handler, engines, ctx, decl_id)? } parsed::Declaration::EnumDeclaration(decl_id) => { - let enum_decl = engines.pe().get_enum(decl_id).as_ref().clone(); - ctx.insert_parsed_symbol(handler, engines, enum_decl.name.clone(), decl)?; + TyEnumDecl::collect(handler, engines, ctx, decl_id)? } parsed::Declaration::EnumVariantDeclaration(_decl) => {} parsed::Declaration::FunctionDeclaration(decl_id) => { - let decl_id = *decl_id; - let mut fn_decl = engines.pe().get_function(&decl_id).as_ref().clone(); - let _ = ctx.insert_parsed_symbol(handler, engines, fn_decl.name.clone(), decl); - let (_ret, lexical_scope_id) = ctx.scoped(engines, |scoped_ctx| { - TyCodeBlock::collect(handler, engines, scoped_ctx, &fn_decl.body) - }); - fn_decl.lexical_scope = lexical_scope_id; - engines.pe().replace(decl_id, fn_decl); + TyFunctionDecl::collect(handler, engines, ctx, decl_id)? } parsed::Declaration::TraitDeclaration(decl_id) => { - let trait_decl = engines.pe().get_trait(decl_id).as_ref().clone(); - ctx.insert_parsed_symbol(handler, engines, trait_decl.name.clone(), decl)?; + TyTraitDecl::collect(handler, engines, ctx, decl_id)? } parsed::Declaration::ImplSelfOrTrait(decl_id) => { - let impl_trait = engines - .pe() - .get_impl_self_or_trait(decl_id) - .as_ref() - .clone(); - ctx.insert_parsed_symbol( - handler, - engines, - impl_trait.trait_name.suffix.clone(), - decl, - )?; + TyImplSelfOrTrait::collect(handler, engines, ctx, decl_id)? } parsed::Declaration::StructDeclaration(decl_id) => { - let struct_decl = engines.pe().get_struct(decl_id).as_ref().clone(); - ctx.insert_parsed_symbol(handler, engines, struct_decl.name.clone(), decl)?; + TyStructDecl::collect(handler, engines, ctx, decl_id)? } parsed::Declaration::AbiDeclaration(decl_id) => { - let abi_decl = engines.pe().get_abi(decl_id).as_ref().clone(); - ctx.insert_parsed_symbol(handler, engines, abi_decl.name.clone(), decl)?; + TyAbiDecl::collect(handler, engines, ctx, decl_id)? } parsed::Declaration::StorageDeclaration(decl_id) => { - let _storage_decl = engines.pe().get_storage(decl_id).as_ref().clone(); - //ctx.insert_parsed_symbol(handler, storage_decl.name.clone(), decl)?; + TyStorageDecl::collect(handler, engines, ctx, decl_id)? } parsed::Declaration::TypeAliasDeclaration(decl_id) => { - let type_alias_decl = engines.pe().get_type_alias(decl_id).as_ref().clone(); - ctx.insert_parsed_symbol(handler, engines, type_alias_decl.name, decl.clone())?; + TyTypeAliasDecl::collect(handler, engines, ctx, decl_id)? } }; @@ -114,89 +87,15 @@ impl TyDecl { let decl = match decl { parsed::Declaration::VariableDeclaration(decl_id) => { - let var_decl = engines.pe().get_variable(&decl_id); - let mut type_ascription = var_decl.type_ascription.clone(); - - type_ascription.type_id = ctx - .resolve_type( - handler, - type_ascription.type_id, - &type_ascription.span, - EnforceTypeArguments::Yes, - None, - ) - .unwrap_or_else(|err| { - type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None) - }); - let mut ctx = ctx - .with_type_annotation(type_ascription.type_id) - .with_help_text( - "Variable declaration's type annotation does not match up \ - with the assigned expression's type.", - ); - let result = ty::TyExpression::type_check(handler, ctx.by_ref(), &var_decl.body); - let body = result.unwrap_or_else(|err| { - ty::TyExpression::error(err, var_decl.name.span(), engines) - }); - - // TODO: Integers shouldn't be anything special. RHS expressions should be written in - // a way to always use the context provided from the LHS, and if the LHS is - // an integer, RHS should properly unify or type check should fail. - // Remove this special case as a part of the initiative of improving type inference. - // Integers are special in the sense that we can't only rely on the type of `body` - // to get the type of the variable. The type of the variable *has* to follow - // `type_ascription` if `type_ascription` is a concrete integer type that does not - // conflict with the type of `body` (i.e. passes the type checking above). - let return_type = match &*type_engine.get(type_ascription.type_id) { - TypeInfo::UnsignedInteger(_) => type_ascription.type_id, - _ => match &*type_engine.get(body.return_type) { - // If RHS type check ends up in an error we want to use the - // provided type ascription as the variable type. E.g.: - // let v: Struct = Struct { x: 0 }; // `v` should be "Struct". - // let v: ExistingType = non_existing_identifier; // `v` should be "ExistingType". - // let v = ; // `v` will remain "{unknown}". - // TODO: Refine and improve this further. E.g., - // let v: Struct { /* MISSING FIELDS */ }; // Despite the error, `v` should be of type "Struct". - TypeInfo::ErrorRecovery(_) => type_ascription.type_id, - _ => body.return_type, - }, + let decl = engines.pe().get_variable(&decl_id).as_ref().clone(); + let name = decl.name.clone(); + let span = decl.name.span(); + let var_decl = match ty::TyVariableDecl::type_check(handler, ctx.by_ref(), decl) { + Ok(res) => res, + Err(err) => return Ok(ty::TyDecl::ErrorRecovery(span, err)), }; - - if !ctx.code_block_first_pass() { - let previous_symbol = ctx - .namespace() - .module(engines) - .current_items() - .check_symbols_unique_while_collecting_unifications(&var_decl.name.clone()) - .ok(); - - if let Some(ResolvedDeclaration::Typed(ty::TyDecl::VariableDecl( - variable_decl, - ))) = previous_symbol - { - type_engine.unify( - handler, - engines, - body.return_type, - variable_decl.body.return_type, - &decl.span(engines), - "", - None, - ); - } - } - - let typed_var_decl = ty::TyDecl::VariableDecl(Box::new(ty::TyVariableDecl { - name: var_decl.name.clone(), - body, - mutability: ty::VariableMutability::new_from_ref_mut( - false, - var_decl.is_mutable, - ), - return_type, - type_ascription, - })); - ctx.insert_symbol(handler, var_decl.name.clone(), typed_var_decl.clone())?; + let typed_var_decl = ty::TyDecl::VariableDecl(Box::new(var_decl)); + ctx.insert_symbol(handler, name, typed_var_decl.clone())?; typed_var_decl } parsed::Declaration::ConstantDeclaration(decl_id) => { @@ -665,8 +564,8 @@ impl TypeCheckAnalysis for TyDecl { ctx: &mut TypeCheckAnalysisContext, ) -> Result<(), ErrorEmitted> { match self { - TyDecl::VariableDecl(node) => { - node.type_check_analyze(handler, ctx)?; + TyDecl::VariableDecl(var_decl) => { + var_decl.type_check_analyze(handler, ctx)?; } TyDecl::ConstantDecl(node) => { let const_decl = ctx.engines.de().get_constant(&node.decl_id); diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs b/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs index f07975ee2d7..7dc878e858f 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs @@ -1,11 +1,33 @@ use crate::{ + decl_engine::parsed_id::ParsedDeclId, language::{parsed::*, ty, CallPath}, semantic_analysis::{type_check_context::EnforceTypeArguments, *}, type_system::*, + Engines, }; use sway_error::handler::{ErrorEmitted, Handler}; +use symbol_collection_context::SymbolCollectionContext; impl ty::TyEnumDecl { + pub(crate) fn collect( + handler: &Handler, + engines: &Engines, + ctx: &mut SymbolCollectionContext, + decl_id: &ParsedDeclId, + ) -> Result<(), ErrorEmitted> { + let enum_decl = engines.pe().get_enum(decl_id); + ctx.insert_parsed_symbol( + handler, + engines, + enum_decl.name.clone(), + Declaration::EnumDeclaration(*decl_id), + )?; + + // create a namespace for the decl, used to create a scope for generics + let _ = ctx.scoped(engines, enum_decl.span.clone(), |mut _ctx| Ok(())); + Ok(()) + } + pub fn type_check( handler: &Handler, ctx: TypeCheckContext, @@ -22,7 +44,7 @@ impl ty::TyEnumDecl { } = decl; // create a namespace for the decl, used to create a scope for generics - ctx.scoped(|mut ctx| { + ctx.scoped(handler, Some(span.clone()), |mut ctx| { // Type check the type parameters. let new_type_parameters = TypeParameter::type_check_type_params( handler, diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/function.rs b/sway-core/src/semantic_analysis/ast_node/declaration/function.rs index 6582c0d3c87..7ce58ac20cb 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/function.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/function.rs @@ -5,9 +5,10 @@ use sway_error::{ handler::{ErrorEmitted, Handler}, warning::{CompileWarning, Warning}, }; +use symbol_collection_context::SymbolCollectionContext; use crate::{ - decl_engine::{DeclId, DeclRefFunction}, + decl_engine::{parsed_id::ParsedDeclId, DeclId, DeclRefFunction}, language::{ parsed::*, ty::{self, TyCodeBlock, TyFunctionDecl}, @@ -15,10 +16,32 @@ use crate::{ }, semantic_analysis::{type_check_context::EnforceTypeArguments, *}, type_system::*, + Engines, }; use sway_types::{style::is_snake_case, Spanned}; impl ty::TyFunctionDecl { + pub(crate) fn collect( + handler: &Handler, + engines: &Engines, + ctx: &mut SymbolCollectionContext, + decl_id: &ParsedDeclId, + ) -> Result<(), ErrorEmitted> { + let fn_decl = engines.pe().get_function(decl_id); + let _ = ctx.insert_parsed_symbol( + handler, + engines, + fn_decl.name.clone(), + Declaration::FunctionDeclaration(*decl_id), + ); + + // create a namespace for the function + let _ = ctx.scoped(engines, fn_decl.span.clone(), |scoped_ctx| { + TyCodeBlock::collect(handler, engines, scoped_ctx, &fn_decl.body) + }); + Ok(()) + } + pub fn type_check( handler: &Handler, mut ctx: TypeCheckContext, @@ -85,7 +108,7 @@ impl ty::TyFunctionDecl { ctx.by_ref() .with_const_shadowing_mode(ConstShadowingMode::Sequential) .disallow_functions() - .scoped(|mut ctx| { + .scoped(handler, Some(span.clone()), |mut ctx| { // Type check the type parameters. let new_type_parameters = TypeParameter::type_check_type_params( handler, @@ -182,7 +205,7 @@ impl ty::TyFunctionDecl { ctx.by_ref() .with_const_shadowing_mode(ConstShadowingMode::Sequential) .disallow_functions() - .scoped(|mut ctx| { + .scoped(handler, Some(fn_decl.span.clone()), |mut ctx| { let FunctionDeclaration { body, .. } = fn_decl; let ty::TyFunctionDecl { diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs b/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs index 5d47d1616d7..f47a6c055cc 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs @@ -15,11 +15,15 @@ use crate::{ engine_threading::*, language::{ parsed::*, - ty::{self, TyDecl, TyImplItem, TyImplSelfOrTrait, TyTraitInterfaceItem, TyTraitItem}, + ty::{ + self, TyConstantDecl, TyDecl, TyFunctionDecl, TyImplItem, TyImplSelfOrTrait, + TyTraitInterfaceItem, TyTraitItem, TyTraitType, + }, *, }, namespace::{IsExtendingExistingImpl, IsImplSelf, TryInsertingTraitImplOnFailure}, semantic_analysis::{ + symbol_collection_context::SymbolCollectionContext, type_check_context::EnforceTypeArguments, AbiMode, ConstShadowingMode, TyNodeDepGraphNodeId, TypeCheckAnalysis, TypeCheckAnalysisContext, TypeCheckContext, TypeCheckFinalization, TypeCheckFinalizationContext, @@ -28,6 +32,37 @@ use crate::{ }; impl TyImplSelfOrTrait { + pub(crate) fn collect( + handler: &Handler, + engines: &Engines, + ctx: &mut SymbolCollectionContext, + decl_id: &ParsedDeclId, + ) -> Result<(), ErrorEmitted> { + let impl_trait = engines.pe().get_impl_self_or_trait(decl_id); + ctx.insert_parsed_symbol( + handler, + engines, + impl_trait.trait_name.suffix.clone(), + Declaration::ImplSelfOrTrait(*decl_id), + )?; + + let _ = ctx.scoped(engines, impl_trait.block_span.clone(), |scoped_ctx| { + impl_trait.items.iter().for_each(|item| match item { + ImplItem::Fn(decl_id) => { + let _ = TyFunctionDecl::collect(handler, engines, scoped_ctx, decl_id); + } + ImplItem::Constant(decl_id) => { + let _ = TyConstantDecl::collect(handler, engines, scoped_ctx, decl_id); + } + ImplItem::Type(decl_id) => { + let _ = TyTraitType::collect(handler, engines, scoped_ctx, decl_id); + } + }); + Ok(()) + }); + Ok(()) + } + pub(crate) fn type_check_impl_trait( handler: &Handler, mut ctx: TypeCheckContext, @@ -57,7 +92,7 @@ impl TyImplSelfOrTrait { .with_const_shadowing_mode(ConstShadowingMode::ItemStyle) .with_self_type(Some(self_type_id)) .allow_functions() - .scoped(|mut ctx| { + .scoped(handler, Some(block_span.clone()), |mut ctx| { // Type check the type parameters let new_impl_type_parameters = TypeParameter::type_check_type_params( handler, @@ -304,7 +339,7 @@ impl TyImplSelfOrTrait { // create the namespace for the impl ctx.with_const_shadowing_mode(ConstShadowingMode::ItemStyle) .allow_functions() - .scoped(|mut ctx| { + .scoped(handler, Some(block_span.clone()), |mut ctx| { // Create a new type parameter for the "self type". let self_type_param = TypeParameter::new_self_type(engines, implementing_for.span()); diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/mod.rs b/sway-core/src/semantic_analysis/ast_node/declaration/mod.rs index 525055e892e..ba84c359614 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/mod.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/mod.rs @@ -14,5 +14,6 @@ mod r#trait; mod trait_fn; mod trait_type; mod type_alias; +mod variable; pub(crate) use supertrait::*; diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/storage.rs b/sway-core/src/semantic_analysis/ast_node/declaration/storage.rs index 8b0028f7333..08e0984b7ed 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/storage.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/storage.rs @@ -1,16 +1,20 @@ use std::collections::HashMap; use crate::{ + decl_engine::parsed_id::ParsedDeclId, fuel_prelude::fuel_tx::StorageSlot, ir_generation::{ const_eval::compile_constant_expression_to_constant, storage::{get_storage_key_string, serialize_to_storage_slots}, }, - language::ty::{self, TyExpression, TyStorageField}, + language::{ + parsed::StorageDeclaration, + ty::{self, TyExpression, TyStorageField}, + }, metadata::MetadataManager, semantic_analysis::{ - TypeCheckAnalysis, TypeCheckAnalysisContext, TypeCheckFinalization, - TypeCheckFinalizationContext, + symbol_collection_context::SymbolCollectionContext, TypeCheckAnalysis, + TypeCheckAnalysisContext, TypeCheckFinalization, TypeCheckFinalizationContext, }, Engines, }; @@ -24,6 +28,15 @@ use sway_ir::{ConstantValue, Context, Module}; use sway_types::{u256::U256, Spanned}; impl ty::TyStorageDecl { + pub(crate) fn collect( + _handler: &Handler, + _engines: &Engines, + _ctx: &mut SymbolCollectionContext, + _decl_id: &ParsedDeclId, + ) -> Result<(), ErrorEmitted> { + Ok(()) + } + pub(crate) fn get_initialized_storage_slots( &self, handler: &Handler, diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs b/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs index a04efa0f274..77688776b3b 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs @@ -1,11 +1,33 @@ use crate::{ + decl_engine::parsed_id::ParsedDeclId, language::{parsed::*, ty, CallPath}, semantic_analysis::{type_check_context::EnforceTypeArguments, *}, type_system::*, + Engines, }; use sway_error::handler::{ErrorEmitted, Handler}; +use symbol_collection_context::SymbolCollectionContext; impl ty::TyStructDecl { + pub(crate) fn collect( + handler: &Handler, + engines: &Engines, + ctx: &mut SymbolCollectionContext, + decl_id: &ParsedDeclId, + ) -> Result<(), ErrorEmitted> { + let struct_decl = engines.pe().get_struct(decl_id); + ctx.insert_parsed_symbol( + handler, + engines, + struct_decl.name.clone(), + Declaration::StructDeclaration(*decl_id), + )?; + + // create a namespace for the decl, used to create a scope for generics + let _ = ctx.scoped(engines, struct_decl.span.clone(), |_scoped_ctx| Ok(())); + Ok(()) + } + pub(crate) fn type_check( handler: &Handler, ctx: TypeCheckContext, @@ -22,7 +44,7 @@ impl ty::TyStructDecl { } = decl; // create a namespace for the decl, used to create a scope for generics - ctx.scoped(|mut ctx| { + ctx.scoped(handler, Some(span.clone()), |mut ctx| { // Type check the type parameters. let new_type_parameters = TypeParameter::type_check_type_params( handler, diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs b/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs index 552bab4bba8..6beb4ea7f4f 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs @@ -1,5 +1,6 @@ use std::collections::{BTreeMap, HashSet}; +use parsed_id::ParsedDeclId; use sway_error::{ error::CompileError, handler::{ErrorEmitted, Handler}, @@ -11,19 +12,68 @@ use crate::{ decl_engine::*, language::{ parsed::*, - ty::{self, TyImplItem, TyTraitDecl, TyTraitItem}, + ty::{ + self, TyConstantDecl, TyFunctionDecl, TyImplItem, TyTraitDecl, TyTraitFn, TyTraitItem, + TyTraitType, + }, CallPath, }, namespace::{IsExtendingExistingImpl, IsImplSelf}, semantic_analysis::{ declaration::{insert_supertraits_into_namespace, SupertraitOf}, + symbol_collection_context::SymbolCollectionContext, AbiMode, TypeCheckAnalysis, TypeCheckAnalysisContext, TypeCheckContext, TypeCheckFinalization, TypeCheckFinalizationContext, }, type_system::*, + Engines, }; +impl TyTraitItem { + pub(crate) fn collect( + handler: &Handler, + engines: &Engines, + ctx: &mut SymbolCollectionContext, + item: &TraitItem, + ) -> Result<(), ErrorEmitted> { + match item { + TraitItem::TraitFn(decl_id) => TyTraitFn::collect(handler, engines, ctx, decl_id), + TraitItem::Constant(decl_id) => TyConstantDecl::collect(handler, engines, ctx, decl_id), + TraitItem::Type(decl_id) => TyTraitType::collect(handler, engines, ctx, decl_id), + TraitItem::Error(_, _) => Ok(()), + } + } +} + impl TyTraitDecl { + pub(crate) fn collect( + handler: &Handler, + engines: &Engines, + ctx: &mut SymbolCollectionContext, + decl_id: &ParsedDeclId, + ) -> Result<(), ErrorEmitted> { + let trait_decl = engines.pe().get_trait(decl_id); + ctx.insert_parsed_symbol( + handler, + engines, + trait_decl.name.clone(), + Declaration::TraitDeclaration(*decl_id), + )?; + + // A temporary namespace for checking within the trait's scope. + let _ = ctx.scoped(engines, trait_decl.span.clone(), |scoped_ctx| { + trait_decl.interface_surface.iter().for_each(|item| { + let _ = TyTraitItem::collect(handler, engines, scoped_ctx, item); + }); + + trait_decl.methods.iter().for_each(|decl_id| { + let _ = TyFunctionDecl::collect(handler, engines, scoped_ctx, decl_id); + }); + Ok(()) + }); + Ok(()) + } + pub(crate) fn type_check( handler: &Handler, ctx: TypeCheckContext, @@ -55,172 +105,177 @@ impl TyTraitDecl { let self_type = self_type_param.type_id; // A temporary namespace for checking within the trait's scope. - ctx.with_self_type(Some(self_type)).scoped(|mut ctx| { - // Type check the type parameters. - let new_type_parameters = TypeParameter::type_check_type_params( - handler, - ctx.by_ref(), - type_parameters, - Some(self_type_param.clone()), - )?; - - // Recursively make the interface surfaces and methods of the - // supertraits available to this trait. - insert_supertraits_into_namespace( - handler, - ctx.by_ref(), - self_type, - &supertraits, - &SupertraitOf::Trait, - )?; - - // type check the interface surface - let mut new_interface_surface = vec![]; - let mut dummy_interface_surface = vec![]; - - let mut ids: HashSet = HashSet::default(); - - for item in interface_surface.clone().into_iter() { - let decl_name = match item { - TraitItem::TraitFn(_) => None, - TraitItem::Constant(_) => None, - TraitItem::Type(decl_id) => { - let type_decl = engines.pe().get_trait_type(&decl_id).as_ref().clone(); - let type_decl = - ty::TyTraitType::type_check(handler, ctx.by_ref(), type_decl.clone())?; - let decl_ref = decl_engine.insert(type_decl.clone(), Some(&decl_id)); - dummy_interface_surface.push(ty::TyImplItem::Type(decl_ref.clone())); - new_interface_surface - .push(ty::TyTraitInterfaceItem::Type(decl_ref.clone())); - - Some(type_decl.name) - } - TraitItem::Error(_, _) => None, - }; + ctx.with_self_type(Some(self_type)) + .scoped(handler, Some(span.clone()), |mut ctx| { + // Type check the type parameters. + let new_type_parameters = TypeParameter::type_check_type_params( + handler, + ctx.by_ref(), + type_parameters, + Some(self_type_param.clone()), + )?; - if let Some(decl_name) = decl_name { - if !ids.insert(decl_name.clone()) { - handler.emit_err(CompileError::MultipleDefinitionsOfName { - name: decl_name.clone(), - span: decl_name.span(), - }); + // Recursively make the interface surfaces and methods of the + // supertraits available to this trait. + insert_supertraits_into_namespace( + handler, + ctx.by_ref(), + self_type, + &supertraits, + &SupertraitOf::Trait, + )?; + + // type check the interface surface + let mut new_interface_surface = vec![]; + let mut dummy_interface_surface = vec![]; + + let mut ids: HashSet = HashSet::default(); + + for item in interface_surface.clone().into_iter() { + let decl_name = match item { + TraitItem::TraitFn(_) => None, + TraitItem::Constant(_) => None, + TraitItem::Type(decl_id) => { + let type_decl = engines.pe().get_trait_type(&decl_id).as_ref().clone(); + let type_decl = ty::TyTraitType::type_check( + handler, + ctx.by_ref(), + type_decl.clone(), + )?; + let decl_ref = decl_engine.insert(type_decl.clone(), Some(&decl_id)); + dummy_interface_surface.push(ty::TyImplItem::Type(decl_ref.clone())); + new_interface_surface + .push(ty::TyTraitInterfaceItem::Type(decl_ref.clone())); + + Some(type_decl.name) + } + TraitItem::Error(_, _) => None, + }; + + if let Some(decl_name) = decl_name { + if !ids.insert(decl_name.clone()) { + handler.emit_err(CompileError::MultipleDefinitionsOfName { + name: decl_name.clone(), + span: decl_name.span(), + }); + } } } - } - // insert placeholder functions representing the interface surface - // to allow methods to use those functions - ctx.insert_trait_implementation( - handler, - CallPath::ident_to_fullpath(name.clone(), ctx.namespace), - new_type_parameters.iter().map(|x| x.into()).collect(), - self_type, - &dummy_interface_surface, - &span, - None, - IsImplSelf::No, - IsExtendingExistingImpl::No, - )?; - let mut dummy_interface_surface = vec![]; - - for item in interface_surface.into_iter() { - let decl_name = match item { - TraitItem::TraitFn(decl_id) => { - let method = engines.pe().get_trait_fn(&decl_id); - let method = ty::TyTraitFn::type_check(handler, ctx.by_ref(), &method)?; - let decl_ref = decl_engine.insert(method.clone(), Some(&decl_id)); - dummy_interface_surface.push(ty::TyImplItem::Fn( - decl_engine - .insert( - method.to_dummy_func(AbiMode::NonAbi, Some(self_type)), - None, - ) - .with_parent(decl_engine, (*decl_ref.id()).into()), - )); - new_interface_surface.push(ty::TyTraitInterfaceItem::TraitFn(decl_ref)); - Some(method.name.clone()) - } - TraitItem::Constant(decl_id) => { - let const_decl = engines.pe().get_constant(&decl_id).as_ref().clone(); - let const_decl = - ty::TyConstantDecl::type_check(handler, ctx.by_ref(), const_decl)?; - let decl_ref = ctx.engines.de().insert(const_decl.clone(), Some(&decl_id)); - new_interface_surface - .push(ty::TyTraitInterfaceItem::Constant(decl_ref.clone())); - - let const_name = const_decl.call_path.suffix.clone(); - ctx.insert_symbol( - handler, - const_name.clone(), - ty::TyDecl::ConstantDecl(ty::ConstantDecl { - decl_id: *decl_ref.id(), - }), - )?; - - Some(const_name) - } - TraitItem::Type(_) => None, - TraitItem::Error(_, _) => { - continue; - } - }; + // insert placeholder functions representing the interface surface + // to allow methods to use those functions + ctx.insert_trait_implementation( + handler, + CallPath::ident_to_fullpath(name.clone(), ctx.namespace), + new_type_parameters.iter().map(|x| x.into()).collect(), + self_type, + &dummy_interface_surface, + &span, + None, + IsImplSelf::No, + IsExtendingExistingImpl::No, + )?; + let mut dummy_interface_surface = vec![]; + + for item in interface_surface.into_iter() { + let decl_name = match item { + TraitItem::TraitFn(decl_id) => { + let method = engines.pe().get_trait_fn(&decl_id); + let method = ty::TyTraitFn::type_check(handler, ctx.by_ref(), &method)?; + let decl_ref = decl_engine.insert(method.clone(), Some(&decl_id)); + dummy_interface_surface.push(ty::TyImplItem::Fn( + decl_engine + .insert( + method.to_dummy_func(AbiMode::NonAbi, Some(self_type)), + None, + ) + .with_parent(decl_engine, (*decl_ref.id()).into()), + )); + new_interface_surface.push(ty::TyTraitInterfaceItem::TraitFn(decl_ref)); + Some(method.name.clone()) + } + TraitItem::Constant(decl_id) => { + let const_decl = engines.pe().get_constant(&decl_id).as_ref().clone(); + let const_decl = + ty::TyConstantDecl::type_check(handler, ctx.by_ref(), const_decl)?; + let decl_ref = + ctx.engines.de().insert(const_decl.clone(), Some(&decl_id)); + new_interface_surface + .push(ty::TyTraitInterfaceItem::Constant(decl_ref.clone())); + + let const_name = const_decl.call_path.suffix.clone(); + ctx.insert_symbol( + handler, + const_name.clone(), + ty::TyDecl::ConstantDecl(ty::ConstantDecl { + decl_id: *decl_ref.id(), + }), + )?; + + Some(const_name) + } + TraitItem::Type(_) => None, + TraitItem::Error(_, _) => { + continue; + } + }; - if let Some(decl_name) = decl_name { - if !ids.insert(decl_name.clone()) { - handler.emit_err(CompileError::MultipleDefinitionsOfName { - name: decl_name.clone(), - span: decl_name.span(), - }); + if let Some(decl_name) = decl_name { + if !ids.insert(decl_name.clone()) { + handler.emit_err(CompileError::MultipleDefinitionsOfName { + name: decl_name.clone(), + span: decl_name.span(), + }); + } } } - } - // insert placeholder functions representing the interface surface - // to allow methods to use those functions - ctx.insert_trait_implementation( - handler, - CallPath::ident_to_fullpath(name.clone(), ctx.namespace()), - new_type_parameters.iter().map(|x| x.into()).collect(), - self_type, - &dummy_interface_surface, - &span, - None, - IsImplSelf::No, - IsExtendingExistingImpl::Yes, - )?; - - // Type check the items. - let mut new_items = vec![]; - for method_decl_id in methods.into_iter() { - let method = engines.pe().get_function(&method_decl_id); - let method = ty::TyFunctionDecl::type_check( + // insert placeholder functions representing the interface surface + // to allow methods to use those functions + ctx.insert_trait_implementation( handler, - ctx.by_ref(), - &method, - true, - false, - Some(self_type_param.type_id), - ) - .unwrap_or_else(|_| ty::TyFunctionDecl::error(&method)); - new_items.push(ty::TyTraitItem::Fn( - decl_engine.insert(method, Some(&method_decl_id)), - )); - } + CallPath::ident_to_fullpath(name.clone(), ctx.namespace()), + new_type_parameters.iter().map(|x| x.into()).collect(), + self_type, + &dummy_interface_surface, + &span, + None, + IsImplSelf::No, + IsExtendingExistingImpl::Yes, + )?; + + // Type check the items. + let mut new_items = vec![]; + for method_decl_id in methods.into_iter() { + let method = engines.pe().get_function(&method_decl_id); + let method = ty::TyFunctionDecl::type_check( + handler, + ctx.by_ref(), + &method, + true, + false, + Some(self_type_param.type_id), + ) + .unwrap_or_else(|_| ty::TyFunctionDecl::error(&method)); + new_items.push(ty::TyTraitItem::Fn( + decl_engine.insert(method, Some(&method_decl_id)), + )); + } - let typed_trait_decl = ty::TyTraitDecl { - name: name.clone(), - type_parameters: new_type_parameters, - self_type: self_type_param, - interface_surface: new_interface_surface, - items: new_items, - supertraits, - visibility, - attributes, - call_path: CallPath::from(name).to_fullpath(ctx.engines(), ctx.namespace()), - span, - }; - Ok(typed_trait_decl) - }) + let typed_trait_decl = ty::TyTraitDecl { + name: name.clone(), + type_parameters: new_type_parameters, + self_type: self_type_param, + interface_surface: new_interface_surface, + items: new_items, + supertraits, + visibility, + attributes, + call_path: CallPath::from(name).to_fullpath(ctx.engines(), ctx.namespace()), + span, + }; + Ok(typed_trait_decl) + }) } /// Retrieves the interface surface and implemented items for this trait. diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/trait_fn.rs b/sway-core/src/semantic_analysis/ast_node/declaration/trait_fn.rs index 241fb856db7..e6b45f08919 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/trait_fn.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/trait_fn.rs @@ -1,9 +1,16 @@ use sway_types::Spanned; use crate::{ - decl_engine::DeclId, - language::{parsed, ty, CallPath, Visibility}, - semantic_analysis::type_check_context::EnforceTypeArguments, + decl_engine::{parsed_id::ParsedDeclId, DeclId}, + language::{ + parsed::{self, Declaration, TraitFn}, + ty, CallPath, Visibility, + }, + semantic_analysis::{ + symbol_collection_context::SymbolCollectionContext, + type_check_context::EnforceTypeArguments, + }, + Engines, }; use sway_error::handler::{ErrorEmitted, Handler}; @@ -13,6 +20,23 @@ use crate::{ }; impl ty::TyTraitFn { + pub(crate) fn collect( + handler: &Handler, + engines: &Engines, + ctx: &mut SymbolCollectionContext, + decl_id: &ParsedDeclId, + ) -> Result<(), ErrorEmitted> { + let trait_fn = engines.pe().get_trait_fn(decl_id); + ctx.insert_parsed_symbol( + handler, + engines, + trait_fn.name.clone(), + Declaration::TraitFnDeclaration(*decl_id), + )?; + let _ = ctx.scoped(engines, trait_fn.span.clone(), |_scoped_ctx| Ok(())); + Ok(()) + } + pub(crate) fn type_check( handler: &Handler, mut ctx: TypeCheckContext, @@ -31,7 +55,7 @@ impl ty::TyTraitFn { let engines = ctx.engines(); // Create a namespace for the trait function. - ctx.by_ref().scoped(|mut ctx| { + ctx.by_ref().scoped(handler, Some(span.clone()), |mut ctx| { // TODO: when we add type parameters to trait fns, type check them here // Type check the parameters. diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/trait_type.rs b/sway-core/src/semantic_analysis/ast_node/declaration/trait_type.rs index 103c721321e..c387ecdb27b 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/trait_type.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/trait_type.rs @@ -5,11 +5,13 @@ use sway_error::{ use sway_types::Span; use crate::{ + decl_engine::parsed_id::ParsedDeclId, language::{ - parsed, + parsed::{self, Declaration, TraitTypeDeclaration}, ty::{self, TyTraitType}, }, semantic_analysis::{ + symbol_collection_context::SymbolCollectionContext, type_check_context::EnforceTypeArguments, TypeCheckAnalysis, TypeCheckAnalysisContext, TypeCheckContext, }, @@ -18,6 +20,21 @@ use crate::{ }; impl ty::TyTraitType { + pub(crate) fn collect( + handler: &Handler, + engines: &Engines, + ctx: &mut SymbolCollectionContext, + decl_id: &ParsedDeclId, + ) -> Result<(), ErrorEmitted> { + let trait_type_decl = engines.pe().get_trait_type(decl_id); + ctx.insert_parsed_symbol( + handler, + engines, + trait_type_decl.name.clone(), + Declaration::TraitTypeDeclaration(*decl_id), + ) + } + pub(crate) fn type_check( handler: &Handler, mut ctx: TypeCheckContext, diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/type_alias.rs b/sway-core/src/semantic_analysis/ast_node/declaration/type_alias.rs index 90eb2ad673e..7bcf3fb06c3 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/type_alias.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/type_alias.rs @@ -1,9 +1,34 @@ use crate::{ - language::ty::TyTypeAliasDecl, - semantic_analysis::{TypeCheckFinalization, TypeCheckFinalizationContext}, + decl_engine::parsed_id::ParsedDeclId, + language::{ + parsed::{Declaration, TypeAliasDeclaration}, + ty::TyTypeAliasDecl, + }, + semantic_analysis::{ + symbol_collection_context::SymbolCollectionContext, TypeCheckFinalization, + TypeCheckFinalizationContext, + }, + Engines, }; use sway_error::handler::{ErrorEmitted, Handler}; +impl TyTypeAliasDecl { + pub(crate) fn collect( + handler: &Handler, + engines: &Engines, + ctx: &mut SymbolCollectionContext, + decl_id: &ParsedDeclId, + ) -> Result<(), ErrorEmitted> { + let type_alias = engines.pe().get_type_alias(decl_id); + ctx.insert_parsed_symbol( + handler, + engines, + type_alias.name.clone(), + Declaration::TypeAliasDeclaration(*decl_id), + ) + } +} + impl TypeCheckFinalization for TyTypeAliasDecl { fn type_check_finalize( &mut self, diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/variable.rs b/sway-core/src/semantic_analysis/ast_node/declaration/variable.rs new file mode 100644 index 00000000000..32dccb078db --- /dev/null +++ b/sway-core/src/semantic_analysis/ast_node/declaration/variable.rs @@ -0,0 +1,139 @@ +use crate::{ + decl_engine::parsed_id::ParsedDeclId, + language::{ + parsed::*, + ty::{self, TyExpression, TyVariableDecl}, + }, + namespace::ResolvedDeclaration, + semantic_analysis::{type_check_context::EnforceTypeArguments, *}, + type_system::*, + Engines, +}; +use sway_error::handler::{ErrorEmitted, Handler}; +use sway_types::Spanned; +use symbol_collection_context::SymbolCollectionContext; + +impl ty::TyVariableDecl { + pub(crate) fn collect( + handler: &Handler, + engines: &Engines, + ctx: &mut SymbolCollectionContext, + decl_id: &ParsedDeclId, + ) -> Result<(), ErrorEmitted> { + let var_decl = engines.pe().get_variable(decl_id); + ctx.insert_parsed_symbol( + handler, + engines, + var_decl.name.clone(), + Declaration::VariableDeclaration(*decl_id), + )?; + TyExpression::collect(handler, engines, ctx, &var_decl.body) + } + + pub fn type_check( + handler: &Handler, + mut ctx: TypeCheckContext, + var_decl: VariableDeclaration, + ) -> Result { + let engines = &ctx.engines(); + let type_engine = engines.te(); + + let mut type_ascription = var_decl.type_ascription.clone(); + + type_ascription.type_id = ctx + .resolve_type( + handler, + type_ascription.type_id, + &type_ascription.span, + EnforceTypeArguments::Yes, + None, + ) + .unwrap_or_else(|err| type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None)); + let mut ctx = ctx + .with_type_annotation(type_ascription.type_id) + .with_help_text( + "Variable declaration's type annotation does not match up \ + with the assigned expression's type.", + ); + let result = ty::TyExpression::type_check(handler, ctx.by_ref(), &var_decl.body); + let body = result + .unwrap_or_else(|err| ty::TyExpression::error(err, var_decl.name.span(), engines)); + + // TODO: Integers shouldn't be anything special. RHS expressions should be written in + // a way to always use the context provided from the LHS, and if the LHS is + // an integer, RHS should properly unify or type check should fail. + // Remove this special case as a part of the initiative of improving type inference. + // Integers are special in the sense that we can't only rely on the type of `body` + // to get the type of the variable. The type of the variable *has* to follow + // `type_ascription` if `type_ascription` is a concrete integer type that does not + // conflict with the type of `body` (i.e. passes the type checking above). + let return_type = match &*type_engine.get(type_ascription.type_id) { + TypeInfo::UnsignedInteger(_) => type_ascription.type_id, + _ => match &*type_engine.get(body.return_type) { + // If RHS type check ends up in an error we want to use the + // provided type ascription as the variable type. E.g.: + // let v: Struct = Struct { x: 0 }; // `v` should be "Struct". + // let v: ExistingType = non_existing_identifier; // `v` should be "ExistingType". + // let v = ; // `v` will remain "{unknown}". + // TODO: Refine and improve this further. E.g., + // let v: Struct { /* MISSING FIELDS */ }; // Despite the error, `v` should be of type "Struct". + TypeInfo::ErrorRecovery(_) => type_ascription.type_id, + _ => body.return_type, + }, + }; + + if !ctx.code_block_first_pass() { + let previous_symbol = ctx + .namespace() + .module(engines) + .current_items() + .check_symbols_unique_while_collecting_unifications(&var_decl.name.clone()) + .ok(); + + if let Some(ResolvedDeclaration::Typed(ty::TyDecl::VariableDecl(variable_decl))) = + previous_symbol + { + type_engine.unify( + handler, + engines, + body.return_type, + variable_decl.body.return_type, + &variable_decl.span(), + "", + None, + ); + } + } + + let typed_var_decl = ty::TyVariableDecl { + name: var_decl.name.clone(), + body, + mutability: ty::VariableMutability::new_from_ref_mut(false, var_decl.is_mutable), + return_type, + type_ascription, + }; + + Ok(typed_var_decl) + } +} + +impl TypeCheckAnalysis for TyVariableDecl { + fn type_check_analyze( + &self, + handler: &Handler, + ctx: &mut TypeCheckAnalysisContext, + ) -> Result<(), ErrorEmitted> { + self.body.type_check_analyze(handler, ctx)?; + Ok(()) + } +} + +impl TypeCheckFinalization for TyVariableDecl { + fn type_check_finalize( + &mut self, + handler: &Handler, + ctx: &mut TypeCheckFinalizationContext, + ) -> Result<(), ErrorEmitted> { + self.body.type_check_finalize(handler, ctx) + } +} diff --git a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_match_branch.rs b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_match_branch.rs index 0a1c3870106..f8b530e2107 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_match_branch.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_match_branch.rs @@ -128,7 +128,7 @@ impl ty::TyMatchBranch { )?; // create a new namespace for this branch result - ctx.scoped(|mut scoped_ctx| { + ctx.scoped(handler, Some(branch_span.clone()), |mut scoped_ctx| { // for every variable that comes into result block, create a variable declaration, // insert it into the branch namespace, and add it to the block of code statements let mut code_block_contents: Vec = vec![]; diff --git a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_match_expression.rs b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_match_expression.rs index 7abdfbc54a3..bd271a7f638 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_match_expression.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_match_expression.rs @@ -607,10 +607,12 @@ impl ty::TyMatchExpression { matched_or_variant_index_vars, condition, result, + span: branch_span, .. } in self.branches.iter().rev() { if let ControlFlow::Break(_) = self.convert_to_typed_if_expression_inner_branch( + branch_span.clone(), &mut typed_if_exp, condition, result, @@ -629,6 +631,7 @@ impl ty::TyMatchExpression { #[allow(clippy::too_many_arguments)] fn convert_to_typed_if_expression_inner_branch( &self, + branch_span: Span, typed_if_exp: &mut Option, condition: &Option, result: &TyExpression, @@ -655,7 +658,7 @@ impl ty::TyMatchExpression { }; } let ctx = ctx.by_ref().with_type_annotation(self.return_type_id); - ctx.scoped(|mut branch_ctx| { + ctx.scoped(handler, Some(branch_span), |mut branch_ctx| { let result_span = result.span.clone(); let condition = condition .clone() diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs index f7505d07b0a..f02e51b9987 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs @@ -49,6 +49,7 @@ use sway_error::{ warning::{CompileWarning, Warning}, }; use sway_types::{integer_bits::IntegerBits, u256::U256, Ident, Named, Span, Spanned}; +use symbol_collection_context::SymbolCollectionContext; #[allow(clippy::too_many_arguments)] impl ty::TyExpression { @@ -138,6 +139,143 @@ impl ty::TyExpression { Ok(exp) } + pub(crate) fn collect( + handler: &Handler, + engines: &Engines, + ctx: &mut SymbolCollectionContext, + expr: &Expression, + ) -> Result<(), ErrorEmitted> { + match &expr.kind { + ExpressionKind::Error(_, _) => {} + ExpressionKind::Literal(_) => {} + ExpressionKind::AmbiguousPathExpression(expr) => { + expr.args + .iter() + .map(|arg_expr| Self::collect(handler, engines, ctx, arg_expr)) + .collect::, ErrorEmitted>>()?; + } + ExpressionKind::FunctionApplication(expr) => { + expr.arguments + .iter() + .map(|arg_expr| Self::collect(handler, engines, ctx, arg_expr)) + .collect::, ErrorEmitted>>()?; + } + ExpressionKind::LazyOperator(expr) => { + Self::collect(handler, engines, ctx, &expr.lhs)?; + Self::collect(handler, engines, ctx, &expr.rhs)?; + } + ExpressionKind::AmbiguousVariableExpression(_) => {} + ExpressionKind::Variable(_) => {} + ExpressionKind::Tuple(exprs) => { + exprs + .iter() + .map(|expr| Self::collect(handler, engines, ctx, expr)) + .collect::, ErrorEmitted>>()?; + } + ExpressionKind::TupleIndex(expr) => { + Self::collect(handler, engines, ctx, &expr.prefix)?; + } + ExpressionKind::Array(expr) => { + expr.contents + .iter() + .map(|expr| Self::collect(handler, engines, ctx, expr)) + .collect::, ErrorEmitted>>()?; + } + ExpressionKind::Struct(expr) => { + expr.fields + .iter() + .map(|field| Self::collect(handler, engines, ctx, &field.value)) + .collect::, ErrorEmitted>>()?; + } + ExpressionKind::CodeBlock(code_block) => { + TyCodeBlock::collect(handler, engines, ctx, code_block)? + } + ExpressionKind::If(if_expr) => { + Self::collect(handler, engines, ctx, &if_expr.condition)?; + Self::collect(handler, engines, ctx, &if_expr.then)?; + if let Some(r#else) = &if_expr.r#else { + Self::collect(handler, engines, ctx, r#else)? + } + } + ExpressionKind::Match(expr) => { + Self::collect(handler, engines, ctx, &expr.value)?; + expr.branches + .iter() + .map(|branch| { + // create a new namespace for this branch result + ctx.scoped(engines, branch.span.clone(), |scoped_ctx| { + Self::collect(handler, engines, scoped_ctx, &branch.result) + }) + .0 + }) + .collect::, ErrorEmitted>>()?; + } + ExpressionKind::Asm(_) => {} + ExpressionKind::MethodApplication(expr) => { + expr.arguments + .iter() + .map(|expr| Self::collect(handler, engines, ctx, expr)) + .collect::, ErrorEmitted>>()?; + } + ExpressionKind::Subfield(expr) => { + Self::collect(handler, engines, ctx, &expr.prefix)?; + } + ExpressionKind::DelineatedPath(expr) => { + if let Some(expr_args) = &expr.args { + expr_args + .iter() + .map(|arg_expr| Self::collect(handler, engines, ctx, arg_expr)) + .collect::, ErrorEmitted>>()?; + } + } + ExpressionKind::AbiCast(expr) => { + Self::collect(handler, engines, ctx, &expr.address)?; + } + ExpressionKind::ArrayIndex(expr) => { + Self::collect(handler, engines, ctx, &expr.prefix)?; + Self::collect(handler, engines, ctx, &expr.index)?; + } + ExpressionKind::StorageAccess(_) => {} + ExpressionKind::IntrinsicFunction(expr) => { + expr.arguments + .iter() + .map(|arg_expr| Self::collect(handler, engines, ctx, arg_expr)) + .collect::, ErrorEmitted>>()?; + } + ExpressionKind::WhileLoop(expr) => { + Self::collect(handler, engines, ctx, &expr.condition)?; + TyCodeBlock::collect(handler, engines, ctx, &expr.body)? + } + ExpressionKind::ForLoop(expr) => { + Self::collect(handler, engines, ctx, &expr.desugared)?; + } + ExpressionKind::Break => {} + ExpressionKind::Continue => {} + ExpressionKind::Reassignment(expr) => { + match &expr.lhs { + ReassignmentTarget::ElementAccess(expr) => { + Self::collect(handler, engines, ctx, expr)?; + } + ReassignmentTarget::Deref(expr) => { + Self::collect(handler, engines, ctx, expr)?; + } + } + Self::collect(handler, engines, ctx, &expr.rhs)?; + } + ExpressionKind::ImplicitReturn(expr) => Self::collect(handler, engines, ctx, expr)?, + ExpressionKind::Return(expr) => { + Self::collect(handler, engines, ctx, expr)?; + } + ExpressionKind::Ref(expr) => { + Self::collect(handler, engines, ctx, &expr.value)?; + } + ExpressionKind::Deref(expr) => { + Self::collect(handler, engines, ctx, expr)?; + } + } + Ok(()) + } + pub(crate) fn type_check( handler: &Handler, mut ctx: TypeCheckContext, @@ -2768,6 +2906,7 @@ mod tests { use super::*; use crate::{Engines, ExperimentalFlags}; use sway_error::type_error::TypeError; + use symbol_collection_context::SymbolCollectionContext; fn do_type_check( handler: &Handler, @@ -2776,6 +2915,9 @@ mod tests { type_annotation: TypeId, experimental: ExperimentalFlags, ) -> Result { + let collection_ctx_ns = Namespace::new(); + let mut collection_ctx = SymbolCollectionContext::new(collection_ctx_ns); + let root_module_name = sway_types::Ident::new_no_span("do_type_check_test".to_string()); let mut root_module = namespace::Root::from(namespace::Module::new( root_module_name, @@ -2783,8 +2925,13 @@ mod tests { None, )); let mut namespace = Namespace::init_root(&mut root_module); - let ctx = TypeCheckContext::from_namespace(&mut namespace, engines, experimental) - .with_type_annotation(type_annotation); + let ctx = TypeCheckContext::from_namespace( + &mut namespace, + &mut collection_ctx, + engines, + experimental, + ) + .with_type_annotation(type_annotation); ty::TyExpression::type_check(handler, ctx, expr) } diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_instantiation.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_instantiation.rs index a6b331768ec..11b1495bdc4 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_instantiation.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_instantiation.rs @@ -305,7 +305,7 @@ pub(crate) fn struct_instantiation( let instantiation_span = inner_span.clone(); ctx.with_generic_shadowing_mode(GenericShadowingMode::Allow) - .scoped(|mut scoped_ctx| { + .scoped(handler, None, |mut scoped_ctx| { // Insert struct type parameter into namespace. // This is required so check_type_parameter_bounds can resolve generic trait type parameters. for type_parameter in struct_decl.type_parameters.iter() { diff --git a/sway-core/src/semantic_analysis/ast_node/mod.rs b/sway-core/src/semantic_analysis/ast_node/mod.rs index 04aab70d407..3a6ea5f2153 100644 --- a/sway-core/src/semantic_analysis/ast_node/mod.rs +++ b/sway-core/src/semantic_analysis/ast_node/mod.rs @@ -34,7 +34,9 @@ impl ty::TyAstNode { } AstNodeContent::IncludeStatement(_i) => (), AstNodeContent::Declaration(decl) => ty::TyDecl::collect(handler, engines, ctx, decl)?, - AstNodeContent::Expression(_expr) => (), + AstNodeContent::Expression(expr) => { + ty::TyExpression::collect(handler, engines, ctx, &expr)? + } AstNodeContent::Error(_spans, _err) => (), }; diff --git a/sway-core/src/semantic_analysis/namespace/contract_helpers.rs b/sway-core/src/semantic_analysis/namespace/contract_helpers.rs index 9a58cd80c64..822d4262156 100644 --- a/sway-core/src/semantic_analysis/namespace/contract_helpers.rs +++ b/sway-core/src/semantic_analysis/namespace/contract_helpers.rs @@ -12,7 +12,7 @@ use crate::{ ty::{TyAstNode, TyAstNodeContent}, Visibility, }, - semantic_analysis::TypeCheckContext, + semantic_analysis::{symbol_collection_context::SymbolCollectionContext, TypeCheckContext}, transform::to_parsed_lang, Engines, Namespace, }; @@ -106,8 +106,12 @@ fn default_with_contract_id_inner( }; let mut root = Root::from(Module::new(ns_name.clone(), Visibility::Public, None)); let mut ns = Namespace::init_root(&mut root); + + let symbol_ctx_ns = Namespace::default(); + let mut symbol_ctx = SymbolCollectionContext::new(symbol_ctx_ns); // This is pretty hacky but that's okay because of this code is being removed pretty soon - let type_check_ctx = TypeCheckContext::from_namespace(&mut ns, engines, experimental); + let type_check_ctx = + TypeCheckContext::from_namespace(&mut ns, &mut symbol_ctx, engines, experimental); let typed_node = TyAstNode::type_check(handler, type_check_ctx, &ast_node).unwrap(); // get the decl out of the typed node: // we know as an invariant this must be a const decl, as we hardcoded a const decl in diff --git a/sway-core/src/semantic_analysis/namespace/module.rs b/sway-core/src/semantic_analysis/namespace/module.rs index 9230af73984..36f14f2050f 100644 --- a/sway-core/src/semantic_analysis/namespace/module.rs +++ b/sway-core/src/semantic_analysis/namespace/module.rs @@ -7,7 +7,7 @@ use super::{ }; use rustc_hash::FxHasher; -use std::hash::BuildHasherDefault; +use std::{collections::HashMap, hash::BuildHasherDefault}; use sway_error::handler::Handler; use sway_error::{error::CompileError, handler::ErrorEmitted}; use sway_types::{span::Span, Spanned}; @@ -34,6 +34,8 @@ pub struct Module { pub lexical_scopes: Vec, /// Current lexical scope id in the lexical scope hierarchy stack. pub current_lexical_scope_id: LexicalScopeId, + /// Maps between a span and the corresponding lexical scope id. + pub lexical_scopes_spans: HashMap, /// Name of the module, package name for root module, module name for other modules. /// Module name used is the same as declared in `mod name;`. name: Ident, @@ -51,12 +53,19 @@ pub struct Module { pub(crate) mod_path: ModulePathBuf, } +impl Default for Module { + fn default() -> Self { + Self::new(Ident::dummy(), Visibility::Public, None) + } +} + impl Module { pub fn new(name: Ident, visibility: Visibility, span: Option) -> Self { Self { visibility, submodules: Default::default(), lexical_scopes: vec![LexicalScope::default()], + lexical_scopes_spans: Default::default(), current_lexical_scope_id: 0, name, span, @@ -78,6 +87,7 @@ impl Module { visibility, submodules: self.submodules.clone(), lexical_scopes: self.lexical_scopes.clone(), + lexical_scopes_spans: self.lexical_scopes_spans.clone(), current_lexical_scope_id: self.current_lexical_scope_id, name, span, @@ -221,8 +231,28 @@ impl Module { self.current_lexical_scope_id } + /// Enters the scope with the given span in the module's lexical scope hierarchy. + pub fn enter_lexical_scope( + &mut self, + handler: &Handler, + _engines: &Engines, + span: Span, + ) -> Result { + let id_opt = self.lexical_scopes_spans.get(&span); + match id_opt { + Some(id) => { + self.current_lexical_scope_id = *id; + Ok(*id) + } + None => Err(handler.emit_err(CompileError::Internal( + "Could not find a valid lexical scope for this source location.", + span.clone(), + ))), + } + } + /// Pushes a new scope to the module's lexical scope hierarchy. - pub fn push_new_lexical_scope(&mut self) -> LexicalScopeId { + pub fn push_new_lexical_scope(&mut self, span: Span) -> LexicalScopeId { let previous_scope_id = self.current_lexical_scope_id(); let new_scoped_id = { self.lexical_scopes.push(LexicalScope { @@ -234,6 +264,7 @@ impl Module { let previous_scope = self.lexical_scopes.get_mut(previous_scope_id).unwrap(); previous_scope.children.push(new_scoped_id); self.current_lexical_scope_id = new_scoped_id; + self.lexical_scopes_spans.insert(span, new_scoped_id); new_scoped_id } diff --git a/sway-core/src/semantic_analysis/namespace/namespace.rs b/sway-core/src/semantic_analysis/namespace/namespace.rs index a3aed9205c9..47bb53e3138 100644 --- a/sway-core/src/semantic_analysis/namespace/namespace.rs +++ b/sway-core/src/semantic_analysis/namespace/namespace.rs @@ -23,7 +23,7 @@ pub enum TryInsertingTraitImplOnFailure { } /// The set of items that represent the namespace context passed throughout type checking. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct Namespace { /// An immutable namespace that consists of the names that should always be present, no matter /// what module or scope we are currently checking. @@ -47,6 +47,14 @@ pub struct Namespace { } impl Namespace { + pub fn new() -> Self { + Self { + init: Module::default(), + mod_path: vec![], + root: Root::default(), + } + } + pub fn program_id(&self, engines: &Engines) -> &Module { self.root .module diff --git a/sway-core/src/semantic_analysis/namespace/root.rs b/sway-core/src/semantic_analysis/namespace/root.rs index b6770d6db8a..020c5e19111 100644 --- a/sway-core/src/semantic_analysis/namespace/root.rs +++ b/sway-core/src/semantic_analysis/namespace/root.rs @@ -159,7 +159,7 @@ impl ResolvedDeclaration { /// canonical paths, or that use canonical paths internally, are *only* called from the root. This /// normally includes methods that first lookup some canonical path via `use_synonyms` before using /// that canonical path to look up the symbol declaration. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct Root { pub(crate) module: Module, } diff --git a/sway-core/src/semantic_analysis/program.rs b/sway-core/src/semantic_analysis/program.rs index c70a442fc1a..581a630d9b6 100644 --- a/sway-core/src/semantic_analysis/program.rs +++ b/sway-core/src/semantic_analysis/program.rs @@ -44,6 +44,7 @@ impl TyProgram { handler: &Handler, engines: &Engines, parsed: &ParseProgram, + collection_ctx: &mut SymbolCollectionContext, mut namespace: namespace::Namespace, package_name: &str, build_config: Option<&BuildConfig>, @@ -55,8 +56,9 @@ impl TyProgram { new_encoding: false, }); - let mut ctx = TypeCheckContext::from_root(&mut namespace, engines, experimental) - .with_kind(parsed.kind); + let mut ctx = + TypeCheckContext::from_root(&mut namespace, collection_ctx, engines, experimental) + .with_kind(parsed.kind); let ParseProgram { root, kind } = parsed; diff --git a/sway-core/src/semantic_analysis/symbol_collection_context.rs b/sway-core/src/semantic_analysis/symbol_collection_context.rs index ca8d1c2b961..2a3be6aa35d 100644 --- a/sway-core/src/semantic_analysis/symbol_collection_context.rs +++ b/sway-core/src/semantic_analysis/symbol_collection_context.rs @@ -40,12 +40,13 @@ impl SymbolCollectionContext { pub fn scoped( &mut self, engines: &Engines, + span: Span, with_scoped_ctx: impl FnOnce(&mut SymbolCollectionContext) -> Result, ) -> (Result, LexicalScopeId) { let lexical_scope_id: LexicalScopeId = self .namespace .module_mut(engines) - .write(engines, |m| m.push_new_lexical_scope()); + .write(engines, |m| m.push_new_lexical_scope(span.clone())); let ret = with_scoped_ctx(self); self.namespace .module_mut(engines) @@ -53,18 +54,20 @@ impl SymbolCollectionContext { (ret, lexical_scope_id) } - /// Enter the lexical scope and produce a collection context ready for - /// collecting its content. + /// Enter the lexical scope corresponding to the given span and produce a + /// collection context ready for collecting its content. /// /// Returns the result of the given `with_ctx` function. pub fn enter_lexical_scope( &mut self, + handler: &Handler, engines: &Engines, - with_ctx: impl FnOnce(&mut SymbolCollectionContext) -> T, - ) -> T { - self.namespace - .module_mut(engines) - .write(engines, |m| m.push_new_lexical_scope()); + span: Span, + with_ctx: impl FnOnce(&mut SymbolCollectionContext) -> Result, + ) -> Result { + self.namespace.module_mut(engines).write(engines, |m| { + m.enter_lexical_scope(handler, engines, span.clone()) + })?; let ret = with_ctx(self); self.namespace .module_mut(engines) diff --git a/sway-core/src/semantic_analysis/symbol_resolve_context.rs b/sway-core/src/semantic_analysis/symbol_resolve_context.rs index c2558697fe8..0e88ffd543c 100644 --- a/sway-core/src/semantic_analysis/symbol_resolve_context.rs +++ b/sway-core/src/semantic_analysis/symbol_resolve_context.rs @@ -79,17 +79,23 @@ impl<'a> SymbolResolveContext<'a> { } /// Scope the `SymbolResolveContext` with a new namespace lexical scope. - pub fn scoped( + pub fn enter_lexical_scope( self, + handler: &Handler, + span: Span, with_scoped_ctx: impl FnOnce(SymbolResolveContext) -> Result, ) -> Result { let engines = self.engines; - self.symbol_collection_ctx - .enter_lexical_scope(engines, |sub_scope_collect_ctx| { + self.symbol_collection_ctx.enter_lexical_scope( + handler, + engines, + span, + |sub_scope_collect_ctx| { let sub_scope_resolve_ctx = SymbolResolveContext::new(engines, sub_scope_collect_ctx); with_scoped_ctx(sub_scope_resolve_ctx) - }) + }, + ) } /// Enter the submodule with the given name and a symbol resolve context ready for diff --git a/sway-core/src/semantic_analysis/type_check_context.rs b/sway-core/src/semantic_analysis/type_check_context.rs index 29d47918532..66dd12166cb 100644 --- a/sway-core/src/semantic_analysis/type_check_context.rs +++ b/sway-core/src/semantic_analysis/type_check_context.rs @@ -27,7 +27,7 @@ use sway_error::{ use sway_types::{span::Span, Ident, Spanned}; use sway_utils::iter_prefixes; -use super::GenericShadowingMode; +use super::{symbol_collection_context::SymbolCollectionContext, GenericShadowingMode}; /// Contextual state tracked and accumulated throughout type-checking. pub struct TypeCheckContext<'a> { @@ -46,6 +46,9 @@ pub struct TypeCheckContext<'a> { /// Set of experimental flags. pub(crate) experimental: ExperimentalFlags, + /// Keeps the accumulated symbols previously collected. + pub(crate) collection_ctx: &'a mut SymbolCollectionContext, + // The following set of fields are intentionally private. When a `TypeCheckContext` is passed // into a new node during type checking, these fields should be updated using the `with_*` // methods which provides a new `TypeCheckContext`, ensuring we don't leak our changes into @@ -108,12 +111,14 @@ impl<'a> TypeCheckContext<'a> { /// Initialize a type-checking context with a namespace. pub fn from_namespace( namespace: &'a mut Namespace, + collection_ctx: &'a mut SymbolCollectionContext, engines: &'a Engines, experimental: ExperimentalFlags, ) -> Self { Self { namespace, engines, + collection_ctx, type_annotation: engines.te().insert(engines, TypeInfo::Unknown, None), function_type_annotation: engines.te().insert(engines, TypeInfo::Unknown, None), unify_generic: false, @@ -141,18 +146,21 @@ impl<'a> TypeCheckContext<'a> { /// - help_text: "" pub fn from_root( root_namespace: &'a mut Namespace, + collection_ctx: &'a mut SymbolCollectionContext, engines: &'a Engines, experimental: ExperimentalFlags, ) -> Self { - Self::from_module_namespace(root_namespace, engines, experimental) + Self::from_module_namespace(root_namespace, collection_ctx, engines, experimental) } fn from_module_namespace( namespace: &'a mut Namespace, + collection_ctx: &'a mut SymbolCollectionContext, engines: &'a Engines, experimental: ExperimentalFlags, ) -> Self { Self { + collection_ctx, namespace, engines, type_annotation: engines.te().insert(engines, TypeInfo::Unknown, None), @@ -184,6 +192,7 @@ impl<'a> TypeCheckContext<'a> { pub fn by_ref(&mut self) -> TypeCheckContext<'_> { TypeCheckContext { namespace: self.namespace, + collection_ctx: self.collection_ctx, type_annotation: self.type_annotation, function_type_annotation: self.function_type_annotation, unify_generic: self.unify_generic, @@ -203,60 +212,131 @@ impl<'a> TypeCheckContext<'a> { } } - /// Scope the `TypeCheckContext` with a new namespace. + /// Scope the `TypeCheckContext` with a new namespace, and set up the collection context + /// so it enters the lexical scope corresponding to the given span. pub fn scoped( self, + handler: &Handler, + span: Option, with_scoped_ctx: impl FnOnce(TypeCheckContext) -> Result, ) -> Result { let mut namespace = self.namespace.clone(); - let ctx = TypeCheckContext { - namespace: &mut namespace, - type_annotation: self.type_annotation, - function_type_annotation: self.function_type_annotation, - unify_generic: self.unify_generic, - self_type: self.self_type, - type_subst: self.type_subst, - abi_mode: self.abi_mode, - const_shadowing_mode: self.const_shadowing_mode, - generic_shadowing_mode: self.generic_shadowing_mode, - help_text: self.help_text, - kind: self.kind, - engines: self.engines, - disallow_functions: self.disallow_functions, - storage_declaration: self.storage_declaration, - experimental: self.experimental, - collecting_unifications: self.collecting_unifications, - code_block_first_pass: self.code_block_first_pass, - }; - with_scoped_ctx(ctx) + if let Some(span) = span { + self.collection_ctx.enter_lexical_scope( + handler, + self.engines, + span, + |scoped_collection_ctx| { + let ctx = TypeCheckContext { + namespace: &mut namespace, + collection_ctx: scoped_collection_ctx, + type_annotation: self.type_annotation, + function_type_annotation: self.function_type_annotation, + unify_generic: self.unify_generic, + self_type: self.self_type, + type_subst: self.type_subst, + abi_mode: self.abi_mode, + const_shadowing_mode: self.const_shadowing_mode, + generic_shadowing_mode: self.generic_shadowing_mode, + help_text: self.help_text, + kind: self.kind, + engines: self.engines, + disallow_functions: self.disallow_functions, + storage_declaration: self.storage_declaration, + experimental: self.experimental, + collecting_unifications: self.collecting_unifications, + code_block_first_pass: self.code_block_first_pass, + }; + with_scoped_ctx(ctx) + }, + ) + } else { + let ctx = TypeCheckContext { + collection_ctx: self.collection_ctx, + namespace: &mut namespace, + type_annotation: self.type_annotation, + function_type_annotation: self.function_type_annotation, + unify_generic: self.unify_generic, + self_type: self.self_type, + type_subst: self.type_subst, + abi_mode: self.abi_mode, + const_shadowing_mode: self.const_shadowing_mode, + generic_shadowing_mode: self.generic_shadowing_mode, + help_text: self.help_text, + kind: self.kind, + engines: self.engines, + disallow_functions: self.disallow_functions, + storage_declaration: self.storage_declaration, + experimental: self.experimental, + collecting_unifications: self.collecting_unifications, + code_block_first_pass: self.code_block_first_pass, + }; + with_scoped_ctx(ctx) + } } /// Scope the `TypeCheckContext` with a new namespace and returns it in case of success. + /// Also sets up the collection context so it enters the lexical scope corresponding to + /// the given span. pub fn scoped_and_namespace( self, + handler: &Handler, + span: Option, with_scoped_ctx: impl FnOnce(TypeCheckContext) -> Result, ) -> Result<(T, Namespace), ErrorEmitted> { let mut namespace = self.namespace.clone(); - let ctx = TypeCheckContext { - namespace: &mut namespace, - type_annotation: self.type_annotation, - function_type_annotation: self.function_type_annotation, - unify_generic: self.unify_generic, - self_type: self.self_type, - type_subst: self.type_subst, - abi_mode: self.abi_mode, - const_shadowing_mode: self.const_shadowing_mode, - generic_shadowing_mode: self.generic_shadowing_mode, - help_text: self.help_text, - kind: self.kind, - engines: self.engines, - disallow_functions: self.disallow_functions, - storage_declaration: self.storage_declaration, - experimental: self.experimental, - collecting_unifications: self.collecting_unifications, - code_block_first_pass: self.code_block_first_pass, - }; - Ok((with_scoped_ctx(ctx)?, namespace)) + if let Some(span) = span { + self.collection_ctx.enter_lexical_scope( + handler, + self.engines, + span, + |scoped_collection_ctx| { + let ctx = TypeCheckContext { + collection_ctx: scoped_collection_ctx, + namespace: &mut namespace, + type_annotation: self.type_annotation, + function_type_annotation: self.function_type_annotation, + unify_generic: self.unify_generic, + self_type: self.self_type, + type_subst: self.type_subst, + abi_mode: self.abi_mode, + const_shadowing_mode: self.const_shadowing_mode, + generic_shadowing_mode: self.generic_shadowing_mode, + help_text: self.help_text, + kind: self.kind, + engines: self.engines, + disallow_functions: self.disallow_functions, + storage_declaration: self.storage_declaration, + experimental: self.experimental, + collecting_unifications: self.collecting_unifications, + code_block_first_pass: self.code_block_first_pass, + }; + Ok((with_scoped_ctx(ctx)?, namespace)) + }, + ) + } else { + let ctx = TypeCheckContext { + collection_ctx: self.collection_ctx, + namespace: &mut namespace, + type_annotation: self.type_annotation, + function_type_annotation: self.function_type_annotation, + unify_generic: self.unify_generic, + self_type: self.self_type, + type_subst: self.type_subst, + abi_mode: self.abi_mode, + const_shadowing_mode: self.const_shadowing_mode, + generic_shadowing_mode: self.generic_shadowing_mode, + help_text: self.help_text, + kind: self.kind, + engines: self.engines, + disallow_functions: self.disallow_functions, + storage_declaration: self.storage_declaration, + experimental: self.experimental, + collecting_unifications: self.collecting_unifications, + code_block_first_pass: self.code_block_first_pass, + }; + Ok((with_scoped_ctx(ctx)?, namespace)) + } } /// Enter the submodule with the given name and produce a type-check context ready for @@ -264,7 +344,7 @@ impl<'a> TypeCheckContext<'a> { /// /// Returns the result of the given `with_submod_ctx` function. pub fn enter_submodule( - mut self, + self, mod_name: Ident, visibility: Visibility, module_span: Span, @@ -275,11 +355,28 @@ impl<'a> TypeCheckContext<'a> { // We're checking a submodule, so no need to pass through anything other than the // namespace and the engines. let engines = self.engines; - let mut submod_ns = - self.namespace_mut() - .enter_submodule(engines, mod_name, visibility, module_span); - let submod_ctx = TypeCheckContext::from_namespace(&mut submod_ns, engines, experimental); - with_submod_ctx(submod_ctx) + let mut submod_ns = self.namespace.enter_submodule( + engines, + mod_name.clone(), + visibility, + module_span.clone(), + ); + + self.collection_ctx.enter_submodule( + engines, + mod_name, + visibility, + module_span, + |submod_collection_ctx| { + let submod_ctx = TypeCheckContext::from_namespace( + &mut submod_ns, + submod_collection_ctx, + engines, + experimental, + ); + with_submod_ctx(submod_ctx) + }, + ) } /// Returns a mutable reference to the current namespace. diff --git a/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs b/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs index 4144d0b085c..b48cce083eb 100644 --- a/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs +++ b/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs @@ -598,7 +598,6 @@ pub fn item_fn_to_function_declaration( .unwrap_or(vec![]), kind, implementing_type, - lexical_scope: 0, }; let decl_id = engines.pe().insert(fn_decl); Ok(decl_id) From a0f5cf07f8531312c226106bd8ef75e98c2c1e5c Mon Sep 17 00:00:00 2001 From: Sophie Dankel <47993817+sdankel@users.noreply.github.com> Date: Thu, 19 Sep 2024 13:52:29 -0700 Subject: [PATCH 025/115] fix: forc-deploy block url (#6570) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description It looks like there was a change in how fuel core client returns the block height. It used to be a hex number and we had to convert it to decimal, but now it’s returning the number as a decimal so we don't need to convert it. ## Checklist - [ ] 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. - [ ] 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). - [ ] I have requested a review from the relevant team or maintainers. --- forc-plugins/forc-client/src/op/deploy.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/forc-plugins/forc-client/src/op/deploy.rs b/forc-plugins/forc-client/src/op/deploy.rs index ab4919fe98d..45f616dda91 100644 --- a/forc-plugins/forc-client/src/op/deploy.rs +++ b/forc-plugins/forc-client/src/op/deploy.rs @@ -1426,14 +1426,8 @@ fn create_deployment_artifact( ); let block_height = deployment_artifact.deployed_block_height; - if block_height.is_some() { - let block_height_formatted = - match u32::from_str_radix(&block_height.unwrap().to_string(), 16) { - Ok(decimal) => format!("{block_url}{decimal}"), - Err(_) => block_height.unwrap().to_string(), - }; - - println_action_green("Deployed", &format!("in block {block_height_formatted}")); + if let Some(block_height) = block_height { + println_action_green("Deployed", &format!("in block {block_url}{block_height}")); } let output_dir = cmd From ab1e030f984768f8e85531cb7d121dce79b1ef5b Mon Sep 17 00:00:00 2001 From: Alfie John Date: Sat, 21 Sep 2024 09:48:34 +1000 Subject: [PATCH 026/115] Move all crate dependencies to the workspace Cargo.toml (#6179) (#6563) ## Description For #6179, PR #6501 kept bumping into errors as it was doing too many things, so I've split that PR into multiple PRs. This is the first, and the only thing it does is move all of the various `Cargo.toml` dependencies into the single workspace `Cargo.toml`. Future PRs will: - Update dependency versions - Update code that breaks from the version bumps ## 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. --- Cargo.lock | 201 +++----------------- Cargo.toml | 212 ++++++++++++++++++++-- forc-pkg/Cargo.toml | 60 +++--- forc-plugins/forc-client/Cargo.toml | 65 ++++--- forc-plugins/forc-crypto/Cargo.toml | 40 ++-- forc-plugins/forc-debug/Cargo.toml | 34 ++-- forc-plugins/forc-doc/Cargo.toml | 36 ++-- forc-plugins/forc-fmt/Cargo.toml | 24 +-- forc-plugins/forc-lsp/Cargo.toml | 12 +- forc-plugins/forc-tx/Cargo.toml | 18 +- forc-test/Cargo.toml | 18 +- forc-tracing/Cargo.toml | 8 +- forc-util/Cargo.toml | 42 ++--- forc/Cargo.toml | 60 +++--- scripts/mdbook-forc-documenter/Cargo.toml | 12 +- sway-ast/Cargo.toml | 14 +- sway-core/Cargo.toml | 78 ++++---- sway-error/Cargo.toml | 18 +- sway-ir/Cargo.toml | 28 +-- sway-ir/sway-ir-macros/Cargo.toml | 10 +- sway-lsp/Cargo.toml | 71 ++++---- sway-lsp/tests/utils/Cargo.toml | 20 +- sway-parse/Cargo.toml | 22 +-- sway-types/Cargo.toml | 28 +-- sway-utils/Cargo.toml | 6 +- swayfmt/Cargo.toml | 30 +-- test/Cargo.toml | 64 +++---- test/src/sdk-harness/Cargo.toml | 19 +- 28 files changed, 641 insertions(+), 609 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e18e19a0114..5b7cd0ec58f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,7 +44,7 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom 0.2.15", + "getrandom", "once_cell", "version_check", ] @@ -56,7 +56,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if 1.0.0", - "getrandom 0.2.15", + "getrandom", "once_cell", "version_check", "zerocopy", @@ -178,12 +178,6 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" -[[package]] -name = "arrayvec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" - [[package]] name = "arrayvec" version = "0.7.4" @@ -396,17 +390,6 @@ dependencies = [ "wyz", ] -[[package]] -name = "blake2b_simd" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" -dependencies = [ - "arrayref", - "arrayvec 0.5.2", - "constant_time_eq 0.1.5", -] - [[package]] name = "blake3" version = "1.5.3" @@ -414,10 +397,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9ec96fe9a81b5e365f9db71fe00edc4fe4ca2cc7dcb7861f0603012a7caa210" dependencies = [ "arrayref", - "arrayvec 0.7.4", + "arrayvec", "cc", "cfg-if 1.0.0", - "constant_time_eq 0.3.0", + "constant_time_eq", ] [[package]] @@ -919,12 +902,6 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" -[[package]] -name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - [[package]] name = "constant_time_eq" version = "0.3.0" @@ -1477,17 +1454,6 @@ version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "363641827cb8d8387a69364aa2f85433db83b8b00270ed2c786235d83bf0aa0a" -[[package]] -name = "dirs" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" -dependencies = [ - "libc", - "redox_users 0.3.5", - "winapi", -] - [[package]] name = "dirs" version = "3.0.2" @@ -1523,7 +1489,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" dependencies = [ "libc", - "redox_users 0.4.5", + "redox_users", "winapi", ] @@ -1534,7 +1500,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" dependencies = [ "libc", - "redox_users 0.4.5", + "redox_users", "winapi", ] @@ -2035,8 +2001,8 @@ dependencies = [ "sway-utils", "term-table", "tokio", - "toml 0.7.8", - "toml_edit 0.19.15", + "toml 0.8.19", + "toml_edit 0.21.1", "tracing", "url", "uwuify", @@ -2173,7 +2139,7 @@ dependencies = [ "forc-pkg", "forc-tracing 0.63.6", "forc-util", - "prettydiff 0.5.1", + "prettydiff", "sway-core", "sway-utils", "swayfmt", @@ -2960,17 +2926,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - [[package]] name = "getrandom" version = "0.2.15" @@ -2979,7 +2934,7 @@ checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if 1.0.0", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", ] [[package]] @@ -4375,7 +4330,7 @@ checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "log", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys 0.48.0", ] @@ -4387,7 +4342,7 @@ checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ "hermit-abi 0.3.9", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys 0.52.0", ] @@ -4907,7 +4862,7 @@ version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ - "arrayvec 0.7.4", + "arrayvec", "bitvec", "byte-slice-cast", "impl-trait-for-tuples", @@ -5269,17 +5224,6 @@ dependencies = [ "yansi", ] -[[package]] -name = "prettydiff" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5671a83709b2755fe5b776d4915701bf36ed2cd9575035502ec12818141d71" -dependencies = [ - "ansi_term", - "prettytable-rs 0.8.0", - "structopt", -] - [[package]] name = "prettydiff" version = "0.6.4" @@ -5288,24 +5232,10 @@ checksum = "8ff1fec61082821f8236cf6c0c14e8172b62ce8a72a0eedc30d3b247bb68dc11" dependencies = [ "ansi_term", "pad", - "prettytable-rs 0.10.0", + "prettytable-rs", "structopt", ] -[[package]] -name = "prettytable-rs" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fd04b170004fa2daccf418a7f8253aaf033c27760b5f225889024cf66d7ac2e" -dependencies = [ - "atty", - "csv", - "encode_unicode 0.3.6", - "lazy_static", - "term 0.5.2", - "unicode-width", -] - [[package]] name = "prettytable-rs" version = "0.10.0" @@ -5316,7 +5246,7 @@ dependencies = [ "encode_unicode 1.0.0", "is-terminal", "lazy_static", - "term 0.7.0", + "term", "unicode-width", ] @@ -5556,7 +5486,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.15", + "getrandom", ] [[package]] @@ -5599,12 +5529,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "redox_syscall" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" - [[package]] name = "redox_syscall" version = "0.2.16" @@ -5638,24 +5562,13 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20145670ba436b55d91fc92d25e71160fbfbdd57831631c8d7d36377a476f1cb" -[[package]] -name = "redox_users" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" -dependencies = [ - "getrandom 0.1.16", - "redox_syscall 0.1.57", - "rust-argon2", -] - [[package]] name = "redox_users" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ - "getrandom 0.2.15", + "getrandom", "libredox 0.1.3", "thiserror", ] @@ -5877,7 +5790,7 @@ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", "cfg-if 1.0.0", - "getrandom 0.2.15", + "getrandom", "libc", "spin", "untrusted", @@ -5987,25 +5900,13 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "rust-argon2" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb" -dependencies = [ - "base64 0.13.1", - "blake2b_simd", - "constant_time_eq 0.1.5", - "crossbeam-utils", -] - [[package]] name = "rust_decimal" version = "1.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a" dependencies = [ - "arrayvec 0.7.4", + "arrayvec", "borsh", "bytes", "num-traits", @@ -6935,7 +6836,7 @@ dependencies = [ "itertools 0.10.5", "once_cell", "peg", - "prettydiff 0.6.4", + "prettydiff", "rustc-hash", "slotmap", "sway-ir-macros", @@ -6996,7 +6897,7 @@ dependencies = [ "thiserror", "tikv-jemallocator", "tokio", - "toml_edit 0.19.15", + "toml_edit 0.21.1", "tower", "tower-lsp", "tracing", @@ -7005,7 +6906,7 @@ dependencies = [ [[package]] name = "sway-lsp-test-utils" -version = "0.1.0" +version = "0.63.6" dependencies = [ "assert-json-diff", "futures", @@ -7072,7 +6973,7 @@ dependencies = [ "forc-tracing 0.63.6", "indoc", "paste", - "prettydiff 0.6.4", + "prettydiff", "ropey", "serde", "serde_ignored", @@ -7084,7 +6985,7 @@ dependencies = [ "sway-utils", "test-macros", "thiserror", - "toml 0.7.8", + "toml 0.8.19", ] [[package]] @@ -7271,17 +7172,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "term" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42" -dependencies = [ - "byteorder", - "dirs 1.0.5", - "winapi", -] - [[package]] name = "term" version = "0.7.0" @@ -7357,7 +7247,7 @@ dependencies = [ "insta", "libtest-mimic", "miden", - "prettydiff 0.6.4", + "prettydiff", "rand", "regex", "revm", @@ -7369,7 +7259,7 @@ dependencies = [ "sway-utils", "textwrap 0.16.1", "tokio", - "toml 0.7.8", + "toml 0.8.19", "tracing", "vte 0.13.0", ] @@ -7379,7 +7269,7 @@ name = "test-macros" version = "0.0.0" dependencies = [ "paste", - "prettydiff 0.6.4", + "prettydiff", ] [[package]] @@ -7654,18 +7544,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit 0.19.15", -] - [[package]] name = "toml" version = "0.8.19" @@ -7687,19 +7565,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap 2.4.0", - "serde", - "serde_spanned", - "toml_datetime", - "winnow 0.5.40", -] - [[package]] name = "toml_edit" version = "0.21.1" @@ -8072,7 +7937,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ - "getrandom 0.2.15", + "getrandom", "serde", ] @@ -8148,7 +8013,7 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5022b5fbf9407086c180e9557be968742d839e68346af7792b8592489732197" dependencies = [ - "arrayvec 0.7.4", + "arrayvec", "utf8parse", "vte_generate_state_changes", ] @@ -8159,7 +8024,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40eb22ae96f050e0c0d6f7ce43feeae26c348fc4dea56928ca81537cfaa6188b" dependencies = [ - "arrayvec 0.7.4", + "arrayvec", "utf8parse", "vte_generate_state_changes", ] @@ -8193,12 +8058,6 @@ dependencies = [ "try-lock", ] -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index b9fe0d0c4ea..e6848e284d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,32 +32,204 @@ exclude = [ "forc-test/test_data" ] +[workspace.package] +edition = "2021" +version = "0.63.6" +authors = ["Fuel Labs "] +homepage = "https://fuel.network/" +license = "Apache-2.0" +repository = "https://github.com/FuelLabs/sway" + [workspace.dependencies] +# +# Internal dependencies in order to propagate `workspace.version` +# + +forc = { path = "forc/" } +forc-pkg = { path = "forc-pkg/" } +forc-test = { path = "forc-test/" } +forc-tracing = { path = "forc-tracing/" } +forc-util = { path = "forc-util/" } + +# Forc plugins +forc-plugins = { path = "forc-plugins/" } +forc-client = { path = "forc-plugins/forc-client/" } +forc-crypto = { path = "forc-plugins/forc-crypto/" } +forc-debug = { path = "forc-plugins/forc-debug/" } +forc-doc = { path = "forc-plugins/forc-doc/" } +forc-fmt = { path = "forc-plugins/forc-fmt/" } +forc-lsp = { path = "forc-plugins/forc-lsp/" } +forc-tx = { path = "forc-plugins/forc-tx/" } + +sway-ast = { path = "sway-ast/" } +sway-core = { path = "sway-core/" } +sway-error = { path = "sway-error/" } +sway-lsp = { path = "sway-lsp/" } +sway-parse = { path = "sway-parse/" } +sway-types = { path = "sway-types/" } +sway-utils = { path = "sway-utils/" } +swayfmt = { path = "swayfmt/" } + +# Sway IR +sway-ir = { path = "sway-ir/" } +sway-ir-macros = { path = "sway-ir/sway-ir-macros" } + +# +# External Fuel dependencies +# + +# Dependencies from the `fuel-abi-types` repository: +fuel-abi-types = "0.7" + # Dependencies from the `fuel-core` repository: +# +# Although ALL verions are "X.Y", we need the complete semver for +# fuel-core-client as the GitHub Actions workflow parses this value to pull down +# the correct tarball fuel-core-client = { version = "0.35.0", default-features = false } -fuel-core-types = { version = "0.35.0", default-features = false } - -# Dependencies from the `fuel-vm` repository: -fuel-asm = "0.56.0" -fuel-crypto = "0.56.0" -fuel-types = "0.56.0" -fuel-tx = "0.56.0" -fuel-vm = "0.56.0" +fuel-core-types = { version = "0.35", default-features = false } # Dependencies from the `fuels-rs` repository: -fuels-core = "0.66.4" -fuels-accounts = "0.66.4" -fuels = "0.66.4" +fuels = "0.66" +fuels-core = "0.66" +fuels-accounts = "0.66" + +# Dependencies from the `fuel-vm` repository: +fuel-asm = "0.56" +fuel-crypto = "0.56" +fuel-types = "0.56" +fuel-tx = "0.56" +fuel-vm = "0.56" # Dependencies from the `forc-wallet` repository: -forc-wallet = "0.9.0" +forc-wallet = "0.9" -# Dependencies from the `fuel-abi-types` repository: -fuel-abi-types = "0.7.0" +# +# External dependencies +# -[workspace.package] -edition = "2021" -authors = ["Fuel Labs "] -homepage = "https://fuel.network/" -license = "Apache-2.0" -repository = "https://github.com/FuelLabs/sway" +annotate-snippets = "0.10" +ansi_term = "0.12" +anyhow = "1.0" +assert-json-diff = "2.0" +async-trait = "0.1" +atty = "0.2" +byte-unit = "5.1" +bytecount = "0.6" +bytes = "1.3" +chrono = { version = "0.4", default-features = false } +cid = "0.11" +clap = "4.5" +clap_complete = "4.5" +clap_complete_fig = "4.5" +colored = "2.0" +comrak = "0.16" +crossbeam-channel = "0.5" +dap = "0.4.1-alpha" +dashmap = "5.4" +derivative = "2.2" +devault = "0.1" +dialoguer = "0.11" +dirs = "3.0" +downcast-rs = "1.2" +either = "1.9" +ethabi = { package = "fuel-ethabi", version = "18.0" } +etk-asm = { package = "fuel-etk-asm", version = "0.3.1-dev" } +etk-ops = { package = "fuel-etk-ops", version = "0.3.1-dev" } +extension-trait = "1.0" +fd-lock = "4.0" +filecheck = "0.5" +fs_extra = "1.2" +futures = { version = "0.3", default-features = false } +gag = "1.0" +gimli = "0.28" +git2 = "0.19" +gix-url = "0.27" +glob = "0.3" +graph-cycles = "0.1" +hashbrown = "0.13" +hex = "0.4" +horrorshow = "0.8" +im = "15.0" +in_definite = "1.0" +include_dir = "0.7" +indexmap = "2.0" +indoc = "2.0" +insta = "1.39" +ipfs-api-backend-hyper = "0.6" +itertools = "0.10" +lazy_static = "1.4" +libp2p-identity = "0.2" +libtest-mimic = "0.7" +lsp-types = "0.94" +mdbook = { version = "0.4", default-features = false } +miden = "0.3" +miden-core = "0.3" +minifier = "0.3" +notify = "5.0" +notify-debouncer-mini = "0.2" +num-bigint = "0.4" +num-traits = "0.2" +object = "0.32" +once_cell = "1.18" +opener = "0.5" +parking_lot = "0.12" +paste = "1.0" +peg = "0.7" +pest = "2.1" +pest_derive = "2.1" +petgraph = "0.6" +phf = "0.10" +pretty_assertions = "1.4" +prettydiff = "0.6" +proc-macro2 = "1.0" +quote = "1.0" +rand = "0.8" +rayon = "1.7" +rayon-cond = "0.3" +regex = "1.10" +reqwest = "0.12" +revm = "2.3" +ropey = "1.5" +rpassword = "7.2" +rustc-hash = "1.1" +semver = "1.0" +serde = "1.0" +serde_ignored = "0.1" +serde_json = "1.0" +serde_with = "3.3" +serde_yaml = "0.9" +serial_test = "3.0" +sha2 = "0.9" +sha3 = "0.10" +shellfish = "0.6" +slotmap = "1.0" +smallvec = "1.7" +strsim = "0.11" +strum = "0.24" +syn = "1.0" +taplo = "0.7" +tar = "0.4" +tempfile = "3" +term-table = "1.3" +termion = "2.0" +textwrap = "0.16" +thiserror = "1.0" +tikv-jemallocator = "0.5" +tokio = "1.12" +toml = "0.8" +toml_edit = "0.21" +tower = { version = "0.4", default-features = false } +tower-lsp = "0.20" +tracing = "0.1" +tracing-subscriber = "0.3" +uint = "0.9" +unicode-bidi = "0.3" +unicode-xid = "0.2" +url = "2.2" +urlencoding = "2.1" +uwuify = "^0.2" +vec1 = "1.8" +vte = "0.13" +walkdir = "2.3" +whoami = "1.1" diff --git a/forc-pkg/Cargo.toml b/forc-pkg/Cargo.toml index b5d0346327c..7c5618d4a4e 100644 --- a/forc-pkg/Cargo.toml +++ b/forc-pkg/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "forc-pkg" -version = "0.63.6" +version.workspace = true description = "Building, locking, fetching and updating Sway projects as Forc packages." authors.workspace = true edition.workspace = true @@ -9,38 +9,38 @@ license.workspace = true repository.workspace = true [dependencies] -ansi_term = "0.12" -anyhow = "1" -byte-unit = "5.1.4" -cid = "0.11" -forc-tracing = { version = "0.63.6", path = "../forc-tracing" } -forc-util = { version = "0.63.6", path = "../forc-util" } -fuel-abi-types = { workspace = true } -futures = "0.3" -git2 = { version = "0.19", features = [ +ansi_term.workspace = true +anyhow.workspace = true +byte-unit.workspace = true +cid.workspace = true +forc-tracing.workspace = true +forc-util.workspace = true +fuel-abi-types.workspace = true +futures.workspace = true +git2 = { workspace = true, features = [ "vendored-libgit2", "vendored-openssl", ] } -gix-url = { version = "0.27", features = ["serde"] } -hex = "0.4.3" -ipfs-api-backend-hyper = { version = "0.6", features = ["with-builder"] } -petgraph = { version = "0.6", features = ["serde-1"] } -reqwest = "0.12" -semver = { version = "1.0", features = ["serde"] } -serde = { version = "1.0", features = ["derive"] } -serde_ignored = "0.1.9" -serde_json = "1.0" -serde_with = "3.3.0" -sway-core = { version = "0.63.6", path = "../sway-core" } -sway-error = { version = "0.63.6", path = "../sway-error" } -sway-types = { version = "0.63.6", path = "../sway-types" } -sway-utils = { version = "0.63.6", path = "../sway-utils" } -tar = "0.4.38" -toml = { version = "0.8", features = ["parse"] } -tracing = "0.1" -url = { version = "2.2", features = ["serde"] } -vec1 = "1.8.0" -walkdir = "2" +gix-url = { workspace = true, features = ["serde"] } +hex.workspace = true +ipfs-api-backend-hyper = { workspace = true, features = ["with-builder"] } +petgraph = { workspace = true, features = ["serde-1"] } +reqwest.workspace = true +semver = { workspace = true, features = ["serde"] } +serde = { workspace = true, features = ["derive"] } +serde_ignored.workspace = true +serde_json.workspace = true +serde_with.workspace = true +sway-core.workspace = true +sway-error.workspace = true +sway-types.workspace = true +sway-utils.workspace = true +tar.workspace = true +toml = { workspace = true, features = ["parse"] } +tracing.workspace = true +url = { workspace = true, features = ["serde"] } +vec1.workspace = true +walkdir.workspace = true [dev-dependencies] regex = "^1.10.2" diff --git a/forc-plugins/forc-client/Cargo.toml b/forc-plugins/forc-client/Cargo.toml index 09ba62cf416..8b7f1455daf 100644 --- a/forc-plugins/forc-client/Cargo.toml +++ b/forc-plugins/forc-client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "forc-client" -version = "0.63.6" +version.workspace = true description = "A `forc` plugin for interacting with a Fuel node." authors.workspace = true edition.workspace = true @@ -9,45 +9,44 @@ license.workspace = true repository.workspace = true [dependencies] -anyhow = "1" -async-trait = "0.1.58" -chrono = { version = "0.4", default-features = false, features = ["std"] } -clap = { version = "4.5.4", features = ["derive", "env"] } -devault = "0.1" -dialoguer = "0.11" -forc = { version = "0.63.6", path = "../../forc" } -forc-pkg = { version = "0.63.6", path = "../../forc-pkg" } -forc-tracing = { version = "0.63.6", path = "../../forc-tracing" } -forc-tx = { version = "0.63.6", path = "../forc-tx" } -forc-util = { version = "0.63.6", path = "../../forc-util" } -forc-wallet = { workspace = true } -fuel-abi-types = { workspace = true } +anyhow.workspace = true +async-trait.workspace = true +chrono = { workspace = true, features = ["std"] } +clap = { workspace = true, features = ["derive", "env"] } +devault.workspace = true +dialoguer.workspace = true +forc.workspace = true +forc-pkg.workspace = true +forc-tracing.workspace = true +forc-tx.workspace = true +forc-util.workspace = true +forc-wallet.workspace = true +fuel-abi-types.workspace = true fuel-core-client = { workspace = true, features = ["subscriptions"] } -fuel-core-types = { workspace = true } -fuel-crypto = { workspace = true } +fuel-core-types.workspace = true +fuel-crypto.workspace = true fuel-tx = { workspace = true, features = ["test-helpers"] } -fuel-vm = { workspace = true } -fuels = { workspace = true } -fuels-accounts = { workspace = true } -fuels-core = { workspace = true } -futures = "0.3" -hex = "0.4.3" -rand = "0.8" -rpassword = "7.2" -serde = "1.0" -serde_json = "1" -sway-core = { version = "0.63.6", path = "../../sway-core" } -sway-types = { version = "0.63.6", path = "../../sway-types" } -sway-utils = { version = "0.63.6", path = "../../sway-utils" } -tokio = { version = "1.8", features = ["macros", "rt-multi-thread", "process"] } -toml_edit = "0.21.1" -tracing = "0.1" +fuel-vm.workspace = true +fuels.workspace = true +fuels-accounts.workspace = true +fuels-core.workspace = true +futures.workspace = true +hex.workspace = true +rand.workspace = true +rpassword.workspace = true +serde.workspace = true +serde_json.workspace = true +sway-core.workspace = true +sway-types.workspace = true +sway-utils.workspace = true +tokio = { workspace = true, features = ["macros", "process", "rt-multi-thread"] } +toml_edit.workspace = true +tracing.workspace = true [dev-dependencies] portpicker = "0.1.1" rexpect = "0.5" tempfile = "3" -toml_edit = "0.21.1" [build-dependencies] regex = "1.5.4" diff --git a/forc-plugins/forc-crypto/Cargo.toml b/forc-plugins/forc-crypto/Cargo.toml index 8860198c657..1faf2be8a23 100644 --- a/forc-plugins/forc-crypto/Cargo.toml +++ b/forc-plugins/forc-crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "forc-crypto" -version = "0.63.6" +version.workspace = true description = "A `forc` plugin for handling various cryptographic operations and conversions." authors.workspace = true edition.workspace = true @@ -9,23 +9,23 @@ license.workspace = true repository.workspace = true [dependencies] -anyhow = "1.0.75" -async-trait = "0.1.58" -atty = "0.2.14" -clap = { version = "4.5.4", features = ["derive", "env"] } -forc-tracing = { version = "0.63.6", path = "../../forc-tracing" } -forc-util = { version = "0.63.6", path = "../../forc-util" } -fuel-core-types = { workspace = true } +anyhow.workspace = true +async-trait.workspace = true +atty.workspace = true +clap = { workspace = true, features = ["derive", "env"] } +forc-tracing.workspace = true +forc-util.workspace = true +fuel-core-types.workspace = true fuel-crypto = { workspace = true, features = ["random"] } -fuels-core = { workspace = true } -futures = "0.3" -hex = "0.4.3" -libp2p-identity = { version = "0.2.4", features = ["secp256k1", "peerid"] } -rand = "0.8" -serde = "1.0" -serde_json = "1" -serde_yaml = "0.9.27" -sha3 = "0.10.8" -termion = "2.0.1" -tokio = { version = "1.8", features = ["macros", "rt-multi-thread", "process"] } -tracing = "0.1" +fuels-core.workspace = true +futures.workspace = true +hex.workspace = true +libp2p-identity = { workspace = true, features = ["peerid", "secp256k1"] } +rand.workspace = true +serde.workspace = true +serde_json.workspace = true +serde_yaml.workspace = true +sha3.workspace = true +termion.workspace = true +tokio = { workspace = true, features = ["macros", "rt-multi-thread", "process"] } +tracing.workspace = true diff --git a/forc-plugins/forc-debug/Cargo.toml b/forc-plugins/forc-debug/Cargo.toml index afb416da4f2..4911d214c2e 100644 --- a/forc-plugins/forc-debug/Cargo.toml +++ b/forc-plugins/forc-debug/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "forc-debug" -version = "0.63.6" +version.workspace = true description = "Supports debugging Sway code via CLI and DAP server." authors.workspace = true edition.workspace = true @@ -9,26 +9,26 @@ license.workspace = true repository.workspace = true [dependencies] -anyhow = "1.0" # Used by the examples and for conversion only -clap = { version = "4.5.4", features = ["derive", "env"] } -dap = "0.4.1-alpha1" -forc-pkg = { version = "0.63.6", path = "../../forc-pkg" } -forc-test = { version = "0.63.6", path = "../../forc-test" } -forc-tracing = { version = "0.63.6", path = "../../forc-tracing" } -fuel-core-client = { workspace = true } +anyhow.workspace = true +clap = { workspace = true, features = ["derive", "env"] } +dap.workspace = true +forc-pkg.workspace = true +forc-test.workspace = true +forc-tracing.workspace = true +fuel-core-client.workspace = true fuel-types = { workspace = true, features = ["serde"] } fuel-vm = { workspace = true, features = ["serde"] } -rayon = "1.7.0" -serde = "1.0" -serde_json = "1.0" -shellfish = { version = "0.6.0", features = ["rustyline", "async", "tokio"] } -sway-core = { version = "0.63.6", path = "../../sway-core" } -sway-types = { version = "0.63.6", path = "../../sway-types" } -thiserror = "1.0" -tokio = { version = "1.8", features = [ - "net", +rayon.workspace = true +serde.workspace = true +serde_json.workspace = true +shellfish = { workspace = true, features = ["async", "rustyline", "tokio"] } +sway-core.workspace = true +sway-types.workspace = true +thiserror.workspace = true +tokio = { workspace = true, features = [ "io-util", "macros", + "net", "rt-multi-thread", ] } diff --git a/forc-plugins/forc-doc/Cargo.toml b/forc-plugins/forc-doc/Cargo.toml index a33a68783c1..e6780e0fe80 100644 --- a/forc-plugins/forc-doc/Cargo.toml +++ b/forc-plugins/forc-doc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "forc-doc" -version = "0.63.6" +version.workspace = true description = "Build the documentation for the local package and all dependencies. The output is placed in `out/doc` in the same format as the project." authors.workspace = true edition.workspace = true @@ -9,23 +9,23 @@ license.workspace = true repository.workspace = true [dependencies] -anyhow = "1.0.65" -clap = { version = "4.5.4", features = ["derive"] } -comrak = "0.16" -forc-pkg = { version = "0.63.6", path = "../../forc-pkg" } -forc-tracing = { version = "0.63.6", path = "../../forc-tracing" } -forc-util = { version = "0.63.6", path = "../../forc-util" } -horrorshow = "0.8.4" -include_dir = "0.7.3" -minifier = "0.3.0" -opener = "0.5.0" -serde = "1.0" -serde_json = "1.0" -sway-ast = { version = "0.63.6", path = "../../sway-ast" } -sway-core = { version = "0.63.6", path = "../../sway-core" } -sway-lsp = { version = "0.63.6", path = "../../sway-lsp" } -sway-types = { version = "0.63.6", path = "../../sway-types" } -swayfmt = { version = "0.63.6", path = "../../swayfmt" } +anyhow.workspace = true +clap = { workspace = true, features = ["derive"] } +comrak.workspace = true +forc-pkg.workspace = true +forc-tracing.workspace = true +forc-util.workspace = true +horrorshow.workspace = true +include_dir.workspace = true +minifier.workspace = true +opener.workspace = true +serde.workspace = true +serde_json.workspace = true +sway-ast.workspace = true +sway-core.workspace = true +sway-lsp.workspace = true +sway-types.workspace = true +swayfmt.workspace = true [dev-dependencies] dir_indexer = "0.0.2" diff --git a/forc-plugins/forc-fmt/Cargo.toml b/forc-plugins/forc-fmt/Cargo.toml index 5826b2c8393..d1fdedcce41 100644 --- a/forc-plugins/forc-fmt/Cargo.toml +++ b/forc-plugins/forc-fmt/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "forc-fmt" -version = "0.63.6" +version.workspace = true description = "A `forc` plugin for running the Sway code formatter." authors.workspace = true edition.workspace = true @@ -9,14 +9,14 @@ license.workspace = true repository.workspace = true [dependencies] -anyhow = "1" -clap = { version = "4.5.4", features = ["derive"] } -forc-pkg = { version = "0.63.6", path = "../../forc-pkg" } -forc-tracing = { version = "0.63.6", path = "../../forc-tracing" } -forc-util = { version = "0.63.6", path = "../../forc-util" } -prettydiff = "0.5" -sway-core = { version = "0.63.6", path = "../../sway-core" } -sway-utils = { version = "0.63.6", path = "../../sway-utils" } -swayfmt = { version = "0.63.6", path = "../../swayfmt" } -taplo = "0.7" -tracing = "0.1" +anyhow.workspace = true +clap = { workspace = true, features = ["derive"] } +forc-pkg.workspace = true +forc-tracing.workspace = true +forc-util.workspace = true +prettydiff.workspace = true +sway-core.workspace = true +sway-utils.workspace = true +swayfmt.workspace = true +taplo.workspace = true +tracing.workspace = true diff --git a/forc-plugins/forc-lsp/Cargo.toml b/forc-plugins/forc-lsp/Cargo.toml index 5cfdda9ff51..83ed86b61ad 100644 --- a/forc-plugins/forc-lsp/Cargo.toml +++ b/forc-plugins/forc-lsp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "forc-lsp" -version = "0.63.6" +version.workspace = true description = "A simple `forc` plugin for starting the sway language server." authors.workspace = true edition.workspace = true @@ -9,8 +9,8 @@ license.workspace = true repository.workspace = true [dependencies] -anyhow = "1" -clap = { version = "4.5.4", features = ["derive"] } -sway-lsp = { version = "0.63.6", path = "../../sway-lsp" } -tikv-jemallocator = "0.5" -tokio = { version = "1.8" } +anyhow.workspace = true +clap = { workspace = true, features = ["derive"] } +sway-lsp.workspace = true +tikv-jemallocator.workspace = true +tokio.workspace = true diff --git a/forc-plugins/forc-tx/Cargo.toml b/forc-plugins/forc-tx/Cargo.toml index 82990ca6ba8..a6a552585a6 100644 --- a/forc-plugins/forc-tx/Cargo.toml +++ b/forc-plugins/forc-tx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "forc-tx" -version = "0.63.6" +version.workspace = true description = "A `forc` plugin for constructing transactions." authors.workspace = true edition.workspace = true @@ -16,12 +16,12 @@ name = "forc-tx" path = "src/main.rs" [dependencies] -anyhow = "1" -clap = { version = "4.5.4", features = ["derive", "env"] } -devault = "0.1" -forc-util = { version = "0.63.6", path = "../../forc-util" } -fuel-tx = { workspace = true, features = ["serde", "test-helpers", "random"] } +anyhow.workspace = true +clap = { workspace = true, features = ["derive", "env"] } +devault.workspace = true +forc-util.workspace = true +fuel-tx = { workspace = true, features = ["random", "serde", "test-helpers"] } fuel-types = { workspace = true, features = ["serde"] } -serde = "1.0" -serde_json = { version = "1" } -thiserror = "1" +serde.workspace = true +serde_json.workspace = true +thiserror.workspace = true diff --git a/forc-test/Cargo.toml b/forc-test/Cargo.toml index 67c3a60db08..3034b60dfbf 100644 --- a/forc-test/Cargo.toml +++ b/forc-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "forc-test" -version = "0.63.6" +version.workspace = true description = "A library for building and running Sway unit tests within Forc packages." authors.workspace = true edition.workspace = true @@ -9,13 +9,13 @@ license.workspace = true repository.workspace = true [dependencies] -anyhow = "1" -forc-pkg = { version = "0.63.6", path = "../forc-pkg" } -fuel-abi-types = { workspace = true } +anyhow.workspace = true +forc-pkg.workspace = true +fuel-abi-types.workspace = true fuel-tx = { workspace = true, features = ["test-helpers"] } fuel-vm = { workspace = true, features = ["random", "test-helpers"] } -fuels-core = { workspace = true } -rand = "0.8" -rayon = "1.7.0" -sway-core = { version = "0.63.6", path = "../sway-core" } -sway-types = { version = "0.63.6", path = "../sway-types" } +fuels-core.workspace = true +rand.workspace = true +rayon.workspace = true +sway-core.workspace = true +sway-types.workspace = true diff --git a/forc-tracing/Cargo.toml b/forc-tracing/Cargo.toml index a851aa674c1..85240eec345 100644 --- a/forc-tracing/Cargo.toml +++ b/forc-tracing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "forc-tracing" -version = "0.63.6" +version.workspace = true description = "Tracing utility shared between forc crates." authors.workspace = true edition.workspace = true @@ -9,9 +9,9 @@ license.workspace = true repository.workspace = true [dependencies] -ansi_term = "0.12" -tracing = "0.1" -tracing-subscriber = { version = "0.3", features = ["ansi", "env-filter", "json"] } +ansi_term.workspace = true +tracing.workspace = true +tracing-subscriber = { workspace = true, features = ["ansi", "env-filter", "json"] } [dev-dependencies] tracing-test = "0.2" \ No newline at end of file diff --git a/forc-util/Cargo.toml b/forc-util/Cargo.toml index 838f6662e4a..47e702cec70 100644 --- a/forc-util/Cargo.toml +++ b/forc-util/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "forc-util" -version = "0.63.6" +version.workspace = true description = "Utility items shared between forc crates." authors.workspace = true edition.workspace = true @@ -9,31 +9,31 @@ license.workspace = true repository.workspace = true [dependencies] -annotate-snippets = { version = "0.10.1" } -ansi_term = "0.12" -anyhow = "1" -clap = { version = "4.5.4", features = ["cargo", "derive", "env"] } -dirs = "3.0.2" -fd-lock = "4.0" -forc-tracing = { version = "0.63.6", path = "../forc-tracing" } +annotate-snippets.workspace = true +ansi_term.workspace = true +anyhow.workspace = true +clap = { workspace = true, features = ["cargo", "derive", "env"] } +dirs.workspace = true +fd-lock.workspace = true +forc-tracing.workspace = true fuel-tx = { workspace = true, features = ["serde"], optional = true } -hex = "0.4.3" -paste = "1.0.14" -regex = "1.10.2" -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0.73" -serial_test = "3.0.0" -sway-core = { version = "0.63.6", path = "../sway-core" } -sway-error = { version = "0.63.6", path = "../sway-error" } -sway-types = { version = "0.63.6", path = "../sway-types" } -sway-utils = { version = "0.63.6", path = "../sway-utils" } -tracing = "0.1" -tracing-subscriber = { version = "0.3", features = [ +hex.workspace = true +paste.workspace = true +regex.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +serial_test.workspace = true +sway-core.workspace = true +sway-error.workspace = true +sway-types.workspace = true +sway-utils.workspace = true +tracing.workspace = true +tracing-subscriber = { workspace = true, features = [ "ansi", "env-filter", "json", ] } -unicode-xid = "0.2.2" +unicode-xid.workspace = true [features] default = ["fuel-tx"] diff --git a/forc/Cargo.toml b/forc/Cargo.toml index 1c3908da5b7..2f5d6dda481 100644 --- a/forc/Cargo.toml +++ b/forc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "forc" -version = "0.63.6" +version.workspace = true description = "Fuel Orchestrator." authors.workspace = true edition.workspace = true @@ -17,35 +17,35 @@ name = "forc" path = "src/main.rs" [dependencies] -annotate-snippets = { version = "0.10.1" } -ansi_term = "0.12" -anyhow = "1.0.41" -clap = { version = "4.5.4", features = ["cargo", "derive", "env"] } -clap_complete = "4.5.2" -clap_complete_fig = "4.5.0" -forc-pkg = { version = "0.63.6", path = "../forc-pkg" } -forc-test = { version = "0.63.6", path = "../forc-test" } -forc-tracing = { version = "0.63.6", path = "../forc-tracing" } -forc-util = { version = "0.63.6", path = "../forc-util" } -fs_extra = "1.2" -fuel-asm = { workspace = true } -hex = "0.4.3" -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0.73" -sway-core = { version = "0.63.6", path = "../sway-core" } -sway-error = { version = "0.63.6", path = "../sway-error" } -sway-ir = { version = "0.63.6", path = "../sway-ir" } -sway-types = { version = "0.63.6", path = "../sway-types" } -sway-utils = { version = "0.63.6", path = "../sway-utils" } -term-table = "1.3" -tokio = { version = "1.8.0", features = ["macros", "rt-multi-thread"] } -toml = { version = "0.7", features = ["parse"] } -toml_edit = "0.19" -tracing = "0.1" -url = "2.2" -uwuify = { version = "^0.2", optional = true } -walkdir = "2.3" -whoami = "1.1" +annotate-snippets.workspace = true +ansi_term.workspace = true +anyhow.workspace = true +clap = { workspace = true, features = ["cargo", "derive", "env"] } +clap_complete.workspace = true +clap_complete_fig.workspace = true +forc-pkg.workspace = true +forc-test.workspace = true +forc-tracing.workspace = true +forc-util.workspace = true +fs_extra.workspace = true +fuel-asm.workspace = true +hex.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +sway-core.workspace = true +sway-error.workspace = true +sway-ir.workspace = true +sway-types.workspace = true +sway-utils.workspace = true +term-table.workspace = true +tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } +toml = { workspace = true, features = ["parse"] } +toml_edit.workspace = true +tracing.workspace = true +url.workspace = true +uwuify = { workspace = true, optional = true } +walkdir.workspace = true +whoami.workspace = true [features] default = [] diff --git a/scripts/mdbook-forc-documenter/Cargo.toml b/scripts/mdbook-forc-documenter/Cargo.toml index eae79eff1ef..8db19ab6db6 100644 --- a/scripts/mdbook-forc-documenter/Cargo.toml +++ b/scripts/mdbook-forc-documenter/Cargo.toml @@ -13,9 +13,9 @@ name = "mdbook_forc_documenter" path = "src/lib.rs" [dependencies] -anyhow = "1" -clap = { version = "4.5.4", features = ["derive"] } -mdbook = { version = "0.4", default-features = false } -semver = "1.0" -serde = "1.0" -serde_json = "1.0" +anyhow.workspace = true +clap = { workspace = true, features = ["derive"] } +mdbook.workspace = true +semver.workspace = true +serde.workspace = true +serde_json.workspace = true diff --git a/sway-ast/Cargo.toml b/sway-ast/Cargo.toml index 1f442bb6933..ad73333213d 100644 --- a/sway-ast/Cargo.toml +++ b/sway-ast/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sway-ast" -version = "0.63.6" +version.workspace = true description = "Sway's AST" authors.workspace = true edition.workspace = true @@ -9,12 +9,12 @@ license.workspace = true repository.workspace = true [dependencies] -extension-trait = "1.0.1" -num-bigint = { version = "0.4.3", features = ["serde"] } -num-traits = "0.2.14" -serde = { version = "1.0", features = ["derive"] } -sway-error = { version = "0.63.6", path = "../sway-error" } -sway-types = { version = "0.63.6", path = "../sway-types" } +extension-trait.workspace = true +num-bigint = { workspace = true, features = ["serde"] } +num-traits.workspace = true +serde = { workspace = true, features = ["derive"] } +sway-error.workspace = true +sway-types.workspace = true [lints.clippy] iter_over_hash_type = "deny" diff --git a/sway-core/Cargo.toml b/sway-core/Cargo.toml index 20931b78bda..d1500d0dfdb 100644 --- a/sway-core/Cargo.toml +++ b/sway-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sway-core" -version = "0.63.6" +version.workspace = true description = "Sway core language." authors.workspace = true edition.workspace = true @@ -9,46 +9,44 @@ license.workspace = true repository.workspace = true [dependencies] -clap = { version = "4.5.4", features = ["derive"] } -derivative = "2.2.0" -dirs = "3.0" -either = "1.9.0" -ethabi = { package = "fuel-ethabi", version = "18.0.0" } -etk-asm = { package = "fuel-etk-asm", version = "0.3.1-dev", features = [ - "backtraces", -] } -etk-ops = { package = "fuel-etk-ops", version = "0.3.1-dev" } -fuel-abi-types = { workspace = true } +clap = { workspace = true, features = ["derive"] } +derivative.workspace = true +dirs.workspace = true +either.workspace = true +ethabi.workspace = true +etk-asm = { workspace = true, features = ["backtraces"] } +etk-ops.workspace = true +fuel-abi-types.workspace = true fuel-vm = { workspace = true, features = ["serde"] } -gimli = "0.28.1" -graph-cycles = "0.1.0" -hashbrown = "0.13.1" -hex = { version = "0.4", optional = true } -im = "15.0" -indexmap = "2.0.0" -itertools = "0.10" -lazy_static = "1.4" -miden-core = "0.3.0" -object = { version = "0.32.2", features = ["write"] } -parking_lot = "0.12" -pest = "2.1.3" -pest_derive = "2.1" -petgraph = "0.6" -rustc-hash = "1.1.0" -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0.91" -sha2 = "0.9" -strum = { version = "0.24.1", features = ["derive"] } -sway-ast = { version = "0.63.6", path = "../sway-ast" } -sway-error = { version = "0.63.6", path = "../sway-error" } -sway-ir = { version = "0.63.6", path = "../sway-ir" } -sway-parse = { version = "0.63.6", path = "../sway-parse" } -sway-types = { version = "0.63.6", path = "../sway-types" } -sway-utils = { version = "0.63.6", path = "../sway-utils" } -thiserror = "1.0" -tracing = "0.1" -uint = "0.9" -vec1 = "1.8.0" +gimli.workspace = true +graph-cycles.workspace = true +hashbrown.workspace = true +hex = { workspace = true, optional = true } +im.workspace = true +indexmap.workspace = true +itertools.workspace = true +lazy_static.workspace = true +miden-core.workspace = true +object = { workspace = true, features = ["write"] } +parking_lot.workspace = true +pest.workspace = true +pest_derive.workspace = true +petgraph.workspace = true +rustc-hash.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +sha2.workspace = true +strum = { workspace = true, features = ["derive"] } +sway-ast.workspace = true +sway-error.workspace = true +sway-ir.workspace = true +sway-parse.workspace = true +sway-types.workspace = true +sway-utils.workspace = true +thiserror.workspace = true +tracing.workspace = true +uint.workspace = true +vec1.workspace = true [target.'cfg(not(target_os = "macos"))'.dependencies] sysinfo = "0.29.0" diff --git a/sway-error/Cargo.toml b/sway-error/Cargo.toml index 8f4f39312bf..c8810d96b91 100644 --- a/sway-error/Cargo.toml +++ b/sway-error/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sway-error" -version = "0.63.6" +version.workspace = true description = "Sway's error handling" authors.workspace = true edition.workspace = true @@ -9,14 +9,14 @@ license.workspace = true repository.workspace = true [dependencies] -either = "1.9.0" -in_definite = "1.0.0" -num-traits = "0.2.14" -smallvec = "1.7" -strsim = "0.11.1" -sway-types = { version = "0.63.6", path = "../sway-types" } -thiserror = "1.0" -uwuify = { version = "^0.2", optional = true } +either.workspace = true +in_definite.workspace = true +num-traits.workspace = true +smallvec.workspace = true +strsim.workspace = true +sway-types.workspace = true +thiserror.workspace = true +uwuify = { workspace = true, optional = true } [features] default = [] diff --git a/sway-ir/Cargo.toml b/sway-ir/Cargo.toml index c81d8eed1a9..a3c4b58f722 100644 --- a/sway-ir/Cargo.toml +++ b/sway-ir/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sway-ir" -version = "0.63.6" +version.workspace = true description = "Sway intermediate representation." authors.workspace = true edition.workspace = true @@ -9,19 +9,19 @@ license.workspace = true repository.workspace = true [dependencies] -anyhow = "1.0" -downcast-rs = "1.2.0" -filecheck = "0.5" -indexmap = { version = "2.0.0", features = ["rayon"] } -itertools = "0.10.3" -once_cell = "1.18.0" -peg = "0.7" -prettydiff = "0.6.4" -rustc-hash = "1.1.0" -slotmap = "1.0.7" -sway-ir-macros = { version = "0.63.6", path = "sway-ir-macros" } -sway-types = { version = "0.63.6", path = "../sway-types" } -sway-utils = { version = "0.63.6", path = "../sway-utils" } +anyhow.workspace = true +downcast-rs.workspace = true +filecheck.workspace = true +indexmap = { workspace = true, features = ["rayon"] } +itertools.workspace = true +once_cell.workspace = true +peg.workspace = true +prettydiff.workspace = true +rustc-hash.workspace = true +slotmap.workspace = true +sway-ir-macros.workspace = true +sway-types.workspace = true +sway-utils.workspace = true [lints.clippy] iter_over_hash_type = "deny" diff --git a/sway-ir/sway-ir-macros/Cargo.toml b/sway-ir/sway-ir-macros/Cargo.toml index 6f2fc7ecae7..f0efd249588 100644 --- a/sway-ir/sway-ir-macros/Cargo.toml +++ b/sway-ir/sway-ir-macros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sway-ir-macros" -version = "0.63.6" +version.workspace = true description = "Macros for sway's intermediate representation." authors.workspace = true edition.workspace = true @@ -12,10 +12,10 @@ repository.workspace = true proc-macro = true [dependencies] -itertools = "0.10.3" -proc-macro2 = "1.0.43" -quote = "1.0.21" -syn = { version = "1.0.99", features = ["derive", "extra-traits"] } +itertools.workspace = true +proc-macro2.workspace = true +quote.workspace = true +syn = { workspace = true, features = ["derive", "extra-traits", "parsing"] } [lints.clippy] iter_over_hash_type = "deny" diff --git a/sway-lsp/Cargo.toml b/sway-lsp/Cargo.toml index 34c835e967f..9a0dc17976a 100644 --- a/sway-lsp/Cargo.toml +++ b/sway-lsp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sway-lsp" -version = "0.63.6" +version.workspace = true description = "LSP server for Sway." authors.workspace = true edition.workspace = true @@ -8,36 +8,39 @@ homepage.workspace = true license.workspace = true repository.workspace = true +[package.metadata.cargo-udeps.ignore] +normal = ["tower"] + [dependencies] -anyhow = "1.0.41" -crossbeam-channel = "0.5" -dashmap = "5.4" -fd-lock = "4.0" -forc-pkg = { version = "0.63.6", path = "../forc-pkg" } -forc-tracing = { version = "0.63.6", path = "../forc-tracing" } -forc-util = { version = "0.63.6", path = "../forc-util" } -indexmap = { version = "2.0.0", features = ["rayon"] } -lsp-types = { version = "0.94", features = ["proposed"] } -notify = "5.0.0" -notify-debouncer-mini = { version = "0.2.0" } -parking_lot = "0.12.1" -proc-macro2 = "1.0.5" -quote = "1.0.9" -rayon = "1.5.0" -rayon-cond = "0.3" -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0.60" -sway-ast = { version = "0.63.6", path = "../sway-ast" } -sway-core = { version = "0.63.6", path = "../sway-core" } -sway-error = { version = "0.63.6", path = "../sway-error" } -sway-parse = { version = "0.63.6", path = "../sway-parse" } -sway-types = { version = "0.63.6", path = "../sway-types" } -sway-utils = { version = "0.63.6", path = "../sway-utils" } -swayfmt = { version = "0.63.6", path = "../swayfmt" } -syn = { version = "1.0.73", features = ["full"] } -tempfile = "3" -thiserror = "1.0.30" -tokio = { version = "1.3", features = [ +anyhow.workspace = true +crossbeam-channel.workspace = true +dashmap.workspace = true +fd-lock.workspace = true +forc-pkg.workspace = true +forc-tracing.workspace = true +forc-util.workspace = true +indexmap = { workspace = true, features = ["rayon"] } +lsp-types = { workspace = true, features = ["proposed"] } +notify.workspace = true +notify-debouncer-mini.workspace = true +parking_lot.workspace = true +proc-macro2.workspace = true +quote.workspace = true +rayon.workspace = true +rayon-cond.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +sway-ast.workspace = true +sway-core.workspace = true +sway-error.workspace = true +sway-parse.workspace = true +sway-types.workspace = true +sway-utils.workspace = true +swayfmt.workspace = true +syn = { workspace = true, features = ["full"] } +tempfile.workspace = true +thiserror.workspace = true +tokio = { workspace = true, features = [ "fs", "io-std", "io-util", @@ -47,10 +50,10 @@ tokio = { version = "1.3", features = [ "sync", "time", ] } -toml_edit = "0.19" -tower-lsp = { version = "0.20", features = ["proposed"] } -tracing = "0.1" -urlencoding = "2.1.2" +toml_edit.workspace = true +tower-lsp = { workspace = true, features = ["proposed"] } +tracing.workspace = true +urlencoding.workspace = true [dev-dependencies] assert-json-diff = "2.0" diff --git a/sway-lsp/tests/utils/Cargo.toml b/sway-lsp/tests/utils/Cargo.toml index 1901ec8c701..70d174f7237 100644 --- a/sway-lsp/tests/utils/Cargo.toml +++ b/sway-lsp/tests/utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sway-lsp-test-utils" -version = "0.1.0" +version.workspace = true description = "Test utils for the Sway LSP Server." publish = false authors.workspace = true @@ -10,12 +10,12 @@ license.workspace = true repository.workspace = true [dependencies] -assert-json-diff = "2.0" -futures = { version = "0.3", default-features = false, features = ["std", "async-await"] } -lsp-types = { version = "0.94", features = ["proposed"] } -rand = "0.8" -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0.60" -tokio = { version = "1.3", features = ["io-std", "io-util", "macros", "net", "rt-multi-thread", "sync", "time"] } -tower = { version = "0.4.12", default-features = false, features = ["util"] } -tower-lsp = { version = "0.20", features = ["proposed"] } +assert-json-diff.workspace = true +futures = { workspace = true, features = ["async-await", "std"] } +lsp-types = { workspace = true, features = ["proposed"] } +rand.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +tokio = { workspace = true, features = ["io-util", "io-std", "macros", "net", "rt-multi-thread", "sync", "time"] } +tower = { workspace = true, features = ["util"] } +tower-lsp = { workspace = true, features = ["proposed"] } diff --git a/sway-parse/Cargo.toml b/sway-parse/Cargo.toml index dbef9841bf6..eb7ebbc150c 100644 --- a/sway-parse/Cargo.toml +++ b/sway-parse/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sway-parse" -version = "0.63.6" +version.workspace = true description = "Sway's parser" authors.workspace = true edition.workspace = true @@ -9,16 +9,16 @@ license.workspace = true repository.workspace = true [dependencies] -extension-trait = "1.0.1" -num-bigint = "0.4.3" -num-traits = "0.2.14" -phf = { version = "0.10.1", features = ["macros"] } -sway-ast = { version = "0.63.6", path = "../sway-ast" } -sway-error = { version = "0.63.6", path = "../sway-error" } -sway-types = { version = "0.63.6", path = "../sway-types" } -thiserror = "1.0" -unicode-bidi = "0.3.13" -unicode-xid = "0.2.2" +extension-trait.workspace = true +num-bigint.workspace = true +num-traits.workspace = true +phf = { workspace = true, features = ["macros"] } +sway-ast.workspace = true +sway-error.workspace = true +sway-types.workspace = true +thiserror.workspace = true +unicode-bidi.workspace = true +unicode-xid.workspace = true [dev-dependencies] assert_matches = "1.5.0" diff --git a/sway-types/Cargo.toml b/sway-types/Cargo.toml index 699233eb13f..aad3c5e52ac 100644 --- a/sway-types/Cargo.toml +++ b/sway-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sway-types" -version = "0.63.6" +version.workspace = true description = "Sway core types." authors.workspace = true edition.workspace = true @@ -9,19 +9,19 @@ license.workspace = true repository.workspace = true [dependencies] -bytecount = "0.6" -fuel-asm = { workspace = true } -fuel-crypto = { workspace = true } -fuel-tx = { workspace = true } -indexmap = "2.0.0" -lazy_static = "1.4" -num-bigint = "0.4.3" -num-traits = "0.2.16" -parking_lot = "0.12" -rustc-hash = "1.1.0" -serde = { version = "1.0", features = ["derive"] } -sway-utils = { version = "0.63.6", path = "../sway-utils" } -thiserror = "1" +bytecount.workspace = true +fuel-asm.workspace = true +fuel-crypto.workspace = true +fuel-tx.workspace = true +indexmap.workspace = true +lazy_static.workspace = true +num-bigint.workspace = true +num-traits.workspace = true +parking_lot.workspace = true +rustc-hash.workspace = true +serde = { workspace = true, features = ["derive"] } +sway-utils.workspace = true +thiserror.workspace = true [features] no-span-debug = [] diff --git a/sway-utils/Cargo.toml b/sway-utils/Cargo.toml index ea26eceda60..1a379a23d51 100644 --- a/sway-utils/Cargo.toml +++ b/sway-utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sway-utils" -version = "0.63.6" +version.workspace = true description = "Sway common utils." authors.workspace = true edition.workspace = true @@ -9,8 +9,8 @@ license.workspace = true repository.workspace = true [dependencies] -serde = { version = "1.0", features = ["derive"] } -walkdir = "2.3.3" +serde = { workspace = true, features = ["derive"] } +walkdir.workspace = true [lints.clippy] iter_over_hash_type = "deny" diff --git a/swayfmt/Cargo.toml b/swayfmt/Cargo.toml index a96a4a8f079..584bc0320ec 100644 --- a/swayfmt/Cargo.toml +++ b/swayfmt/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "swayfmt" -version = "0.63.6" +version.workspace = true description = "Sway language formatter." authors.workspace = true edition.workspace = true @@ -9,20 +9,20 @@ license.workspace = true repository.workspace = true [dependencies] -anyhow = "1" -forc-tracing = { version = "0.63.6", path = "../forc-tracing" } -indoc = "2.0" -ropey = "1.5" -serde = { version = "1.0", features = ["derive"] } -serde_ignored = "0.1.9" -sway-ast = { version = "0.63.6", path = "../sway-ast" } -sway-core = { version = "0.63.6", path = "../sway-core" } -sway-error = { version = "0.63.6", path = "../sway-error" } -sway-parse = { version = "0.63.6", path = "../sway-parse" } -sway-types = { version = "0.63.6", path = "../sway-types" } -sway-utils = { version = "0.63.6", path = "../sway-utils" } -thiserror = "1.0.30" -toml = { version = "0.7", features = ["parse"] } +anyhow.workspace = true +forc-tracing.workspace = true +indoc.workspace = true +ropey.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_ignored.workspace = true +sway-ast.workspace = true +sway-core.workspace = true +sway-error.workspace = true +sway-parse.workspace = true +sway-types.workspace = true +sway-utils.workspace = true +thiserror.workspace = true +toml = { workspace = true, features = ["parse"] } [dev-dependencies] difference = "2.0.0" diff --git a/test/Cargo.toml b/test/Cargo.toml index 9d1d5248d68..932c09590ae 100644 --- a/test/Cargo.toml +++ b/test/Cargo.toml @@ -6,39 +6,39 @@ authors.workspace = true edition.workspace = true [dependencies] -anyhow = "1.0.41" -bytes = "1.3.0" -clap = { version = "4.5.4", features = ["derive", "env"] } -colored = "2.0.0" -filecheck = "0.5" -forc = { path = "../forc", features = ["test"], default-features = false } -forc-client = { path = "../forc-plugins/forc-client" } -forc-pkg = { path = "../forc-pkg" } -forc-test = { path = "../forc-test" } -forc-tracing = { path = "../forc-tracing" } +anyhow.workspace = true +bytes.workspace = true +clap = { workspace = true, features = ["derive", "env"] } +colored.workspace = true +filecheck.workspace = true +forc = { workspace = true, features = ["test"] } +forc-client.workspace = true +forc-pkg.workspace = true +forc-test.workspace = true +forc-tracing.workspace = true fuel-vm = { workspace = true, features = ["random"] } -futures = "0.3.24" -gag = "1.0" -glob = "0.3.1" -hex = "0.4.3" -insta = "1.39.0" -libtest-mimic = "0.7.3" -miden = "0.3.0" -prettydiff = "0.6" -rand = "0.8" -regex = "1.7" -revm = "2.3.1" -serde_json = "1.0.73" -sway-core = { path = "../sway-core" } -sway-error = { path = "../sway-error" } -sway-ir = { path = "../sway-ir" } -sway-types = { path = "../sway-types" } -sway-utils = { path = "../sway-utils" } -textwrap = "0.16.0" -tokio = "1.12" -toml = { version = "0.7", features = ["parse"] } -tracing = "0.1" -vte = "0.13.0" +futures.workspace = true +gag.workspace = true +glob.workspace = true +hex.workspace = true +insta.workspace = true +libtest-mimic.workspace = true +miden.workspace = true +prettydiff.workspace = true +rand.workspace = true +regex.workspace = true +revm.workspace = true +serde_json.workspace = true +sway-core.workspace = true +sway-error.workspace = true +sway-ir.workspace = true +sway-types.workspace = true +sway-utils.workspace = true +textwrap.workspace = true +tokio.workspace = true +toml = { workspace = true, features = ["parse"] } +tracing.workspace = true +vte.workspace = true [[test]] name = "tests" diff --git a/test/src/sdk-harness/Cargo.toml b/test/src/sdk-harness/Cargo.toml index d6e74f9ad9f..363dfde5adf 100644 --- a/test/src/sdk-harness/Cargo.toml +++ b/test/src/sdk-harness/Cargo.toml @@ -7,26 +7,27 @@ version = "0.0.0" publish = false [dependencies] -assert_matches = "1.5.0" +assert_matches = "1.5" # Dependencies from the `fuel-core` repository: -fuel-core = { version = "0.35.0", default-features = false } +fuel-core = { version = "0.35", default-features = false } +# Using full semver as the workspace Cargo.toml (see the comment there) fuel-core-client = { version = "0.35.0", default-features = false } # Dependencies from the `fuel-vm` repository: -fuel-vm = { version = "0.56.0", features = ["random"] } +fuel-vm = { version = "0.56", features = ["random"] } # Dependencies from the `fuels-rs` repository: -fuels = { version = "0.66.4", features = ["fuel-core-lib"] } +fuels = { version = "0.66", features = ["fuel-core-lib"] } -hex = "0.4.3" -paste = "1.0.14" -pretty_assertions = "1.4.0" +hex = "0.4" +paste = "1.0" +pretty_assertions = "1.4" rand = "0.8" sha2 = "0.10" -sha3 = "0.10.1" +sha3 = "0.10" tai64 = { version = "4.0", features = ["serde"] } -tokio = { version = "1.12", features = ["rt", "macros"] } +tokio = { version = "1.12", features = ["macros", "rt"] } [[test]] harness = true From 28c8ae46d96d99c55cba9ef991c524b949104878 Mon Sep 17 00:00:00 2001 From: Oksana Date: Sat, 21 Sep 2024 03:15:15 +0300 Subject: [PATCH 027/115] docs: added a link to the Fuel blockchain (#6574) Hello. Made changes to the documentation, namely inserted a link to the blockchain ## Description ## Checklist - [ ] 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. - [ ] 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). - [ ] I have requested a review from the relevant team or maintainers. Co-authored-by: Joshua Batty --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 14eb838f01f..737fb61ebc7 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![docs](https://docs.rs/forc/badge.svg)](https://docs.rs/forc/) [![discord](https://img.shields.io/badge/chat%20on-discord-orange?&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://discord.gg/xfpK4Pe) -Sway is a language developed for the Fuel blockchain. It is heavily inspired by Rust and aims to bring modern language development and performance to the blockchain ecosystem. +Sway is a language developed for the [Fuel](https://docs.fuel.network/docs/intro/what-is-fuel/) blockchain. It is heavily inspired by Rust and aims to bring modern language development and performance to the blockchain ecosystem. ## Documentation From 3a6e937f9977e9e2e9bb3eebd602b0d5e7cf94a3 Mon Sep 17 00:00:00 2001 From: Joshua Batty Date: Sat, 21 Sep 2024 17:48:32 +1000 Subject: [PATCH 028/115] fix OOB slab panic when creating runnables on a did_save event (#6575) ## Description I noticed that the language server would crash when compilation was triggered from a did save event as we were trying to create runnables from the Engines that had GC applied to it. We now check to ensure that the correct Engines is accessed to avoid a panic when creating runnables. After fixing this bug, I noticed that optimised builds was not returning diagnostics. I've opened #6576 to work on this and have temporarily disabled the optimisation so diagnostics continue to work. ## 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-lsp/src/core/session.rs | 13 ++++++++++++- sway-lsp/src/handlers/notification.rs | 3 ++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/sway-lsp/src/core/session.rs b/sway-lsp/src/core/session.rs index 7f4ed2a9153..c55869d5f66 100644 --- a/sway-lsp/src/core/session.rs +++ b/sway-lsp/src/core/session.rs @@ -477,7 +477,18 @@ pub fn parse_project( if let Some(typed) = &session.compiled_program.read().typed { session.runnables.clear(); - create_runnables(&session.runnables, typed, engines.de(), engines.se()); + let path = uri.to_file_path().unwrap(); + let program_id = program_id_from_path(&path, engines)?; + if let Some(metrics) = session.metrics.get(&program_id) { + // Check if the cached AST was returned by the compiler for the users workspace. + // If it was, then we need to use the original engines. + let engines = if metrics.reused_programs > 0 { + &*session.engines.read() + } else { + engines + }; + create_runnables(&session.runnables, typed, engines.de(), engines.se()); + } } Ok(()) } diff --git a/sway-lsp/src/handlers/notification.rs b/sway-lsp/src/handlers/notification.rs index 928262efb51..7c7dfddf7cc 100644 --- a/sway-lsp/src/handlers/notification.rs +++ b/sway-lsp/src/handlers/notification.rs @@ -111,7 +111,8 @@ pub async fn handle_did_change_text_document( session.clone(), &uri, Some(params.text_document.version), - true, + // TODO: Set this back to true once https://github.com/FuelLabs/sway/issues/6576 is fixed. + false, file_versions, ); Ok(()) From 1d50da1a4b7af80b74c1a70b8010eb1f1ba43a37 Mon Sep 17 00:00:00 2001 From: Alfie John Date: Sat, 21 Sep 2024 18:09:08 +1000 Subject: [PATCH 029/115] Version bump all crate dependencies after the workspace move (#6571) ## Description This is a continuation of #6179, and follows on from PR #6501. These are broken into separate PRs so that we can discuss each PR `HEAD` separately so that the PRs that can get merged, do so quickly. Otherwise, the further along they get stale the more work they all need in order to keep up to `master` without being hard to find which change introduced a possible broken build. This PR only does a version bump to every crate dependency that does not need any code changes to apply cleanly. Following this PR will be a new PR, where every commit updates a single crate along with the files that were needed to be changed in order to work again. The crates that will need code changes are: - tokio 1.12: -> 1.40 - rustc-hash: 1.1 -> 2.0 - miden-core: 0.3 -> 0.10 - notify: 5.0 -> 6.1 - notify-debouncer-mini: 0.2 -> 0.4 - revm: 2.3 -> 14.0 - syn: 1.0 -> 2.0 - tikv-jemallocator: 0.5 -> 0.6 - toml_edit: 0.21 -> 0.22 There should also be a commit to upgrade Rust itself to >= `1.81.0`. ... and for another day, there's 3 crates that will take a bit of time to get working, and so will go under a different issue #6536: - annotate-snippets - lsp-types - uint ## 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. Co-authored-by: Joshua Batty --- Cargo.lock | 480 +++++++++++++++++++------------- Cargo.toml | 48 ++-- sway-lsp/Cargo.toml | 3 - sway-lsp/tests/utils/Cargo.toml | 3 + 4 files changed, 321 insertions(+), 213 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5b7cd0ec58f..e99b3c0383f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -172,6 +172,12 @@ version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +[[package]] +name = "arc-swap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + [[package]] name = "arrayref" version = "0.3.8" @@ -277,7 +283,7 @@ dependencies = [ "cfg-if 1.0.0", "libc", "miniz_oxide", - "object 0.36.3", + "object", "rustc-demangle", "serde", ] @@ -529,6 +535,16 @@ version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +[[package]] +name = "caseless" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808dab3318747be122cb31d36de18d4d1c81277a76f8332a02b81a3d73463d7f" +dependencies = [ + "regex", + "unicode-normalization", +] + [[package]] name = "cast" version = "0.3.0" @@ -705,13 +721,11 @@ checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "clipboard-win" -version = "4.5.0" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7191c27c2357d9b7ef96baac1773290d4ca63b24205b82a3fd8a0637afcf0362" +checksum = "15efe7a882b08f34e38556b14f2fb3daa98769d06c7f0c1b076dfd0d983bc892" dependencies = [ "error-code", - "str-buf", - "winapi", ] [[package]] @@ -864,16 +878,16 @@ dependencies = [ [[package]] name = "comrak" -version = "0.16.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784836d0812dade01579cc0cc9b1684847044e716fd7aa6bffbc172e42199500" +checksum = "c93ab3577cca16b4a1d80a88c2e0cd8b6e969e51696f0bbb0d1dcb0157109832" dependencies = [ + "caseless", "clap 4.5.16", + "derive_builder", "entities", "memchr", "once_cell", - "pest", - "pest_derive", "regex", "shell-words", "slug", @@ -978,9 +992,9 @@ dependencies = [ [[package]] name = "countme" -version = "2.0.4" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "328b822bdcba4d4e402be8d9adb6eebf269f969f8eadef977a553ff3c4fbcb58" +checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636" [[package]] name = "cpufeatures" @@ -1304,6 +1318,20 @@ dependencies = [ "parking_lot_core 0.9.10", ] +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core 0.9.10", +] + [[package]] name = "data-encoding" version = "2.6.0" @@ -1372,6 +1400,37 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive_builder" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd33f37ee6a119146a1781d3356a7c26028f83d779b2e04ecd45fdc75c76877b" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7431fa049613920234f22c47fdc33e6cf3ee83067091ea4277a3f8c4587aae38" +dependencies = [ + "darling 0.20.10", + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "derive_builder_macro" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4abae7035bf79b9877b779505d8cf3749285b80c43941eda66604841889451dc" +dependencies = [ + "derive_builder_core", + "syn 2.0.74", +] + [[package]] name = "derive_more" version = "0.99.18" @@ -1393,9 +1452,9 @@ checksum = "339544cc9e2c4dc3fc7149fd630c5f22263a4fdf18a98afd0075784968b5cf00" [[package]] name = "devault" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc1d36b1abcd53bf307972de38ed2da0a57ddeb762b141420067149d3952c9a" +checksum = "b6bd8149b97caf4a72d9dd6b09a4192fcc07c2551ef5c949ea488554a9994649" dependencies = [ "proc-macro2", "quote", @@ -1456,20 +1515,20 @@ checksum = "363641827cb8d8387a69364aa2f85433db83b8b00270ed2c786235d83bf0aa0a" [[package]] name = "dirs" -version = "3.0.2" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" dependencies = [ - "dirs-sys", + "dirs-sys 0.3.7", ] [[package]] name = "dirs" -version = "4.0.0" +version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" dependencies = [ - "dirs-sys", + "dirs-sys 0.4.1", ] [[package]] @@ -1493,6 +1552,18 @@ dependencies = [ "winapi", ] +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + [[package]] name = "dirs-sys-next" version = "0.1.2" @@ -1723,13 +1794,9 @@ dependencies = [ [[package]] name = "error-code" -version = "2.3.1" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64f18991e7bf11e7ffee451b5318b5c1a73c52d0d0ada6e5a3017c8c1ced6a21" -dependencies = [ - "libc", - "str-buf", -] +checksum = "a5d9305ccc6942a704f4335694ecd3de2ea531b114ac2d51f5f843750787a92f" [[package]] name = "escape8259" @@ -1869,16 +1936,6 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" -[[package]] -name = "fd-lock" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0010f02effd88c702318c5dde0463206be67495d0b4d906ba7c0a8f166cc7f06" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "fd-lock" version = "4.0.2" @@ -2074,7 +2131,7 @@ dependencies = [ "serde_json", "serde_yaml", "sha3", - "termion", + "termion 4.0.2", "tokio", "tracing", ] @@ -2120,7 +2177,7 @@ dependencies = [ "horrorshow", "include_dir", "minifier", - "opener 0.5.2", + "opener", "serde", "serde_json", "sway-ast", @@ -2139,7 +2196,7 @@ dependencies = [ "forc-pkg", "forc-tracing 0.63.6", "forc-util", - "prettydiff", + "prettydiff 0.7.0", "sway-core", "sway-utils", "swayfmt", @@ -2255,8 +2312,8 @@ dependencies = [ "ansi_term", "anyhow", "clap 4.5.16", - "dirs 3.0.2", - "fd-lock 4.0.2", + "dirs 5.0.1", + "fd-lock", "forc-tracing 0.63.6", "fuel-tx", "hex", @@ -2294,7 +2351,7 @@ dependencies = [ "rand", "rpassword", "serde_json", - "termion", + "termion 2.0.3", "tiny-bip39", "tokio", "url", @@ -2939,20 +2996,20 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" -dependencies = [ - "fallible-iterator", - "indexmap 2.4.0", - "stable_deref_trait", -] +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" +dependencies = [ + "fallible-iterator", + "indexmap 2.5.0", + "stable_deref_trait", +] [[package]] name = "git2" @@ -3030,6 +3087,19 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "globset" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", +] + [[package]] name = "graph-cycles" version = "0.1.0" @@ -3074,7 +3144,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.4.0", + "indexmap 2.5.0", "slab", "tokio", "tokio-util", @@ -3093,7 +3163,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.1.0", - "indexmap 2.4.0", + "indexmap 2.5.0", "slab", "tokio", "tokio-util", @@ -3133,12 +3203,6 @@ dependencies = [ "byteorder", ] -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" - [[package]] name = "hashbrown" version = "0.12.3" @@ -3495,7 +3559,7 @@ dependencies = [ "pin-project-lite", "socket2", "tokio", - "tower", + "tower 0.4.13", "tower-service", "tracing", ] @@ -3663,9 +3727,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", "hashbrown 0.14.5", @@ -3710,9 +3774,9 @@ dependencies = [ [[package]] name = "insta" -version = "1.39.0" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "810ae6042d48e2c9e9215043563a58a80b877bc863228a74cf10c49d4620a6f5" +checksum = "6593a41c7a73841868772495db7dc1e8ecab43bb5c0b6da2059246c4b506ab60" dependencies = [ "console", "lazy_static", @@ -3824,6 +3888,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -4150,7 +4223,7 @@ dependencies = [ "log", "memchr", "once_cell", - "opener 0.7.2", + "opener", "pulldown-cmark", "regex", "serde", @@ -4452,42 +4525,40 @@ dependencies = [ [[package]] name = "nix" -version = "0.20.2" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5e06129fb611568ef4e868c14b326274959aa70ff7776e9d55323531c374945" +checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" dependencies = [ + "autocfg", "bitflags 1.2.1", - "cc", "cfg-if 1.0.0", "libc", "memoffset 0.6.5", + "pin-utils", ] [[package]] name = "nix" -version = "0.25.1" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" dependencies = [ - "autocfg", "bitflags 1.2.1", "cfg-if 1.0.0", "libc", - "memoffset 0.6.5", + "memoffset 0.7.1", "pin-utils", ] [[package]] name = "nix" -version = "0.26.4" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 1.2.1", + "bitflags 2.6.0", "cfg-if 1.0.0", "libc", - "memoffset 0.7.1", - "pin-utils", ] [[package]] @@ -4686,27 +4757,18 @@ checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" [[package]] name = "object" -version = "0.32.2" +version = "0.36.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" dependencies = [ "crc32fast", "flate2", "hashbrown 0.14.5", - "indexmap 2.4.0", + "indexmap 2.5.0", "memchr", "ruzstd", ] -[[package]] -name = "object" -version = "0.36.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.19.0" @@ -4747,16 +4809,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" -[[package]] -name = "opener" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "293c15678e37254c15bd2f092314abb4e51d7fdde05c2021279c12631b54f005" -dependencies = [ - "bstr", - "winapi", -] - [[package]] name = "opener" version = "0.7.2" @@ -4823,6 +4875,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "overload" version = "0.1.1" @@ -4835,6 +4893,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2386b4ebe91c2f7f51082d4cefa145d030e33a1842a96b12e4885cc3c01f7a55" +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + [[package]] name = "p256" version = "0.13.2" @@ -4957,9 +5021,9 @@ dependencies = [ [[package]] name = "peg" -version = "0.7.0" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07c0b841ea54f523f7aa556956fbd293bcbe06f2e67d2eb732b7278aaf1d166a" +checksum = "295283b02df346d1ef66052a757869b2876ac29a6bb0ac3f5f7cd44aebe40e8f" dependencies = [ "peg-macros", "peg-runtime", @@ -4967,9 +5031,9 @@ dependencies = [ [[package]] name = "peg-macros" -version = "0.7.0" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aa52829b8decbef693af90202711348ab001456803ba2a98eb4ec8fb70844c" +checksum = "bdad6a1d9cf116a059582ce415d5f5566aabcd4008646779dab7fdc2a9a9d426" dependencies = [ "peg-runtime", "proc-macro2", @@ -4978,9 +5042,9 @@ dependencies = [ [[package]] name = "peg-runtime" -version = "0.7.0" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c719dcf55f09a3a7e764c6649ab594c18a177e3599c467983cdf644bfc0a4088" +checksum = "e3aeb8f54c078314c2065ee649a7241f46b9d8e418e1a9581ba0546657d7aa3a" [[package]] name = "percent-encoding" @@ -5040,27 +5104,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.4.0", + "indexmap 2.5.0", "serde", "serde_derive", ] [[package]] name = "phf" -version = "0.10.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ "phf_macros", "phf_shared", - "proc-macro-hack", ] [[package]] name = "phf_generator" -version = "0.10.0" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" dependencies = [ "phf_shared", "rand", @@ -5068,23 +5131,22 @@ dependencies = [ [[package]] name = "phf_macros" -version = "0.10.0" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" dependencies = [ "phf_generator", "phf_shared", - "proc-macro-hack", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.74", ] [[package]] name = "phf_shared" -version = "0.10.0" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" dependencies = [ "siphasher", ] @@ -5144,7 +5206,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016" dependencies = [ "base64 0.22.1", - "indexmap 2.4.0", + "indexmap 2.5.0", "quick-xml", "serde", "time", @@ -5236,6 +5298,17 @@ dependencies = [ "structopt", ] +[[package]] +name = "prettydiff" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abec3fb083c10660b3854367697da94c674e9e82aa7511014dc958beeb7215e9" +dependencies = [ + "owo-colors 3.5.0", + "pad", + "prettytable-rs", +] + [[package]] name = "prettytable-rs" version = "0.10.0" @@ -5315,12 +5388,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "proc-macro-hack" -version = "0.5.20+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" - [[package]] name = "proc-macro2" version = "1.0.86" @@ -5868,13 +5935,12 @@ dependencies = [ [[package]] name = "rowan" -version = "0.14.1" +version = "0.15.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f77412a3d1f26af0c0783c23b3555a301b1a49805cba7bf9a7827a9e9e285f0" +checksum = "0a542b0253fa46e632d27a1dc5cf7b930de4df8659dc6e720b647fc72147ae3d" dependencies = [ "countme", - "hashbrown 0.11.2", - "memoffset 0.6.5", + "hashbrown 0.14.5", "rustc-hash", "text-size", ] @@ -6047,22 +6113,20 @@ checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "rustyline" -version = "8.2.0" +version = "13.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbd4eaf7a7738f76c98e4f0395253ae853be3eb018f7b0bb57fe1b6c17e31874" +checksum = "02a2d683a4ac90aeef5b1013933f6d977bd37d51ff3f4dad829d4931a7e6be86" dependencies = [ - "bitflags 1.2.1", + "bitflags 2.6.0", "cfg-if 1.0.0", "clipboard-win", - "dirs-next", - "fd-lock 2.0.0", + "fd-lock", + "home", "libc", "log", "memchr", - "nix 0.20.2", + "nix 0.27.1", "radix_trie", - "scopeguard", - "smallvec", "unicode-segmentation", "unicode-width", "utf8parse", @@ -6071,12 +6135,10 @@ dependencies = [ [[package]] name = "ruzstd" -version = "0.5.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58c4eb8a81997cf040a091d1f7e1938aeab6749d3a0dfa73af43cdc32393483d" +checksum = "99c3938e133aac070997ddc684d4b393777d293ba170f2988c8fd5ea2ad4ce21" dependencies = [ - "byteorder", - "derive_more", "twox-hash", ] @@ -6363,7 +6425,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.4.0", + "indexmap 2.5.0", "serde", "serde_derive", "serde_json", @@ -6389,7 +6451,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.5.0", "itoa", "ryu", "serde", @@ -6472,14 +6534,16 @@ checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" [[package]] name = "shellfish" -version = "0.6.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c66e6fc7a668d89939ee241fb342f401f8c11a80da8fb72fd14681f8d47440b" +checksum = "fef42fa3356b28a29aee098d1656681670da7eb15be0e89bba6f05aea540df3d" dependencies = [ "async-trait", "cfg-if 1.0.0", "rustyline", + "thiserror", "tokio", + "version_check", "yansi", ] @@ -6640,12 +6704,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "str-buf" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0" - [[package]] name = "str_indices" version = "0.4.3" @@ -6709,6 +6767,15 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros 0.26.4", +] + [[package]] name = "strum_macros" version = "0.24.3" @@ -6735,6 +6802,19 @@ dependencies = [ "syn 2.0.74", ] +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.74", +] + [[package]] name = "substrate-bn" version = "0.6.0" @@ -6772,23 +6852,23 @@ version = "0.63.6" dependencies = [ "clap 4.5.16", "derivative", - "dirs 3.0.2", + "dirs 5.0.1", "either", "fuel-abi-types", "fuel-ethabi", "fuel-etk-asm", "fuel-etk-ops", "fuel-vm", - "gimli 0.28.1", + "gimli 0.31.0", "graph-cycles", - "hashbrown 0.13.2", + "hashbrown 0.14.5", "hex", "im", - "indexmap 2.4.0", - "itertools 0.10.5", + "indexmap 2.5.0", + "itertools 0.13.0", "lazy_static", "miden-core", - "object 0.32.2", + "object", "parking_lot 0.12.3", "pest", "pest_derive", @@ -6796,8 +6876,8 @@ dependencies = [ "rustc-hash", "serde", "serde_json", - "sha2 0.9.9", - "strum 0.24.1", + "sha2 0.10.8", + "strum 0.26.3", "sway-ast", "sway-error", "sway-ir", @@ -6832,11 +6912,11 @@ dependencies = [ "anyhow", "downcast-rs", "filecheck", - "indexmap 2.4.0", - "itertools 0.10.5", + "indexmap 2.5.0", + "itertools 0.13.0", "once_cell", "peg", - "prettydiff", + "prettydiff 0.7.0", "rustc-hash", "slotmap", "sway-ir-macros", @@ -6848,7 +6928,7 @@ dependencies = [ name = "sway-ir-macros" version = "0.63.6" dependencies = [ - "itertools 0.10.5", + "itertools 0.13.0", "proc-macro2", "quote", "syn 1.0.109", @@ -6863,14 +6943,14 @@ dependencies = [ "codspeed-criterion-compat", "criterion", "crossbeam-channel", - "dashmap", + "dashmap 6.1.0", "dirs 4.0.0", - "fd-lock 4.0.2", + "fd-lock", "forc-pkg", "forc-tracing 0.63.6", "forc-util", "futures", - "indexmap 2.4.0", + "indexmap 2.5.0", "lsp-types", "notify", "notify-debouncer-mini", @@ -6898,7 +6978,7 @@ dependencies = [ "tikv-jemallocator", "tokio", "toml_edit 0.21.1", - "tower", + "tower 0.4.13", "tower-lsp", "tracing", "urlencoding", @@ -6915,7 +6995,7 @@ dependencies = [ "serde", "serde_json", "tokio", - "tower", + "tower 0.5.1", "tower-lsp", ] @@ -6945,7 +7025,7 @@ dependencies = [ "fuel-asm", "fuel-crypto", "fuel-tx", - "indexmap 2.4.0", + "indexmap 2.5.0", "lazy_static", "num-bigint", "num-traits", @@ -6973,7 +7053,7 @@ dependencies = [ "forc-tracing 0.63.6", "indoc", "paste", - "prettydiff", + "prettydiff 0.6.4", "ropey", "serde", "serde_ignored", @@ -7133,19 +7213,23 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "taplo" -version = "0.7.0" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5d17cb5ff4095af064048f25a0a8df815384f63ce21c7410e96b93016757259" +checksum = "010941ac4171eaf12f1e26dfc11dadaf78619ea2330940fef01fe6bb0442d14d" dependencies = [ - "glob", - "indexmap 1.9.3", + "ahash 0.8.11", + "arc-swap", + "either", + "globset", + "itertools 0.10.5", "logos", - "regex", + "once_cell", "rowan", - "semver", - "smallvec", - "toml 0.5.11", - "wasm-bindgen", + "serde", + "serde_json", + "thiserror", + "time", + "tracing", ] [[package]] @@ -7225,6 +7309,18 @@ dependencies = [ "redox_termios", ] +[[package]] +name = "termion" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ccce68e518d1173e80876edd54760b60b792750d0cab6444a79101c6ea03848" +dependencies = [ + "libc", + "libredox 0.0.2", + "numtoa", + "redox_termios", +] + [[package]] name = "test" version = "0.0.0" @@ -7247,7 +7343,7 @@ dependencies = [ "insta", "libtest-mimic", "miden", - "prettydiff", + "prettydiff 0.7.0", "rand", "regex", "revm", @@ -7269,7 +7365,7 @@ name = "test-macros" version = "0.0.0" dependencies = [ "paste", - "prettydiff", + "prettydiff 0.6.4", ] [[package]] @@ -7571,7 +7667,7 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.5.0", "toml_datetime", "winnow 0.5.40", ] @@ -7582,7 +7678,7 @@ version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.5.0", "serde", "serde_spanned", "toml_datetime", @@ -7610,6 +7706,20 @@ dependencies = [ "tower-service", ] +[[package]] +name = "tower" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper 0.1.2", + "tower-layer", + "tower-service", +] + [[package]] name = "tower-layer" version = "0.3.3" @@ -7625,7 +7735,7 @@ dependencies = [ "async-trait", "auto_impl", "bytes", - "dashmap", + "dashmap 5.5.3", "futures", "httparse", "lsp-types", @@ -7634,7 +7744,7 @@ dependencies = [ "serde_json", "tokio", "tokio-util", - "tower", + "tower 0.4.13", "tower-lsp-macros", "tracing", ] @@ -7954,7 +8064,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3db6840b7adcfd2e866c79157cc890ecdbbc1f739607134039ae64eaa6c07e24" dependencies = [ "clap 2.34.0", - "owo-colors", + "owo-colors 1.3.0", "parking_lot 0.11.2", "thiserror", ] @@ -8078,8 +8188,6 @@ checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if 1.0.0", "once_cell", - "serde", - "serde_json", "wasm-bindgen-macro", ] diff --git a/Cargo.toml b/Cargo.toml index e6848e284d9..95b4809a0dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -116,21 +116,21 @@ async-trait = "0.1" atty = "0.2" byte-unit = "5.1" bytecount = "0.6" -bytes = "1.3" +bytes = "1.7" chrono = { version = "0.4", default-features = false } cid = "0.11" clap = "4.5" clap_complete = "4.5" clap_complete_fig = "4.5" colored = "2.0" -comrak = "0.16" +comrak = "0.28" crossbeam-channel = "0.5" dap = "0.4.1-alpha" -dashmap = "5.4" +dashmap = "6.1" derivative = "2.2" -devault = "0.1" +devault = "0.2" dialoguer = "0.11" -dirs = "3.0" +dirs = "5.0" downcast-rs = "1.2" either = "1.9" ethabi = { package = "fuel-ethabi", version = "18.0" } @@ -142,22 +142,22 @@ filecheck = "0.5" fs_extra = "1.2" futures = { version = "0.3", default-features = false } gag = "1.0" -gimli = "0.28" +gimli = "0.31" git2 = "0.19" gix-url = "0.27" glob = "0.3" graph-cycles = "0.1" -hashbrown = "0.13" +hashbrown = "0.14" hex = "0.4" horrorshow = "0.8" im = "15.0" in_definite = "1.0" include_dir = "0.7" -indexmap = "2.0" +indexmap = "2.5" indoc = "2.0" -insta = "1.39" +insta = "1.40" ipfs-api-backend-hyper = "0.6" -itertools = "0.10" +itertools = "0.13" lazy_static = "1.4" libp2p-identity = "0.2" libtest-mimic = "0.7" @@ -170,18 +170,18 @@ notify = "5.0" notify-debouncer-mini = "0.2" num-bigint = "0.4" num-traits = "0.2" -object = "0.32" +object = "0.36" once_cell = "1.18" -opener = "0.5" +opener = "0.7" parking_lot = "0.12" paste = "1.0" -peg = "0.7" -pest = "2.1" -pest_derive = "2.1" +peg = "0.8" +pest = "2.7" +pest_derive = "2.7" petgraph = "0.6" -phf = "0.10" +phf = "0.11" pretty_assertions = "1.4" -prettydiff = "0.6" +prettydiff = "0.7" proc-macro2 = "1.0" quote = "1.0" rand = "0.8" @@ -200,26 +200,26 @@ serde_json = "1.0" serde_with = "3.3" serde_yaml = "0.9" serial_test = "3.0" -sha2 = "0.9" +sha2 = "0.10" sha3 = "0.10" -shellfish = "0.6" +shellfish = "0.9" slotmap = "1.0" smallvec = "1.7" strsim = "0.11" -strum = "0.24" +strum = "0.26" syn = "1.0" -taplo = "0.7" +taplo = "0.13" tar = "0.4" tempfile = "3" term-table = "1.3" -termion = "2.0" +termion = "4.0" textwrap = "0.16" thiserror = "1.0" tikv-jemallocator = "0.5" tokio = "1.12" toml = "0.8" toml_edit = "0.21" -tower = { version = "0.4", default-features = false } +tower = { version = "0.5", default-features = false } tower-lsp = "0.20" tracing = "0.1" tracing-subscriber = "0.3" @@ -232,4 +232,4 @@ uwuify = "^0.2" vec1 = "1.8" vte = "0.13" walkdir = "2.3" -whoami = "1.1" +whoami = "1.5" diff --git a/sway-lsp/Cargo.toml b/sway-lsp/Cargo.toml index 9a0dc17976a..8129d1e7443 100644 --- a/sway-lsp/Cargo.toml +++ b/sway-lsp/Cargo.toml @@ -8,9 +8,6 @@ homepage.workspace = true license.workspace = true repository.workspace = true -[package.metadata.cargo-udeps.ignore] -normal = ["tower"] - [dependencies] anyhow.workspace = true crossbeam-channel.workspace = true diff --git a/sway-lsp/tests/utils/Cargo.toml b/sway-lsp/tests/utils/Cargo.toml index 70d174f7237..cbb98baae8e 100644 --- a/sway-lsp/tests/utils/Cargo.toml +++ b/sway-lsp/tests/utils/Cargo.toml @@ -9,6 +9,9 @@ homepage.workspace = true license.workspace = true repository.workspace = true +[package.metadata.cargo-udeps.ignore] +normal = ["tower"] + [dependencies] assert-json-diff.workspace = true futures = { workspace = true, features = ["async-await", "std"] } From 3f163c7222a5d15477d6677445ce3930ef377c64 Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite Date: Mon, 23 Sep 2024 06:33:17 +0100 Subject: [PATCH 030/115] fix array element type algorithm to avoid selecting never (#6511) ## Description This PR fixes the array element type selection algorithm to avoid selecting `Never`. ## 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) - [ ] 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. --- .../src/language/ty/expression/expression.rs | 74 +++-- .../ast_node/expression/typed_expression.rs | 84 +++-- sway-core/src/type_system/id.rs | 46 ++- .../array_wrong_elements_types/Forc.lock | 16 + .../array_wrong_elements_types/Forc.toml | 10 + .../array_wrong_elements_types/snapshot.toml | 0 .../array_wrong_elements_types/src/main.sw | 49 +++ .../array_wrong_elements_types/stdout.snap | 295 ++++++++++++++++++ .../type_check_analyze_errors/src/main.sw | 19 +- .../type_check_analyze_errors/stdout.snap | 174 ++--------- test/tests/tests.rs | 2 +- 11 files changed, 503 insertions(+), 266 deletions(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/snapshot.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/stdout.snap diff --git a/sway-core/src/language/ty/expression/expression.rs b/sway-core/src/language/ty/expression/expression.rs index b4ac96b8d83..e4fc0fcda07 100644 --- a/sway-core/src/language/ty/expression/expression.rs +++ b/sway-core/src/language/ty/expression/expression.rs @@ -123,35 +123,8 @@ impl TypeCheckAnalysis for TyExpression { } } } - // Check all array items are the same - TyExpressionVariant::Array { - elem_type, - contents, - } => { - let array_elem_type = ctx.engines.te().get(*elem_type); - if !matches!(&*array_elem_type, TypeInfo::Never) { - let unify = crate::type_system::unify::unifier::Unifier::new( - ctx.engines, - "", - unify::unifier::UnifyKind::Default, - ); - for element in contents { - let element_type = ctx.engines.te().get(element.return_type); - - // If the element is never, we do not need to check - if matches!(&*element_type, TypeInfo::Never) { - continue; - } - - unify.unify( - handler, - element.return_type, - *elem_type, - &element.span, - true, - ) - } - } + TyExpressionVariant::Array { .. } => { + self.as_array_unify_elements(handler, ctx.engines); } _ => {} } @@ -500,4 +473,47 @@ impl TyExpression { _ => None, } } + + /// Unify elem_type with each element return type. + /// Must be called on arrays. + pub fn as_array_unify_elements(&self, handler: &Handler, engines: &Engines) { + let TyExpressionVariant::Array { + elem_type, + contents, + } = &self.expression + else { + unreachable!("Should only be called on Arrays") + }; + + let array_elem_type = engines.te().get(*elem_type); + if !matches!(&*array_elem_type, TypeInfo::Never) { + let unify = crate::type_system::unify::unifier::Unifier::new( + engines, + "", + unify::unifier::UnifyKind::Default, + ); + for element in contents { + let element_type = engines.te().get(element.return_type); + + // If the element is never, we do not need to check + if matches!(&*element_type, TypeInfo::Never) { + continue; + } + + let h = Handler::default(); + unify.unify(&h, element.return_type, *elem_type, &element.span, true); + + // unification error points to type that failed + // we want to report the element type instead + if h.has_errors() { + handler.emit_err(CompileError::TypeError(TypeError::MismatchedType { + expected: format!("{:?}", engines.help_out(&array_elem_type)), + received: format!("{:?}", engines.help_out(element_type)), + help_text: String::new(), + span: element.span.clone(), + })); + } + } + } + } } diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs index f02e51b9987..24af43873ff 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs @@ -38,7 +38,6 @@ use crate::{ use ast_node::declaration::{insert_supertraits_into_namespace, SupertraitOf}; use either::Either; use indexmap::IndexMap; -use itertools::Itertools; use rustc_hash::FxHashSet; use std::collections::{HashMap, VecDeque}; use sway_ast::intrinsics::Intrinsic; @@ -1947,7 +1946,7 @@ impl ty::TyExpression { } fn type_check_array( - handler: &Handler, + _handler: &Handler, mut ctx: TypeCheckContext, contents: &[Expression], span: Span, @@ -1979,8 +1978,8 @@ impl ty::TyExpression { }); }; - // start each element with the known array element type, or Unknown if it is to be inferred - // from the elements + // capture the expected array element type from context, + // otherwise, fallback to Unknown. let initial_type = match &*ctx.engines().te().get(ctx.type_annotation()) { TypeInfo::Array(element_type, _) => { let element_type = (*ctx.engines().te().get(element_type.type_id)).clone(); @@ -2001,44 +2000,32 @@ impl ty::TyExpression { .by_ref() .with_help_text("") .with_type_annotation(type_engine.insert(engines, initial_type.clone(), None)); - Self::type_check(handler, ctx, expr) + + // type_check_analyze unification will give the final error + let handler = Handler::default(); + Self::type_check(&handler, ctx, expr) .unwrap_or_else(|err| ty::TyExpression::error(err, span, engines)) }) .collect(); - // choose the best type to be the array elem type - use itertools::FoldWhile::{Continue, Done}; - let elem_type = typed_contents - .iter() - .fold_while(None, |last, current| match last { - None => Continue(Some(current.return_type)), - Some(last) => { - if last.is_concrete(engines, TreatNumericAs::Abstract) { - return Done(Some(last)); - } - - if current - .return_type - .is_concrete(engines, TreatNumericAs::Abstract) - { - return Done(Some(current.return_type)); - } - - let last_info = ctx.engines().te().get(last); - let current_info = ctx.engines().te().get(current.return_type); - match (&*last_info, &*current_info) { - (TypeInfo::Numeric, TypeInfo::UnsignedInteger(_)) => { - Done(Some(current.return_type)) - } - _ => Continue(Some(last)), - } - } - }) - .into_inner(); - let elem_type = elem_type.unwrap_or_else(|| typed_contents[0].return_type); + // if the element type is still unknown, and all elements are Never, + // fallback to unit + let initial_type = if matches!(initial_type, TypeInfo::Unknown) { + let is_all_elements_never = typed_contents + .iter() + .all(|expr| matches!(&*engines.te().get(expr.return_type), TypeInfo::Never)); + if is_all_elements_never { + TypeInfo::Tuple(vec![]) + } else { + initial_type + } + } else { + initial_type + }; + let elem_type = type_engine.insert(engines, initial_type.clone(), None); let array_count = typed_contents.len(); - Ok(ty::TyExpression { + let expr = ty::TyExpression { expression: ty::TyExpressionVariant::Array { elem_type, contents: typed_contents, @@ -2055,9 +2042,15 @@ impl ty::TyExpression { Length::new(array_count, Span::dummy()), ), None, - ), // Maybe? + ), span, - }) + }; + + // type_check_analyze unification will give the final error + let handler = Handler::default(); + expr.as_array_unify_elements(&handler, ctx.engines); + + Ok(expr) } fn type_check_array_index( @@ -2940,7 +2933,7 @@ mod tests { expr: &Expression, ) -> Result { let engines = Engines::default(); - do_type_check( + let expr = do_type_check( handler, &engines, expr, @@ -2960,7 +2953,9 @@ mod tests { ExperimentalFlags { new_encoding: false, }, - ) + )?; + expr.type_check_analyze(handler, &mut TypeCheckAnalysisContext::new(&engines))?; + Ok(expr) } #[test] @@ -3021,7 +3016,7 @@ mod tests { let _comp_res = do_type_check_for_boolx2(&handler, &expr); let (errors, _warnings) = handler.consume(); - assert!(errors.len() == 2); + assert!(errors.len() == 1); assert!(matches!(&errors[0], CompileError::TypeError(TypeError::MismatchedType { expected, @@ -3029,13 +3024,6 @@ mod tests { .. }) if expected == "bool" && received == "u64")); - assert!(matches!(&errors[1], - CompileError::TypeError(TypeError::MismatchedType { - expected, - received, - .. - }) if expected == "[bool; 2]" - && received == "[u64; 2]")); } #[test] diff --git a/sway-core/src/type_system/id.rs b/sway-core/src/type_system/id.rs index 709a1bf7a23..6bd1a07950d 100644 --- a/sway-core/src/type_system/id.rs +++ b/sway-core/src/type_system/id.rs @@ -463,33 +463,27 @@ impl TypeId { })) } - pub(crate) fn is_concrete( - &self, - engines: &Engines, - numeric_non_concrete: TreatNumericAs, - ) -> bool { + pub(crate) fn is_concrete(&self, engines: &Engines, treat_numeric_as: TreatNumericAs) -> bool { let nested_types = (*self).extract_nested_types(engines); - !nested_types - .into_iter() - .any(|x| match numeric_non_concrete { - TreatNumericAs::Abstract => matches!( - x, - TypeInfo::UnknownGeneric { .. } - | TypeInfo::Custom { .. } - | TypeInfo::Placeholder(..) - | TypeInfo::TraitType { .. } - | TypeInfo::TypeParam(..) - | TypeInfo::Numeric - ), - TreatNumericAs::Concrete => matches!( - x, - TypeInfo::UnknownGeneric { .. } - | TypeInfo::Custom { .. } - | TypeInfo::Placeholder(..) - | TypeInfo::TraitType { .. } - | TypeInfo::TypeParam(..) - ), - }) + !nested_types.into_iter().any(|x| match treat_numeric_as { + TreatNumericAs::Abstract => matches!( + x, + TypeInfo::UnknownGeneric { .. } + | TypeInfo::Custom { .. } + | TypeInfo::Placeholder(..) + | TypeInfo::TraitType { .. } + | TypeInfo::TypeParam(..) + | TypeInfo::Numeric + ), + TreatNumericAs::Concrete => matches!( + x, + TypeInfo::UnknownGeneric { .. } + | TypeInfo::Custom { .. } + | TypeInfo::Placeholder(..) + | TypeInfo::TraitType { .. } + | TypeInfo::TypeParam(..) + ), + }) } /// `check_type_parameter_bounds` does two types of checks. Lets use the example below for demonstrating the two checks: diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/Forc.lock new file mode 100644 index 00000000000..6587bc2240d --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/Forc.lock @@ -0,0 +1,16 @@ +[[package]] +name = "array_wrong_elements_types" +source = "member" +dependencies = [ + "core", + "std", +] + +[[package]] +name = "core" +source = "path+from-root-C125AFC4EC59A434" + +[[package]] +name = "std" +source = "path+from-root-C125AFC4EC59A434" +dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/Forc.toml new file mode 100644 index 00000000000..8bbe2f8fe40 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/Forc.toml @@ -0,0 +1,10 @@ +[project] +authors = ["Fuel Labs "] +license = "Apache-2.0" +name = "array_wrong_elements_types" +entry = "main.sw" +implicit-std = false + +[dependencies] +core = { path = "../../../../../../sway-lib-core" } +std = { path = "../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/snapshot.toml b/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/snapshot.toml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw new file mode 100644 index 00000000000..ca7e2611018 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw @@ -0,0 +1,49 @@ +script; + +fn vec() -> Vec { + Vec::new() +} + +fn main() { + // unexpected u16 + let a: [u8;1] = [1u16]; + + // unexpected u16 + let _ = [1u8, 1u16]; + let a = [1, 2u8, 3u16, 4u32, 5u64]; + + // unexpected u8 + let _ = [1, 1u16, a[0]]; + + // unexpected string slice + let _ = [1, "", 1u8, 1u16]; + + // unexpected u8 + let _ = [return, 1u8, 1u16]; + + // unexpected u16 + let _ = [1u8, return, 1u16]; + + // unexpected u16 + let _ = [1, return, 1u8, 1u16]; + + // unexpected str + let _ = [1, "", 1u16]; + let _ = [1, 2, "hello"]; + let _ = [1, return, "", 1u16]; + let _ = [1, "", return, 1u16]; + + // unexpected Vec + let _ = [Vec::new(), vec::(), vec::()]; + + // unexpected Option + let a = [None, Some(1), Some(1u8)]; + let _b: Option = a[1]; + + // unexpected u8 + let a = [8, 256u16, 8u8]; + let b: u32 = a[2]; + + // Should not warn or error + let _ : [u8 ; 0] = []; +} diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/stdout.snap new file mode 100644 index 00000000000..3df03eb69cf --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/stdout.snap @@ -0,0 +1,295 @@ +--- +source: test/tests/tests.rs +--- +exit status: 1 +stdout: + Building src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types + Compiling library core (sway-lib-core) + Compiling library std (sway-lib-std) + Compiling script array_wrong_elements_types (test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types) + +stderr: +error + --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:41:27 + | +39 | +40 | let a = [None, Some(1), Some(1u8)]; +41 | let _b: Option = a[1]; + | ^^^^ Mismatched types. +expected: Option +found: Option. +help: Variable declaration's type annotation does not match up with the assigned expression's type. +42 | +43 | // unexpected u8 + | +____ + +error + --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:45:18 + | +43 | +44 | let a = [8, 256u16, 8u8]; +45 | let b: u32 = a[2]; + | ^^^^ Mismatched types. +expected: u32 +found: u16. +help: Variable declaration's type annotation does not match up with the assigned expression's type. +46 | +47 | // Should not warn or error + | +____ + +error + --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:9:22 + | + 7 | + 8 | // unexpected u16 + 9 | let a: [u8;1] = [1u16]; + | ^^^^ Mismatched types. +expected: u8 +found: u16. + +10 | +11 | // unexpected u16 + | +____ + +error + --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:12:19 + | +10 | +11 | // unexpected u16 +12 | let _ = [1u8, 1u16]; + | ^^^^ Mismatched types. +expected: u8 +found: u16. + +13 | let a = [1, 2u8, 3u16, 4u32, 5u64]; + | +____ + +error + --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:13:22 + | +11 | +12 | let _ = [1u8, 1u16]; +13 | let a = [1, 2u8, 3u16, 4u32, 5u64]; + | ^^^^ Mismatched types. +expected: u8 +found: u16. + +14 | +15 | // unexpected u8 + | +____ + +error + --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:13:28 + | +11 | +12 | let _ = [1u8, 1u16]; +13 | let a = [1, 2u8, 3u16, 4u32, 5u64]; + | ^^^^ Mismatched types. +expected: u8 +found: u32. + +14 | +15 | // unexpected u8 + | +____ + +error + --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:13:34 + | +11 | +12 | let _ = [1u8, 1u16]; +13 | let a = [1, 2u8, 3u16, 4u32, 5u64]; + | ^^^^ Mismatched types. +expected: u8 +found: u64. + +14 | +15 | // unexpected u8 + | +____ + +error + --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:16:23 + | +14 | +15 | // unexpected u8 +16 | let _ = [1, 1u16, a[0]]; + | ^^^^ Mismatched types. +expected: u16 +found: u8. + +17 | +18 | // unexpected string slice + | +____ + +error + --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:19:17 + | +17 | +18 | // unexpected string slice +19 | let _ = [1, "", 1u8, 1u16]; + | ^^ Mismatched types. +expected: u8 +found: str. + +20 | +21 | // unexpected u8 + | +____ + +error + --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:19:26 + | +17 | +18 | // unexpected string slice +19 | let _ = [1, "", 1u8, 1u16]; + | ^^^^ Mismatched types. +expected: u8 +found: u16. + +20 | +21 | // unexpected u8 + | +____ + +error + --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:22:27 + | +20 | +21 | // unexpected u8 +22 | let _ = [return, 1u8, 1u16]; + | ^^^^ Mismatched types. +expected: u8 +found: u16. + +23 | +24 | // unexpected u16 + | +____ + +error + --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:25:27 + | +23 | +24 | // unexpected u16 +25 | let _ = [1u8, return, 1u16]; + | ^^^^ Mismatched types. +expected: u8 +found: u16. + +26 | +27 | // unexpected u16 + | +____ + +error + --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:28:30 + | +26 | +27 | // unexpected u16 +28 | let _ = [1, return, 1u8, 1u16]; + | ^^^^ Mismatched types. +expected: u8 +found: u16. + +29 | +30 | // unexpected str + | +____ + +error + --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:31:17 + | +29 | +30 | // unexpected str +31 | let _ = [1, "", 1u16]; + | ^^ Mismatched types. +expected: u16 +found: str. + +32 | let _ = [1, 2, "hello"]; +33 | let _ = [1, return, "", 1u16]; + | +____ + +error + --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:32:20 + | +30 | +31 | let _ = [1, "", 1u16]; +32 | let _ = [1, 2, "hello"]; + | ^^^^^^^ Mismatched types. +expected: numeric +found: str. + +33 | let _ = [1, return, "", 1u16]; +34 | let _ = [1, "", return, 1u16]; + | +____ + +error + --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:33:25 + | +31 | +32 | let _ = [1, 2, "hello"]; +33 | let _ = [1, return, "", 1u16]; + | ^^ Mismatched types. +expected: u16 +found: str. + +34 | let _ = [1, "", return, 1u16]; + | +____ + +error + --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:34:17 + | +32 | +33 | let _ = [1, return, "", 1u16]; +34 | let _ = [1, "", return, 1u16]; + | ^^ Mismatched types. +expected: u16 +found: str. + +35 | +36 | // unexpected Vec + | +____ + +error + --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:37:39 + | +35 | +36 | // unexpected Vec +37 | let _ = [Vec::new(), vec::(), vec::()]; + | ^^^^^^^^^^^^ Mismatched types. +expected: Vec +found: Vec. + +38 | +39 | // unexpected Option + | +____ + +error + --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:44:25 + | +42 | +43 | // unexpected u8 +44 | let a = [8, 256u16, 8u8]; + | ^^^ Mismatched types. +expected: u16 +found: u8. + +45 | let b: u32 = a[2]; + | +____ + + Aborting due to 19 errors. +error: Failed to compile array_wrong_elements_types diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/src/main.sw index e0d26feec0b..6fae9c87c7e 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/src/main.sw @@ -1,30 +1,19 @@ script; fn main() { + // 0x100 does not fit into a u8 let _a = 0x100; Vec::::new().push(_a); - // u16 + // 0x10000 does not fit into a u16 let _a = 0x10000; Vec::::new().push(_a); - // u32 + // 0x100000000 does not fit into a u32 let _a = 0x100000000; Vec::::new().push(_a); - // Array - let a = [1, 2, "hello"]; - - // Array - different numerics - let a = [1, 2u8, 3u16, 4u32, 5u64]; - - // Array - unspecified generic structs - let a = [None, Some(1), Some(1u8)]; - let _b: Option = a[1]; - - // Wrong cast - let a = [8, 256u16, 8u8]; - let b: u32 = a[2]; + } fn insufficient_type_check(arg: u64) -> [u32;2] { diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/stdout.snap index c5ea41c4161..976078dcd1b 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/stdout.snap @@ -1,6 +1,5 @@ --- source: test/tests/tests.rs -assertion_line: 50 --- exit status: 1 stdout: @@ -11,171 +10,52 @@ stdout: stderr: error - --> test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/src/main.sw:16:14 - | -14 | -15 | // Array -16 | let a = [1, 2, "hello"]; - | ^ Mismatched types. -expected: str -found: numeric. - -17 | -18 | // Array - different numerics - | -____ - -error - --> test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/src/main.sw:16:17 - | -14 | -15 | // Array -16 | let a = [1, 2, "hello"]; - | ^ Mismatched types. -expected: str -found: numeric. - -17 | -18 | // Array - different numerics - | -____ - -error - --> test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/src/main.sw:19:22 - | -17 | -18 | // Array - different numerics -19 | let a = [1, 2u8, 3u16, 4u32, 5u64]; - | ^^^^ Mismatched types. -expected: u8 -found: u16. - -20 | -21 | // Array - unspecified generic structs - | -____ - -error - --> test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/src/main.sw:19:28 - | -17 | -18 | // Array - different numerics -19 | let a = [1, 2u8, 3u16, 4u32, 5u64]; - | ^^^^ Mismatched types. -expected: u8 -found: u32. - -20 | -21 | // Array - unspecified generic structs - | -____ - -error - --> test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/src/main.sw:19:34 - | -17 | -18 | // Array - different numerics -19 | let a = [1, 2u8, 3u16, 4u32, 5u64]; - | ^^^^ Mismatched types. -expected: u8 -found: u64. - -20 | -21 | // Array - unspecified generic structs - | -____ - -error - --> test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/src/main.sw:23:27 - | -21 | -22 | let a = [None, Some(1), Some(1u8)]; -23 | let _b: Option = a[1]; - | ^^^^ Mismatched types. -expected: Option -found: Option. -help: Variable declaration's type annotation does not match up with the assigned expression's type. -24 | -25 | // Wrong cast - | + --> test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/src/main.sw:5:14 + | +3 | +4 | // 0x100 does not fit into a u8 +5 | let _a = 0x100; + | ^^^^^ Literal would overflow because its value does not fit into "u8" +6 | Vec::::new().push(_a); + | ____ error - --> test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/src/main.sw:26:25 + --> test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/src/main.sw:9:14 | -24 | -25 | // Wrong cast -26 | let a = [8, 256u16, 8u8]; - | ^^^ Mismatched types. -expected: u16 -found: u8. - -27 | let b: u32 = a[2]; -28 | } + 7 | + 8 | // 0x10000 does not fit into a u16 + 9 | let _a = 0x10000; + | ^^^^^^^ Literal would overflow because its value does not fit into "u16" +10 | Vec::::new().push(_a); | ____ error - --> test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/src/main.sw:27:18 + --> test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/src/main.sw:13:14 | -25 | -26 | let a = [8, 256u16, 8u8]; -27 | let b: u32 = a[2]; - | ^^^^ Mismatched types. -expected: u32 -found: u16. -help: Variable declaration's type annotation does not match up with the assigned expression's type. -28 | } +11 | +12 | // 0x100000000 does not fit into a u32 +13 | let _a = 0x100000000; + | ^^^^^^^^^^^ Literal would overflow because its value does not fit into "u32" +14 | Vec::::new().push(_a); | ____ error - --> test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/src/main.sw:31:22 + --> test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/src/main.sw:20:22 | -29 | -30 | fn insufficient_type_check(arg: u64) -> [u32;2] { -31 | let res = [1u32, arg]; +18 | +19 | fn insufficient_type_check(arg: u64) -> [u32;2] { +20 | let res = [1u32, arg]; | ^^^ Mismatched types. expected: u32 found: u64. -32 | res -33 | } - | -____ - -error - --> test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/src/main.sw:4:14 - | -2 | -3 | fn main() { -4 | let _a = 0x100; - | ^^^^^ Literal would overflow because its value does not fit into "u8" -5 | Vec::::new().push(_a); - | -____ - -error - --> test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/src/main.sw:8:14 - | -6 | -7 | // u16 -8 | let _a = 0x10000; - | ^^^^^^^ Literal would overflow because its value does not fit into "u16" -9 | Vec::::new().push(_a); - | -____ - -error - --> test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/src/main.sw:12:14 - | -10 | -11 | // u32 -12 | let _a = 0x100000000; - | ^^^^^^^^^^^ Literal would overflow because its value does not fit into "u32" -13 | Vec::::new().push(_a); +21 | res +22 | } | ____ - Aborting due to 12 errors. + Aborting due to 4 errors. error: Failed to compile type_check_analyze_errors diff --git a/test/tests/tests.rs b/test/tests/tests.rs index b526159f038..d4121961e6e 100644 --- a/test/tests/tests.rs +++ b/test/tests/tests.rs @@ -47,7 +47,7 @@ pub fn main() { insta.set_prepend_module_to_snapshot(false); insta.set_omit_expression(true); let scope = insta.bind_to_scope(); - insta::assert_snapshot!(snapshot); + insta::assert_snapshot!("stdout", snapshot); drop(scope); } stdout(&format!("../{root}"), &snapshot); From e1546f60ee9e7e35fb033aa7d42e13b38030fc62 Mon Sep 17 00:00:00 2001 From: Alfie John Date: Mon, 23 Sep 2024 16:44:31 +1000 Subject: [PATCH 031/115] Version bump the remaining crate dependencies (#6579) ## Description As part of #6179, this PR updates the remaining quick-fix crates to their latest X.Y versions. Code fixes were needed to get compilation working and tests passing. Issue #6536 lists the crates that will need a bit more work to get working and passing. ## 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. --- Cargo.lock | 663 ++++++++++++++++++----- Cargo.toml | 12 +- forc-plugins/forc-client/src/util/pkg.rs | 2 +- forc-plugins/forc-client/tests/deploy.rs | 6 +- forc/src/ops/forc_template.rs | 4 +- sway-ir/sway-ir-macros/src/lib.rs | 30 +- sway-lsp/Cargo.toml | 2 +- sway-lsp/src/core/sync.rs | 15 +- sway-lsp/src/utils/keyword_docs.rs | 2 +- test/src/e2e_vm_tests/harness.rs | 51 +- test/src/e2e_vm_tests/mod.rs | 18 +- 11 files changed, 613 insertions(+), 192 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e99b3c0383f..24dbdf500b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -77,6 +77,87 @@ version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +[[package]] +name = "alloy-eip2930" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0069cf0642457f87a01a014f6dc29d5d893cd4fd8fddf0c3cdfad1bb3ebafc41" +dependencies = [ + "alloy-primitives", + "alloy-rlp", +] + +[[package]] +name = "alloy-eip7702" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d319bb544ca6caeab58c39cea8921c55d924d4f68f2c60f24f914673f9a74a" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "k256", +] + +[[package]] +name = "alloy-eips" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f923dd5fca5f67a43d81ed3ebad0880bd41f6dd0ada930030353ac356c54cd0f" +dependencies = [ + "alloy-eip2930", + "alloy-eip7702", + "alloy-primitives", + "alloy-rlp", + "c-kzg", + "derive_more 1.0.0", + "once_cell", + "serde", +] + +[[package]] +name = "alloy-primitives" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "411aff151f2a73124ee473708e82ed51b2535f68928b6a1caa8bc1246ae6f7cd" +dependencies = [ + "alloy-rlp", + "bytes", + "cfg-if 1.0.0", + "const-hex", + "derive_more 1.0.0", + "hex-literal", + "itoa", + "k256", + "keccak-asm", + "proptest", + "rand", + "ruint", + "serde", + "tiny-keccak", +] + +[[package]] +name = "alloy-rlp" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26154390b1d205a4a7ac7352aa2eb4f81f391399d4e2f546fb81a2f8bb383f62" +dependencies = [ + "alloy-rlp-derive", + "arrayvec", + "bytes", +] + +[[package]] +name = "alloy-rlp-derive" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d0f2d905ebd295e7effec65e5f6868d153936130ae718352771de3e7d03c75c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + [[package]] name = "android-tzdata" version = "0.1.1" @@ -178,6 +259,130 @@ version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" +[[package]] +name = "ark-ff" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" +dependencies = [ + "ark-ff-asm 0.3.0", + "ark-ff-macros 0.3.0", + "ark-serialize 0.3.0", + "ark-std 0.3.0", + "derivative", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.3.3", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "digest 0.10.7", + "itertools 0.10.5", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.4.0", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" +dependencies = [ + "num-bigint", + "num-traits", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-serialize" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" +dependencies = [ + "ark-std 0.3.0", + "digest 0.9.0", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-std 0.4.0", + "digest 0.10.7", + "num-bigint", +] + +[[package]] +name = "ark-std" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", +] + [[package]] name = "arrayref" version = "0.3.8" @@ -255,6 +460,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "aurora-engine-modexp" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0aef7712851e524f35fbbb74fa6599c5cd8692056a1c36f9ca0d2001b670e7e5" +dependencies = [ + "hex", + "num", +] + [[package]] name = "auto_impl" version = "1.2.0" @@ -427,6 +642,18 @@ dependencies = [ "generic-array", ] +[[package]] +name = "blst" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4378725facc195f1a538864863f6de233b500a8862747e7f165078a419d5e874" +dependencies = [ + "cc", + "glob", + "threadpool", + "zeroize", +] + [[package]] name = "borsh" version = "1.5.1" @@ -535,6 +762,21 @@ version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +[[package]] +name = "c-kzg" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0307f72feab3300336fb803a57134159f6e20139af1357f36c54cb90d8e8928" +dependencies = [ + "blst", + "cc", + "glob", + "hex", + "libc", + "once_cell", + "serde", +] + [[package]] name = "caseless" version = "0.2.1" @@ -910,6 +1152,19 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "const-hex" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8a24a26d37e1ffd45343323dc9fe6654ceea44c12f2fcb3d7ac29e610bc6" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "hex", + "proptest", + "serde", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -1169,7 +1424,7 @@ dependencies = [ "curve25519-dalek-derive", "digest 0.10.7", "fiat-crypto", - "rustc_version", + "rustc_version 0.4.0", "subtle", ] @@ -1440,8 +1695,29 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "rustc_version", + "rustc_version 0.4.0", + "syn 2.0.74", +] + +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "proc-macro2", + "quote", "syn 2.0.74", + "unicode-xid", ] [[package]] @@ -1599,6 +1875,12 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" +[[package]] +name = "dyn-clone" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" + [[package]] name = "ecdsa" version = "0.16.9" @@ -1743,6 +2025,17 @@ dependencies = [ "syn 2.0.74", ] +[[package]] +name = "enumn" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + [[package]] name = "env_filter" version = "0.1.2" @@ -1936,6 +2229,17 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +[[package]] +name = "fastrlp" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + [[package]] name = "fd-lock" version = "4.0.2" @@ -2059,7 +2363,7 @@ dependencies = [ "term-table", "tokio", "toml 0.8.19", - "toml_edit 0.21.1", + "toml_edit 0.22.20", "tracing", "url", "uwuify", @@ -2106,7 +2410,7 @@ dependencies = [ "sway-utils", "tempfile", "tokio", - "toml_edit 0.21.1", + "toml_edit 0.22.20", "tracing", ] @@ -2234,7 +2538,7 @@ dependencies = [ "petgraph", "regex", "reqwest 0.12.5", - "semver", + "semver 1.0.23", "serde", "serde_ignored", "serde_json", @@ -2453,7 +2757,7 @@ checksum = "03ad219bde52b072a2d828f27072982047a77cc02c953ea7e83c23de586d466d" dependencies = [ "anyhow", "cynic", - "derive_more", + "derive_more 0.99.18", "eventsource-client", "fuel-core-types", "futures", @@ -2523,7 +2827,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f06320744b7d53bc7928d1a40a28fd697191a5b6938a353164231a3423ebdcd9" dependencies = [ "anyhow", - "derive_more", + "derive_more 0.99.18", "enum-iterator", "fuel-core-types", "fuel-vm", @@ -2547,7 +2851,7 @@ dependencies = [ "anyhow", "bs58", "derivative", - "derive_more", + "derive_more 0.99.18", "fuel-vm", "rand", "secrecy", @@ -2642,7 +2946,7 @@ version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf17ce8ee5e8b573ea584c223635ff09f1288ad022bcf662954fdccb907602eb" dependencies = [ - "derive_more", + "derive_more 0.99.18", "digest 0.10.7", "fuel-storage", "hashbrown 0.13.2", @@ -2665,7 +2969,7 @@ checksum = "13aae44611588d199dd119e4a0ebd8eb7ae4cde6bf8b4d12715610b1f5e5b731" dependencies = [ "bitflags 2.6.0", "derivative", - "derive_more", + "derive_more 0.99.18", "fuel-asm", "fuel-crypto", "fuel-merkle", @@ -2703,7 +3007,7 @@ dependencies = [ "backtrace", "bitflags 2.6.0", "derivative", - "derive_more", + "derive_more 0.99.18", "ethnum", "fuel-asm", "fuel-crypto", @@ -2760,7 +3064,7 @@ dependencies = [ "fuels-core", "itertools 0.12.1", "rand", - "semver", + "semver 1.0.23", "tai64", "thiserror", "tokio", @@ -3240,7 +3544,7 @@ checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" dependencies = [ "atomic-polyfill", "hash32", - "rustc_version", + "rustc_version 0.4.0", "serde", "spin", "stable_deref_trait", @@ -3297,6 +3601,12 @@ dependencies = [ "serde", ] +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + [[package]] name = "hkdf" version = "0.12.4" @@ -3944,6 +4254,16 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "keccak-asm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "505d1856a39b200489082f90d897c3f07c455563880bc5952e38eabf731c83b6" +dependencies = [ + "digest 0.10.7", + "sha3-asm", +] + [[package]] name = "kqueue" version = "1.0.8" @@ -4241,7 +4561,7 @@ dependencies = [ "anyhow", "clap 4.5.16", "mdbook", - "semver", + "semver 1.0.23", "serde", "serde_json", ] @@ -4572,29 +4892,31 @@ dependencies = [ [[package]] name = "notify" -version = "5.2.0" +version = "6.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "729f63e1ca555a43fe3efa4f3efdf4801c479da85b432242a7b726f353c88486" +checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" dependencies = [ - "bitflags 1.2.1", + "bitflags 2.6.0", "crossbeam-channel", "filetime", "fsevent-sys", "inotify", "kqueue", "libc", + "log", "mio 0.8.11", "walkdir", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] name = "notify-debouncer-mini" -version = "0.2.1" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e23e9fa24f094b143c1eb61f90ac6457de87be6987bc70746e0179f7dbc9007b" +checksum = "5d40b221972a1fc5ef4d858a2f671fb34c75983eb385463dff3780eeff6a9d43" dependencies = [ "crossbeam-channel", + "log", "notify", ] @@ -4695,6 +5017,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -5420,6 +5743,26 @@ dependencies = [ "syn 2.0.74", ] +[[package]] +name = "proptest" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" +dependencies = [ + "bit-set", + "bit-vec", + "bitflags 2.6.0", + "lazy_static", + "num-traits", + "rand", + "rand_chacha", + "rand_xorshift", + "regex-syntax 0.8.4", + "rusty-fork", + "tempfile", + "unarray", +] + [[package]] name = "psl-types" version = "2.0.11" @@ -5483,6 +5826,12 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd348ff538bc9caeda7ee8cad2d1d48236a1f443c1fa3913c6a02fe0043b1dd3" +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quick-protobuf" version = "0.8.1" @@ -5556,6 +5905,15 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core", +] + [[package]] name = "rand_xoshiro" version = "0.6.0" @@ -5781,39 +6139,68 @@ dependencies = [ [[package]] name = "revm" -version = "2.3.1" +version = "14.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73d84c8f9836efb0f5f5f8de4700a953c4e1f3119e5cfcb0aad8e5be73daf991" +checksum = "a9f3f55d0414c3d73902d876ba3d55a654f05fe937089fbf5f34b1ced26d78d5" dependencies = [ - "arrayref", "auto_impl", - "bytes", - "hashbrown 0.13.2", - "num_enum 0.5.11", - "primitive-types", - "revm_precompiles", - "rlp", - "sha3", + "cfg-if 1.0.0", + "dyn-clone", + "revm-interpreter", + "revm-precompile", + "serde", + "serde_json", ] [[package]] -name = "revm_precompiles" -version = "1.1.2" +name = "revm-interpreter" +version = "10.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0353d456ef3e989dc9190f42c6020f09bc2025930c37895826029304413204b5" +checksum = "713dbb271acd13afb06dcd460c1dc43da211e7ac9bc73cdf13528f615f55f96b" dependencies = [ - "bytes", - "hashbrown 0.13.2", - "num", + "revm-primitives", + "serde", +] + +[[package]] +name = "revm-precompile" +version = "11.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f73010c271d53fa7904e9845338e95f3955eb1200a0355e0abfdb89c41aaa9cd" +dependencies = [ + "aurora-engine-modexp", + "blst", + "c-kzg", + "cfg-if 1.0.0", + "k256", "once_cell", - "primitive-types", + "revm-primitives", "ripemd", - "secp256k1 0.24.3", + "secp256k1 0.29.1", "sha2 0.10.8", - "sha3", "substrate-bn", ] +[[package]] +name = "revm-primitives" +version = "9.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a6bff9dbde3370a5ac9555104117f7e6039b3cc76e8d5d9d01899088beca2a" +dependencies = [ + "alloy-eips", + "alloy-primitives", + "auto_impl", + "bitflags 2.6.0", + "bitvec", + "c-kzg", + "cfg-if 1.0.0", + "dyn-clone", + "enumn", + "hashbrown 0.14.5", + "hex", + "serde", +] + [[package]] name = "rexpect" version = "0.4.0" @@ -5966,6 +6353,36 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "ruint" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c3cc4c2511671f327125da14133d0c5c5d137f006a1017a16f557bc85b16286" +dependencies = [ + "alloy-rlp", + "ark-ff 0.3.0", + "ark-ff 0.4.2", + "bytes", + "fastrlp", + "num-bigint", + "num-traits", + "parity-scale-codec", + "primitive-types", + "proptest", + "rand", + "rlp", + "ruint-macro", + "serde", + "valuable", + "zeroize", +] + +[[package]] +name = "ruint-macro" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" + [[package]] name = "rust_decimal" version = "1.35.0" @@ -6000,13 +6417,22 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + [[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver", + "semver 1.0.23", ] [[package]] @@ -6111,6 +6537,18 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +[[package]] +name = "rusty-fork" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + [[package]] name = "rustyline" version = "13.0.0" @@ -6266,37 +6704,38 @@ dependencies = [ [[package]] name = "secp256k1" -version = "0.24.3" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" +checksum = "4124a35fe33ae14259c490fd70fa199a32b9ce9502f2ee6bc4f81ec06fa65894" dependencies = [ - "secp256k1-sys 0.6.1", + "rand", + "secp256k1-sys 0.8.1", ] [[package]] name = "secp256k1" -version = "0.26.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4124a35fe33ae14259c490fd70fa199a32b9ce9502f2ee6bc4f81ec06fa65894" +checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113" dependencies = [ "rand", - "secp256k1-sys 0.8.1", + "secp256k1-sys 0.10.1", ] [[package]] name = "secp256k1-sys" -version = "0.6.1" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83080e2c2fc1006e625be82e5d1eb6a43b7fd9578b617fcc55814daf286bba4b" +checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" dependencies = [ "cc", ] [[package]] name = "secp256k1-sys" -version = "0.8.1" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" +checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9" dependencies = [ "cc", ] @@ -6333,6 +6772,15 @@ dependencies = [ "libc", ] +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + [[package]] name = "semver" version = "1.0.23" @@ -6342,6 +6790,15 @@ dependencies = [ "serde", ] +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + [[package]] name = "serde" version = "1.0.208" @@ -6377,6 +6834,7 @@ version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" dependencies = [ + "indexmap 2.5.0", "itoa", "memchr", "ryu", @@ -6517,6 +6975,16 @@ dependencies = [ "keccak", ] +[[package]] +name = "sha3-asm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28efc5e327c837aa837c59eae585fc250715ef939ac32881bcc11677cd02d46" +dependencies = [ + "cc", + "cfg-if 1.0.0", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -6931,7 +7399,7 @@ dependencies = [ "itertools 0.13.0", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.74", ] [[package]] @@ -6972,12 +7440,12 @@ dependencies = [ "sway-types", "sway-utils", "swayfmt", - "syn 1.0.109", + "syn 2.0.74", "tempfile", "thiserror", "tikv-jemallocator", "tokio", - "toml_edit 0.21.1", + "toml_edit 0.22.20", "tower 0.4.13", "tower-lsp", "tracing", @@ -7435,9 +7903,9 @@ dependencies = [ [[package]] name = "tikv-jemalloc-sys" -version = "0.5.4+5.3.0-patched" +version = "0.6.0+5.3.0-1-ge13ca993e8ccb9ba9847cc330696e02839f328f7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9402443cb8fd499b6f327e40565234ff34dbda27460c5b47db0db77443dd85d1" +checksum = "cd3c60906412afa9c2b5b5a48ca6a5abe5736aec9eb48ad05037a677e52e4e2d" dependencies = [ "cc", "libc", @@ -7445,9 +7913,9 @@ dependencies = [ [[package]] name = "tikv-jemallocator" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "965fe0c26be5c56c94e38ba547249074803efd52adfb66de62107d95aab3eaca" +checksum = "4cec5ff18518d81584f477e9bfdf957f5bb0979b0bac3af4ca30b5b3ae2d2865" dependencies = [ "libc", "tikv-jemalloc-sys", @@ -7918,6 +8386,12 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + [[package]] name = "unicase" version = "2.7.0" @@ -8149,6 +8623,15 @@ dependencies = [ "quote", ] +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + [[package]] name = "walkdir" version = "2.5.0" @@ -8326,15 +8809,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - [[package]] name = "windows-sys" version = "0.48.0" @@ -8362,21 +8836,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - [[package]] name = "windows-targets" version = "0.48.5" @@ -8408,12 +8867,6 @@ dependencies = [ "windows_x86_64_msvc 0.52.6", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -8426,12 +8879,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -8444,12 +8891,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -8468,12 +8909,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -8486,12 +8921,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -8504,12 +8933,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -8522,12 +8945,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - [[package]] name = "windows_x86_64_msvc" version = "0.48.5" diff --git a/Cargo.toml b/Cargo.toml index 95b4809a0dd..0af9f4fcdc8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -166,8 +166,8 @@ mdbook = { version = "0.4", default-features = false } miden = "0.3" miden-core = "0.3" minifier = "0.3" -notify = "5.0" -notify-debouncer-mini = "0.2" +notify = "6.1" +notify-debouncer-mini = "0.4" num-bigint = "0.4" num-traits = "0.2" object = "0.36" @@ -189,7 +189,7 @@ rayon = "1.7" rayon-cond = "0.3" regex = "1.10" reqwest = "0.12" -revm = "2.3" +revm = "14.0" ropey = "1.5" rpassword = "7.2" rustc-hash = "1.1" @@ -207,7 +207,7 @@ slotmap = "1.0" smallvec = "1.7" strsim = "0.11" strum = "0.26" -syn = "1.0" +syn = "2.0" taplo = "0.13" tar = "0.4" tempfile = "3" @@ -215,10 +215,10 @@ term-table = "1.3" termion = "4.0" textwrap = "0.16" thiserror = "1.0" -tikv-jemallocator = "0.5" +tikv-jemallocator = "0.6" tokio = "1.12" toml = "0.8" -toml_edit = "0.21" +toml_edit = "0.22" tower = { version = "0.5", default-features = false } tower-lsp = "0.20" tracing = "0.1" diff --git a/forc-plugins/forc-client/src/util/pkg.rs b/forc-plugins/forc-client/src/util/pkg.rs index 3aa8f6b2236..c93df24bacc 100644 --- a/forc-plugins/forc-client/src/util/pkg.rs +++ b/forc-plugins/forc-client/src/util/pkg.rs @@ -26,7 +26,7 @@ pub(crate) fn update_proxy_address_in_manifest( let mut toml = String::new(); let mut file = File::open(manifest.path())?; file.read_to_string(&mut toml)?; - let mut manifest_toml = toml.parse::()?; + let mut manifest_toml = toml.parse::()?; if manifest.proxy().is_some() { manifest_toml["proxy"]["address"] = toml_edit::value(address); let mut file = std::fs::OpenOptions::new() diff --git a/forc-plugins/forc-client/tests/deploy.rs b/forc-plugins/forc-client/tests/deploy.rs index c0016c74c67..0a31fb91ccb 100644 --- a/forc-plugins/forc-client/tests/deploy.rs +++ b/forc-plugins/forc-client/tests/deploy.rs @@ -23,7 +23,7 @@ use std::{ str::FromStr, }; use tempfile::tempdir; -use toml_edit::{value, Document, InlineTable, Item, Table, Value}; +use toml_edit::{value, DocumentMut, InlineTable, Item, Table, Value}; fn get_workspace_root() -> PathBuf { PathBuf::from(env!("CARGO_MANIFEST_DIR")) @@ -75,7 +75,7 @@ fn patch_manifest_file_with_path_std(manifest_dir: &Path) -> anyhow::Result<()> let toml_path = manifest_dir.join(sway_utils::constants::MANIFEST_FILE_NAME); let toml_content = fs::read_to_string(&toml_path).unwrap(); - let mut doc = toml_content.parse::().unwrap(); + let mut doc = toml_content.parse::().unwrap(); let new_std_path = get_workspace_root().join("sway-lib-std"); let mut std_dependency = InlineTable::new(); @@ -89,7 +89,7 @@ fn patch_manifest_file_with_path_std(manifest_dir: &Path) -> anyhow::Result<()> fn patch_manifest_file_with_proxy_table(manifest_dir: &Path, proxy: Proxy) -> anyhow::Result<()> { let toml_path = manifest_dir.join(sway_utils::constants::MANIFEST_FILE_NAME); let toml_content = fs::read_to_string(&toml_path)?; - let mut doc = toml_content.parse::()?; + let mut doc = toml_content.parse::()?; let proxy_table = doc.entry("proxy").or_insert(Item::Table(Table::new())); let proxy_table = proxy_table.as_table_mut().unwrap(); diff --git a/forc/src/ops/forc_template.rs b/forc/src/ops/forc_template.rs index 23703ea575e..0304a9d298a 100644 --- a/forc/src/ops/forc_template.rs +++ b/forc/src/ops/forc_template.rs @@ -84,7 +84,7 @@ fn edit_forc_toml(out_dir: &Path, project_name: &str, real_name: &str) -> Result let mut file = File::open(out_dir.join(constants::MANIFEST_FILE_NAME))?; let mut toml = String::new(); file.read_to_string(&mut toml)?; - let mut manifest_toml = toml.parse::()?; + let mut manifest_toml = toml.parse::()?; let mut authors = Vec::new(); let forc_toml: toml::Value = toml::de::from_str(&toml)?; @@ -144,7 +144,7 @@ fn edit_cargo_toml(out_dir: &Path, project_name: &str, real_name: &str) -> Resul } updated_authors.push(real_name); - let mut manifest_toml = toml.parse::()?; + let mut manifest_toml = toml.parse::()?; manifest_toml["package"]["authors"] = toml_edit::value(updated_authors); manifest_toml["package"]["name"] = toml_edit::value(project_name); diff --git a/sway-ir/sway-ir-macros/src/lib.rs b/sway-ir/sway-ir-macros/src/lib.rs index d6bcd7a7fc5..514a3986a75 100644 --- a/sway-ir/sway-ir-macros/src/lib.rs +++ b/sway-ir/sway-ir-macros/src/lib.rs @@ -4,7 +4,7 @@ use { quote::{format_ident, quote}, syn::{ parse_macro_input, Attribute, Data, DeriveInput, Fields, FieldsNamed, FieldsUnnamed, Ident, - Meta, NestedMeta, Variant, + Variant, }, }; @@ -170,7 +170,7 @@ fn pass_through_context(field_name: &Ident, attrs: &[Attribute]) -> proc_macro2: attrs .iter() .filter_map(|attr| { - let attr_name = attr.path.get_ident()?; + let attr_name = attr.path().get_ident()?; if attr_name != "in_context" { return None; } @@ -199,20 +199,16 @@ fn pass_through_context(field_name: &Ident, attrs: &[Attribute]) -> proc_macro2: } fn try_parse_context_field_from_attr(attr: &Attribute) -> Option { - let meta = attr.parse_meta().ok()?; - let Meta::List(meta_list) = meta else { - return None; - }; - if meta_list.nested.len() != 1 { - return None; + let mut context_fields = Vec::new(); + + let _ = attr.parse_nested_meta(|nested_meta| { + context_fields.push(nested_meta.path.get_ident().unwrap().clone()); + Ok(()) + }); + + if context_fields.len() != 1 { + None + } else { + context_fields.pop() } - let nested_meta = meta_list.nested.first()?; - let NestedMeta::Meta(inner_meta) = nested_meta else { - return None; - }; - let Meta::Path(path) = inner_meta else { - return None; - }; - let context_field_name = path.get_ident()?.clone(); - Some(context_field_name) } diff --git a/sway-lsp/Cargo.toml b/sway-lsp/Cargo.toml index 8129d1e7443..f9648768eb5 100644 --- a/sway-lsp/Cargo.toml +++ b/sway-lsp/Cargo.toml @@ -65,7 +65,7 @@ pretty_assertions = "1.4.0" rand = "0.8" regex = "^1.10.2" sway-lsp-test-utils = { path = "tests/utils" } -tikv-jemallocator = "0.5" +tikv-jemallocator = "0.6" tower = { version = "0.4.12", default-features = false, features = ["util"] } [[bench]] diff --git a/sway-lsp/src/core/sync.rs b/sway-lsp/src/core/sync.rs index f00189880fe..8c405f5e801 100644 --- a/sway-lsp/src/core/sync.rs +++ b/sway-lsp/src/core/sync.rs @@ -194,13 +194,12 @@ impl SyncWorkspace { let handle = tokio::spawn(async move { let (tx, mut rx) = tokio::sync::mpsc::channel(10); // Setup debouncer. No specific tickrate, max debounce time 2 seconds - let mut debouncer = - new_debouncer(Duration::from_secs(1), None, move |event| { - if let Ok(e) = event { - let _ = tx.blocking_send(e); - } - }) - .unwrap(); + let mut debouncer = new_debouncer(Duration::from_secs(1), move |event| { + if let Ok(e) = event { + let _ = tx.blocking_send(e); + } + }) + .unwrap(); debouncer .watcher() @@ -286,7 +285,7 @@ pub(crate) fn edit_manifest_dependency_paths( if let Ok(mut file) = File::open(manifest.path()) { let mut toml = String::new(); let _ = file.read_to_string(&mut toml); - if let Ok(mut manifest_toml) = toml.parse::() { + if let Ok(mut manifest_toml) = toml.parse::() { for (name, abs_path) in dependency_map { manifest_toml["dependencies"][&name]["path"] = toml_edit::value(abs_path.display().to_string()); diff --git a/sway-lsp/src/utils/keyword_docs.rs b/sway-lsp/src/utils/keyword_docs.rs index f26d48a3b37..060118fa234 100644 --- a/sway-lsp/src/utils/keyword_docs.rs +++ b/sway-lsp/src/utils/keyword_docs.rs @@ -802,7 +802,7 @@ impl KeywordDocs { let name = ident.trim_end_matches("_keyword").to_owned(); let mut documentation = String::new(); keyword.attrs.iter().for_each(|attr| { - let tokens = attr.tokens.to_token_stream(); + let tokens = attr.meta.clone().to_token_stream(); let lit = extract_lit(tokens); writeln!(documentation, "{lit}").unwrap(); }); diff --git a/test/src/e2e_vm_tests/harness.rs b/test/src/e2e_vm_tests/harness.rs index a77a01acd84..e2a3236db07 100644 --- a/test/src/e2e_vm_tests/harness.rs +++ b/test/src/e2e_vm_tests/harness.rs @@ -140,7 +140,7 @@ pub(crate) async fn runs_on_node( pub(crate) enum VMExecutionResult { Fuel(ProgramState, Vec), - Evm(revm::ExecutionResult), + Evm(revm::primitives::result::ExecutionResult), MidenVM(miden::ExecutionTrace), } @@ -214,31 +214,38 @@ pub(crate) fn runs_in_vm( )) } BuildTarget::EVM => { - let mut evm = revm::new(); - evm.database(revm::InMemoryDB::default()); - evm.env = revm::Env::default(); + let mut evm = revm::EvmBuilder::default() + .with_db(revm::InMemoryDB::default()) + .with_clear_env() + .build(); // Transaction to create the smart contract - evm.env.tx.transact_to = revm::TransactTo::create(); - evm.env.tx.data = bytes::Bytes::from(script.bytecode.bytes.into_boxed_slice()); - let result = evm.transact_commit(); - - match result.out { - revm::TransactOut::None => Err(anyhow!("Could not create smart contract")), - revm::TransactOut::Call(_) => todo!(), - revm::TransactOut::Create(ref _bytes, account_opt) => { - match account_opt { - Some(account) => { - evm.env.tx.transact_to = revm::TransactTo::Call(account); - - // Now issue a call. - //evm.env.tx. = bytes::Bytes::from(script.bytecode.into_boxed_slice()); - let result = evm.transact_commit(); - Ok(VMExecutionResult::Evm(result)) + let result = evm + .transact_commit() + .map_err(|e| anyhow::anyhow!("Could not create smart contract on EVM: {e:?}"))?; + + match result { + revm::primitives::ExecutionResult::Revert { .. } + | revm::primitives::ExecutionResult::Halt { .. } => todo!(), + revm::primitives::ExecutionResult::Success { ref output, .. } => match output { + revm::primitives::result::Output::Call(_) => todo!(), + revm::primitives::result::Output::Create(_bytes, address_opt) => { + match address_opt { + None => todo!(), + Some(address) => { + evm.tx_mut().data = script.bytecode.bytes.into(); + evm.tx_mut().transact_to = + revm::interpreter::primitives::TransactTo::Call(*address); + + let result = evm + .transact_commit() + .map_err(|e| anyhow::anyhow!("Failed call on EVM: {e:?}"))?; + + Ok(VMExecutionResult::Evm(result)) + } } - None => todo!(), } - } + }, } } BuildTarget::MidenVM => { diff --git a/test/src/e2e_vm_tests/mod.rs b/test/src/e2e_vm_tests/mod.rs index 947ad9b20cc..ca7550d3940 100644 --- a/test/src/e2e_vm_tests/mod.rs +++ b/test/src/e2e_vm_tests/mod.rs @@ -414,14 +414,16 @@ impl TestContext { } } } - harness::VMExecutionResult::Evm(state) => match state.exit_reason { - revm::Return::Continue => todo!(), - revm::Return::Stop => TestResult::Result(0), - revm::Return::Return => todo!(), - revm::Return::SelfDestruct => todo!(), - revm::Return::Revert => TestResult::Revert(0), - _ => { - panic!("EVM exited with unhandled reason: {:?}", state.exit_reason); + harness::VMExecutionResult::Evm(state) => match state { + revm::primitives::ExecutionResult::Success { reason, .. } => match reason { + revm::primitives::SuccessReason::Stop => TestResult::Result(0), + revm::primitives::SuccessReason::Return => todo!(), + revm::primitives::SuccessReason::SelfDestruct => todo!(), + revm::primitives::SuccessReason::EofReturnContract => todo!(), + }, + revm::primitives::ExecutionResult::Revert { .. } => TestResult::Result(0), + revm::primitives::ExecutionResult::Halt { reason, .. } => { + panic!("EVM exited with unhandled reason: {:?}", reason); } }, harness::VMExecutionResult::MidenVM(trace) => { From 99f11c05dd22309662842228b7c7e1c99eba367b Mon Sep 17 00:00:00 2001 From: Joshua Batty Date: Mon, 23 Sep 2024 17:04:40 +1000 Subject: [PATCH 032/115] Add inlay hints for function parameters (#6513) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description Inlay hints are now displayed in function parameter locations if a variable with the same name is not present. This should be identical to the behaviour of rust-analyzer. The inlay_hints benchmark is slower because we are now also calculating inlay hints for function_params and variable decls in the same iteration. See screen shot below for all supported types. ![Screenshot 2024-09-21 at 10 47 12 AM](https://github.com/user-attachments/assets/c3aaa901-e01d-4e88-a405-f1077d2d2dce) closes #5196 ## 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-lsp/src/capabilities/inlay_hints.rs | 146 +++++++++++++----- sway-lsp/src/handlers/request.rs | 2 +- .../tests/fixtures/inlay_hints/.gitignore | 2 + sway-lsp/tests/fixtures/inlay_hints/Forc.toml | 9 ++ .../tests/fixtures/inlay_hints/src/main.sw | 51 ++++++ sway-lsp/tests/integration/lsp.rs | 123 +++++++++++++++ sway-lsp/tests/lib.rs | 5 + 7 files changed, 302 insertions(+), 36 deletions(-) create mode 100644 sway-lsp/tests/fixtures/inlay_hints/.gitignore create mode 100644 sway-lsp/tests/fixtures/inlay_hints/Forc.toml create mode 100644 sway-lsp/tests/fixtures/inlay_hints/src/main.sw diff --git a/sway-lsp/src/capabilities/inlay_hints.rs b/sway-lsp/src/capabilities/inlay_hints.rs index f6bdb95a128..a832948fc96 100644 --- a/sway-lsp/src/capabilities/inlay_hints.rs +++ b/sway-lsp/src/capabilities/inlay_hints.rs @@ -7,13 +7,16 @@ use crate::{ }; use lsp_types::{self, Range, Url}; use std::sync::Arc; -use sway_core::{language::ty::TyDecl, type_system::TypeInfo}; -use sway_types::Spanned; +use sway_core::{ + language::ty::{TyDecl, TyExpression, TyExpressionVariant}, + type_system::TypeInfo, +}; +use sway_types::{Ident, Spanned}; -// Future PR's will add more kinds #[derive(Clone, Debug, PartialEq, Eq)] pub enum InlayKind { TypeHint, + Parameter, } #[derive(Debug)] @@ -23,22 +26,27 @@ pub struct InlayHint { pub label: String, } +/// Generates inlay hints for the provided range. pub fn inlay_hints( session: Arc, uri: &Url, range: &Range, config: &InlayHintsConfig, ) -> Option> { - let _p = tracing::trace_span!("inlay_hints").entered(); - // 1. Loop through all our tokens and filter out all tokens that aren't TypedVariableDeclaration tokens - // 2. Also filter out all tokens that have a span that fall outside of the provided range - // 3. Filter out all variable tokens that have a type_ascription - // 4. Look up the type id for the remaining tokens - // 5. Convert the type into a string + let _span = tracing::trace_span!("inlay_hints").entered(); + if !config.type_hints { return None; } + // 1. Iterate through all tokens in the file + // 2. Filter for TypedVariableDeclaration tokens within the provided range + // 3. For each variable declaration: + // a. If it's a function application, generate parameter hints + // b. If it doesn't have a type ascription and its type is known: + // - Look up the type information + // - Generate a type hint + // 4. Collect all generated hints into a single vector let hints: Vec = session .token_map() .tokens_for_file(uri) @@ -46,58 +54,126 @@ pub fn inlay_hints( let token = item.value(); token.typed.as_ref().and_then(|t| match t { TypedAstToken::TypedDeclaration(TyDecl::VariableDecl(var_decl)) => { - if var_decl.type_ascription.call_path_tree.is_some() { - None + let var_range = get_range_from_span(&var_decl.name.span()); + if var_range.start >= range.start && var_range.end <= range.end { + Some(var_decl.clone()) } else { - let var_range = get_range_from_span(&var_decl.name.span()); - if var_range.start >= range.start && var_range.end <= range.end { - Some(var_decl.clone()) - } else { - None - } + None } } _ => None, }) }) - .filter_map(|var| { - let type_info = session.engines.read().te().get(var.type_ascription.type_id); - match &*type_info { - TypeInfo::Unknown | TypeInfo::UnknownGeneric { .. } => None, - _ => Some(var), + .flat_map(|var| { + let mut hints = Vec::new(); + + // Function parameter hints + if let TyExpressionVariant::FunctionApplication { arguments, .. } = &var.body.expression + { + hints.extend(handle_function_parameters(arguments, config)); } - }) - .map(|var| { - let range = get_range_from_span(&var.name.span()); - let kind = InlayKind::TypeHint; - let label = format!("{}", session.engines.read().help_out(var.type_ascription)); - let inlay_hint = InlayHint { range, kind, label }; - self::inlay_hint(config.render_colons, inlay_hint) + + // Variable declaration hints + if var.type_ascription.call_path_tree.is_none() { + let type_info = session.engines.read().te().get(var.type_ascription.type_id); + if !matches!( + *type_info, + TypeInfo::Unknown | TypeInfo::UnknownGeneric { .. } + ) { + let range = get_range_from_span(&var.name.span()); + let kind = InlayKind::TypeHint; + let label = format!("{}", session.engines.read().help_out(var.type_ascription)); + let inlay_hint = InlayHint { range, kind, label }; + hints.push(self::inlay_hint(config, inlay_hint)); + } + } + hints }) .collect(); Some(hints) } -fn inlay_hint(render_colons: bool, inlay_hint: InlayHint) -> lsp_types::InlayHint { +fn handle_function_parameters( + arguments: &[(Ident, TyExpression)], + config: &InlayHintsConfig, +) -> Vec { + arguments + .iter() + .flat_map(|(name, exp)| { + let mut hints = Vec::new(); + let (should_create_hint, span) = match &exp.expression { + TyExpressionVariant::Literal(_) + | TyExpressionVariant::ConstantExpression { .. } + | TyExpressionVariant::Tuple { .. } + | TyExpressionVariant::Array { .. } + | TyExpressionVariant::ArrayIndex { .. } + | TyExpressionVariant::FunctionApplication { .. } + | TyExpressionVariant::StructFieldAccess { .. } + | TyExpressionVariant::TupleElemAccess { .. } => (true, &exp.span), + TyExpressionVariant::EnumInstantiation { + call_path_binding, .. + } => (true, &call_path_binding.span), + _ => (false, &exp.span), + }; + if should_create_hint { + let range = get_range_from_span(span); + let kind = InlayKind::Parameter; + let label = name.as_str().to_string(); + let inlay_hint = InlayHint { range, kind, label }; + hints.push(self::inlay_hint(config, inlay_hint)); + } + // Handle nested function applications + if let TyExpressionVariant::FunctionApplication { + arguments: nested_args, + .. + } = &exp.expression + { + hints.extend(handle_function_parameters(nested_args, config)); + } + hints + }) + .collect::>() +} + +fn inlay_hint(config: &InlayHintsConfig, inlay_hint: InlayHint) -> lsp_types::InlayHint { + let truncate_label = |label: String| -> String { + if let Some(max_length) = config.max_length { + if label.len() > max_length { + format!("{}...", &label[..max_length.saturating_sub(3)]) + } else { + label + } + } else { + label + } + }; + + let label = match inlay_hint.kind { + InlayKind::TypeHint if config.render_colons => format!(": {}", inlay_hint.label), + InlayKind::Parameter if config.render_colons => format!("{}: ", inlay_hint.label), + _ => inlay_hint.label, + }; + lsp_types::InlayHint { position: match inlay_hint.kind { // after annotated thing InlayKind::TypeHint => inlay_hint.range.end, + InlayKind::Parameter => inlay_hint.range.start, }, - label: lsp_types::InlayHintLabel::String(match inlay_hint.kind { - InlayKind::TypeHint if render_colons => format!(": {}", inlay_hint.label), - InlayKind::TypeHint => inlay_hint.label, - }), + label: lsp_types::InlayHintLabel::String(truncate_label(label)), kind: match inlay_hint.kind { InlayKind::TypeHint => Some(lsp_types::InlayHintKind::TYPE), + InlayKind::Parameter => Some(lsp_types::InlayHintKind::PARAMETER), }, tooltip: None, padding_left: Some(match inlay_hint.kind { - InlayKind::TypeHint => !render_colons, + InlayKind::TypeHint => !config.render_colons, + InlayKind::Parameter => false, }), padding_right: Some(match inlay_hint.kind { InlayKind::TypeHint => false, + InlayKind::Parameter => !config.render_colons, }), text_edits: None, data: None, diff --git a/sway-lsp/src/handlers/request.rs b/sway-lsp/src/handlers/request.rs index 1703948c561..fb4b72d86a8 100644 --- a/sway-lsp/src/handlers/request.rs +++ b/sway-lsp/src/handlers/request.rs @@ -333,7 +333,7 @@ pub async fn handle_semantic_tokens_full( } } -pub(crate) async fn handle_inlay_hints( +pub async fn handle_inlay_hints( state: &ServerState, params: InlayHintParams, ) -> Result>> { diff --git a/sway-lsp/tests/fixtures/inlay_hints/.gitignore b/sway-lsp/tests/fixtures/inlay_hints/.gitignore new file mode 100644 index 00000000000..77d3844f58c --- /dev/null +++ b/sway-lsp/tests/fixtures/inlay_hints/.gitignore @@ -0,0 +1,2 @@ +out +target diff --git a/sway-lsp/tests/fixtures/inlay_hints/Forc.toml b/sway-lsp/tests/fixtures/inlay_hints/Forc.toml new file mode 100644 index 00000000000..57a6803b1f1 --- /dev/null +++ b/sway-lsp/tests/fixtures/inlay_hints/Forc.toml @@ -0,0 +1,9 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "inlay_hints" +implicit-std = false + +[dependencies] +std = { git = "https://github.com/FuelLabs/sway", tag = "v0.63.5" } diff --git a/sway-lsp/tests/fixtures/inlay_hints/src/main.sw b/sway-lsp/tests/fixtures/inlay_hints/src/main.sw new file mode 100644 index 00000000000..f3071c0f912 --- /dev/null +++ b/sway-lsp/tests/fixtures/inlay_hints/src/main.sw @@ -0,0 +1,51 @@ +script; + +const CONSTANT: u64 = 42; + +enum MyEnum { + A: u64, +} +struct MyStruct { + a: u64, +} +fn my_function(foo: u64, bar: u64, long_argument_name: u64) -> u64 { + foo + bar + long_argument_name +} +fn identity(x: T) -> T { + x +} +fn two_generics(_a: A, b: B) -> B { + b +} +fn three_generics(a: A, b: B, _c: C) -> B { + let _a: A = a; + b +} + +fn main() { + let _x = my_function(1, 2, 3); + let foo = 1; + let _y = my_function(foo, 2, 3); + let bar = 2; + let _function_call = identity(my_function(1, bar, 3)); + let _z = my_function(foo, bar, 3); + let long_argument_name = 3; + let _w = my_function(foo, bar, long_argument_name); + let _a: bool = identity(true); + let _b: u32 = identity(10u32); + let _c: u64 = identity(42); + let _e: str = identity("foo"); + let _f: u64 = two_generics(true, 10); + let _g: str = three_generics(true, "foo", 10); + let _const = identity(CONSTANT); + let _tuple = identity((1, 2, 3)); + let _array = identity([1, 2, 3]); + let _enum = identity(MyEnum::A(1)); + let s = MyStruct { a: 1 }; + let _struct_field_access = identity(s.a); + let t = (0, 1, 9); + let _tuple_elem_access = identity(t.2); + let a = [1, 2, 3]; + let _array_index = identity(a[1]); +} + diff --git a/sway-lsp/tests/integration/lsp.rs b/sway-lsp/tests/integration/lsp.rs index 3fd9ca2dc5b..7f26570846a 100644 --- a/sway-lsp/tests/integration/lsp.rs +++ b/sway-lsp/tests/integration/lsp.rs @@ -663,3 +663,126 @@ pub fn create_did_change_params( }], } } + +pub(crate) async fn inlay_hints_request<'a>( + server: &ServerState, + uri: &Url, +) -> Option> { + let params = InlayHintParams { + text_document: TextDocumentIdentifier { uri: uri.clone() }, + range: Range { + start: Position { + line: 25, + character: 0, + }, + end: Position { + line: 26, + character: 1, + }, + }, + work_done_progress_params: Default::default(), + }; + let res = request::handle_inlay_hints(server, params) + .await + .unwrap() + .unwrap(); + let expected = vec![ + InlayHint { + position: Position { + line: 25, + character: 25, + }, + label: InlayHintLabel::String("foo: ".to_string()), + kind: Some(InlayHintKind::PARAMETER), + text_edits: None, + tooltip: None, + padding_left: Some(false), + padding_right: Some(false), + data: None, + }, + InlayHint { + position: Position { + line: 25, + character: 28, + }, + label: InlayHintLabel::String("bar: ".to_string()), + kind: Some(InlayHintKind::PARAMETER), + text_edits: None, + tooltip: None, + padding_left: Some(false), + padding_right: Some(false), + data: None, + }, + InlayHint { + position: Position { + line: 25, + character: 31, + }, + label: InlayHintLabel::String("long_argument_name: ".to_string()), + kind: Some(InlayHintKind::PARAMETER), + text_edits: None, + tooltip: None, + padding_left: Some(false), + padding_right: Some(false), + data: None, + }, + InlayHint { + position: Position { + line: 25, + character: 10, + }, + label: InlayHintLabel::String(": u64".to_string()), + kind: Some(InlayHintKind::TYPE), + text_edits: None, + tooltip: None, + padding_left: Some(false), + padding_right: Some(false), + data: None, + }, + ]; + + assert!( + compare_inlay_hint_vecs(&expected, &res), + "InlayHint vectors are not equal.\nExpected:\n{:#?}\n\nActual:\n{:#?}", + expected, + res + ); + Some(res) +} + +// This is a helper function to compare two inlay hints. because PartialEq is not implemented for InlayHint +fn compare_inlay_hints(a: &InlayHint, b: &InlayHint) -> bool { + a.position == b.position + && compare_inlay_hint_labels(&a.label, &b.label) + && a.kind == b.kind + && a.text_edits == b.text_edits + && compare_inlay_hint_tooltips(&a.tooltip, &b.tooltip) + && a.padding_left == b.padding_left + && a.padding_right == b.padding_right + && a.data == b.data +} + +fn compare_inlay_hint_vecs(a: &[InlayHint], b: &[InlayHint]) -> bool { + a.len() == b.len() && a.iter().zip(b).all(|(a, b)| compare_inlay_hints(a, b)) +} + +fn compare_inlay_hint_labels(a: &InlayHintLabel, b: &InlayHintLabel) -> bool { + match (a, b) { + (InlayHintLabel::String(a), InlayHintLabel::String(b)) => a == b, + _ => false, + } +} + +fn compare_inlay_hint_tooltips(a: &Option, b: &Option) -> bool { + match (a, b) { + (None, None) => true, + (Some(a), Some(b)) => match (a, b) { + (InlayHintTooltip::String(a), InlayHintTooltip::String(b)) => a == b, + (InlayHintTooltip::MarkupContent(a), InlayHintTooltip::MarkupContent(b)) => { + a.kind == b.kind && a.value == b.value + } + _ => false, + }, + _ => false, + } +} diff --git a/sway-lsp/tests/lib.rs b/sway-lsp/tests/lib.rs index 8eebe036aef..ef383c9ddba 100644 --- a/sway-lsp/tests/lib.rs +++ b/sway-lsp/tests/lib.rs @@ -2090,6 +2090,11 @@ lsp_capability_test!( lsp::completion_request, test_fixtures_dir().join("completion/src/main.sw") ); +lsp_capability_test!( + inlay_hints_function_params, + lsp::inlay_hints_request, + test_fixtures_dir().join("inlay_hints/src/main.sw") +); // This method iterates over all of the examples in the e2e language should_pass dir // and saves the lexed, parsed, and typed ASTs to the users home directory. From e549ca50854bf6943aa02e755aa8b9c94a162125 Mon Sep 17 00:00:00 2001 From: Vaivaswatha N Date: Mon, 23 Sep 2024 14:18:22 +0530 Subject: [PATCH 033/115] Common sub-expression elimination pass (#6413) ## Description This PR introduces a value-numbering based CSE pass. A reference to the algorithm used is mentioned as a comment in `cse.rs`. --------- Co-authored-by: IGI-111 Co-authored-by: Sophie Dankel <47993817+sdankel@users.noreply.github.com> --- sway-ir/src/analysis/dominator.rs | 56 ++- sway-ir/src/instruction.rs | 6 +- sway-ir/src/optimize.rs | 2 + sway-ir/src/optimize/conditional_constprop.rs | 14 +- sway-ir/src/optimize/cse.rs | 408 ++++++++++++++++++ sway-ir/src/optimize/mem2reg.rs | 4 +- sway-ir/src/pass_manager.rs | 23 +- sway-ir/tests/cse/cse1.ir | 21 + sway-ir/tests/cse/cse2.ir | 22 + sway-ir/tests/cse/cse3.ir | 29 ++ sway-ir/tests/tests.rs | 29 +- .../json_abi_oracle_new_encoding.json | 32 +- .../json_abi_oracle_new_encoding.json | 2 +- .../array_of_structs_caller/src/main.sw | 2 +- .../asset_ops_test/src/main.sw | 2 +- .../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 +- 25 files changed, 597 insertions(+), 75 deletions(-) create mode 100644 sway-ir/src/optimize/cse.rs create mode 100644 sway-ir/tests/cse/cse1.ir create mode 100644 sway-ir/tests/cse/cse2.ir create mode 100644 sway-ir/tests/cse/cse3.ir diff --git a/sway-ir/src/analysis/dominator.rs b/sway-ir/src/analysis/dominator.rs index 72de08fb690..9919cd2f556 100644 --- a/sway-ir/src/analysis/dominator.rs +++ b/sway-ir/src/analysis/dominator.rs @@ -28,7 +28,8 @@ impl DomTreeNode { } // The dominator tree is represented by mapping each Block to its DomTreeNode. -pub type DomTree = FxIndexMap; +#[derive(Default)] +pub struct DomTree(FxIndexMap); impl AnalysisResultT for DomTree {} // Dominance frontier sets. @@ -120,11 +121,11 @@ fn compute_dom_tree( let entry = function.get_entry_block(context); // This is to make the algorithm happy. It'll be changed to None later. - dom_tree.insert(entry, DomTreeNode::new(Some(entry))); + dom_tree.0.insert(entry, DomTreeNode::new(Some(entry))); // initialize the dominators tree. This allows us to do dom_tree[b] fearlessly. // Note that we just previously initialized "entry", so we skip that here. for b in po.po_to_block.iter().take(po.po_to_block.len() - 1) { - dom_tree.insert(*b, DomTreeNode::new(None)); + dom_tree.0.insert(*b, DomTreeNode::new(None)); } let mut changed = true; @@ -149,12 +150,12 @@ fn compute_dom_tree( .pred_iter(context) .filter(|p| **p != picked_pred && po.block_to_po.contains_key(p)) { - if dom_tree[p].parent.is_some() { + if dom_tree.0[p].parent.is_some() { // if doms[p] already calculated new_idom = intersect(po, &dom_tree, *p, new_idom); } } - let b_node = dom_tree.get_mut(b).unwrap(); + let b_node = dom_tree.0.get_mut(b).unwrap(); match b_node.parent { Some(idom) if idom == new_idom => {} _ => { @@ -175,29 +176,54 @@ fn compute_dom_tree( ) -> Block { while finger1 != finger2 { while po.block_to_po[&finger1] < po.block_to_po[&finger2] { - finger1 = dom_tree[&finger1].parent.unwrap(); + finger1 = dom_tree.0[&finger1].parent.unwrap(); } while po.block_to_po[&finger2] < po.block_to_po[&finger1] { - finger2 = dom_tree[&finger2].parent.unwrap(); + finger2 = dom_tree.0[&finger2].parent.unwrap(); } } finger1 } // Fix the root. - dom_tree.get_mut(&entry).unwrap().parent = None; + dom_tree.0.get_mut(&entry).unwrap().parent = None; // Build the children. let child_parent: Vec<_> = dom_tree + .0 .iter() .filter_map(|(n, n_node)| n_node.parent.map(|n_parent| (*n, n_parent))) .collect(); for (child, parent) in child_parent { - dom_tree.get_mut(&parent).unwrap().children.push(child); + dom_tree.0.get_mut(&parent).unwrap().children.push(child); } Ok(Box::new(dom_tree)) } +impl DomTree { + /// Does `dominator` dominate `dominatee`? + pub fn dominates(&self, dominator: Block, dominatee: Block) -> bool { + let mut node_opt = Some(dominatee); + while let Some(node) = node_opt { + if node == dominator { + return true; + } + node_opt = self.0[&node].parent; + } + false + } + + /// Get an iterator over the children nodes + pub fn children(&self, node: Block) -> impl Iterator + '_ { + self.0[&node].children.iter().cloned() + } + + /// Get i'th child of a given node + pub fn child(&self, node: Block, i: usize) -> Option { + self.0[&node].children.get(i).cloned() + } +} + pub const DOM_FRONTS_NAME: &str = "dominance-frontiers"; pub fn create_dom_fronts_pass() -> Pass { @@ -217,23 +243,23 @@ fn compute_dom_fronts( ) -> Result { let dom_tree: &DomTree = analyses.get_analysis_result(function); let mut res = DomFronts::default(); - for (b, _) in dom_tree.iter() { + for (b, _) in dom_tree.0.iter() { res.insert(*b, IndexSet::default()); } // for all nodes, b - for (b, _) in dom_tree.iter() { + for (b, _) in dom_tree.0.iter() { // if the number of predecessors of b >= 2 if b.num_predecessors(context) > 1 { // unwrap() is safe as b is not "entry", and hence must have idom. - let b_idom = dom_tree[b].parent.unwrap(); + let b_idom = dom_tree.0[b].parent.unwrap(); // for all (reachable) predecessors, p, of b - for p in b.pred_iter(context).filter(|&p| dom_tree.contains_key(p)) { + for p in b.pred_iter(context).filter(|&p| dom_tree.0.contains_key(p)) { let mut runner = *p; while runner != b_idom { // add b to runner’s dominance frontier set res.get_mut(&runner).unwrap().insert(*b); - runner = dom_tree[&runner].parent.unwrap(); + runner = dom_tree.0[&runner].parent.unwrap(); } } } @@ -244,7 +270,7 @@ fn compute_dom_fronts( /// Print dominator tree in the graphviz dot format. pub fn print_dot(context: &Context, func_name: &str, dom_tree: &DomTree) -> String { let mut res = format!("digraph {func_name} {{\n"); - for (b, idom) in dom_tree.iter() { + for (b, idom) in dom_tree.0.iter() { if let Some(idom) = idom.parent { let _ = writeln!( res, diff --git a/sway-ir/src/instruction.rs b/sway-ir/src/instruction.rs index 1db5a4663ed..9e7b92fb5e0 100644 --- a/sway-ir/src/instruction.rs +++ b/sway-ir/src/instruction.rs @@ -205,19 +205,19 @@ pub enum FuelVmInstruction { } /// Comparison operations. -#[derive(Debug, Clone, Copy, Hash)] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] pub enum Predicate { Equal, LessThan, GreaterThan, } -#[derive(Debug, Clone, Copy, Hash)] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] pub enum UnaryOpKind { Not, } -#[derive(Debug, Clone, Copy, Hash)] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] pub enum BinaryOpKind { Add, Sub, diff --git a/sway-ir/src/optimize.rs b/sway-ir/src/optimize.rs index 5a1dbeab9bf..564002fff13 100644 --- a/sway-ir/src/optimize.rs +++ b/sway-ir/src/optimize.rs @@ -21,6 +21,8 @@ pub mod constants; pub use constants::*; pub mod conditional_constprop; pub use conditional_constprop::*; +pub mod cse; +pub use cse::*; pub mod dce; pub use dce::*; pub mod inline; diff --git a/sway-ir/src/optimize/conditional_constprop.rs b/sway-ir/src/optimize/conditional_constprop.rs index 44daf1f5484..deb5a1b1623 100644 --- a/sway-ir/src/optimize/conditional_constprop.rs +++ b/sway-ir/src/optimize/conditional_constprop.rs @@ -59,17 +59,13 @@ pub fn ccp( } // lets walk the dominator tree from the root. - let Some((root_block, _root_node)) = - dom_tree.iter().find(|(_block, node)| node.parent.is_none()) - else { - panic!("Dominator tree without root"); - }; + let root_block = function.get_entry_block(context); if dom_region_replacements.is_empty() { return Ok(false); } - let mut stack = vec![(*root_block, 0)]; + let mut stack = vec![(root_block, 0)]; let mut replacements = FxHashMap::default(); while let Some((block, next_child)) = stack.last().cloned() { let cur_replacement_opt = dom_region_replacements.get(&block); @@ -83,14 +79,12 @@ pub fn ccp( block.replace_values(context, &replacements); } - let block_node = &dom_tree[&block]; - // walk children. - if let Some(child) = block_node.children.get(next_child) { + if let Some(child) = dom_tree.child(block, next_child) { // When we arrive back at "block" next time, we should process the next child. stack.last_mut().unwrap().1 = next_child + 1; // Go on to process the child. - stack.push((*child, 0)); + stack.push((child, 0)); } else { // No children left to process. Start postorder processing. if let Some(cur_replacement) = cur_replacement_opt { diff --git a/sway-ir/src/optimize/cse.rs b/sway-ir/src/optimize/cse.rs new file mode 100644 index 00000000000..7423cc2fa62 --- /dev/null +++ b/sway-ir/src/optimize/cse.rs @@ -0,0 +1,408 @@ +//! Value numbering based common subexpression elimination. +//! Reference: Value Driven Redundancy Elimination - Loren Taylor Simpson. + +use core::panic; +use itertools::Itertools; +use rustc_hash::{FxHashMap, FxHashSet, FxHasher}; +use slotmap::Key; +use std::{ + collections::hash_map, + fmt::Debug, + hash::{Hash, Hasher}, +}; + +use crate::{ + AnalysisResults, BinaryOpKind, Context, DebugWithContext, DomTree, Function, InstOp, IrError, + Pass, PassMutability, PostOrder, Predicate, ScopedPass, Type, UnaryOpKind, Value, + DOMINATORS_NAME, POSTORDER_NAME, +}; + +pub const CSE_NAME: &str = "cse"; + +pub fn create_cse_pass() -> Pass { + Pass { + name: CSE_NAME, + descr: "Common subexpression elimination", + runner: ScopedPass::FunctionPass(PassMutability::Transform(cse)), + deps: vec![POSTORDER_NAME, DOMINATORS_NAME], + } +} + +#[derive(Clone, Copy, Eq, PartialEq, Hash, DebugWithContext)] +enum ValueNumber { + // Top of the lattice = Don't know = uninitialized + Top, + // Belongs to a congruence class represented by the inner value. + Number(Value), +} + +impl Debug for ValueNumber { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Top => write!(f, "Top"), + Self::Number(arg0) => write!(f, "v{:?}", arg0.0.data()), + } + } +} + +#[derive(Clone, Debug, Eq, PartialEq, Hash, DebugWithContext)] +enum Expr { + Phi(Vec), + UnaryOp { + op: UnaryOpKind, + arg: ValueNumber, + }, + BinaryOp { + op: BinaryOpKind, + arg1: ValueNumber, + arg2: ValueNumber, + }, + BitCast(ValueNumber, Type), + CastPtr(ValueNumber, Type), + Cmp(Predicate, ValueNumber, ValueNumber), + GetElemPtr { + base: ValueNumber, + elem_ptr_ty: Type, + indices: Vec, + }, + IntToPtr(ValueNumber, Type), + PtrToInt(ValueNumber, Type), +} + +/// Convert an instruction to an expression for hashing +/// Instructions that we don't handle will have their value numbers be equal to themselves. +fn instr_to_expr(context: &Context, vntable: &VNTable, instr: Value) -> Option { + match &instr.get_instruction(context).unwrap().op { + InstOp::AsmBlock(_, _) => None, + InstOp::UnaryOp { op, arg } => Some(Expr::UnaryOp { + op: *op, + arg: vntable.value_map.get(arg).cloned().unwrap(), + }), + InstOp::BinaryOp { op, arg1, arg2 } => Some(Expr::BinaryOp { + op: *op, + arg1: vntable.value_map.get(arg1).cloned().unwrap(), + arg2: vntable.value_map.get(arg2).cloned().unwrap(), + }), + InstOp::BitCast(val, ty) => Some(Expr::BitCast( + vntable.value_map.get(val).cloned().unwrap(), + *ty, + )), + InstOp::Branch(_) => None, + InstOp::Call(_, _) => None, + InstOp::CastPtr(val, ty) => Some(Expr::CastPtr( + vntable.value_map.get(val).cloned().unwrap(), + *ty, + )), + InstOp::Cmp(pred, val1, val2) => Some(Expr::Cmp( + *pred, + vntable.value_map.get(val1).cloned().unwrap(), + vntable.value_map.get(val2).cloned().unwrap(), + )), + InstOp::ConditionalBranch { .. } => None, + InstOp::ContractCall { .. } => None, + InstOp::FuelVm(_) => None, + InstOp::GetLocal(_) => None, + InstOp::GetConfig(_, _) => None, + InstOp::GetElemPtr { + base, + elem_ptr_ty, + indices, + } => Some(Expr::GetElemPtr { + base: vntable.value_map.get(base).cloned().unwrap(), + elem_ptr_ty: *elem_ptr_ty, + indices: indices + .iter() + .map(|idx| vntable.value_map.get(idx).cloned().unwrap()) + .collect(), + }), + InstOp::IntToPtr(val, ty) => Some(Expr::IntToPtr( + vntable.value_map.get(val).cloned().unwrap(), + *ty, + )), + InstOp::Load(_) => None, + InstOp::MemCopyBytes { .. } => None, + InstOp::MemCopyVal { .. } => None, + InstOp::Nop => None, + InstOp::PtrToInt(val, ty) => Some(Expr::PtrToInt( + vntable.value_map.get(val).cloned().unwrap(), + *ty, + )), + InstOp::Ret(_, _) => None, + InstOp::Store { .. } => None, + } +} + +/// Convert a PHI argument to Expr +fn phi_to_expr(context: &Context, vntable: &VNTable, phi_arg: Value) -> Expr { + let phi_arg = phi_arg.get_argument(context).unwrap(); + let phi_args = phi_arg + .block + .pred_iter(context) + .map(|pred| { + let incoming_val = phi_arg + .get_val_coming_from(context, pred) + .expect("No parameter from predecessor"); + vntable.value_map.get(&incoming_val).cloned().unwrap() + }) + .collect(); + Expr::Phi(phi_args) +} + +#[derive(Default)] +struct VNTable { + value_map: FxHashMap, + expr_map: FxHashMap, +} + +impl Debug for VNTable { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + writeln!(f, "value_map:")?; + self.value_map.iter().for_each(|(key, value)| { + if format!("v{:?}", key.0.data()) == "v620v3" { + writeln!(f, "\tv{:?} -> {:?}", key.0.data(), value).expect("writeln! failed"); + } + }); + Ok(()) + } +} + +/// Wrapper around [DomTree::dominates] to work at instruction level. +/// Does `inst1` dominate `inst2` ? +fn dominates(context: &Context, dom_tree: &DomTree, inst1: Value, inst2: Value) -> bool { + let block1 = match &context.values[inst1.0].value { + crate::ValueDatum::Argument(arg) => arg.block, + crate::ValueDatum::Constant(_) => { + panic!("Shouldn't be querying dominance info for constants") + } + crate::ValueDatum::Instruction(i) => i.parent, + }; + let block2 = match &context.values[inst2.0].value { + crate::ValueDatum::Argument(arg) => arg.block, + crate::ValueDatum::Constant(_) => { + panic!("Shouldn't be querying dominance info for constants") + } + crate::ValueDatum::Instruction(i) => i.parent, + }; + + if block1 == block2 { + let inst1_idx = block1 + .instruction_iter(context) + .position(|inst| inst == inst1) + // Not found indicates a block argument + .unwrap_or(0); + let inst2_idx = block1 + .instruction_iter(context) + .position(|inst| inst == inst2) + // Not found indicates a block argument + .unwrap_or(0); + inst1_idx < inst2_idx + } else { + dom_tree.dominates(block1, block2) + } +} + +pub fn cse( + context: &mut Context, + analyses: &AnalysisResults, + function: Function, +) -> Result { + let mut vntable = VNTable::default(); + + // Function arg values map to themselves. + for arg in function.args_iter(context) { + vntable.value_map.insert(arg.1, ValueNumber::Number(arg.1)); + } + + // Map all other arg values map to Top. + for block in function.block_iter(context).skip(1) { + for arg in block.arg_iter(context) { + vntable.value_map.insert(*arg, ValueNumber::Top); + } + } + + // Initialize all instructions and constants. Constants need special treatmemt. + // They don't have PartialEq implemented. So we need to value number them manually. + // This map maps the hash of a constant value to all possible collisions of it. + let mut const_map = FxHashMap::>::default(); + for (_, inst) in function.instruction_iter(context) { + vntable.value_map.insert(inst, ValueNumber::Top); + for (const_opd_val, const_opd_const) in inst + .get_instruction(context) + .unwrap() + .op + .get_operands() + .iter() + .filter_map(|opd| opd.get_constant(context).map(|copd| (opd, copd))) + { + let mut state = FxHasher::default(); + const_opd_const.hash(&mut state); + let hash = state.finish(); + if let Some(existing_const) = const_map.get(&hash).and_then(|consts| { + consts.iter().find(|val| { + let c = val + .get_constant(context) + .expect("const_map can only contain consts"); + const_opd_const.eq(context, c) + }) + }) { + vntable + .value_map + .insert(*const_opd_val, ValueNumber::Number(*existing_const)); + } else { + const_map + .entry(hash) + .and_modify(|consts| consts.push(*const_opd_val)) + .or_insert_with(|| vec![*const_opd_val]); + vntable + .value_map + .insert(*const_opd_val, ValueNumber::Number(*const_opd_val)); + } + } + } + + // We need to iterate over the blocks in RPO. + let post_order: &PostOrder = analyses.get_analysis_result(function); + + // RPO based value number (Sec 4.2). + let mut changed = true; + while changed { + changed = false; + // For each block in RPO: + for (block_idx, block) in post_order.po_to_block.iter().rev().enumerate() { + // Process PHIs and then the other instructions. + if block_idx != 0 { + // Entry block arguments are not PHIs. + for (phi, expr_opt) in block + .arg_iter(context) + .map(|arg| (*arg, Some(phi_to_expr(context, &vntable, *arg)))) + .collect_vec() + { + let expr = expr_opt.expect("PHIs must always translate to a valid Expr"); + // We first try to see if PHIs can be simplified into a single value. + let vn = { + let Expr::Phi(ref phi_args) = expr else { + panic!("Expr must be a PHI") + }; + phi_args + .iter() + .map(|vn| Some(*vn)) + .reduce(|vn1, vn2| { + // Here `None` indicates Bottom of the lattice. + if let (Some(vn1), Some(vn2)) = (vn1, vn2) { + match (vn1, vn2) { + (ValueNumber::Top, ValueNumber::Top) => { + Some(ValueNumber::Top) + } + (ValueNumber::Top, ValueNumber::Number(vn)) + | (ValueNumber::Number(vn), ValueNumber::Top) => { + Some(ValueNumber::Number(vn)) + } + (ValueNumber::Number(vn1), ValueNumber::Number(vn2)) => { + (vn1 == vn2).then_some(ValueNumber::Number(vn1)) + } + } + } else { + None + } + }) + .flatten() + // The PHI couldn't be simplified to a single ValueNumber. + .unwrap_or(ValueNumber::Number(phi)) + }; + + match vntable.value_map.entry(phi) { + hash_map::Entry::Occupied(occ) if *occ.get() == vn => {} + _ => { + changed = true; + vntable.value_map.insert(phi, vn); + } + } + } + } + + for (inst, expr_opt) in block + .instruction_iter(context) + .map(|instr| (instr, instr_to_expr(context, &vntable, instr))) + .collect_vec() + { + // lookup(expr, x) + let vn = if let Some(expr) = expr_opt { + match vntable.expr_map.entry(expr) { + hash_map::Entry::Occupied(occ) => *occ.get(), + hash_map::Entry::Vacant(vac) => *(vac.insert(ValueNumber::Number(inst))), + } + } else { + // Instructions that always map to their own value number + // (i.e., they can never be equal to some other instruction). + ValueNumber::Number(inst) + }; + match vntable.value_map.entry(inst) { + hash_map::Entry::Occupied(occ) if *occ.get() == vn => {} + _ => { + changed = true; + vntable.value_map.insert(inst, vn); + } + } + } + } + vntable.expr_map.clear(); + } + + // create a partition of congruent (equal) values. + let mut partition = FxHashMap::>::default(); + vntable.value_map.iter().for_each(|(v, vn)| { + // If v is a constant or its value number is itself, don't add to the partition. + // The latter condition is so that we have only > 1 sized partitions. + if v.is_constant(context) + || matches!(vn, ValueNumber::Top) + || matches!(vn, ValueNumber::Number(v2) if (v == v2 || v2.is_constant(context))) + { + return; + } + partition + .entry(*vn) + .and_modify(|part| { + part.insert(*v); + }) + .or_insert(vec![*v].into_iter().collect()); + }); + + // For convenience, now add back back `v` into `partition[VN[v]]` if it isn't already there. + partition.iter_mut().for_each(|(vn, v_part)| { + let ValueNumber::Number(v) = vn else { + panic!("We cannot have Top at this point"); + }; + v_part.insert(*v); + assert!( + v_part.len() > 1, + "We've only created partitions with size greater than 1" + ); + }); + + // There are two ways to replace congruent values (see the paper cited, Sec 5). + // 1. Dominator based. If v1 and v2 are equal, v1 dominates v2, we just remove v2 + // and replace its uses with v1. Simple, and what we're going to do. + // 2. AVAIL based. More powerful, but also requires a data-flow-analysis for AVAIL + // and later on, mem2reg again since replacements will need breaking SSA. + let dom_tree: &DomTree = analyses.get_analysis_result(function); + let mut replace_map = FxHashMap::::default(); + let mut modified = false; + // Check every set in the partition. + partition.iter().for_each(|(_leader, vals)| { + // Iterate over every pair of values, checking if one can replace the other. + for v_pair in vals.iter().combinations(2) { + let (v1, v2) = (*v_pair[0], *v_pair[1]); + if dominates(context, dom_tree, v1, v2) { + modified = true; + replace_map.insert(v2, v1); + } else if dominates(context, dom_tree, v2, v1) { + modified = true; + replace_map.insert(v1, v2); + } + } + }); + + function.replace_values(context, &replace_map, None); + + Ok(modified) +} diff --git a/sway-ir/src/optimize/mem2reg.rs b/sway-ir/src/optimize/mem2reg.rs index 0a3484cec4a..c7c8a5b847b 100644 --- a/sway-ir/src/optimize/mem2reg.rs +++ b/sway-ir/src/optimize/mem2reg.rs @@ -319,12 +319,12 @@ pub fn promote_to_registers( } // Process dominator children. - for child in dom_tree[&node].children.iter() { + for child in dom_tree.children(node) { record_rewrites( context, function, dom_tree, - *child, + child, safe_locals, phi_to_local, name_stack, diff --git a/sway-ir/src/pass_manager.rs b/sway-ir/src/pass_manager.rs index 7318016fae5..9edb21626c3 100644 --- a/sway-ir/src/pass_manager.rs +++ b/sway-ir/src/pass_manager.rs @@ -1,14 +1,15 @@ use crate::{ create_arg_demotion_pass, create_ccp_pass, create_const_demotion_pass, - create_const_folding_pass, create_dce_pass, create_dom_fronts_pass, create_dominators_pass, - create_escaped_symbols_pass, create_fn_dce_pass, create_fn_dedup_debug_profile_pass, - create_fn_dedup_release_profile_pass, create_fn_inline_pass, create_mem2reg_pass, - create_memcpyopt_pass, create_misc_demotion_pass, create_module_printer_pass, - create_module_verifier_pass, create_postorder_pass, create_ret_demotion_pass, - create_simplify_cfg_pass, create_sroa_pass, Context, Function, IrError, Module, - ARG_DEMOTION_NAME, CCP_NAME, CONST_DEMOTION_NAME, CONST_FOLDING_NAME, DCE_NAME, FN_DCE_NAME, - FN_DEDUP_DEBUG_PROFILE_NAME, FN_DEDUP_RELEASE_PROFILE_NAME, FN_INLINE_NAME, MEM2REG_NAME, - MEMCPYOPT_NAME, MISC_DEMOTION_NAME, RET_DEMOTION_NAME, SIMPLIFY_CFG_NAME, SROA_NAME, + create_const_folding_pass, create_cse_pass, create_dce_pass, create_dom_fronts_pass, + create_dominators_pass, create_escaped_symbols_pass, create_fn_dce_pass, + create_fn_dedup_debug_profile_pass, create_fn_dedup_release_profile_pass, + create_fn_inline_pass, create_mem2reg_pass, create_memcpyopt_pass, create_misc_demotion_pass, + create_module_printer_pass, create_module_verifier_pass, create_postorder_pass, + create_ret_demotion_pass, create_simplify_cfg_pass, create_sroa_pass, Context, Function, + IrError, Module, ARG_DEMOTION_NAME, CCP_NAME, CONST_DEMOTION_NAME, CONST_FOLDING_NAME, + CSE_NAME, DCE_NAME, FN_DCE_NAME, FN_DEDUP_DEBUG_PROFILE_NAME, FN_DEDUP_RELEASE_PROFILE_NAME, + FN_INLINE_NAME, MEM2REG_NAME, MEMCPYOPT_NAME, MISC_DEMOTION_NAME, RET_DEMOTION_NAME, + SIMPLIFY_CFG_NAME, SROA_NAME, }; use downcast_rs::{impl_downcast, Downcast}; use rustc_hash::FxHashMap; @@ -400,6 +401,7 @@ pub fn register_known_passes(pm: &mut PassManager) { pm.register(create_simplify_cfg_pass()); pm.register(create_fn_dce_pass()); pm.register(create_dce_pass()); + pm.register(create_cse_pass()); pm.register(create_arg_demotion_pass()); pm.register(create_const_demotion_pass()); pm.register(create_ret_demotion_pass()); @@ -408,7 +410,7 @@ pub fn register_known_passes(pm: &mut PassManager) { } pub fn create_o1_pass_group() -> PassGroup { - // Create a configuration to specify which passes we want to run now. + // Create a create_ccp_passo specify which passes we want to run now. let mut o1 = PassGroup::default(); // Configure to run our passes. o1.append_pass(MEM2REG_NAME); @@ -420,6 +422,7 @@ pub fn create_o1_pass_group() -> PassGroup { o1.append_pass(CCP_NAME); o1.append_pass(CONST_FOLDING_NAME); o1.append_pass(SIMPLIFY_CFG_NAME); + o1.append_pass(CSE_NAME); o1.append_pass(CONST_FOLDING_NAME); o1.append_pass(SIMPLIFY_CFG_NAME); o1.append_pass(FN_DCE_NAME); diff --git a/sway-ir/tests/cse/cse1.ir b/sway-ir/tests/cse/cse1.ir new file mode 100644 index 00000000000..687c12f8d76 --- /dev/null +++ b/sway-ir/tests/cse/cse1.ir @@ -0,0 +1,21 @@ +// regex: ID=[[:alpha:]0-9]+ +// regex: VAR=v\d+ + +script { + fn main() -> bool { + entry(): + v0 = const u64 11 + v1 = const u64 0 + // check: $(v3=$VAR) = add + v3 = add v0, v1 + // check: $(v4=$VAR) = add + v4 = add v0, v1 + v10 = const u64 10 + v11 = add v1, v0 + // check: cmp eq $v3 $v3 + v2 = cmp eq v3 v4 + v3 = cmp eq v11 v3 + v4 = cmp eq v2 v3 + ret bool v4 + } +} diff --git a/sway-ir/tests/cse/cse2.ir b/sway-ir/tests/cse/cse2.ir new file mode 100644 index 00000000000..ec609f74d60 --- /dev/null +++ b/sway-ir/tests/cse/cse2.ir @@ -0,0 +1,22 @@ +// regex: ID=[[:alpha:]0-9]+ +// regex: VAR=v\d+ + +script { + fn main() -> bool { + entry(): + v0 = const u64 11 + v0_dup = const u64 11 + v1 = const u64 0 + // check: $(v3=$VAR) = add + v3 = add v0, v1 + // check: $(v4=$VAR) = add + v4 = add v0, v1 + // check: $(v5=$VAR) = sub + v5 = sub v0, v3 + // check: $(v6=$VAR) = sub + v6 = sub v0_dup, v4 + // check: cmp eq $v5 $v5 + v2 = cmp eq v5 v6 + ret bool v2 + } +} diff --git a/sway-ir/tests/cse/cse3.ir b/sway-ir/tests/cse/cse3.ir new file mode 100644 index 00000000000..89a3df2fdd3 --- /dev/null +++ b/sway-ir/tests/cse/cse3.ir @@ -0,0 +1,29 @@ +// regex: ID=[[:alpha:]0-9]+ +// regex: VAR=v\d+ + +script { + entry fn main(a: u64, b: u64) -> () { + entry(a: u64, b: u64): + // check: $(v5=$VAR) = add a, b + v5 = add a, b + v6 = const u64 0 + br while(v6, v5) + + while(v3: u64, v4: u64): + // check: cmp lt $VAR $v5 + v8 = cmp lt v3 v4 + cbr v8, while_body(), end_while() + + while_body(): + // check: $(v10=$VAR) = add a, b + v10 = add a, b + v11 = const u64 1 + v12 = add v3, v11 + // check: br while($VAR, $v5) + br while(v12, v10) + + end_while(): + v14 = const unit () + ret () v14 + } +} diff --git a/sway-ir/tests/tests.rs b/sway-ir/tests/tests.rs index 0a577c00c9c..197d67d400e 100644 --- a/sway-ir/tests/tests.rs +++ b/sway-ir/tests/tests.rs @@ -3,12 +3,13 @@ use std::path::PathBuf; use itertools::Itertools; use sway_ir::{ create_arg_demotion_pass, create_ccp_pass, create_const_demotion_pass, - create_const_folding_pass, create_dce_pass, create_dom_fronts_pass, create_dominators_pass, - create_escaped_symbols_pass, create_mem2reg_pass, create_memcpyopt_pass, - create_misc_demotion_pass, create_postorder_pass, create_ret_demotion_pass, - create_simplify_cfg_pass, metadata_to_inline, optimize as opt, register_known_passes, Context, - ExperimentalFlags, Function, IrError, PassGroup, PassManager, Value, DCE_NAME, FN_DCE_NAME, - FN_DEDUP_DEBUG_PROFILE_NAME, FN_DEDUP_RELEASE_PROFILE_NAME, MEM2REG_NAME, SROA_NAME, + create_const_folding_pass, create_cse_pass, create_dce_pass, create_dom_fronts_pass, + create_dominators_pass, create_escaped_symbols_pass, create_mem2reg_pass, + create_memcpyopt_pass, create_misc_demotion_pass, create_postorder_pass, + create_ret_demotion_pass, create_simplify_cfg_pass, metadata_to_inline, optimize as opt, + register_known_passes, Context, ExperimentalFlags, Function, IrError, PassGroup, PassManager, + Value, DCE_NAME, FN_DCE_NAME, FN_DEDUP_DEBUG_PROFILE_NAME, FN_DEDUP_RELEASE_PROFILE_NAME, + MEM2REG_NAME, SROA_NAME, }; use sway_types::SourceEngine; @@ -282,6 +283,22 @@ fn dce() { // ------------------------------------------------------------------------------------------------- +#[allow(clippy::needless_collect)] +#[test] +fn cse() { + run_tests("cse", |_first_line, ir: &mut Context| { + let mut pass_mgr = PassManager::default(); + let mut pass_group = PassGroup::default(); + pass_mgr.register(create_postorder_pass()); + pass_mgr.register(create_dominators_pass()); + let pass = pass_mgr.register(create_cse_pass()); + pass_group.append_pass(pass); + pass_mgr.run(ir, &pass_group).unwrap() + }) +} + +// ------------------------------------------------------------------------------------------------- + #[allow(clippy::needless_collect)] #[test] fn mem2reg() { diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle_new_encoding.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle_new_encoding.json index 0662cd80d0d..b5e886d1a19 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle_new_encoding.json +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle_new_encoding.json @@ -62,82 +62,82 @@ { "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", "name": "BOOL", - "offset": 7208 + "offset": 7216 }, { "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", "name": "U8", - "offset": 7400 + "offset": 7408 }, { "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", "name": "ANOTHER_U8", - "offset": 7136 + "offset": 7144 }, { "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", "name": "U16", - "offset": 7344 + "offset": 7352 }, { "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", "name": "U32", - "offset": 7384 + "offset": 7392 }, { "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", "name": "U64", - "offset": 7392 + "offset": 7400 }, { "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", "name": "U256", - "offset": 7352 + "offset": 7360 }, { "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", "name": "B256", - "offset": 7176 + "offset": 7184 }, { "concreteTypeId": "81fc10c4681a3271cf2d66b2ec6fbc8ed007a442652930844fcf11818c295bff", "name": "CONFIGURABLE_STRUCT", - "offset": 7296 + "offset": 7304 }, { "concreteTypeId": "a2922861f03be8a650595dd76455b95383a61b46dd418f02607fa2e00dc39d5c", "name": "CONFIGURABLE_ENUM_A", - "offset": 7216 + "offset": 7224 }, { "concreteTypeId": "a2922861f03be8a650595dd76455b95383a61b46dd418f02607fa2e00dc39d5c", "name": "CONFIGURABLE_ENUM_B", - "offset": 7256 + "offset": 7264 }, { "concreteTypeId": "4926d35d1a5157936b0a29bc126b8aace6d911209a5c130e9b716b0c73643ea6", "name": "ARRAY_BOOL", - "offset": 7144 + "offset": 7152 }, { "concreteTypeId": "776fb5a3824169d6736138565fdc20aad684d9111266a5ff6d5c675280b7e199", "name": "ARRAY_U64", - "offset": 7152 + "offset": 7160 }, { "concreteTypeId": "c998ca9a5f221fe7b5c66ae70c8a9562b86d964408b00d17f883c906bc1fe4be", "name": "TUPLE_BOOL_U64", - "offset": 7328 + "offset": 7336 }, { "concreteTypeId": "94f0fa95c830be5e4f711963e83259fe7e8bc723278ab6ec34449e791a99b53a", "name": "STR_4", - "offset": 7320 + "offset": 7328 }, { "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", "name": "NOT_USED", - "offset": 7312 + "offset": 7320 } ], "encodingVersion": "1", diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/u256/u256_abi/json_abi_oracle_new_encoding.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/u256/u256_abi/json_abi_oracle_new_encoding.json index 49a75d8d5c1..5b834c3566e 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/u256/u256_abi/json_abi_oracle_new_encoding.json +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/u256/u256_abi/json_abi_oracle_new_encoding.json @@ -9,7 +9,7 @@ { "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", "name": "SOME_U256", - "offset": 816 + "offset": 808 } ], "encodingVersion": "1", 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 aba7556d410..575ca323135 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 = 0xf9f1fec713b977865880637fc24e58cda9e69f6e711ed8e5efe7de9ce51c88ec; // AUTO-CONTRACT-ID ../../test_contracts/array_of_structs_contract --release +const CONTRACT_ID = 0xbbda20fb25bdb4b18451501418b06324376c61cb984e75fcbc983fc0a047f85b; // AUTO-CONTRACT-ID ../../test_contracts/array_of_structs_contract --release fn get_address() -> Option { Some(CONTRACT_ID.into()) 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 f1458b54293..e177370b102 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 @@ -14,7 +14,7 @@ const FUEL_COIN_CONTRACT_ID = 0xf2fecff29038dab2ef571397ea5507359265c9154608e7de #[cfg(experimental_new_encoding = false)] const BALANCE_CONTRACT_ID = 0xf6cd545152ac83225e8e7df2efb5c6fa6e37bc9b9e977b5ea8103d28668925df; #[cfg(experimental_new_encoding = true)] -const BALANCE_CONTRACT_ID = 0xccf637b5b0071861f3074fcf963ef2339dab5d306d919b4c7e65024a7fbc64e6; // AUTO-CONTRACT-ID ../../test_contracts/balance_test_contract --release +const BALANCE_CONTRACT_ID = 0xebe7a84ed5198e9d7d3e002a571058dc24d56f61f2526ca30328f519528f98eb; // 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 a739f0d408c..3afdbe1afc2 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 = 0xccf637b5b0071861f3074fcf963ef2339dab5d306d919b4c7e65024a7fbc64e6; // AUTO-CONTRACT-ID ../../test_contracts/balance_test_contract --release +const CONTRACT_ID = 0xebe7a84ed5198e9d7d3e002a571058dc24d56f61f2526ca30328f519528f98eb; // 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 57633b2de20..49d7c83bf80 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 = 0x0328999650df8c33503c894fd6ac49b0299c9d64147feb69daa1606521dbe86e; // AUTO-CONTRACT-ID ../../test_contracts/abi_with_tuples_contract --release +const CONTRACT_ID = 0x95bff8249257356f042d500e9f7db1a964ab5739a1b156eafaca3c7a4efc8aaa; // 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 4e2144117af..b1166cfb9fb 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 = 0x23afacfc8eaa13d36c3f2f4d764b66e53d284e4cd31477e8bd72b4ccc411022b; // AUTO-CONTRACT-ID ../../test_contracts/basic_storage --release +const CONTRACT_ID = 0xd8e3576d2f7b2ed2d5f8935aef4837e6ff32b1c092d8ae369ad0fdd955a52169; // 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 aacf8538eba..bc2f5881cd6 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 = 0xfffcb364f01ce902477fa73720ae48bfb8bc735447f75d55d441a76943a27a65; // AUTO-CONTRACT-ID ../../test_contracts/contract_with_type_aliases --release +const CONTRACT_ID = 0x514dae6ddad19623646033458f970d1286ef111806145daf80d06ca679604a96; // 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 85deb2bb2ba..f518c022f5b 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 = 0x5229470a8bb907a909aba79325a347bd8849a8aceb9c8116e3d1c73ea4977b6d; // AUTO-CONTRACT-ID ../../test_contracts/increment_contract --release +const CONTRACT_ID = 0xc906accda9e1e516ee3122770217d913edca1ae6e3b8bad15c2c1a53ebf5e13e; // 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 ac6240cfd81..c3e736cb17f 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 = 0x4bb9cb0a4b3df7981e702609cbce4b684b3d9c21e474e9988825f48fae81b06d; // AUTO-CONTRACT-ID ../../test_contracts/storage_enum_contract --release +const CONTRACT_ID = 0xaa4e990e0796764624423b63c1bb14fdc02918294fab87682c1ee768de745a7e; // 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 6b47bf9d3a1..931e9f010df 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 = 0xbbd538c6fc4f6a805b4e178529e1460453aee648b5e49949bdfc8a12a585e7d2; // AUTO-CONTRACT-ID ../../test_contracts/auth_testing_contract --release +const CONTRACT_ID = 0x57892f3d8bd8c58137b35d177a8c03121193d51138ad2218e814af505e90a7f2; // 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 8da2675ccda..0f6ed8007b6 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 = 0x7821bf368390972d4892e1f382fd954fea5b567e533eed6fac0f173800647945; // AUTO-CONTRACT-ID ../../test_contracts/context_testing_contract --release +const CONTRACT_ID = 0x6c159e40368c6a37b8c479cd63f5462832d5dbdc8d872c4b30edc38e230b7e51; // 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 ed163d5076d..8410b0175e8 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 = 0x90fdb746b560d271261d8fab6eba6a4381f173432b7fa8c93e2765c38bca508b; // AUTO-CONTRACT-ID ../../test_contracts/nested_struct_args_contract --release +const CONTRACT_ID = 0xc26e4f54f9bca811be460d07aaedfa12d46477378573947ae95653affba962be; // 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 eb9d9d24411..13dd55fec91 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 = 0x3da675876942326fd4c66b079216742f75e5f15681271a5db54a9cf19a813b22; // AUTO-CONTRACT-ID ../../test_contracts/storage_access_contract --release +const CONTRACT_ID = 0x83ec366b3623ee28ec09d3d92dcc2e113cc7427adb194fb42608103b0188fb83; // AUTO-CONTRACT-ID ../../test_contracts/storage_access_contract --release fn main() -> bool { let caller = abi(StorageAccess, CONTRACT_ID); From 93efc18c6b81a316856978f869524520a0935b97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaya=20G=C3=B6kalp?= Date: Mon, 23 Sep 2024 02:39:18 -0700 Subject: [PATCH 034/115] fix: use build script for proxy deployments as well (#6580) --- forc-plugins/forc-client/build.rs | 7 +- forc-plugins/forc-client/src/op/deploy.rs | 729 +--------------------- 2 files changed, 7 insertions(+), 729 deletions(-) diff --git a/forc-plugins/forc-client/build.rs b/forc-plugins/forc-client/build.rs index 7a596f76b94..00e28aaef3a 100644 --- a/forc-plugins/forc-client/build.rs +++ b/forc-plugins/forc-client/build.rs @@ -71,6 +71,9 @@ fn main() { let util_tx_path = PathBuf::from("src/util/tx.rs"); update_proxy_abi_decl_with_file(&util_tx_path, &minified_json); - let util_tx_path = PathBuf::from("tests/deploy.rs"); - update_proxy_abi_decl_with_file(&util_tx_path, &minified_json); + let test_path = PathBuf::from("tests/deploy.rs"); + update_proxy_abi_decl_with_file(&test_path, &minified_json); + + let deploy_path = PathBuf::from("src/op/deploy.rs"); + update_proxy_abi_decl_with_file(&deploy_path, &minified_json); } diff --git a/forc-plugins/forc-client/src/op/deploy.rs b/forc-plugins/forc-client/src/op/deploy.rs index 45f616dda91..0f05e020782 100644 --- a/forc-plugins/forc-client/src/op/deploy.rs +++ b/forc-plugins/forc-client/src/op/deploy.rs @@ -23,6 +23,7 @@ use fuel_crypto::fuel_types::ChainId; use fuel_tx::{Salt, Transaction}; use fuel_vm::prelude::*; use fuels::{ + macros::abigen, programs::contract::{LoadConfiguration, StorageConfiguration}, types::{bech32::Bech32ContractId, transaction_builders::Blob}, }; @@ -203,733 +204,7 @@ async fn deploy_new_proxy( provider: &Provider, signing_key: &SecretKey, ) -> Result { - fuels::macros::abigen!(Contract( - name = "ProxyContract", - abi = r#"{ - "programType": "contract", - "specVersion": "1", - "encodingVersion": "1", - "concreteTypes": [ - { - "type": "()", - "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "type": "enum standards::src5::AccessError", - "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d", - "metadataTypeId": 1 - }, - { - "type": "enum standards::src5::State", - "concreteTypeId": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", - "metadataTypeId": 2 - }, - { - "type": "enum std::option::Option", - "concreteTypeId": "0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8", - "metadataTypeId": 4, - "typeArguments": [ - "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" - ] - }, - { - "type": "enum sway_libs::ownership::errors::InitializationError", - "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893", - "metadataTypeId": 5 - }, - { - "type": "enum sway_libs::upgradability::errors::SetProxyOwnerError", - "concreteTypeId": "3c6e90ae504df6aad8b34a93ba77dc62623e00b777eecacfa034a8ac6e890c74", - "metadataTypeId": 6 - }, - { - "type": "str", - "concreteTypeId": "8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a" - }, - { - "type": "struct std::contract_id::ContractId", - "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", - "metadataTypeId": 9 - }, - { - "type": "struct sway_libs::upgradability::events::ProxyOwnerSet", - "concreteTypeId": "96dd838b44f99d8ccae2a7948137ab6256c48ca4abc6168abc880de07fba7247", - "metadataTypeId": 10 - }, - { - "type": "struct sway_libs::upgradability::events::ProxyTargetSet", - "concreteTypeId": "1ddc0adda1270a016c08ffd614f29f599b4725407c8954c8b960bdf651a9a6c8", - "metadataTypeId": 11 - } - ], - "metadataTypes": [ - { - "type": "b256", - "metadataTypeId": 0 - }, - { - "type": "enum standards::src5::AccessError", - "metadataTypeId": 1, - "components": [ - { - "name": "NotOwner", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - } - ] - }, - { - "type": "enum standards::src5::State", - "metadataTypeId": 2, - "components": [ - { - "name": "Uninitialized", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "Initialized", - "typeId": 3 - }, - { - "name": "Revoked", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - } - ] - }, - { - "type": "enum std::identity::Identity", - "metadataTypeId": 3, - "components": [ - { - "name": "Address", - "typeId": 8 - }, - { - "name": "ContractId", - "typeId": 9 - } - ] - }, - { - "type": "enum std::option::Option", - "metadataTypeId": 4, - "components": [ - { - "name": "None", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "Some", - "typeId": 7 - } - ], - "typeParameters": [ - 7 - ] - }, - { - "type": "enum sway_libs::ownership::errors::InitializationError", - "metadataTypeId": 5, - "components": [ - { - "name": "CannotReinitialized", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - } - ] - }, - { - "type": "enum sway_libs::upgradability::errors::SetProxyOwnerError", - "metadataTypeId": 6, - "components": [ - { - "name": "CannotUninitialize", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - } - ] - }, - { - "type": "generic T", - "metadataTypeId": 7 - }, - { - "type": "struct std::address::Address", - "metadataTypeId": 8, - "components": [ - { - "name": "bits", - "typeId": 0 - } - ] - }, - { - "type": "struct std::contract_id::ContractId", - "metadataTypeId": 9, - "components": [ - { - "name": "bits", - "typeId": 0 - } - ] - }, - { - "type": "struct sway_libs::upgradability::events::ProxyOwnerSet", - "metadataTypeId": 10, - "components": [ - { - "name": "new_proxy_owner", - "typeId": 2 - } - ] - }, - { - "type": "struct sway_libs::upgradability::events::ProxyTargetSet", - "metadataTypeId": 11, - "components": [ - { - "name": "new_target", - "typeId": 9 - } - ] - } - ], - "functions": [ - { - "inputs": [], - "name": "proxy_target", - "output": "0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8", - "attributes": [ - { - "name": "doc-comment", - "arguments": [ - " Returns the target contract of the proxy contract." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Returns" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * [Option] - The new proxy contract to which all fallback calls will be passed or `None`." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Number of Storage Accesses" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * Reads: `1`" - ] - }, - { - "name": "storage", - "arguments": [ - "read" - ] - } - ] - }, - { - "inputs": [ - { - "name": "new_target", - "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" - } - ], - "name": "set_proxy_target", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", - "attributes": [ - { - "name": "doc-comment", - "arguments": [ - " Change the target contract of the proxy contract." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Additional Information" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " This method can only be called by the `proxy_owner`." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Arguments" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * `new_target`: [ContractId] - The new proxy contract to which all fallback calls will be passed." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Reverts" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * When not called by `proxy_owner`." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Number of Storage Accesses" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * Reads: `1`" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * Write: `1`" - ] - }, - { - "name": "storage", - "arguments": [ - "read", - "write" - ] - } - ] - }, - { - "inputs": [], - "name": "proxy_owner", - "output": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", - "attributes": [ - { - "name": "doc-comment", - "arguments": [ - " Returns the owner of the proxy contract." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Returns" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * [State] - Represents the state of ownership for this contract." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Number of Storage Accesses" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * Reads: `1`" - ] - }, - { - "name": "storage", - "arguments": [ - "read" - ] - } - ] - }, - { - "inputs": [], - "name": "initialize_proxy", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", - "attributes": [ - { - "name": "doc-comment", - "arguments": [ - " Initializes the proxy contract." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Additional Information" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " This method sets the storage values using the values of the configurable constants `INITIAL_TARGET` and `INITIAL_OWNER`." - ] - }, - { - "name": "doc-comment", - "arguments": [ - " This then allows methods that write to storage to be called." - ] - }, - { - "name": "doc-comment", - "arguments": [ - " This method can only be called once." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Reverts" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * When `storage::SRC14.proxy_owner` is not [State::Uninitialized]." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Number of Storage Accesses" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * Writes: `2`" - ] - }, - { - "name": "storage", - "arguments": [ - "write" - ] - } - ] - }, - { - "inputs": [ - { - "name": "new_proxy_owner", - "concreteTypeId": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c" - } - ], - "name": "set_proxy_owner", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", - "attributes": [ - { - "name": "doc-comment", - "arguments": [ - " Changes proxy ownership to the passed State." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Additional Information" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " This method can be used to transfer ownership between Identities or to revoke ownership." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Arguments" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * `new_proxy_owner`: [State] - The new state of the proxy ownership." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Reverts" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * When the sender is not the current proxy owner." - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * When the new state of the proxy ownership is [State::Uninitialized]." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " # Number of Storage Accesses" - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * Reads: `1`" - ] - }, - { - "name": "doc-comment", - "arguments": [ - " * Writes: `1`" - ] - }, - { - "name": "storage", - "arguments": [ - "write" - ] - } - ] - } - ], - "loggedTypes": [ - { - "logId": "4571204900286667806", - "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d" - }, - { - "logId": "2151606668983994881", - "concreteTypeId": "1ddc0adda1270a016c08ffd614f29f599b4725407c8954c8b960bdf651a9a6c8" - }, - { - "logId": "2161305517876418151", - "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893" - }, - { - "logId": "4354576968059844266", - "concreteTypeId": "3c6e90ae504df6aad8b34a93ba77dc62623e00b777eecacfa034a8ac6e890c74" - }, - { - "logId": "10870989709723147660", - "concreteTypeId": "96dd838b44f99d8ccae2a7948137ab6256c48ca4abc6168abc880de07fba7247" - }, - { - "logId": "10098701174489624218", - "concreteTypeId": "8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a" - } - ], - "messagesTypes": [], - "configurables": [ - { - "name": "INITIAL_TARGET", - "concreteTypeId": "0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8", - "offset": 13368 - }, - { - "name": "INITIAL_OWNER", - "concreteTypeId": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", - "offset": 13320 - } - ] -}"#, - )); + abigen!(Contract(name = "ProxyContract", abi = "{\"programType\":\"contract\",\"specVersion\":\"1\",\"encodingVersion\":\"1\",\"concreteTypes\":[{\"type\":\"()\",\"concreteTypeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"},{\"type\":\"enum standards::src5::AccessError\",\"concreteTypeId\":\"3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d\",\"metadataTypeId\":1},{\"type\":\"enum standards::src5::State\",\"concreteTypeId\":\"192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c\",\"metadataTypeId\":2},{\"type\":\"enum std::option::Option\",\"concreteTypeId\":\"0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8\",\"metadataTypeId\":4,\"typeArguments\":[\"29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54\"]},{\"type\":\"enum sway_libs::ownership::errors::InitializationError\",\"concreteTypeId\":\"1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893\",\"metadataTypeId\":5},{\"type\":\"enum sway_libs::upgradability::errors::SetProxyOwnerError\",\"concreteTypeId\":\"3c6e90ae504df6aad8b34a93ba77dc62623e00b777eecacfa034a8ac6e890c74\",\"metadataTypeId\":6},{\"type\":\"str\",\"concreteTypeId\":\"8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a\"},{\"type\":\"struct std::contract_id::ContractId\",\"concreteTypeId\":\"29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54\",\"metadataTypeId\":9},{\"type\":\"struct sway_libs::upgradability::events::ProxyOwnerSet\",\"concreteTypeId\":\"96dd838b44f99d8ccae2a7948137ab6256c48ca4abc6168abc880de07fba7247\",\"metadataTypeId\":10},{\"type\":\"struct sway_libs::upgradability::events::ProxyTargetSet\",\"concreteTypeId\":\"1ddc0adda1270a016c08ffd614f29f599b4725407c8954c8b960bdf651a9a6c8\",\"metadataTypeId\":11}],\"metadataTypes\":[{\"type\":\"b256\",\"metadataTypeId\":0},{\"type\":\"enum standards::src5::AccessError\",\"metadataTypeId\":1,\"components\":[{\"name\":\"NotOwner\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"}]},{\"type\":\"enum standards::src5::State\",\"metadataTypeId\":2,\"components\":[{\"name\":\"Uninitialized\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"},{\"name\":\"Initialized\",\"typeId\":3},{\"name\":\"Revoked\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"}]},{\"type\":\"enum std::identity::Identity\",\"metadataTypeId\":3,\"components\":[{\"name\":\"Address\",\"typeId\":8},{\"name\":\"ContractId\",\"typeId\":9}]},{\"type\":\"enum std::option::Option\",\"metadataTypeId\":4,\"components\":[{\"name\":\"None\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"},{\"name\":\"Some\",\"typeId\":7}],\"typeParameters\":[7]},{\"type\":\"enum sway_libs::ownership::errors::InitializationError\",\"metadataTypeId\":5,\"components\":[{\"name\":\"CannotReinitialized\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"}]},{\"type\":\"enum sway_libs::upgradability::errors::SetProxyOwnerError\",\"metadataTypeId\":6,\"components\":[{\"name\":\"CannotUninitialize\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"}]},{\"type\":\"generic T\",\"metadataTypeId\":7},{\"type\":\"struct std::address::Address\",\"metadataTypeId\":8,\"components\":[{\"name\":\"bits\",\"typeId\":0}]},{\"type\":\"struct std::contract_id::ContractId\",\"metadataTypeId\":9,\"components\":[{\"name\":\"bits\",\"typeId\":0}]},{\"type\":\"struct sway_libs::upgradability::events::ProxyOwnerSet\",\"metadataTypeId\":10,\"components\":[{\"name\":\"new_proxy_owner\",\"typeId\":2}]},{\"type\":\"struct sway_libs::upgradability::events::ProxyTargetSet\",\"metadataTypeId\":11,\"components\":[{\"name\":\"new_target\",\"typeId\":9}]}],\"functions\":[{\"inputs\":[],\"name\":\"proxy_target\",\"output\":\"0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Returns the target contract of the proxy contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Returns\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * [Option] - The new proxy contract to which all fallback calls will be passed or `None`.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Reads: `1`\"]},{\"name\":\"storage\",\"arguments\":[\"read\"]}]},{\"inputs\":[{\"name\":\"new_target\",\"concreteTypeId\":\"29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54\"}],\"name\":\"set_proxy_target\",\"output\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Change the target contract of the proxy contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Additional Information\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This method can only be called by the `proxy_owner`.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Arguments\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * `new_target`: [ContractId] - The new proxy contract to which all fallback calls will be passed.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Reverts\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * When not called by `proxy_owner`.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Reads: `1`\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Write: `1`\"]},{\"name\":\"storage\",\"arguments\":[\"read\",\"write\"]}]},{\"inputs\":[],\"name\":\"proxy_owner\",\"output\":\"192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Returns the owner of the proxy contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Returns\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * [State] - Represents the state of ownership for this contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Reads: `1`\"]},{\"name\":\"storage\",\"arguments\":[\"read\"]}]},{\"inputs\":[],\"name\":\"initialize_proxy\",\"output\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Initializes the proxy contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Additional Information\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This method sets the storage values using the values of the configurable constants `INITIAL_TARGET` and `INITIAL_OWNER`.\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This then allows methods that write to storage to be called.\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This method can only be called once.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Reverts\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * When `storage::SRC14.proxy_owner` is not [State::Uninitialized].\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Writes: `2`\"]},{\"name\":\"storage\",\"arguments\":[\"write\"]}]},{\"inputs\":[{\"name\":\"new_proxy_owner\",\"concreteTypeId\":\"192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c\"}],\"name\":\"set_proxy_owner\",\"output\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Changes proxy ownership to the passed State.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Additional Information\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This method can be used to transfer ownership between Identities or to revoke ownership.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Arguments\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * `new_proxy_owner`: [State] - The new state of the proxy ownership.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Reverts\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * When the sender is not the current proxy owner.\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * When the new state of the proxy ownership is [State::Uninitialized].\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Reads: `1`\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Writes: `1`\"]},{\"name\":\"storage\",\"arguments\":[\"write\"]}]}],\"loggedTypes\":[{\"logId\":\"4571204900286667806\",\"concreteTypeId\":\"3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d\"},{\"logId\":\"2151606668983994881\",\"concreteTypeId\":\"1ddc0adda1270a016c08ffd614f29f599b4725407c8954c8b960bdf651a9a6c8\"},{\"logId\":\"2161305517876418151\",\"concreteTypeId\":\"1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893\"},{\"logId\":\"4354576968059844266\",\"concreteTypeId\":\"3c6e90ae504df6aad8b34a93ba77dc62623e00b777eecacfa034a8ac6e890c74\"},{\"logId\":\"10870989709723147660\",\"concreteTypeId\":\"96dd838b44f99d8ccae2a7948137ab6256c48ca4abc6168abc880de07fba7247\"},{\"logId\":\"10098701174489624218\",\"concreteTypeId\":\"8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a\"}],\"messagesTypes\":[],\"configurables\":[{\"name\":\"INITIAL_TARGET\",\"concreteTypeId\":\"0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8\",\"offset\":13368},{\"name\":\"INITIAL_OWNER\",\"concreteTypeId\":\"192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c\",\"offset\":13320}]}",)); let proxy_dir_output = create_proxy_contract(pkg_name)?; let address = bech32_from_secret(signing_key)?; let wallet = WalletUnlocked::new_from_private_key(*signing_key, Some(provider.clone())); From a98d9087384806c36b5211c3e5e72f11cdc54058 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaya=20G=C3=B6kalp?= Date: Mon, 23 Sep 2024 15:54:59 -0700 Subject: [PATCH 035/115] chore: update fuel-core to 0.36.0, fuels-* to 0.66.5 (#6582) ## Description closes #6581. Updates fuel-core version used to 0.36.0 and fuels-* version to 0.66.5 --- Cargo.lock | 117 ++--- Cargo.toml | 14 +- forc-plugins/forc-client/src/util/tx.rs | 18 +- test/src/sdk-harness/Cargo.lock | 429 ++++++++++-------- test/src/sdk-harness/Cargo.toml | 6 +- .../test_projects/tx_fields/mod.rs | 64 +-- 6 files changed, 352 insertions(+), 296 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 24dbdf500b2..1e22bfca8ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2637,9 +2637,9 @@ dependencies = [ [[package]] name = "forc-wallet" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84fb8dd372e7141efc5a63a1e6036e4ae0789774087ec9936b6cf426ef19bb16" +checksum = "c595f65f380e2f63332ef84c4473ea4418407d32631acc49637f50d5495acb18" dependencies = [ "anyhow", "clap 4.5.16", @@ -2719,9 +2719,9 @@ dependencies = [ [[package]] name = "fuel-asm" -version = "0.56.0" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "122c27ab46707017063bf1c6e0b4f3de881e22e81b4059750a0dc95033d9cc26" +checksum = "b29ea55a794c00d0dfaad06f11720a05fa928603f812dca1c38163f2b240860a" dependencies = [ "bitflags 2.6.0", "fuel-types", @@ -2731,9 +2731,9 @@ dependencies = [ [[package]] name = "fuel-core-chain-config" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "318a5a9733255cffac64a4b5acf6a7f41e438bec3ead506fc9f74730ce956528" +checksum = "7a4c5a71702426b8354bff2010131c0abb4a4f0b608cc7a6dfd72f9e785ba478" dependencies = [ "anyhow", "bech32", @@ -2751,9 +2751,9 @@ dependencies = [ [[package]] name = "fuel-core-client" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03ad219bde52b072a2d828f27072982047a77cc02c953ea7e83c23de586d466d" +checksum = "5770dbda6220e641eb57ee204dd5914fa15170afe3009473f57cdf15e2339fd8" dependencies = [ "anyhow", "cynic", @@ -2775,9 +2775,9 @@ dependencies = [ [[package]] name = "fuel-core-metrics" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88eb1bd81016b49493181b8bc29526678229350a780d4d04db137415028db179" +checksum = "8f671e9e813b81873ef07e1cfe8697ba3f9fd0f05313879ed0933446da4c1c14" dependencies = [ "parking_lot 0.12.3", "pin-project-lite", @@ -2788,9 +2788,9 @@ dependencies = [ [[package]] name = "fuel-core-poa" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef478ff684ee6c2eac57070322ba05525842670576328414da7fd6c40af4e25" +checksum = "9b698e7c184ab4acbaabe7bad73fdc7dfc9ebfc3a6856b1d719a4fd4c1921873" dependencies = [ "anyhow", "async-trait", @@ -2807,9 +2807,9 @@ dependencies = [ [[package]] name = "fuel-core-services" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "064b31213ea0b56f6558a0493b264cbd79e060a56de2bd35f8a10d7e78f526fa" +checksum = "998a4f9d057bf3efe43be574bd200ef64c3318007fd04523ce6bd51cc7bb963c" dependencies = [ "anyhow", "async-trait", @@ -2822,9 +2822,9 @@ dependencies = [ [[package]] name = "fuel-core-storage" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f06320744b7d53bc7928d1a40a28fd697191a5b6938a353164231a3423ebdcd9" +checksum = "1daa7422e48120b1623b53fe1a1152d11314f30fb290a73dc80f7e128c1f9014" dependencies = [ "anyhow", "derive_more 0.99.18", @@ -2844,9 +2844,9 @@ dependencies = [ [[package]] name = "fuel-core-types" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84fda0c6dc7b3bd24a993b3902f55862b8db0fa6de5b0f1d45f5942bc59792eb" +checksum = "7aa1c54f09cc7c29a11ca1129f73105745f8374a192e3e24040c10822871d83f" dependencies = [ "anyhow", "bs58", @@ -2862,9 +2862,9 @@ dependencies = [ [[package]] name = "fuel-crypto" -version = "0.56.0" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33548590131674e8f272a3e056be4dbaa1de7cb364eab2b17987cd5c0dc31cb0" +checksum = "2661b2a6c43e811be4892250513a6f4c46a69cc7092a1e5b240f49697f08292e" dependencies = [ "coins-bip32", "coins-bip39", @@ -2875,7 +2875,7 @@ dependencies = [ "lazy_static", "p256", "rand", - "secp256k1 0.26.0", + "secp256k1", "serde", "sha2 0.10.8", "zeroize", @@ -2883,9 +2883,9 @@ dependencies = [ [[package]] name = "fuel-derive" -version = "0.56.0" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f49fdbfc1615d88d2849650afc2b0ac2fecd69661ebadd31a073d8416747764" +checksum = "03509567813a351ca60d8507b2ac476b06c1590f2e9edbe72bc205bb04e0af12" dependencies = [ "proc-macro2", "quote", @@ -2942,9 +2942,9 @@ dependencies = [ [[package]] name = "fuel-merkle" -version = "0.56.0" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf17ce8ee5e8b573ea584c223635ff09f1288ad022bcf662954fdccb907602eb" +checksum = "24938ee8a5e9efe71994203527dffb4c81872aa2953de0c347ad38696527b58a" dependencies = [ "derive_more 0.99.18", "digest 0.10.7", @@ -2957,15 +2957,15 @@ dependencies = [ [[package]] name = "fuel-storage" -version = "0.56.0" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c1b711f28553ddc5f3546711bd220e144ce4c1af7d9e9a1f70b2f20d9f5b791" +checksum = "4283f9cabc26a1154a31268e79de1e0f317d57231b4dc8d7282efb22e49d2ed3" [[package]] name = "fuel-tx" -version = "0.56.0" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13aae44611588d199dd119e4a0ebd8eb7ae4cde6bf8b4d12715610b1f5e5b731" +checksum = "572f9e8fdda6abfe83cf1456a11eabf1de66d682176fb097f2f950704cc50c26" dependencies = [ "bitflags 2.6.0", "derivative", @@ -2986,9 +2986,9 @@ dependencies = [ [[package]] name = "fuel-types" -version = "0.56.0" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b6fb26bcb408b6897e603f68cf60bbbaf6d15381c99f54a69ea743a58235ac1" +checksum = "7f196060a10db0293cdfca455f7e2f3a7914f46f25e0fbc2d28cf0a11e835a86" dependencies = [ "fuel-derive", "hex", @@ -2998,9 +2998,9 @@ dependencies = [ [[package]] name = "fuel-vm" -version = "0.56.0" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64fc4695efac9207276f6229f2dd9811848b328a13604a698f7bce1d452bd986" +checksum = "a6f4e0cc4ae65d00df6f3dcae90b81dd21135b45b932a79e368f35d255df12a1" dependencies = [ "anyhow", "async-trait", @@ -3032,9 +3032,9 @@ dependencies = [ [[package]] name = "fuels" -version = "0.66.4" +version = "0.66.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9699101cadc9ad3f1eff2a71532d755ab5526419414b99702e89c1d8b92b5938" +checksum = "aaf7ca0443308f4c3d3e9dd7ed67cb18369ae63d208302056d6d5f3a09efb031" dependencies = [ "fuel-core-client", "fuel-crypto", @@ -3048,9 +3048,9 @@ dependencies = [ [[package]] name = "fuels-accounts" -version = "0.66.4" +version = "0.66.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e97cf3bb16c8b6436dd6e3a6f9cea5c1ffda8daf7cdb335c60b74c31572f57" +checksum = "92ea69afa418ba67b9572a5b4cb612b80ee2113c9f755e93acf7adc9fc1454d1" dependencies = [ "async-trait", "chrono", @@ -3073,9 +3073,9 @@ dependencies = [ [[package]] name = "fuels-code-gen" -version = "0.66.4" +version = "0.66.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47552a5e8b6935595131ef38b14ef4eee8db870174ea62c8db804dbfa02f57d6" +checksum = "d8d1949debe40c9eb731a93b22a50da560007d85f6f7983679d217c01b9dc867" dependencies = [ "Inflector", "fuel-abi-types", @@ -3089,9 +3089,9 @@ dependencies = [ [[package]] name = "fuels-core" -version = "0.66.4" +version = "0.66.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b687c021466238851b07e2d39f974a614ffafc7e57dc9be00840d74c74c5febd" +checksum = "e720a87a7c99fcc5477cbb251738406de752a10eb237e15c79c1d99b64f4679f" dependencies = [ "async-trait", "bech32", @@ -3117,9 +3117,9 @@ dependencies = [ [[package]] name = "fuels-macros" -version = "0.66.4" +version = "0.66.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9dd9359ca6c0e7ad300d487e59babe03f64c6b7b169a0743d13f5c58837b589" +checksum = "f4f7b391259fceb75331bcbde2878cd9765b579e9167abd818641205b4c96b9a" dependencies = [ "fuels-code-gen", "itertools 0.12.1", @@ -3130,9 +3130,9 @@ dependencies = [ [[package]] name = "fuels-programs" -version = "0.66.4" +version = "0.66.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3288fc4b64e8f93a39b8ffa36fcaef8753232ffda5399662d28e24c172a7d00c" +checksum = "cbf719a68184ad4999c24dd53cf68bdd247d02fe16a9d67ccba177c8e44771b9" dependencies = [ "async-trait", "fuel-abi-types", @@ -3149,9 +3149,9 @@ dependencies = [ [[package]] name = "fuels-test-helpers" -version = "0.66.4" +version = "0.66.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11e18f84f11543ab29e787e2170eeed7f390b791f16ef8be363e3700ea21833d" +checksum = "8a615a59644d3cfce8dc1089db0764b4cca2bcea42b2a08eca826e2b8f892936" dependencies = [ "fuel-core-chain-config", "fuel-core-client", @@ -6176,7 +6176,7 @@ dependencies = [ "once_cell", "revm-primitives", "ripemd", - "secp256k1 0.29.1", + "secp256k1", "sha2 0.10.8", "substrate-bn", ] @@ -6702,16 +6702,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "secp256k1" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4124a35fe33ae14259c490fd70fa199a32b9ce9502f2ee6bc4f81ec06fa65894" -dependencies = [ - "rand", - "secp256k1-sys 0.8.1", -] - [[package]] name = "secp256k1" version = "0.29.1" @@ -6719,16 +6709,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113" dependencies = [ "rand", - "secp256k1-sys 0.10.1", -] - -[[package]] -name = "secp256k1-sys" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" -dependencies = [ - "cc", + "secp256k1-sys", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 0af9f4fcdc8..697b359e662 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -86,8 +86,8 @@ fuel-abi-types = "0.7" # Although ALL verions are "X.Y", we need the complete semver for # fuel-core-client as the GitHub Actions workflow parses this value to pull down # the correct tarball -fuel-core-client = { version = "0.35.0", default-features = false } -fuel-core-types = { version = "0.35", default-features = false } +fuel-core-client = { version = "0.36.0", default-features = false } +fuel-core-types = { version = "0.36", default-features = false } # Dependencies from the `fuels-rs` repository: fuels = "0.66" @@ -95,11 +95,11 @@ fuels-core = "0.66" fuels-accounts = "0.66" # Dependencies from the `fuel-vm` repository: -fuel-asm = "0.56" -fuel-crypto = "0.56" -fuel-types = "0.56" -fuel-tx = "0.56" -fuel-vm = "0.56" +fuel-asm = "0.57" +fuel-crypto = "0.57" +fuel-types = "0.57" +fuel-tx = "0.57" +fuel-vm = "0.57" # Dependencies from the `forc-wallet` repository: forc-wallet = "0.9" diff --git a/forc-plugins/forc-client/src/util/tx.rs b/forc-plugins/forc-client/src/util/tx.rs index 4371df2fc13..f826d86bf62 100644 --- a/forc-plugins/forc-client/src/util/tx.rs +++ b/forc-plugins/forc-client/src/util/tx.rs @@ -64,7 +64,7 @@ fn ask_user_yes_no_question(question: &str) -> Result { fn collect_user_accounts( wallet_path: &Path, password: &str, -) -> Result> { +) -> Result> { let verification = AccountVerification::Yes(password.to_string()); let accounts = collect_accounts_with_verification(wallet_path, verification).map_err(|e| { if e.to_string().contains("Mac Mismatch") { @@ -151,7 +151,7 @@ async fn collect_account_balances( ) -> Result { let accounts: Vec<_> = accounts_map .values() - .map(|addr| Wallet::from_address(addr.clone(), Some(provider.clone()))) + .map(|addr| Wallet::from_address((*addr).into(), Some(provider.clone()))) .collect(); futures::future::try_join_all(accounts.iter().map(|acc| acc.get_balances())) @@ -437,19 +437,21 @@ mod tests { fn test_format_base_asset_account_balances() { let mut accounts_map: AccountsMap = BTreeMap::new(); - let address1 = Bech32Address::from_str( + let address1: fuel_tx::Address = Bech32Address::from_str( "fuel1dved7k25uxadatl7l5kql309jnw07dcn4t3a6x9hm9nxyjcpqqns50p7n2", ) - .expect("address1"); - let address2 = Bech32Address::from_str( + .expect("address1") + .into(); + let address2: fuel_tx::Address = Bech32Address::from_str( "fuel1x9f3ysyk7fmey5ac23s2p4rwg4gjye2kke3nu3pvrs5p4qc4m4qqwx56k3", ) - .expect("address2"); + .expect("address2") + .into(); let base_asset_id = AssetId::zeroed(); - accounts_map.insert(0, address1.clone()); - accounts_map.insert(1, address2.clone()); + accounts_map.insert(0, address1); + accounts_map.insert(1, address2); let mut account_balances: AccountBalances = Vec::new(); let mut balance1 = HashMap::new(); diff --git a/test/src/sdk-harness/Cargo.lock b/test/src/sdk-harness/Cargo.lock index bbf2ab01abb..23af427650a 100644 --- a/test/src/sdk-harness/Cargo.lock +++ b/test/src/sdk-harness/Cargo.lock @@ -527,21 +527,6 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" -[[package]] -name = "bit-set" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" - [[package]] name = "bitflags" version = "1.3.2" @@ -1714,16 +1699,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "122c27ab46707017063bf1c6e0b4f3de881e22e81b4059750a0dc95033d9cc26" dependencies = [ "bitflags 2.5.0", - "fuel-types", + "fuel-types 0.56.0", + "serde", + "strum 0.24.1", +] + +[[package]] +name = "fuel-asm" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b29ea55a794c00d0dfaad06f11720a05fa928603f812dca1c38163f2b240860a" +dependencies = [ + "bitflags 2.5.0", + "fuel-types 0.57.0", "serde", "strum 0.24.1", ] [[package]] name = "fuel-core" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "023265fe375de17c0ad26ae5d01feb4841653524deab82cbc70979ea5d346b94" +checksum = "a36ed389d86361845a354d4d0e80620e811c575f937840a11c616e6e409021f8" dependencies = [ "anyhow", "async-graphql", @@ -1745,14 +1742,13 @@ dependencies = [ "fuel-core-services", "fuel-core-storage", "fuel-core-txpool", - "fuel-core-types", + "fuel-core-types 0.36.0", "fuel-core-upgradable-executor", "futures", "hex", "hyper", "indicatif", "itertools 0.12.1", - "postcard", "rand", "serde", "serde_json", @@ -1770,15 +1766,15 @@ dependencies = [ [[package]] name = "fuel-core-chain-config" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "318a5a9733255cffac64a4b5acf6a7f41e438bec3ead506fc9f74730ce956528" +checksum = "7a4c5a71702426b8354bff2010131c0abb4a4f0b608cc7a6dfd72f9e785ba478" dependencies = [ "anyhow", "bech32", "derivative", "fuel-core-storage", - "fuel-core-types", + "fuel-core-types 0.36.0", "itertools 0.12.1", "postcard", "rand", @@ -1790,15 +1786,15 @@ dependencies = [ [[package]] name = "fuel-core-client" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03ad219bde52b072a2d828f27072982047a77cc02c953ea7e83c23de586d466d" +checksum = "5770dbda6220e641eb57ee204dd5914fa15170afe3009473f57cdf15e2339fd8" dependencies = [ "anyhow", "cynic", "derive_more", "eventsource-client", - "fuel-core-types", + "fuel-core-types 0.36.0", "futures", "hex", "hyper-rustls", @@ -1814,38 +1810,38 @@ dependencies = [ [[package]] name = "fuel-core-consensus-module" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e43c7a168ee26efee5fa2fc54e4ba003b386f8f6d1f407db3e5c98bcdec6d0a2" +checksum = "9f97a3fc636d057db88cf7087aa996de9825335980092c4e894749674d599f7d" dependencies = [ "anyhow", "fuel-core-chain-config", "fuel-core-poa", "fuel-core-storage", - "fuel-core-types", + "fuel-core-types 0.36.0", ] [[package]] name = "fuel-core-database" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e7c0e04807ec39d71910ee1cab9c1f9eb27ee9bf05a3d8788c3db6801c6ac27" +checksum = "5844c2cf72d4a29d512bcb295f5528c9b8ddbf8ecbf82c3f41001451f5f4ec6f" dependencies = [ "anyhow", "derive_more", "fuel-core-storage", - "fuel-core-types", + "fuel-core-types 0.36.0", ] [[package]] name = "fuel-core-executor" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "061f43f469181ac6991e83458147e3d07a503a23f48e1cedc10ea83e8700d6d8" +checksum = "e46400b0e816da2efeee58e5822dfe7ffc1218516456159939968a59417a20af" dependencies = [ "anyhow", "fuel-core-storage", - "fuel-core-types", + "fuel-core-types 0.36.0", "hex", "parking_lot", "serde", @@ -1854,19 +1850,20 @@ dependencies = [ [[package]] name = "fuel-core-gas-price-service" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50015fb2a24f21c441a59e4e81e2a5eee3626285784119cf9346be6e37bfe199" +checksum = "390c5c33743633c1c70eaa5aaef27f87ad2ab9a79adba7a321c4899fad4c53ee" dependencies = [ "anyhow", "async-trait", "enum-iterator", "fuel-core-services", "fuel-core-storage", - "fuel-core-types", + "fuel-core-types 0.36.0", "fuel-gas-price-algorithm", "futures", "num_enum", + "reqwest", "serde", "strum 0.25.0", "strum_macros 0.25.3", @@ -1878,15 +1875,15 @@ dependencies = [ [[package]] name = "fuel-core-importer" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69fd6d1c72316511bd7c00084f2d8684a736dd57f97f912564d9af8ea13929c9" +checksum = "8d6710d343bf04f100f8c3bd4324ce60164e7ca3a8c167915a907180abf23332" dependencies = [ "anyhow", "derive_more", "fuel-core-metrics", "fuel-core-storage", - "fuel-core-types", + "fuel-core-types 0.36.0", "parking_lot", "rayon", "tokio", @@ -1895,9 +1892,9 @@ dependencies = [ [[package]] name = "fuel-core-metrics" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88eb1bd81016b49493181b8bc29526678229350a780d4d04db137415028db179" +checksum = "8f671e9e813b81873ef07e1cfe8697ba3f9fd0f05313879ed0933446da4c1c14" dependencies = [ "parking_lot", "pin-project-lite", @@ -1908,9 +1905,9 @@ dependencies = [ [[package]] name = "fuel-core-p2p" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd4d69e535e914be87cb92843d4ac6b7b8b60110364f88efe8e509052368aaa3" +checksum = "2453df795ce5e9a22f7ac10bc3436974612d0d698dcb918b2179c5e24b4bfb4a" dependencies = [ "anyhow", "async-trait", @@ -1918,9 +1915,10 @@ dependencies = [ "fuel-core-metrics", "fuel-core-services", "fuel-core-storage", - "fuel-core-types", + "fuel-core-types 0.36.0", "futures", "hex", + "hickory-resolver", "ip_network", "libp2p", "libp2p-mplex", @@ -1941,16 +1939,16 @@ dependencies = [ [[package]] name = "fuel-core-poa" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef478ff684ee6c2eac57070322ba05525842670576328414da7fd6c40af4e25" +checksum = "9b698e7c184ab4acbaabe7bad73fdc7dfc9ebfc3a6856b1d719a4fd4c1921873" dependencies = [ "anyhow", "async-trait", "fuel-core-chain-config", "fuel-core-services", "fuel-core-storage", - "fuel-core-types", + "fuel-core-types 0.36.0", "serde", "serde_json", "tokio", @@ -1960,15 +1958,15 @@ dependencies = [ [[package]] name = "fuel-core-producer" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d09fa42cdfe3c72fe325043e6b7860586d7f34c60baaef9f4a18a13bdcc6f4" +checksum = "ff23a51239988a9aaf451afa05a1ca7920b4e900319d511bd40bf1e04e414ce1" dependencies = [ "anyhow", "async-trait", "derive_more", "fuel-core-storage", - "fuel-core-types", + "fuel-core-types 0.36.0", "tokio", "tokio-rayon", "tracing", @@ -1976,9 +1974,9 @@ dependencies = [ [[package]] name = "fuel-core-services" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "064b31213ea0b56f6558a0493b264cbd79e060a56de2bd35f8a10d7e78f526fa" +checksum = "998a4f9d057bf3efe43be574bd200ef64c3318007fd04523ce6bd51cc7bb963c" dependencies = [ "anyhow", "async-trait", @@ -1991,15 +1989,15 @@ dependencies = [ [[package]] name = "fuel-core-storage" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f06320744b7d53bc7928d1a40a28fd697191a5b6938a353164231a3423ebdcd9" +checksum = "1daa7422e48120b1623b53fe1a1152d11314f30fb290a73dc80f7e128c1f9014" dependencies = [ "anyhow", "derive_more", "enum-iterator", - "fuel-core-types", - "fuel-vm", + "fuel-core-types 0.36.0", + "fuel-vm 0.57.0", "impl-tools", "itertools 0.12.1", "mockall", @@ -2015,9 +2013,9 @@ dependencies = [ [[package]] name = "fuel-core-txpool" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9deaa3a9b5a2d49bf12fba5af16cc29142d58318eeb5ec8e67258d2dc1ec66ff" +checksum = "bc5d2c7d515be53c36070fadbae61a59025ef4a41d20d38e7f2ad71237c4dded" dependencies = [ "anyhow", "async-trait", @@ -2025,7 +2023,7 @@ dependencies = [ "fuel-core-metrics", "fuel-core-services", "fuel-core-storage", - "fuel-core-types", + "fuel-core-types 0.36.0", "mockall", "num-rational", "parking_lot", @@ -2040,12 +2038,28 @@ name = "fuel-core-types" version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84fda0c6dc7b3bd24a993b3902f55862b8db0fa6de5b0f1d45f5942bc59792eb" +dependencies = [ + "anyhow", + "derivative", + "derive_more", + "fuel-vm 0.56.0", + "secrecy", + "serde", + "tai64", + "zeroize", +] + +[[package]] +name = "fuel-core-types" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aa1c54f09cc7c29a11ca1129f73105745f8374a192e3e24040c10822871d83f" dependencies = [ "anyhow", "bs58", "derivative", "derive_more", - "fuel-vm", + "fuel-vm 0.57.0", "rand", "secrecy", "serde", @@ -2055,15 +2069,15 @@ dependencies = [ [[package]] name = "fuel-core-upgradable-executor" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c104eb427f63ab720ffa2cd08e35df3064753648ff5dace9853a68f7ae98e1b" +checksum = "89c636782a522cc49f9e5d43e29b15632a5db930959b8bca9dbf8a6adac76415" dependencies = [ "anyhow", "derive_more", "fuel-core-executor", "fuel-core-storage", - "fuel-core-types", + "fuel-core-types 0.36.0", "fuel-core-wasm-executor", "parking_lot", "postcard", @@ -2073,16 +2087,18 @@ dependencies = [ [[package]] name = "fuel-core-wasm-executor" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e2277ef1637329cb879d9cf370dae9fa3b23f28031eb59800f39e552b81aefe" +checksum = "52d69a92fba4ccba773b207dd740f04893dbdd0c76dffbebddfebb13c69eea0c" dependencies = [ "anyhow", "fuel-core-executor", "fuel-core-storage", - "fuel-core-types", + "fuel-core-types 0.35.0", + "fuel-core-types 0.36.0", "postcard", "serde", + "serde_json", ] [[package]] @@ -2090,12 +2106,28 @@ name = "fuel-crypto" version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33548590131674e8f272a3e056be4dbaa1de7cb364eab2b17987cd5c0dc31cb0" +dependencies = [ + "ecdsa", + "ed25519-dalek", + "fuel-types 0.56.0", + "k256", + "p256", + "serde", + "sha2 0.10.8", + "zeroize", +] + +[[package]] +name = "fuel-crypto" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2661b2a6c43e811be4892250513a6f4c46a69cc7092a1e5b240f49697f08292e" dependencies = [ "coins-bip32", "coins-bip39", "ecdsa", "ed25519-dalek", - "fuel-types", + "fuel-types 0.57.0", "k256", "lazy_static", "p256", @@ -2118,13 +2150,24 @@ dependencies = [ "synstructure 0.13.1", ] +[[package]] +name = "fuel-derive" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03509567813a351ca60d8507b2ac476b06c1590f2e9edbe72bc205bb04e0af12" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.63", + "synstructure 0.13.1", +] + [[package]] name = "fuel-gas-price-algorithm" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cca4572eaa61de46ba3e78c90b27bc16d13af2da165273bee66e3ac034513e2" +checksum = "3a69655b9d140ad98d3e8a333e64814876c63ffe6097fd80e68cdd427514912d" dependencies = [ - "proptest", "serde", "thiserror", ] @@ -2137,7 +2180,22 @@ checksum = "cf17ce8ee5e8b573ea584c223635ff09f1288ad022bcf662954fdccb907602eb" dependencies = [ "derive_more", "digest 0.10.7", - "fuel-storage", + "fuel-storage 0.56.0", + "hashbrown 0.13.2", + "hex", + "serde", + "sha2 0.10.8", +] + +[[package]] +name = "fuel-merkle" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24938ee8a5e9efe71994203527dffb4c81872aa2953de0c347ad38696527b58a" +dependencies = [ + "derive_more", + "digest 0.10.7", + "fuel-storage 0.57.0", "hashbrown 0.13.2", "hex", "serde", @@ -2150,6 +2208,12 @@ version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c1b711f28553ddc5f3546711bd220e144ce4c1af7d9e9a1f70b2f20d9f5b791" +[[package]] +name = "fuel-storage" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4283f9cabc26a1154a31268e79de1e0f317d57231b4dc8d7282efb22e49d2ed3" + [[package]] name = "fuel-tx" version = "0.56.0" @@ -2159,10 +2223,32 @@ dependencies = [ "bitflags 2.5.0", "derivative", "derive_more", - "fuel-asm", - "fuel-crypto", - "fuel-merkle", - "fuel-types", + "fuel-asm 0.56.0", + "fuel-crypto 0.56.0", + "fuel-merkle 0.56.0", + "fuel-types 0.56.0", + "hashbrown 0.14.5", + "itertools 0.10.5", + "postcard", + "serde", + "serde_json", + "strum 0.24.1", + "strum_macros 0.24.3", +] + +[[package]] +name = "fuel-tx" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "572f9e8fdda6abfe83cf1456a11eabf1de66d682176fb097f2f950704cc50c26" +dependencies = [ + "bitflags 2.5.0", + "derivative", + "derive_more", + "fuel-asm 0.57.0", + "fuel-crypto 0.57.0", + "fuel-merkle 0.57.0", + "fuel-types 0.57.0", "hashbrown 0.14.5", "itertools 0.10.5", "postcard", @@ -2179,7 +2265,18 @@ version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b6fb26bcb408b6897e603f68cf60bbbaf6d15381c99f54a69ea743a58235ac1" dependencies = [ - "fuel-derive", + "fuel-derive 0.56.0", + "hex", + "serde", +] + +[[package]] +name = "fuel-types" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f196060a10db0293cdfca455f7e2f3a7914f46f25e0fbc2d28cf0a11e835a86" +dependencies = [ + "fuel-derive 0.57.0", "hex", "rand", "serde", @@ -2190,6 +2287,37 @@ name = "fuel-vm" version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64fc4695efac9207276f6229f2dd9811848b328a13604a698f7bce1d452bd986" +dependencies = [ + "async-trait", + "backtrace", + "bitflags 2.5.0", + "derivative", + "derive_more", + "ethnum", + "fuel-asm 0.56.0", + "fuel-crypto 0.56.0", + "fuel-merkle 0.56.0", + "fuel-storage 0.56.0", + "fuel-tx 0.56.0", + "fuel-types 0.56.0", + "hashbrown 0.14.5", + "itertools 0.10.5", + "libm", + "paste", + "percent-encoding", + "primitive-types", + "serde", + "serde_with", + "sha3", + "static_assertions", + "strum 0.24.1", +] + +[[package]] +name = "fuel-vm" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6f4e0cc4ae65d00df6f3dcae90b81dd21135b45b932a79e368f35d255df12a1" dependencies = [ "anyhow", "async-trait", @@ -2198,12 +2326,12 @@ dependencies = [ "derivative", "derive_more", "ethnum", - "fuel-asm", - "fuel-crypto", - "fuel-merkle", - "fuel-storage", - "fuel-tx", - "fuel-types", + "fuel-asm 0.57.0", + "fuel-crypto 0.57.0", + "fuel-merkle 0.57.0", + "fuel-storage 0.57.0", + "fuel-tx 0.57.0", + "fuel-types 0.57.0", "hashbrown 0.14.5", "itertools 0.10.5", "libm", @@ -2221,13 +2349,13 @@ dependencies = [ [[package]] name = "fuels" -version = "0.66.4" +version = "0.66.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9699101cadc9ad3f1eff2a71532d755ab5526419414b99702e89c1d8b92b5938" +checksum = "aaf7ca0443308f4c3d3e9dd7ed67cb18369ae63d208302056d6d5f3a09efb031" dependencies = [ "fuel-core-client", - "fuel-crypto", - "fuel-tx", + "fuel-crypto 0.57.0", + "fuel-tx 0.57.0", "fuels-accounts", "fuels-core", "fuels-macros", @@ -2237,19 +2365,19 @@ dependencies = [ [[package]] name = "fuels-accounts" -version = "0.66.4" +version = "0.66.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e97cf3bb16c8b6436dd6e3a6f9cea5c1ffda8daf7cdb335c60b74c31572f57" +checksum = "92ea69afa418ba67b9572a5b4cb612b80ee2113c9f755e93acf7adc9fc1454d1" dependencies = [ "async-trait", "chrono", "elliptic-curve", "eth-keystore", "fuel-core-client", - "fuel-core-types", - "fuel-crypto", - "fuel-tx", - "fuel-types", + "fuel-core-types 0.36.0", + "fuel-crypto 0.57.0", + "fuel-tx 0.57.0", + "fuel-types 0.57.0", "fuels-core", "itertools 0.12.1", "rand", @@ -2262,9 +2390,9 @@ dependencies = [ [[package]] name = "fuels-code-gen" -version = "0.66.4" +version = "0.66.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47552a5e8b6935595131ef38b14ef4eee8db870174ea62c8db804dbfa02f57d6" +checksum = "d8d1949debe40c9eb731a93b22a50da560007d85f6f7983679d217c01b9dc867" dependencies = [ "Inflector", "fuel-abi-types", @@ -2278,22 +2406,22 @@ dependencies = [ [[package]] name = "fuels-core" -version = "0.66.4" +version = "0.66.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b687c021466238851b07e2d39f974a614ffafc7e57dc9be00840d74c74c5febd" +checksum = "e720a87a7c99fcc5477cbb251738406de752a10eb237e15c79c1d99b64f4679f" dependencies = [ "async-trait", "bech32", "chrono", "fuel-abi-types", - "fuel-asm", + "fuel-asm 0.57.0", "fuel-core-chain-config", "fuel-core-client", - "fuel-core-types", - "fuel-crypto", - "fuel-tx", - "fuel-types", - "fuel-vm", + "fuel-core-types 0.36.0", + "fuel-crypto 0.57.0", + "fuel-tx 0.57.0", + "fuel-types 0.57.0", + "fuel-vm 0.57.0", "fuels-macros", "hex", "itertools 0.12.1", @@ -2306,9 +2434,9 @@ dependencies = [ [[package]] name = "fuels-macros" -version = "0.66.4" +version = "0.66.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9dd9359ca6c0e7ad300d487e59babe03f64c6b7b169a0743d13f5c58837b589" +checksum = "f4f7b391259fceb75331bcbde2878cd9765b579e9167abd818641205b4c96b9a" dependencies = [ "fuels-code-gen", "itertools 0.12.1", @@ -2319,15 +2447,15 @@ dependencies = [ [[package]] name = "fuels-programs" -version = "0.66.4" +version = "0.66.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3288fc4b64e8f93a39b8ffa36fcaef8753232ffda5399662d28e24c172a7d00c" +checksum = "cbf719a68184ad4999c24dd53cf68bdd247d02fe16a9d67ccba177c8e44771b9" dependencies = [ "async-trait", "fuel-abi-types", - "fuel-asm", - "fuel-tx", - "fuel-types", + "fuel-asm 0.57.0", + "fuel-tx 0.57.0", + "fuel-types 0.57.0", "fuels-accounts", "fuels-core", "itertools 0.12.1", @@ -2338,19 +2466,19 @@ dependencies = [ [[package]] name = "fuels-test-helpers" -version = "0.66.4" +version = "0.66.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11e18f84f11543ab29e787e2170eeed7f390b791f16ef8be363e3700ea21833d" +checksum = "8a615a59644d3cfce8dc1089db0764b4cca2bcea42b2a08eca826e2b8f892936" dependencies = [ "fuel-core", "fuel-core-chain-config", "fuel-core-client", "fuel-core-poa", "fuel-core-services", - "fuel-core-types", - "fuel-crypto", - "fuel-tx", - "fuel-types", + "fuel-core-types 0.36.0", + "fuel-crypto 0.57.0", + "fuel-tx 0.57.0", + "fuel-types 0.57.0", "fuels-accounts", "fuels-core", "futures", @@ -4057,7 +4185,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", - "libm", ] [[package]] @@ -4492,26 +4619,6 @@ dependencies = [ "syn 2.0.63", ] -[[package]] -name = "proptest" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" -dependencies = [ - "bit-set", - "bit-vec", - "bitflags 2.5.0", - "lazy_static", - "num-traits", - "rand", - "rand_chacha", - "rand_xorshift", - "regex-syntax", - "rusty-fork", - "tempfile", - "unarray", -] - [[package]] name = "psl-types" version = "2.0.11" @@ -4658,15 +4765,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "rand_xorshift" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" -dependencies = [ - "rand_core", -] - [[package]] name = "rayon" version = "1.10.0" @@ -4970,18 +5068,6 @@ version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "092474d1a01ea8278f69e6a358998405fae5b8b963ddaeb2b0b04a128bf1dfb0" -[[package]] -name = "rusty-fork" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" -dependencies = [ - "fnv", - "quick-error", - "tempfile", - "wait-timeout", -] - [[package]] name = "rw-stream-sink" version = "0.4.0" @@ -5087,9 +5173,9 @@ dependencies = [ [[package]] name = "secp256k1" -version = "0.26.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4124a35fe33ae14259c490fd70fa199a32b9ce9502f2ee6bc4f81ec06fa65894" +checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113" dependencies = [ "rand", "secp256k1-sys", @@ -5097,9 +5183,9 @@ dependencies = [ [[package]] name = "secp256k1-sys" -version = "0.8.1" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" +checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9" dependencies = [ "cc", ] @@ -5616,7 +5702,7 @@ dependencies = [ "assert_matches", "fuel-core", "fuel-core-client", - "fuel-vm", + "fuel-vm 0.57.0", "fuels", "hex", "paste", @@ -5947,12 +6033,6 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "unarray" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" - [[package]] name = "unicode-bidi" version = "0.3.15" @@ -6081,15 +6161,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -[[package]] -name = "wait-timeout" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" -dependencies = [ - "libc", -] - [[package]] name = "want" version = "0.3.1" diff --git a/test/src/sdk-harness/Cargo.toml b/test/src/sdk-harness/Cargo.toml index 363dfde5adf..071e3fe3374 100644 --- a/test/src/sdk-harness/Cargo.toml +++ b/test/src/sdk-harness/Cargo.toml @@ -10,12 +10,12 @@ publish = false assert_matches = "1.5" # Dependencies from the `fuel-core` repository: -fuel-core = { version = "0.35", default-features = false } +fuel-core = { version = "0.36", default-features = false } # Using full semver as the workspace Cargo.toml (see the comment there) -fuel-core-client = { version = "0.35.0", default-features = false } +fuel-core-client = { version = "0.36.0", default-features = false } # Dependencies from the `fuel-vm` repository: -fuel-vm = { version = "0.56", features = ["random"] } +fuel-vm = { version = "0.57", features = ["random"] } # Dependencies from the `fuels-rs` repository: fuels = { version = "0.66", features = ["fuel-core-lib"] } diff --git a/test/src/sdk-harness/test_projects/tx_fields/mod.rs b/test/src/sdk-harness/test_projects/tx_fields/mod.rs index 6a4624f3d86..b162010e398 100644 --- a/test/src/sdk-harness/test_projects/tx_fields/mod.rs +++ b/test/src/sdk-harness/test_projects/tx_fields/mod.rs @@ -835,29 +835,30 @@ mod inputs { .await .unwrap(); wallet.set_provider(provider.clone()); - + // Prepare bytecode and subsections let bytecode = fs::read(TX_CONTRACT_BYTECODE_PATH).unwrap(); let subsection_size = 65536; let subsections = UploadSubsection::split_bytecode(&bytecode, subsection_size).unwrap(); - + // Upload each sub section in a separate transaction and include the predicate with the transaction. for subsection in subsections.clone() { let mut builder = UploadTransactionBuilder::prepare_subsection_upload( subsection, TxPolicies::default(), ); - + // Prepare the predicate let predicate_data = TestTxInputCountPredicateEncoder::default() .encode_data(builder.inputs().len() as u16 + 1u16) // Add one for this predicate .unwrap(); - let predicate: Predicate = Predicate::load_from(TX_INPUT_COUNT_PREDICATE_BYTECODE_PATH) - .unwrap() - .with_provider(provider.clone()) - .with_data(predicate_data); + let predicate: Predicate = + Predicate::load_from(TX_INPUT_COUNT_PREDICATE_BYTECODE_PATH) + .unwrap() + .with_provider(provider.clone()) + .with_data(predicate_data); let predicate_coin_amount = 100; - + // Predicate has no funds let predicate_balance = predicate .get_asset_balance(&provider.base_asset_id()) @@ -873,7 +874,7 @@ mod inputs { ) .await .unwrap(); - + // Predicate has funds let predicate_balance = predicate .get_asset_balance(&provider.base_asset_id()) @@ -883,33 +884,33 @@ mod inputs { predicate_balance as usize, predicate_coin_amount as usize * subsections.len() ); - + // Inputs for predicate let predicate_input = predicate .get_asset_inputs_for_amount(*provider.base_asset_id(), 1, None) .await .unwrap(); - + // Outputs for predicate let predicate_output = wallet.get_asset_outputs_for_amount( &wallet.address(), *provider.base_asset_id(), 1, ); - + // Append the predicate to the transaction builder.inputs.push(predicate_input.get(0).unwrap().clone()); builder .outputs .push(predicate_output.get(0).unwrap().clone()); - + wallet.add_witnesses(&mut builder).unwrap(); wallet.adjust_for_fee(&mut builder, 0).await.unwrap(); - + // Submit the transaction let tx = builder.build(&provider).await.unwrap(); provider.send_transaction(tx).await.unwrap(); - + // The predicate has spent it's funds let predicate_balance = predicate .get_asset_balance(&provider.base_asset_id()) @@ -1570,7 +1571,7 @@ mod outputs { .unwrap(); assert_eq!(result.value, None); } - + #[tokio::test] async fn can_get_output_count_in_tx_upload() { // Prepare wallet and provider @@ -1586,29 +1587,30 @@ mod outputs { .await .unwrap(); wallet.set_provider(provider.clone()); - + // Prepare bytecode and subsections let bytecode = fs::read(TX_CONTRACT_BYTECODE_PATH).unwrap(); let subsection_size = 65536; let subsections = UploadSubsection::split_bytecode(&bytecode, subsection_size).unwrap(); - + // Upload each sub section in a separate transaction and include the predicate with the transaction. for subsection in subsections.clone() { let mut builder = UploadTransactionBuilder::prepare_subsection_upload( subsection, TxPolicies::default(), ); - + // Prepare the predicate let predicate_data = TestTxOutputCountPredicateEncoder::default() .encode_data(builder.inputs().len() as u16 + 1u16) // Add one for this predicate .unwrap(); - let predicate: Predicate = Predicate::load_from(TX_OUTPUT_COUNT_PREDICATE_BYTECODE_PATH) - .unwrap() - .with_provider(provider.clone()) - .with_data(predicate_data); + let predicate: Predicate = + Predicate::load_from(TX_OUTPUT_COUNT_PREDICATE_BYTECODE_PATH) + .unwrap() + .with_provider(provider.clone()) + .with_data(predicate_data); let predicate_coin_amount = 100; - + // Predicate has no funds let predicate_balance = predicate .get_asset_balance(&provider.base_asset_id()) @@ -1624,7 +1626,7 @@ mod outputs { ) .await .unwrap(); - + // Predicate has funds let predicate_balance = predicate .get_asset_balance(&provider.base_asset_id()) @@ -1634,33 +1636,33 @@ mod outputs { predicate_balance as usize, predicate_coin_amount as usize * subsections.len() ); - + // Inputs for predicate let predicate_input = predicate .get_asset_inputs_for_amount(*provider.base_asset_id(), 1, None) .await .unwrap(); - + // Outputs for predicate let predicate_output = wallet.get_asset_outputs_for_amount( &wallet.address(), *provider.base_asset_id(), 1, ); - + // Append the predicate to the transaction builder.inputs.push(predicate_input.get(0).unwrap().clone()); builder .outputs .push(predicate_output.get(0).unwrap().clone()); - + wallet.add_witnesses(&mut builder).unwrap(); wallet.adjust_for_fee(&mut builder, 0).await.unwrap(); - + // Submit the transaction let tx = builder.build(&provider).await.unwrap(); provider.send_transaction(tx).await.unwrap(); - + // The predicate has spent it's funds let predicate_balance = predicate .get_asset_balance(&provider.base_asset_id()) From 3e0acc16733be61674e7603dd36105559a7b605c Mon Sep 17 00:00:00 2001 From: Cameron Carstens Date: Tue, 24 Sep 2024 15:54:33 +0545 Subject: [PATCH 036/115] Support `Output::Change` in `output_asset_to()` and `output_asset_id()` (#6562) ## Description Support to get the `to` and `asset_id` fields of an `Output::Change` were added in https://github.com/FuelLabs/fuel-vm/pull/675. The std-lib now enables this. ## 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/outputs.sw | 10 ++- test/src/sdk-harness/Forc.lock | 5 ++ test/src/sdk-harness/Forc.toml | 1 + .../tx_output_change_contract/Forc.toml | 8 ++ .../tx_output_change_contract/src/main.sw | 13 ++++ .../tx_output_predicate/src/main.sw | 6 +- .../test_projects/tx_fields/mod.rs | 74 +++++++++++++++++-- 7 files changed, 106 insertions(+), 11 deletions(-) create mode 100644 test/src/sdk-harness/test_artifacts/tx_output_change_contract/Forc.toml create mode 100644 test/src/sdk-harness/test_artifacts/tx_output_change_contract/src/main.sw diff --git a/sway-lib-std/src/outputs.sw b/sway-lib-std/src/outputs.sw index 34f0c55eb13..69ccac1b23b 100644 --- a/sway-lib-std/src/outputs.sw +++ b/sway-lib-std/src/outputs.sw @@ -200,7 +200,7 @@ pub fn output_amount(index: u64) -> Option { } } -/// Gets the AssetId of the output if it is a `Output::Coin`. +/// Gets the AssetId of the output. /// /// # Arguments /// @@ -208,7 +208,7 @@ pub fn output_amount(index: u64) -> Option { /// /// # Returns /// -/// * [Option] - The AssetId of the output if it is a `Output::Coin`. None otherwise. +/// * [Option] - The AssetId of the output. None otherwise. /// /// # Reverts /// @@ -227,11 +227,12 @@ pub fn output_amount(index: u64) -> Option { pub fn output_asset_id(index: u64) -> Option { match output_type(index) { Some(Output::Coin) => Some(AssetId::from(__gtf::(index, GTF_OUTPUT_COIN_ASSET_ID))), + Some(Output::Change) => Some(AssetId::from(__gtf::(index, GTF_OUTPUT_COIN_ASSET_ID))), _ => None, } } -/// Returns the receiver of the output if it is a `Output::Coin`. +/// Returns the receiver of the output. /// /// # Arguments /// @@ -239,7 +240,7 @@ pub fn output_asset_id(index: u64) -> Option { /// /// # Returns /// -/// * [Option
] - The receiver of the output if it is a `Output::Coin`. None otherwise. +/// * [Option
] - The receiver of the output. None otherwise. /// /// # Reverts /// @@ -258,6 +259,7 @@ pub fn output_asset_id(index: u64) -> Option { pub fn output_asset_to(index: u64) -> Option
{ match output_type(index) { Some(Output::Coin) => Some(__gtf::
(index, GTF_OUTPUT_COIN_TO)), + Some(Output::Change) => Some(__gtf::
(index, GTF_OUTPUT_COIN_TO)), _ => None, } } diff --git a/test/src/sdk-harness/Forc.lock b/test/src/sdk-harness/Forc.lock index 37d81fdd61b..b05cb399826 100644 --- a/test/src/sdk-harness/Forc.lock +++ b/test/src/sdk-harness/Forc.lock @@ -409,6 +409,11 @@ name = "tx_input_count_predicate" source = "member" dependencies = ["std"] +[[package]] +name = "tx_output_change_contract" +source = "member" +dependencies = ["std"] + [[package]] name = "tx_output_contract_creation_predicate" source = "member" diff --git a/test/src/sdk-harness/Forc.toml b/test/src/sdk-harness/Forc.toml index f2a1df25d47..97a7001d7da 100644 --- a/test/src/sdk-harness/Forc.toml +++ b/test/src/sdk-harness/Forc.toml @@ -76,6 +76,7 @@ members = [ "test_artifacts/storage_vec/svec_u64", "test_artifacts/tx_contract", "test_artifacts/tx_input_count_predicate", + "test_artifacts/tx_output_change_contract", "test_artifacts/tx_output_contract_creation_predicate", "test_artifacts/tx_output_count_predicate", "test_artifacts/tx_output_predicate", diff --git a/test/src/sdk-harness/test_artifacts/tx_output_change_contract/Forc.toml b/test/src/sdk-harness/test_artifacts/tx_output_change_contract/Forc.toml new file mode 100644 index 00000000000..5a053f78b77 --- /dev/null +++ b/test/src/sdk-harness/test_artifacts/tx_output_change_contract/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "tx_output_change_contract" + +[dependencies] +std = { path = "../../../../../sway-lib-std" } diff --git a/test/src/sdk-harness/test_artifacts/tx_output_change_contract/src/main.sw b/test/src/sdk-harness/test_artifacts/tx_output_change_contract/src/main.sw new file mode 100644 index 00000000000..32aeeb5e7c9 --- /dev/null +++ b/test/src/sdk-harness/test_artifacts/tx_output_change_contract/src/main.sw @@ -0,0 +1,13 @@ +contract; + +use std::asset::transfer; + +abi TxOutputChangeContract { + fn send_assets(to: Address, asset: AssetId, amount: u64); +} + +impl TxOutputChangeContract for Contract { + fn send_assets(to: Address, asset: AssetId, amount: u64) { + transfer(Identity::Address(to), asset, amount); + } +} diff --git a/test/src/sdk-harness/test_artifacts/tx_output_predicate/src/main.sw b/test/src/sdk-harness/test_artifacts/tx_output_predicate/src/main.sw index c7ca99d0d19..e639bd11833 100644 --- a/test/src/sdk-harness/test_artifacts/tx_output_predicate/src/main.sw +++ b/test/src/sdk-harness/test_artifacts/tx_output_predicate/src/main.sw @@ -1,13 +1,15 @@ predicate; -use std::outputs::{output_asset_id, output_asset_to}; +use std::outputs::{output_asset_id, output_asset_to, output_type, Output}; -fn main(index: u64, asset_id: b256, to: b256) -> bool { +fn main(index: u64, asset_id: b256, to: b256, expected_type: Output) -> bool { let tx_asset_id = output_asset_id(index); let tx_to = output_asset_to(index); + let tx_output_type = output_type(index); assert(tx_asset_id.is_some() && tx_asset_id.unwrap().bits() == asset_id); assert(tx_to.is_some() && tx_to.unwrap().bits() == to); + assert(tx_output_type.is_some() && tx_output_type.unwrap() == expected_type); true } diff --git a/test/src/sdk-harness/test_projects/tx_fields/mod.rs b/test/src/sdk-harness/test_projects/tx_fields/mod.rs index b162010e398..0ac934999c7 100644 --- a/test/src/sdk-harness/test_projects/tx_fields/mod.rs +++ b/test/src/sdk-harness/test_projects/tx_fields/mod.rs @@ -14,6 +14,8 @@ const MESSAGE_DATA: [u8; 3] = [1u8, 2u8, 3u8]; const TX_CONTRACT_BYTECODE_PATH: &str = "test_artifacts/tx_contract/out/release/tx_contract.bin"; const TX_OUTPUT_PREDICATE_BYTECODE_PATH: &str = "test_artifacts/tx_output_predicate/out/release/tx_output_predicate.bin"; +const TX_OUTPUT_CHANGE_CONTRACT_BYTECODE_PATH: &str = + "test_artifacts/tx_output_change_contract/out/release/tx_output_change_contract.bin"; const TX_FIELDS_PREDICATE_BYTECODE_PATH: &str = "test_projects/tx_fields/out/release/tx_fields.bin"; const TX_CONTRACT_CREATION_PREDICATE_BYTECODE_PATH: &str = "test_artifacts/tx_output_contract_creation_predicate/out/release/tx_output_contract_creation_predicate.bin"; @@ -27,12 +29,17 @@ const TX_OUTPUT_COUNT_PREDICATE_BYTECODE_PATH: &str = "test_artifacts/tx_output_count_predicate/out/release/tx_output_count_predicate.bin"; use crate::tx_fields::Transaction as SwayTransaction; +use crate::tx_fields::Output as SwayOutput; abigen!( Contract( name = "TxContractTest", abi = "test_artifacts/tx_contract/out/release/tx_contract-abi.json", ), + Contract( + name = "TxOutputChangeContract", + abi = "test_artifacts/tx_output_change_contract/out/release/tx_output_change_contract-abi.json", + ), Predicate( name = "TestPredicate", abi = "test_projects/tx_fields/out/release/tx_fields-abi.json" @@ -165,7 +172,7 @@ async fn generate_predicate_inputs( (predicate_code, predicate_input, predicate_message) } -async fn setup_output_predicate() -> (WalletUnlocked, WalletUnlocked, Predicate, AssetId, AssetId) { +async fn setup_output_predicate(index: u64, expected_output_type: SwayOutput) -> (WalletUnlocked, WalletUnlocked, Predicate, AssetId, AssetId) { let asset_id1 = AssetId::default(); let asset_id2 = AssetId::new([2u8; 32]); let wallets_config = WalletsConfig::new_multiple_assets( @@ -194,7 +201,7 @@ async fn setup_output_predicate() -> (WalletUnlocked, WalletUnlocked, Predicate, let wallet2 = wallets.pop().unwrap(); let predicate_data = TestOutputPredicateEncoder::default() - .encode_data(0, Bits256([0u8; 32]), Bits256(*wallet1.address().hash())) + .encode_data(index, Bits256([0u8; 32]), Bits256(*wallet1.address().hash()), expected_output_type) .unwrap(); let predicate = Predicate::load_from(TX_OUTPUT_PREDICATE_BYTECODE_PATH) @@ -1540,7 +1547,7 @@ mod outputs { #[tokio::test] async fn can_get_tx_output_details() { - let (wallet, _, predicate, asset_id, _) = setup_output_predicate().await; + let (wallet, _, predicate, asset_id, _) = setup_output_predicate(0, SwayOutput::Coin).await; let balance = predicate.get_asset_balance(&asset_id).await.unwrap(); @@ -1671,6 +1678,63 @@ mod outputs { assert_eq!(predicate_balance, 0); } } + + #[tokio::test] + async fn can_get_tx_output_change_details() { + // Prepare predicate + let (wallet, _, predicate, asset_id, _) = setup_output_predicate(2, SwayOutput::Change).await; + let provider = wallet.try_provider().unwrap().clone(); + + let balance = predicate.get_asset_balance(&asset_id).await.unwrap(); + + // Deploy contract + let contract_id = Contract::load_from(TX_OUTPUT_CHANGE_CONTRACT_BYTECODE_PATH, LoadConfiguration::default()) + .unwrap() + .deploy(&wallet, TxPolicies::default()) + .await + .unwrap(); + + let instance = TxOutputChangeContract::new(contract_id.clone(), wallet.clone()); + + // Send tokens to the contract + let _ = wallet + .force_transfer_to_contract(&contract_id, 10, asset_id, TxPolicies::default()) + .await + .unwrap(); + + // Build transaction + let call_handler = instance.methods().send_assets(wallet.clone().address(), asset_id, 10); + let mut tb = call_handler.transaction_builder().await.unwrap(); + + // Inputs for predicate + let transfer_amount = 100; + let predicate_input = predicate + .get_asset_inputs_for_amount(asset_id, transfer_amount, None) + .await + .unwrap(); + + // Outputs for predicate + let predicate_output = wallet.get_asset_outputs_for_amount( + &wallet.address(), + asset_id, + transfer_amount, + ); + + // Append the inputs and outputs to the transaction + tb.inputs.push(predicate_input.get(0).unwrap().clone()); + tb.outputs.push(predicate_output.get(0).unwrap().clone()); + tb.outputs.push(SdkOutput::Change{to: wallet.address().into(), amount: 0, asset_id}); + + wallet.adjust_for_fee(&mut tb, 0).await.unwrap(); + tb.add_signer(wallet.clone()).unwrap(); + + let tx = tb.build(provider.clone()).await.unwrap(); + let _tx_id = provider.send_transaction(tx).await.unwrap(); + + // Assert the predicate balance has changed + let new_balance = predicate.get_asset_balance(&asset_id).await.unwrap(); + assert!(balance - transfer_amount == new_balance); + } } mod revert { @@ -1679,7 +1743,7 @@ mod outputs { #[tokio::test] #[should_panic] async fn fails_output_predicate_when_incorrect_asset() { - let (wallet1, _, predicate, _, asset_id2) = setup_output_predicate().await; + let (wallet1, _, predicate, _, asset_id2) = setup_output_predicate(0, SwayOutput::Coin).await; let transfer_amount = 10; predicate @@ -1696,7 +1760,7 @@ mod outputs { #[tokio::test] #[should_panic] async fn fails_output_predicate_when_incorrect_to() { - let (_, wallet2, predicate, asset_id1, _) = setup_output_predicate().await; + let (_, wallet2, predicate, asset_id1, _) = setup_output_predicate(0, SwayOutput::Coin).await; let transfer_amount = 10; predicate From d2b5431ffd769e6017d9978616a8dd8ca5e52444 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaya=20G=C3=B6kalp?= Date: Tue, 24 Sep 2024 17:28:34 -0700 Subject: [PATCH 037/115] feat: AWS kms signer support for forc-client (#6578) ## Description closes #6560. closes #6559. This PR adds AWS kms signer support. Which is enabled if `--aws-kms-signer ` is present. If that is the case, an aws client is created which is used to create a AwsSigner. With this PR, we are able to supply a signing arn and with that we can sign a transaction. This enables being able to revoke signing authority for aws kms managed keys. So we can control deployments and owner/target changes for a proxy contract. Effectively enabling multi-sig like proxy contracts via aws kms. Edit: Added a usage video for deploying a contract with proxy and updating it while using a aws kms signer below: https://github.com/user-attachments/assets/de26edb0-bbbb-4894-afa0-3fe50fba74cb --------- Co-authored-by: Sophie Dankel <47993817+sdankel@users.noreply.github.com> Co-authored-by: Joshua Batty --- Cargo.lock | 373 ++++++++++++++++++- Cargo.toml | 3 + forc-plugins/forc-client/Cargo.toml | 3 + forc-plugins/forc-client/src/cmd/deploy.rs | 4 + forc-plugins/forc-client/src/op/deploy.rs | 61 ++- forc-plugins/forc-client/src/op/run/mod.rs | 83 +++-- forc-plugins/forc-client/src/util/account.rs | 87 +++++ forc-plugins/forc-client/src/util/aws.rs | 269 +++++++++++++ forc-plugins/forc-client/src/util/gas.rs | 53 --- forc-plugins/forc-client/src/util/mod.rs | 3 +- forc-plugins/forc-client/src/util/tx.rs | 240 ++---------- forc-plugins/forc-client/tests/deploy.rs | 17 +- 12 files changed, 867 insertions(+), 329 deletions(-) create mode 100644 forc-plugins/forc-client/src/util/account.rs create mode 100644 forc-plugins/forc-client/src/util/aws.rs delete mode 100644 forc-plugins/forc-client/src/util/gas.rs diff --git a/Cargo.lock b/Cargo.lock index 1e22bfca8ca..495478e3d1f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -487,6 +487,328 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "aws-config" +version = "1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "848d7b9b605720989929279fa644ce8f244d0ce3146fcca5b70e4eb7b3c020fc" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-sdk-sso", + "aws-sdk-ssooidc", + "aws-sdk-sts", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "hex", + "http 0.2.12", + "ring", + "time", + "tokio", + "tracing", + "url", + "zeroize", +] + +[[package]] +name = "aws-credential-types" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60e8f6b615cb5fc60a98132268508ad104310f0cfb25a1c22eee76efdf9154da" +dependencies = [ + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-types", + "zeroize", +] + +[[package]] +name = "aws-runtime" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a10d5c055aa540164d9561a0e2e74ad30f0dcf7393c3a92f6733ddf9c5762468" +dependencies = [ + "aws-credential-types", + "aws-sigv4", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "http 0.2.12", + "http-body 0.4.6", + "once_cell", + "percent-encoding", + "pin-project-lite", + "tracing", + "uuid 1.10.0", +] + +[[package]] +name = "aws-sdk-kms" +version = "1.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6550445e0913c9383375f4a5a2f550817567a19a178107fce1e1afd767f802a" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "http 0.2.12", + "once_cell", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sdk-sso" +version = "1.43.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a9d27ed1c12b1140c47daf1bc541606c43fdafd918c4797d520db0043ceef2" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "http 0.2.12", + "once_cell", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sdk-ssooidc" +version = "1.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44514a6ca967686cde1e2a1b81df6ef1883d0e3e570da8d8bc5c491dcb6fc29b" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "http 0.2.12", + "once_cell", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sdk-sts" +version = "1.43.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd7a4d279762a35b9df97209f6808b95d4fe78547fe2316b4d200a0283960c5a" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-query", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-smithy-xml", + "aws-types", + "http 0.2.12", + "once_cell", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sigv4" +version = "1.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc8db6904450bafe7473c6ca9123f88cc11089e41a025408f992db4e22d3be68" +dependencies = [ + "aws-credential-types", + "aws-smithy-http", + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes", + "form_urlencoded", + "hex", + "hmac 0.12.1", + "http 0.2.12", + "http 1.1.0", + "once_cell", + "percent-encoding", + "sha2 0.10.8", + "time", + "tracing", +] + +[[package]] +name = "aws-smithy-async" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62220bc6e97f946ddd51b5f1361f78996e704677afc518a4ff66b7a72ea1378c" +dependencies = [ + "futures-util", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "aws-smithy-http" +version = "0.60.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c8bc3e8fdc6b8d07d976e301c02fe553f72a39b7a9fea820e023268467d7ab6" +dependencies = [ + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes", + "bytes-utils", + "futures-core", + "http 0.2.12", + "http-body 0.4.6", + "once_cell", + "percent-encoding", + "pin-project-lite", + "pin-utils", + "tracing", +] + +[[package]] +name = "aws-smithy-json" +version = "0.60.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4683df9469ef09468dad3473d129960119a0d3593617542b7d52086c8486f2d6" +dependencies = [ + "aws-smithy-types", +] + +[[package]] +name = "aws-smithy-query" +version = "0.60.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2fbd61ceb3fe8a1cb7352e42689cec5335833cd9f94103a61e98f9bb61c64bb" +dependencies = [ + "aws-smithy-types", + "urlencoding", +] + +[[package]] +name = "aws-smithy-runtime" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1ce695746394772e7000b39fe073095db6d45a862d0767dd5ad0ac0d7f8eb87" +dependencies = [ + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes", + "fastrand", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "http-body 1.0.1", + "httparse", + "hyper 0.14.30", + "hyper-rustls 0.24.2", + "once_cell", + "pin-project-lite", + "pin-utils", + "rustls 0.21.12", + "tokio", + "tracing", +] + +[[package]] +name = "aws-smithy-runtime-api" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e086682a53d3aa241192aa110fa8dfce98f2f5ac2ead0de84d41582c7e8fdb96" +dependencies = [ + "aws-smithy-async", + "aws-smithy-types", + "bytes", + "http 0.2.12", + "http 1.1.0", + "pin-project-lite", + "tokio", + "tracing", + "zeroize", +] + +[[package]] +name = "aws-smithy-types" +version = "1.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03701449087215b5369c7ea17fef0dd5d24cb93439ec5af0c7615f58c3f22605" +dependencies = [ + "base64-simd", + "bytes", + "bytes-utils", + "futures-core", + "http 0.2.12", + "http 1.1.0", + "http-body 0.4.6", + "http-body 1.0.1", + "http-body-util", + "itoa", + "num-integer", + "pin-project-lite", + "pin-utils", + "ryu", + "serde", + "time", + "tokio", + "tokio-util", +] + +[[package]] +name = "aws-smithy-xml" +version = "0.60.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab0b0166827aa700d3dc519f72f8b3a91c35d0b8d042dc5d643a91e6f80648fc" +dependencies = [ + "xmlparser", +] + +[[package]] +name = "aws-types" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5221b91b3e441e6675310829fd8984801b772cb1546ef6c0e54dec9f1ac13fef" +dependencies = [ + "aws-credential-types", + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-types", + "rustc_version 0.4.0", + "tracing", +] + [[package]] name = "backtrace" version = "0.3.73" @@ -533,6 +855,16 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64-simd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" +dependencies = [ + "outref", + "vsimd", +] + [[package]] name = "base64ct" version = "1.6.0" @@ -762,6 +1094,16 @@ version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +[[package]] +name = "bytes-utils" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dafe3a8757b027e2be6e4e5601ed563c55989fcf1546e933c66c8eb3a058d35" +dependencies = [ + "bytes", + "either", +] + [[package]] name = "c-kzg" version = "1.0.3" @@ -2377,6 +2719,8 @@ version = "0.63.6" dependencies = [ "anyhow", "async-trait", + "aws-config", + "aws-sdk-kms", "chrono", "clap 4.5.16", "devault", @@ -2398,6 +2742,7 @@ dependencies = [ "fuels-core", "futures", "hex", + "k256", "portpicker", "rand", "regex", @@ -4233,9 +4578,9 @@ dependencies = [ [[package]] name = "k256" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ "cfg-if 1.0.0", "ecdsa", @@ -5204,6 +5549,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "outref" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4030760ffd992bef45b0ae3f10ce1aba99e33464c90d14dd7c039884963ddc7a" + [[package]] name = "overload" version = "0.1.1" @@ -6030,6 +6381,12 @@ dependencies = [ "regex-syntax 0.8.4", ] +[[package]] +name = "regex-lite" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" + [[package]] name = "regex-syntax" version = "0.6.29" @@ -8560,6 +8917,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +[[package]] +name = "vsimd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" + [[package]] name = "vt100" version = "0.15.2" @@ -9085,6 +9448,12 @@ version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" +[[package]] +name = "xmlparser" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" + [[package]] name = "yaml-rust" version = "0.4.5" diff --git a/Cargo.toml b/Cargo.toml index 697b359e662..0ecc97ccb14 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -114,6 +114,8 @@ anyhow = "1.0" assert-json-diff = "2.0" async-trait = "0.1" atty = "0.2" +aws-config = "1.5" +aws-sdk-kms = "1.44" byte-unit = "5.1" bytecount = "0.6" bytes = "1.7" @@ -158,6 +160,7 @@ indoc = "2.0" insta = "1.40" ipfs-api-backend-hyper = "0.6" itertools = "0.13" +k256 = "0.13" lazy_static = "1.4" libp2p-identity = "0.2" libtest-mimic = "0.7" diff --git a/forc-plugins/forc-client/Cargo.toml b/forc-plugins/forc-client/Cargo.toml index 8b7f1455daf..f63bb0b99c9 100644 --- a/forc-plugins/forc-client/Cargo.toml +++ b/forc-plugins/forc-client/Cargo.toml @@ -11,6 +11,8 @@ repository.workspace = true [dependencies] anyhow.workspace = true async-trait.workspace = true +aws-config.workspace = true +aws-sdk-kms.workspace = true chrono = { workspace = true, features = ["std"] } clap = { workspace = true, features = ["derive", "env"] } devault.workspace = true @@ -32,6 +34,7 @@ fuels-accounts.workspace = true fuels-core.workspace = true futures.workspace = true hex.workspace = true +k256.workspace = true rand.workspace = true rpassword.workspace = true serde.workspace = true diff --git a/forc-plugins/forc-client/src/cmd/deploy.rs b/forc-plugins/forc-client/src/cmd/deploy.rs index edb9e76d7f0..5553a2fe06b 100644 --- a/forc-plugins/forc-client/src/cmd/deploy.rs +++ b/forc-plugins/forc-client/src/cmd/deploy.rs @@ -87,4 +87,8 @@ pub struct Command { /// Disable the "new encoding" feature #[clap(long)] pub no_encoding_v1: bool, + + /// AWS KMS signer arn. If present forc-deploy will automatically use AWS KMS signer instead of forc-wallet. + #[clap(long)] + pub aws_kms_signer: Option, } diff --git a/forc-plugins/forc-client/src/op/deploy.rs b/forc-plugins/forc-client/src/op/deploy.rs index 0f05e020782..e6070e0af85 100644 --- a/forc-plugins/forc-client/src/op/deploy.rs +++ b/forc-plugins/forc-client/src/op/deploy.rs @@ -2,12 +2,13 @@ use crate::{ cmd, constants::TX_SUBMIT_TIMEOUT_MS, util::{ + account::ForcClientAccount, node_url::get_node_url, pkg::{built_pkgs, create_proxy_contract, update_proxy_address_in_manifest}, target::Target, tx::{ - bech32_from_secret, prompt_forc_wallet_password, select_secret_key, - update_proxy_contract_target, WalletSelectionMode, + prompt_forc_wallet_password, select_account, update_proxy_contract_target, + SignerSelectionMode, }, }, }; @@ -27,7 +28,7 @@ use fuels::{ programs::contract::{LoadConfiguration, StorageConfiguration}, types::{bech32::Bech32ContractId, transaction_builders::Blob}, }; -use fuels_accounts::{provider::Provider, wallet::WalletUnlocked, Account}; +use fuels_accounts::{provider::Provider, Account, ViewOnlyAccount}; use fuels_core::types::{transaction::TxPolicies, transaction_builders::CreateTransactionBuilder}; use futures::FutureExt; use pkg::{manifest::build_profile::ExperimentalFlags, BuildProfile, BuiltPackage}; @@ -159,7 +160,7 @@ async fn deploy_chunked( command: &cmd::Deploy, compiled: &BuiltPackage, salt: Salt, - signing_key: &SecretKey, + account: &ForcClientAccount, provider: &Provider, pkg_name: &str, ) -> anyhow::Result { @@ -173,7 +174,6 @@ async fn deploy_chunked( None => "".to_string(), }; - let wallet = WalletUnlocked::new_from_private_key(*signing_key, Some(provider.clone())); let blobs = compiled .bytecode .bytes @@ -184,7 +184,7 @@ async fn deploy_chunked( let tx_policies = tx_policies_from_cmd(command); let contract_id = fuels::programs::contract::Contract::loader_from_blobs(blobs, salt, storage_slots)? - .deploy(&wallet, tx_policies) + .deploy(account, tx_policies) .await? .into(); @@ -202,12 +202,11 @@ async fn deploy_new_proxy( pkg_name: &str, impl_contract: &fuel_tx::ContractId, provider: &Provider, - signing_key: &SecretKey, + account: &ForcClientAccount, ) -> Result { abigen!(Contract(name = "ProxyContract", abi = "{\"programType\":\"contract\",\"specVersion\":\"1\",\"encodingVersion\":\"1\",\"concreteTypes\":[{\"type\":\"()\",\"concreteTypeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"},{\"type\":\"enum standards::src5::AccessError\",\"concreteTypeId\":\"3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d\",\"metadataTypeId\":1},{\"type\":\"enum standards::src5::State\",\"concreteTypeId\":\"192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c\",\"metadataTypeId\":2},{\"type\":\"enum std::option::Option\",\"concreteTypeId\":\"0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8\",\"metadataTypeId\":4,\"typeArguments\":[\"29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54\"]},{\"type\":\"enum sway_libs::ownership::errors::InitializationError\",\"concreteTypeId\":\"1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893\",\"metadataTypeId\":5},{\"type\":\"enum sway_libs::upgradability::errors::SetProxyOwnerError\",\"concreteTypeId\":\"3c6e90ae504df6aad8b34a93ba77dc62623e00b777eecacfa034a8ac6e890c74\",\"metadataTypeId\":6},{\"type\":\"str\",\"concreteTypeId\":\"8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a\"},{\"type\":\"struct std::contract_id::ContractId\",\"concreteTypeId\":\"29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54\",\"metadataTypeId\":9},{\"type\":\"struct sway_libs::upgradability::events::ProxyOwnerSet\",\"concreteTypeId\":\"96dd838b44f99d8ccae2a7948137ab6256c48ca4abc6168abc880de07fba7247\",\"metadataTypeId\":10},{\"type\":\"struct sway_libs::upgradability::events::ProxyTargetSet\",\"concreteTypeId\":\"1ddc0adda1270a016c08ffd614f29f599b4725407c8954c8b960bdf651a9a6c8\",\"metadataTypeId\":11}],\"metadataTypes\":[{\"type\":\"b256\",\"metadataTypeId\":0},{\"type\":\"enum standards::src5::AccessError\",\"metadataTypeId\":1,\"components\":[{\"name\":\"NotOwner\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"}]},{\"type\":\"enum standards::src5::State\",\"metadataTypeId\":2,\"components\":[{\"name\":\"Uninitialized\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"},{\"name\":\"Initialized\",\"typeId\":3},{\"name\":\"Revoked\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"}]},{\"type\":\"enum std::identity::Identity\",\"metadataTypeId\":3,\"components\":[{\"name\":\"Address\",\"typeId\":8},{\"name\":\"ContractId\",\"typeId\":9}]},{\"type\":\"enum std::option::Option\",\"metadataTypeId\":4,\"components\":[{\"name\":\"None\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"},{\"name\":\"Some\",\"typeId\":7}],\"typeParameters\":[7]},{\"type\":\"enum sway_libs::ownership::errors::InitializationError\",\"metadataTypeId\":5,\"components\":[{\"name\":\"CannotReinitialized\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"}]},{\"type\":\"enum sway_libs::upgradability::errors::SetProxyOwnerError\",\"metadataTypeId\":6,\"components\":[{\"name\":\"CannotUninitialize\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"}]},{\"type\":\"generic T\",\"metadataTypeId\":7},{\"type\":\"struct std::address::Address\",\"metadataTypeId\":8,\"components\":[{\"name\":\"bits\",\"typeId\":0}]},{\"type\":\"struct std::contract_id::ContractId\",\"metadataTypeId\":9,\"components\":[{\"name\":\"bits\",\"typeId\":0}]},{\"type\":\"struct sway_libs::upgradability::events::ProxyOwnerSet\",\"metadataTypeId\":10,\"components\":[{\"name\":\"new_proxy_owner\",\"typeId\":2}]},{\"type\":\"struct sway_libs::upgradability::events::ProxyTargetSet\",\"metadataTypeId\":11,\"components\":[{\"name\":\"new_target\",\"typeId\":9}]}],\"functions\":[{\"inputs\":[],\"name\":\"proxy_target\",\"output\":\"0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Returns the target contract of the proxy contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Returns\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * [Option] - The new proxy contract to which all fallback calls will be passed or `None`.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Reads: `1`\"]},{\"name\":\"storage\",\"arguments\":[\"read\"]}]},{\"inputs\":[{\"name\":\"new_target\",\"concreteTypeId\":\"29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54\"}],\"name\":\"set_proxy_target\",\"output\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Change the target contract of the proxy contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Additional Information\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This method can only be called by the `proxy_owner`.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Arguments\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * `new_target`: [ContractId] - The new proxy contract to which all fallback calls will be passed.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Reverts\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * When not called by `proxy_owner`.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Reads: `1`\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Write: `1`\"]},{\"name\":\"storage\",\"arguments\":[\"read\",\"write\"]}]},{\"inputs\":[],\"name\":\"proxy_owner\",\"output\":\"192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Returns the owner of the proxy contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Returns\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * [State] - Represents the state of ownership for this contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Reads: `1`\"]},{\"name\":\"storage\",\"arguments\":[\"read\"]}]},{\"inputs\":[],\"name\":\"initialize_proxy\",\"output\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Initializes the proxy contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Additional Information\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This method sets the storage values using the values of the configurable constants `INITIAL_TARGET` and `INITIAL_OWNER`.\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This then allows methods that write to storage to be called.\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This method can only be called once.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Reverts\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * When `storage::SRC14.proxy_owner` is not [State::Uninitialized].\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Writes: `2`\"]},{\"name\":\"storage\",\"arguments\":[\"write\"]}]},{\"inputs\":[{\"name\":\"new_proxy_owner\",\"concreteTypeId\":\"192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c\"}],\"name\":\"set_proxy_owner\",\"output\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Changes proxy ownership to the passed State.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Additional Information\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This method can be used to transfer ownership between Identities or to revoke ownership.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Arguments\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * `new_proxy_owner`: [State] - The new state of the proxy ownership.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Reverts\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * When the sender is not the current proxy owner.\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * When the new state of the proxy ownership is [State::Uninitialized].\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Reads: `1`\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Writes: `1`\"]},{\"name\":\"storage\",\"arguments\":[\"write\"]}]}],\"loggedTypes\":[{\"logId\":\"4571204900286667806\",\"concreteTypeId\":\"3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d\"},{\"logId\":\"2151606668983994881\",\"concreteTypeId\":\"1ddc0adda1270a016c08ffd614f29f599b4725407c8954c8b960bdf651a9a6c8\"},{\"logId\":\"2161305517876418151\",\"concreteTypeId\":\"1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893\"},{\"logId\":\"4354576968059844266\",\"concreteTypeId\":\"3c6e90ae504df6aad8b34a93ba77dc62623e00b777eecacfa034a8ac6e890c74\"},{\"logId\":\"10870989709723147660\",\"concreteTypeId\":\"96dd838b44f99d8ccae2a7948137ab6256c48ca4abc6168abc880de07fba7247\"},{\"logId\":\"10098701174489624218\",\"concreteTypeId\":\"8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a\"}],\"messagesTypes\":[],\"configurables\":[{\"name\":\"INITIAL_TARGET\",\"concreteTypeId\":\"0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8\",\"offset\":13368},{\"name\":\"INITIAL_OWNER\",\"concreteTypeId\":\"192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c\",\"offset\":13320}]}",)); let proxy_dir_output = create_proxy_contract(pkg_name)?; - let address = bech32_from_secret(signing_key)?; - let wallet = WalletUnlocked::new_from_private_key(*signing_key, Some(provider.clone())); + let address = account.address(); let storage_path = proxy_dir_output.join("proxy-storage_slots.json"); let storage_configuration = @@ -226,7 +225,7 @@ async fn deploy_new_proxy( proxy_dir_output.join("proxy.bin"), configuration, )? - .deploy(&wallet, tx_policies) + .deploy(account, tx_policies) .await? .into(); @@ -243,7 +242,7 @@ async fn deploy_new_proxy( ); let proxy_contract_bech_id: Bech32ContractId = proxy_contract_id.into(); - let instance = ProxyContract::new(&proxy_contract_bech_id, wallet); + let instance = ProxyContract::new(&proxy_contract_bech_id, account.clone()); instance.methods().initialize_proxy().call().await?; println_action_green("Initialized", &format!("proxy contract for {pkg_name}")); Ok(proxy_contract_id) @@ -334,7 +333,7 @@ pub async fn deploy(command: cmd::Deploy) -> Result> { } // Confirmation step. Summarize the transaction(s) for the deployment. - let (provider, signing_key) = + let (provider, account) = confirm_transaction_details(&pkgs_to_deploy, &command, node_url.clone()).await?; for pkg in pkgs_to_deploy { @@ -362,13 +361,13 @@ pub async fn deploy(command: cmd::Deploy) -> Result> { &command, pkg, salt, - &signing_key, + &account, &provider, &pkg.descriptor.name, ) .await? } else { - deploy_pkg(&command, pkg, salt, &provider, &signing_key).await? + deploy_pkg(&command, pkg, salt, &provider, &account).await? }; let proxy_id = match &pkg.descriptor.manifest_file.proxy { @@ -383,13 +382,8 @@ pub async fn deploy(command: cmd::Deploy) -> Result> { let proxy_contract = ContractId::from_str(proxy_addr).map_err(|e| anyhow::anyhow!(e))?; - update_proxy_contract_target( - &provider, - signing_key, - proxy_contract, - deployed_contract_id, - ) - .await?; + update_proxy_contract_target(&account, proxy_contract, deployed_contract_id) + .await?; Some(proxy_contract) } Some(forc_pkg::manifest::Proxy { @@ -403,7 +397,7 @@ pub async fn deploy(command: cmd::Deploy) -> Result> { pkg_name, &deployed_contract_id, &provider, - &signing_key, + &account, ) .await?; @@ -433,7 +427,7 @@ async fn confirm_transaction_details( pkgs_to_deploy: &[&Arc], command: &cmd::Deploy, node_url: String, -) -> Result<(Provider, SecretKey)> { +) -> Result<(Provider, ForcClientAccount)> { // Confirmation step. Summarize the transaction(s) for the deployment. let mut tx_count = 0; let tx_summary = pkgs_to_deploy @@ -478,27 +472,28 @@ async fn confirm_transaction_details( let provider = Provider::connect(node_url.clone()).await?; let wallet_mode = if command.default_signer || command.signing_key.is_some() { - WalletSelectionMode::Manual + SignerSelectionMode::Manual + } else if let Some(arn) = &command.aws_kms_signer { + SignerSelectionMode::AwsSigner(arn.clone()) } else { println_action_green("", &format!("Wallet: {}", default_wallet_path().display())); let password = prompt_forc_wallet_password()?; - WalletSelectionMode::ForcWallet(password) + SignerSelectionMode::ForcWallet(password) }; // TODO: Display the estimated gas cost of the transaction(s). // https://github.com/FuelLabs/sway/issues/6277 - let signing_key = select_secret_key( + let account = select_account( &wallet_mode, command.default_signer || command.unsigned, command.signing_key, &provider, tx_count, ) - .await? - .ok_or_else(|| anyhow::anyhow!("failed to select a signer for the transaction"))?; + .await?; - Ok((provider.clone(), signing_key)) + Ok((provider.clone(), account)) } /// Deploy a single pkg given deploy command and the manifest file @@ -507,7 +502,7 @@ pub async fn deploy_pkg( compiled: &BuiltPackage, salt: Salt, provider: &Provider, - signing_key: &SecretKey, + account: &ForcClientAccount, ) -> Result { let manifest = &compiled.descriptor.manifest_file; let node_url = provider.url(); @@ -530,10 +525,10 @@ pub async fn deploy_pkg( storage_slots.clone(), tx_policies, ); - let wallet = WalletUnlocked::new_from_private_key(*signing_key, Some(provider.clone())); - wallet.add_witnesses(&mut tb)?; - wallet.adjust_for_fee(&mut tb, 0).await?; + account.add_witnesses(&mut tb)?; + account.adjust_for_fee(&mut tb, 0).await?; + let tx = tb.build(provider).await?; let tx = Transaction::from(tx); diff --git a/forc-plugins/forc-client/src/op/run/mod.rs b/forc-plugins/forc-client/src/op/run/mod.rs index cda23fb14cf..5e58835fca0 100644 --- a/forc-plugins/forc-client/src/op/run/mod.rs +++ b/forc-plugins/forc-client/src/op/run/mod.rs @@ -3,10 +3,9 @@ use crate::{ cmd, constants::TX_SUBMIT_TIMEOUT_MS, util::{ - gas::get_script_gas_used, node_url::get_node_url, pkg::built_pkgs, - tx::{prompt_forc_wallet_password, TransactionBuilderExt, WalletSelectionMode}, + tx::{prompt_forc_wallet_password, select_account, SignerSelectionMode}, }, }; use anyhow::{anyhow, bail, Context, Result}; @@ -14,8 +13,16 @@ use forc_pkg::{self as pkg, fuel_core_not_running, PackageManifestFile}; use forc_tracing::println_warning; use forc_util::tx_utils::format_log_receipts; use fuel_core_client::client::FuelClient; -use fuel_tx::{ContractId, Transaction, TransactionBuilder}; -use fuels_accounts::provider::Provider; +use fuel_tx::{ContractId, Transaction}; +use fuels::{ + programs::calls::{traits::TransactionTuner, ScriptCall}, + types::{ + bech32::Bech32ContractId, + transaction::TxPolicies, + transaction_builders::{BuildableTransaction, VariableOutputPolicy}, + }, +}; +use fuels_accounts::{provider::Provider, Account}; use pkg::{manifest::build_profile::ExperimentalFlags, BuiltPackage}; use std::time::Duration; use std::{path::PathBuf, str::FromStr}; @@ -51,10 +58,10 @@ pub async fn run(command: cmd::Run) -> Result> { let build_opts = build_opts_from_cmd(&command); let built_pkgs_with_manifest = built_pkgs(&curr_dir, &build_opts)?; let wallet_mode = if command.default_signer || command.signing_key.is_some() { - WalletSelectionMode::Manual + SignerSelectionMode::Manual } else { let password = prompt_forc_wallet_password()?; - WalletSelectionMode::ForcWallet(password) + SignerSelectionMode::ForcWallet(password) }; for built in built_pkgs_with_manifest { if built @@ -77,13 +84,34 @@ pub async fn run(command: cmd::Run) -> Result> { Ok(receipts) } +fn tx_policies_from_cmd(cmd: &cmd::Run) -> TxPolicies { + let mut tx_policies = TxPolicies::default(); + if let Some(max_fee) = cmd.gas.max_fee { + tx_policies = tx_policies.with_max_fee(max_fee); + } + if let Some(script_gas_limit) = cmd.gas.script_gas_limit { + tx_policies = tx_policies.with_script_gas_limit(script_gas_limit); + } + tx_policies +} + pub async fn run_pkg( command: &cmd::Run, manifest: &PackageManifestFile, compiled: &BuiltPackage, - wallet_mode: &WalletSelectionMode, + signer_mode: &SignerSelectionMode, ) -> Result { let node_url = get_node_url(&command.node, &manifest.network)?; + let provider = Provider::connect(node_url.clone()).await?; + let tx_count = 1; + let account = select_account( + signer_mode, + command.default_signer || command.unsigned, + command.signing_key, + &provider, + tx_count, + ) + .await?; let script_data = match (&command.data, &command.args) { (None, Some(args)) => { @@ -116,31 +144,28 @@ pub async fn run_pkg( }) .collect::>>()?; - let mut tb = TransactionBuilder::script(compiled.bytecode.bytes.clone(), script_data); - tb.maturity(command.maturity.maturity.into()) - .add_contracts(contract_ids); - - let provider = Provider::connect(node_url.clone()).await?; - - let script_gas_limit = if compiled.bytecode.bytes.is_empty() { - 0 - } else if let Some(script_gas_limit) = command.gas.script_gas_limit { - script_gas_limit - // Dry run tx and get `gas_used` - } else { - get_script_gas_used(tb.clone().finalize_without_signature_inner(), &provider).await? + let script_binary = compiled.bytecode.bytes.clone(); + let external_contracts = contract_ids + .into_iter() + .map(Bech32ContractId::from) + .collect::>(); + let call = ScriptCall { + script_binary, + encoded_args: Ok(script_data), + inputs: vec![], + outputs: vec![], + external_contracts, }; - tb.script_gas_limit(script_gas_limit); - - let tx = tb - .finalize_signed( - Provider::connect(node_url.clone()).await?, - command.default_signer, - command.signing_key, - wallet_mode, - ) + let tx_policies = tx_policies_from_cmd(command); + let mut tb = call + .transaction_builder(tx_policies, VariableOutputPolicy::EstimateMinimum, &account) .await?; + account.add_witnesses(&mut tb)?; + account.adjust_for_fee(&mut tb, 0).await?; + + let tx = tb.build(provider).await?; + if command.dry_run { info!("{:?}", tx); Ok(RanScript { receipts: vec![] }) diff --git a/forc-plugins/forc-client/src/util/account.rs b/forc-plugins/forc-client/src/util/account.rs new file mode 100644 index 00000000000..17ecc6781b8 --- /dev/null +++ b/forc-plugins/forc-client/src/util/account.rs @@ -0,0 +1,87 @@ +use async_trait::async_trait; +use fuel_crypto::{Message, Signature}; +use fuels::{ + prelude::*, + types::{coin_type_id::CoinTypeId, input::Input}, +}; +use fuels_accounts::{wallet::WalletUnlocked, Account}; + +use super::aws::AwsSigner; + +#[derive(Clone, Debug)] +/// Set of different signers available to be used with `forc-client` operations. +pub enum ForcClientAccount { + /// Local signer where the private key owned locally. This can be + /// generated through `forc-wallet` integration or manually by providing + /// a private-key. + Wallet(WalletUnlocked), + /// A KMS Signer specifically using AWS KMS service. The signing key + /// is managed by another entity for KMS signers. Messages are + /// signed by the KMS entity. Signed transactions are retrieved + /// and submitted to the node by `forc-client`. + KmsSigner(AwsSigner), +} + +#[async_trait] +impl Account for ForcClientAccount { + async fn get_asset_inputs_for_amount( + &self, + asset_id: AssetId, + amount: u64, + excluded_coins: Option>, + ) -> Result> { + match self { + ForcClientAccount::Wallet(wallet) => { + wallet + .get_asset_inputs_for_amount(asset_id, amount, excluded_coins) + .await + } + ForcClientAccount::KmsSigner(account) => { + account + .get_asset_inputs_for_amount(asset_id, amount, excluded_coins) + .await + } + } + } + + fn add_witnesses(&self, tb: &mut Tb) -> Result<()> { + tb.add_signer(self.clone())?; + + Ok(()) + } +} + +impl ViewOnlyAccount for ForcClientAccount { + fn address(&self) -> &Bech32Address { + match self { + ForcClientAccount::Wallet(wallet) => wallet.address(), + ForcClientAccount::KmsSigner(account) => { + fuels_accounts::ViewOnlyAccount::address(account) + } + } + } + + fn try_provider(&self) -> Result<&Provider> { + match self { + ForcClientAccount::Wallet(wallet) => wallet.try_provider(), + ForcClientAccount::KmsSigner(account) => Ok(account.provider()), + } + } +} + +#[async_trait] +impl Signer for ForcClientAccount { + async fn sign(&self, message: Message) -> Result { + match self { + ForcClientAccount::Wallet(wallet) => wallet.sign(message).await, + ForcClientAccount::KmsSigner(account) => account.sign(message).await, + } + } + + fn address(&self) -> &Bech32Address { + match self { + ForcClientAccount::Wallet(wallet) => wallet.address(), + ForcClientAccount::KmsSigner(account) => fuels_core::traits::Signer::address(account), + } + } +} diff --git a/forc-plugins/forc-client/src/util/aws.rs b/forc-plugins/forc-client/src/util/aws.rs new file mode 100644 index 00000000000..90da533815c --- /dev/null +++ b/forc-plugins/forc-client/src/util/aws.rs @@ -0,0 +1,269 @@ +use async_trait::async_trait; +use aws_config::{default_provider::credentials::DefaultCredentialsChain, Region, SdkConfig}; +use aws_sdk_kms::config::Credentials; +use aws_sdk_kms::operation::get_public_key::GetPublicKeyOutput; +use aws_sdk_kms::primitives::Blob; +use aws_sdk_kms::types::{MessageType, SigningAlgorithmSpec}; +use aws_sdk_kms::{config::BehaviorVersion, Client}; +use fuel_crypto::Message; +use fuels::prelude::*; +use fuels::types::bech32::{Bech32Address, FUEL_BECH32_HRP}; +use fuels::types::coin_type_id::CoinTypeId; +use fuels::types::input::Input; +use fuels_accounts::provider::Provider; +use fuels_accounts::{Account, ViewOnlyAccount}; +use fuels_core::traits::Signer; + +/// AWS configuration for the `AwsSigner` to be created. +/// De-facto way of creating the configuration is to load it from env. +#[derive(Debug, Clone)] +pub struct AwsConfig { + sdk_config: SdkConfig, +} + +impl AwsConfig { + /// Load configuration from environment variables. + /// For more details see: https://docs.rs/aws-config/latest/aws_config/ + pub async fn from_env() -> Self { + let loader = aws_config::defaults(BehaviorVersion::latest()) + .credentials_provider(DefaultCredentialsChain::builder().build().await); + + let loader = match std::env::var("E2E_TEST_AWS_ENDPOINT") { + Ok(url) => loader.endpoint_url(url), + _ => loader, + }; + + Self { + sdk_config: loader.load().await, + } + } + + pub async fn for_testing(url: String) -> Self { + let sdk_config = aws_config::defaults(BehaviorVersion::latest()) + .credentials_provider(Credentials::new( + "test", + "test", + None, + None, + "Static Credentials", + )) + .endpoint_url(url) + .region(Region::new("us-east-1")) // placeholder region for test + .load() + .await; + + Self { sdk_config } + } + + pub fn url(&self) -> Option<&str> { + self.sdk_config.endpoint_url() + } + + pub fn region(&self) -> Option<&Region> { + self.sdk_config.region() + } +} + +/// A configured `AwsClient` which allows using the AWS KMS SDK. +#[derive(Clone, Debug)] +pub struct AwsClient { + client: Client, +} + +impl AwsClient { + pub fn new(config: AwsConfig) -> Self { + let config = config.sdk_config; + let client = Client::new(&config); + + Self { client } + } + + pub fn inner(&self) -> &Client { + &self.client + } +} + +/// A signer which is capable of signing `fuel_crypto::Message`s using AWS KMS. +/// This is both a `Signer` and `Account`, which means it is directly usable +/// with most of the fuels-* calls, without any additional operations on the +/// representation. +#[derive(Clone, Debug)] +pub struct AwsSigner { + kms: AwsClient, + key_id: String, + bech: Bech32Address, + public_key_bytes: Vec, + provider: Provider, +} + +async fn request_get_pubkey( + kms: &Client, + key_id: String, +) -> std::result::Result { + kms.get_public_key() + .key_id(key_id) + .send() + .await + .map_err(Into::into) +} + +/// Decode an AWS KMS Pubkey response. +fn decode_pubkey(resp: &GetPublicKeyOutput) -> std::result::Result, anyhow::Error> { + let raw = resp + .public_key + .as_ref() + .ok_or(anyhow::anyhow!("public key not found"))?; + Ok(raw.clone().into_inner()) +} + +async fn sign_with_kms( + client: &aws_sdk_kms::Client, + key_id: &str, + public_key_bytes: &[u8], + message: Message, +) -> anyhow::Result { + use k256::{ + ecdsa::{RecoveryId, VerifyingKey}, + pkcs8::DecodePublicKey, + }; + + let reply = client + .sign() + .key_id(key_id) + .signing_algorithm(SigningAlgorithmSpec::EcdsaSha256) + .message_type(MessageType::Digest) + .message(Blob::new(*message)) + .send() + .await + .inspect_err(|err| tracing::error!("Failed to sign with AWS KMS: {err:?}"))?; + let signature_der = reply + .signature + .ok_or_else(|| anyhow::anyhow!("no signature returned from AWS KMS"))? + .into_inner(); + // https://stackoverflow.com/a/71475108 + let sig = k256::ecdsa::Signature::from_der(&signature_der) + .map_err(|_| anyhow::anyhow!("invalid DER signature from AWS KMS"))?; + let sig = sig.normalize_s().unwrap_or(sig); + + // This is a hack to get the recovery id. The signature should be normalized + // before computing the recovery id, but aws kms doesn't support this, and + // instead always computes the recovery id from non-normalized signature. + // So instead the recovery id is determined by checking which variant matches + // the original public key. + + let recid1 = RecoveryId::new(false, false); + let recid2 = RecoveryId::new(true, false); + + let rec1 = VerifyingKey::recover_from_prehash(&*message, &sig, recid1); + let rec2 = VerifyingKey::recover_from_prehash(&*message, &sig, recid2); + + let correct_public_key = k256::PublicKey::from_public_key_der(public_key_bytes) + .map_err(|_| anyhow::anyhow!("invalid DER public key from AWS KMS"))? + .into(); + + let recovery_id = if rec1.map(|r| r == correct_public_key).unwrap_or(false) { + recid1 + } else if rec2.map(|r| r == correct_public_key).unwrap_or(false) { + recid2 + } else { + anyhow::bail!("Invalid signature generated (reduced-x form coordinate)"); + }; + + // Insert the recovery id into the signature + debug_assert!( + !recovery_id.is_x_reduced(), + "reduced-x form coordinates are caught by the if-else chain above" + ); + let v = recovery_id.is_y_odd() as u8; + let mut signature = <[u8; 64]>::from(sig.to_bytes()); + signature[32] = (v << 7) | (signature[32] & 0x7f); + Ok(fuel_crypto::Signature::from_bytes(signature)) +} + +impl AwsSigner { + pub async fn new( + kms: AwsClient, + key_id: String, + provider: Provider, + ) -> std::result::Result { + use k256::pkcs8::DecodePublicKey; + + let resp = request_get_pubkey(kms.inner(), key_id.clone()).await?; + let public_key_bytes = decode_pubkey(&resp)?; + let k256_public_key = k256::PublicKey::from_public_key_der(&public_key_bytes)?; + + let public_key = fuel_crypto::PublicKey::from(k256_public_key); + let hashed = public_key.hash(); + let bech = Bech32Address::new(FUEL_BECH32_HRP, hashed); + Ok(Self { + kms, + key_id, + bech, + public_key_bytes, + provider, + }) + } + + /// Sign a digest with the key associated with a key ID. + pub async fn sign_message_with_key( + &self, + key_id: String, + message: Message, + ) -> std::result::Result { + sign_with_kms(self.kms.inner(), &key_id, &self.public_key_bytes, message).await + } + + /// Sign a digest with this signer's key. + pub async fn sign_message( + &self, + message: Message, + ) -> std::result::Result { + self.sign_message_with_key(self.key_id.clone(), message) + .await + } + + pub fn provider(&self) -> &Provider { + &self.provider + } +} + +#[async_trait] +impl Signer for AwsSigner { + async fn sign(&self, message: Message) -> Result { + let sig = self.sign_message(message).await.map_err(|_| { + fuels_core::types::errors::Error::Other("aws signer failed".to_string()) + })?; + Ok(sig) + } + + fn address(&self) -> &Bech32Address { + &self.bech + } +} + +impl ViewOnlyAccount for AwsSigner { + fn address(&self) -> &Bech32Address { + &self.bech + } + + fn try_provider(&self) -> Result<&Provider> { + Ok(&self.provider) + } +} + +#[async_trait] +impl Account for AwsSigner { + async fn get_asset_inputs_for_amount( + &self, + asset_id: AssetId, + amount: u64, + excluded_coins: Option>, + ) -> Result> { + Ok(self + .get_spendable_resources(asset_id, amount, excluded_coins) + .await? + .into_iter() + .map(Input::resource_signed) + .collect::>()) + } +} diff --git a/forc-plugins/forc-client/src/util/gas.rs b/forc-plugins/forc-client/src/util/gas.rs deleted file mode 100644 index 9667bee8674..00000000000 --- a/forc-plugins/forc-client/src/util/gas.rs +++ /dev/null @@ -1,53 +0,0 @@ -use anyhow::Result; - -use fuel_tx::{ - field::{Inputs, Witnesses}, - Buildable, Chargeable, Input, Script, TxPointer, -}; -use fuels_accounts::provider::Provider; -use fuels_core::types::transaction::ScriptTransaction; - -fn no_spendable_input<'a, I: IntoIterator>(inputs: I) -> bool { - !inputs.into_iter().any(|i| { - matches!( - i, - Input::CoinSigned(_) - | Input::CoinPredicate(_) - | Input::MessageCoinSigned(_) - | Input::MessageCoinPredicate(_) - ) - }) -} - -pub(crate) async fn get_script_gas_used(mut tx: Script, provider: &Provider) -> Result { - let no_spendable_input = no_spendable_input(tx.inputs()); - let base_asset_id = provider.base_asset_id(); - if no_spendable_input { - tx.inputs_mut().push(Input::coin_signed( - Default::default(), - Default::default(), - 1_000_000_000, - *base_asset_id, - TxPointer::default(), - 0, - )); - - // Add an empty `Witness` for the `coin_signed` we just added - // and increase the witness limit - tx.witnesses_mut().push(Default::default()); - } - let consensus_params = provider.consensus_parameters(); - - // Get `max_gas` used by everything except the script execution. Add `1` because of rounding. - let max_gas_per_tx = consensus_params.tx_params().max_gas_per_tx(); - let max_gas = tx.max_gas(consensus_params.gas_costs(), consensus_params.fee_params()) + 1; - // Increase `script_gas_limit` to the maximum allowed value. - tx.set_script_gas_limit(max_gas_per_tx - max_gas); - let script_tx = ScriptTransaction::from(tx); - - let tolerance = 0.1; - let estimated_tx_cost = provider - .estimate_transaction_cost(script_tx, Some(tolerance), None) - .await?; - Ok(estimated_tx_cost.gas_used) -} diff --git a/forc-plugins/forc-client/src/util/mod.rs b/forc-plugins/forc-client/src/util/mod.rs index d8024081b28..2e58fc41c79 100644 --- a/forc-plugins/forc-client/src/util/mod.rs +++ b/forc-plugins/forc-client/src/util/mod.rs @@ -1,5 +1,6 @@ +pub mod account; +pub mod aws; pub(crate) mod encode; -pub(crate) mod gas; pub(crate) mod node_url; pub(crate) mod pkg; pub(crate) mod target; diff --git a/forc-plugins/forc-client/src/util/tx.rs b/forc-plugins/forc-client/src/util/tx.rs index f826d86bf62..d5a002e809f 100644 --- a/forc-plugins/forc-client/src/util/tx.rs +++ b/forc-plugins/forc-client/src/util/tx.rs @@ -1,6 +1,8 @@ -use crate::{constants::DEFAULT_PRIVATE_KEY, util::target::Target}; -use anyhow::{Error, Result}; -use async_trait::async_trait; +use crate::{ + constants::DEFAULT_PRIVATE_KEY, + util::{account::ForcClientAccount, aws::AwsSigner, target::Target}, +}; +use anyhow::Result; use dialoguer::{theme::ColorfulTheme, Confirm, Password, Select}; use forc_tracing::{println_action_green, println_warning}; use forc_wallet::{ @@ -11,47 +13,27 @@ use forc_wallet::{ new::{new_wallet_cli, New}, utils::default_wallet_path, }; -use fuel_crypto::{Message, PublicKey, SecretKey, Signature}; -use fuel_tx::{ - field, Address, AssetId, Buildable, ContractId, Input, Output, TransactionBuilder, Witness, -}; +use fuel_crypto::SecretKey; +use fuel_tx::{AssetId, ContractId}; use fuels::{macros::abigen, programs::responses::CallResponse}; use fuels_accounts::{ provider::Provider, wallet::{Wallet, WalletUnlocked}, ViewOnlyAccount, }; -use fuels_core::types::{ - bech32::{Bech32Address, FUEL_BECH32_HRP}, - coin_type::CoinType, - transaction_builders::{create_coin_input, create_coin_message_input}, -}; -use std::{collections::BTreeMap, io::Write, path::Path, str::FromStr}; +use std::{collections::BTreeMap, path::Path, str::FromStr}; + +use super::aws::{AwsClient, AwsConfig}; #[derive(PartialEq, Eq)] -pub enum WalletSelectionMode { +pub enum SignerSelectionMode { /// Holds the password of forc-wallet instance. ForcWallet(String), + /// Holds ARN of the AWS signer. + AwsSigner(String), Manual, } -fn prompt_address() -> Result { - print!("Please provide the address of the wallet you are going to sign this transaction with:"); - std::io::stdout().flush()?; - let mut buf = String::new(); - std::io::stdin().read_line(&mut buf)?; - Bech32Address::from_str(buf.trim()).map_err(Error::msg) -} - -fn prompt_signature(tx_id: fuel_tx::Bytes32) -> Result { - println!("Transaction id to sign: {tx_id}"); - print!("Please provide the signature:"); - std::io::stdout().flush()?; - let mut buf = String::new(); - std::io::stdin().read_line(&mut buf)?; - Signature::from_str(buf.trim()).map_err(Error::msg) -} - fn ask_user_yes_no_question(question: &str) -> Result { let answer = Confirm::with_theme(&ColorfulTheme::default()) .with_prompt(question) @@ -121,13 +103,6 @@ pub(crate) fn secret_key_from_forc_wallet( Ok(secret_key) } -pub(crate) fn bech32_from_secret(secret_key: &SecretKey) -> Result { - let public_key = PublicKey::from(secret_key); - let hashed = public_key.hash(); - let bech32 = Bech32Address::new(FUEL_BECH32_HRP, hashed); - Ok(bech32) -} - pub(crate) fn select_manual_secret_key( default_signer: bool, signing_key: Option, @@ -180,16 +155,16 @@ pub fn format_base_asset_account_balances( } // TODO: Simplify the function signature once https://github.com/FuelLabs/sway/issues/6071 is closed. -pub(crate) async fn select_secret_key( - wallet_mode: &WalletSelectionMode, +pub(crate) async fn select_account( + wallet_mode: &SignerSelectionMode, default_sign: bool, signing_key: Option, provider: &Provider, tx_count: usize, -) -> Result> { +) -> Result { let chain_info = provider.chain_info().await?; - let signing_key = match wallet_mode { - WalletSelectionMode::ForcWallet(password) => { + match wallet_mode { + SignerSelectionMode::ForcWallet(password) => { let wallet_path = default_wallet_path(); check_and_create_wallet_at_default_path(&wallet_path)?; // TODO: This is a very simple TUI, we should consider adding a nice TUI @@ -249,24 +224,34 @@ pub(crate) async fn select_secret_key( anyhow::bail!("User refused to sign"); } - Some(secret_key) + let wallet = WalletUnlocked::new_from_private_key(secret_key, Some(provider.clone())); + Ok(ForcClientAccount::Wallet(wallet)) + } + SignerSelectionMode::Manual => { + let secret_key = select_manual_secret_key(default_sign, signing_key) + .ok_or_else(|| anyhow::anyhow!("missing manual secret key"))?; + let wallet = WalletUnlocked::new_from_private_key(secret_key, Some(provider.clone())); + Ok(ForcClientAccount::Wallet(wallet)) } - WalletSelectionMode::Manual => select_manual_secret_key(default_sign, signing_key), - }; - Ok(signing_key) + SignerSelectionMode::AwsSigner(arn) => { + let aws_config = AwsConfig::from_env().await; + let aws_client = AwsClient::new(aws_config); + let aws_signer = AwsSigner::new(aws_client, arn.clone(), provider.clone()).await?; + + let account = ForcClientAccount::KmsSigner(aws_signer); + Ok(account) + } + } } pub async fn update_proxy_contract_target( - provider: &Provider, - secret_key: SecretKey, + account: &ForcClientAccount, proxy_contract_id: ContractId, new_target: ContractId, ) -> Result> { abigen!(Contract(name = "ProxyContract", abi = "{\"programType\":\"contract\",\"specVersion\":\"1\",\"encodingVersion\":\"1\",\"concreteTypes\":[{\"type\":\"()\",\"concreteTypeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"},{\"type\":\"enum standards::src5::AccessError\",\"concreteTypeId\":\"3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d\",\"metadataTypeId\":1},{\"type\":\"enum standards::src5::State\",\"concreteTypeId\":\"192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c\",\"metadataTypeId\":2},{\"type\":\"enum std::option::Option\",\"concreteTypeId\":\"0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8\",\"metadataTypeId\":4,\"typeArguments\":[\"29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54\"]},{\"type\":\"enum sway_libs::ownership::errors::InitializationError\",\"concreteTypeId\":\"1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893\",\"metadataTypeId\":5},{\"type\":\"enum sway_libs::upgradability::errors::SetProxyOwnerError\",\"concreteTypeId\":\"3c6e90ae504df6aad8b34a93ba77dc62623e00b777eecacfa034a8ac6e890c74\",\"metadataTypeId\":6},{\"type\":\"str\",\"concreteTypeId\":\"8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a\"},{\"type\":\"struct std::contract_id::ContractId\",\"concreteTypeId\":\"29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54\",\"metadataTypeId\":9},{\"type\":\"struct sway_libs::upgradability::events::ProxyOwnerSet\",\"concreteTypeId\":\"96dd838b44f99d8ccae2a7948137ab6256c48ca4abc6168abc880de07fba7247\",\"metadataTypeId\":10},{\"type\":\"struct sway_libs::upgradability::events::ProxyTargetSet\",\"concreteTypeId\":\"1ddc0adda1270a016c08ffd614f29f599b4725407c8954c8b960bdf651a9a6c8\",\"metadataTypeId\":11}],\"metadataTypes\":[{\"type\":\"b256\",\"metadataTypeId\":0},{\"type\":\"enum standards::src5::AccessError\",\"metadataTypeId\":1,\"components\":[{\"name\":\"NotOwner\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"}]},{\"type\":\"enum standards::src5::State\",\"metadataTypeId\":2,\"components\":[{\"name\":\"Uninitialized\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"},{\"name\":\"Initialized\",\"typeId\":3},{\"name\":\"Revoked\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"}]},{\"type\":\"enum std::identity::Identity\",\"metadataTypeId\":3,\"components\":[{\"name\":\"Address\",\"typeId\":8},{\"name\":\"ContractId\",\"typeId\":9}]},{\"type\":\"enum std::option::Option\",\"metadataTypeId\":4,\"components\":[{\"name\":\"None\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"},{\"name\":\"Some\",\"typeId\":7}],\"typeParameters\":[7]},{\"type\":\"enum sway_libs::ownership::errors::InitializationError\",\"metadataTypeId\":5,\"components\":[{\"name\":\"CannotReinitialized\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"}]},{\"type\":\"enum sway_libs::upgradability::errors::SetProxyOwnerError\",\"metadataTypeId\":6,\"components\":[{\"name\":\"CannotUninitialize\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"}]},{\"type\":\"generic T\",\"metadataTypeId\":7},{\"type\":\"struct std::address::Address\",\"metadataTypeId\":8,\"components\":[{\"name\":\"bits\",\"typeId\":0}]},{\"type\":\"struct std::contract_id::ContractId\",\"metadataTypeId\":9,\"components\":[{\"name\":\"bits\",\"typeId\":0}]},{\"type\":\"struct sway_libs::upgradability::events::ProxyOwnerSet\",\"metadataTypeId\":10,\"components\":[{\"name\":\"new_proxy_owner\",\"typeId\":2}]},{\"type\":\"struct sway_libs::upgradability::events::ProxyTargetSet\",\"metadataTypeId\":11,\"components\":[{\"name\":\"new_target\",\"typeId\":9}]}],\"functions\":[{\"inputs\":[],\"name\":\"proxy_target\",\"output\":\"0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Returns the target contract of the proxy contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Returns\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * [Option] - The new proxy contract to which all fallback calls will be passed or `None`.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Reads: `1`\"]},{\"name\":\"storage\",\"arguments\":[\"read\"]}]},{\"inputs\":[{\"name\":\"new_target\",\"concreteTypeId\":\"29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54\"}],\"name\":\"set_proxy_target\",\"output\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Change the target contract of the proxy contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Additional Information\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This method can only be called by the `proxy_owner`.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Arguments\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * `new_target`: [ContractId] - The new proxy contract to which all fallback calls will be passed.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Reverts\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * When not called by `proxy_owner`.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Reads: `1`\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Write: `1`\"]},{\"name\":\"storage\",\"arguments\":[\"read\",\"write\"]}]},{\"inputs\":[],\"name\":\"proxy_owner\",\"output\":\"192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Returns the owner of the proxy contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Returns\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * [State] - Represents the state of ownership for this contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Reads: `1`\"]},{\"name\":\"storage\",\"arguments\":[\"read\"]}]},{\"inputs\":[],\"name\":\"initialize_proxy\",\"output\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Initializes the proxy contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Additional Information\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This method sets the storage values using the values of the configurable constants `INITIAL_TARGET` and `INITIAL_OWNER`.\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This then allows methods that write to storage to be called.\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This method can only be called once.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Reverts\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * When `storage::SRC14.proxy_owner` is not [State::Uninitialized].\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Writes: `2`\"]},{\"name\":\"storage\",\"arguments\":[\"write\"]}]},{\"inputs\":[{\"name\":\"new_proxy_owner\",\"concreteTypeId\":\"192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c\"}],\"name\":\"set_proxy_owner\",\"output\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Changes proxy ownership to the passed State.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Additional Information\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This method can be used to transfer ownership between Identities or to revoke ownership.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Arguments\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * `new_proxy_owner`: [State] - The new state of the proxy ownership.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Reverts\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * When the sender is not the current proxy owner.\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * When the new state of the proxy ownership is [State::Uninitialized].\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Reads: `1`\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Writes: `1`\"]},{\"name\":\"storage\",\"arguments\":[\"write\"]}]}],\"loggedTypes\":[{\"logId\":\"4571204900286667806\",\"concreteTypeId\":\"3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d\"},{\"logId\":\"2151606668983994881\",\"concreteTypeId\":\"1ddc0adda1270a016c08ffd614f29f599b4725407c8954c8b960bdf651a9a6c8\"},{\"logId\":\"2161305517876418151\",\"concreteTypeId\":\"1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893\"},{\"logId\":\"4354576968059844266\",\"concreteTypeId\":\"3c6e90ae504df6aad8b34a93ba77dc62623e00b777eecacfa034a8ac6e890c74\"},{\"logId\":\"10870989709723147660\",\"concreteTypeId\":\"96dd838b44f99d8ccae2a7948137ab6256c48ca4abc6168abc880de07fba7247\"},{\"logId\":\"10098701174489624218\",\"concreteTypeId\":\"8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a\"}],\"messagesTypes\":[],\"configurables\":[{\"name\":\"INITIAL_TARGET\",\"concreteTypeId\":\"0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8\",\"offset\":13368},{\"name\":\"INITIAL_OWNER\",\"concreteTypeId\":\"192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c\",\"offset\":13320}]}",)); - let wallet = WalletUnlocked::new_from_private_key(secret_key, Some(provider.clone())); - - let proxy_contract = ProxyContract::new(proxy_contract_id, wallet); + let proxy_contract = ProxyContract::new(proxy_contract_id, account.clone()); let result = proxy_contract .methods() @@ -280,158 +265,11 @@ pub async fn update_proxy_contract_target( Ok(result) } -#[async_trait] -pub trait TransactionBuilderExt { - fn add_contract(&mut self, contract_id: ContractId) -> &mut Self; - fn add_contracts(&mut self, contract_ids: Vec) -> &mut Self; - fn add_inputs(&mut self, inputs: Vec) -> &mut Self; - async fn fund( - &mut self, - address: Address, - provider: Provider, - signature_witness_index: u16, - ) -> Result<&mut Self>; - async fn finalize_signed( - &mut self, - client: Provider, - default_signature: bool, - signing_key: Option, - wallet_mode: &WalletSelectionMode, - ) -> Result; -} - -#[async_trait] -impl TransactionBuilderExt for TransactionBuilder { - fn add_contract(&mut self, contract_id: ContractId) -> &mut Self { - let input_index = self - .inputs() - .len() - .try_into() - .expect("limit of 256 inputs exceeded"); - self.add_input(fuel_tx::Input::contract( - fuel_tx::UtxoId::new(fuel_tx::Bytes32::zeroed(), 0), - fuel_tx::Bytes32::zeroed(), - fuel_tx::Bytes32::zeroed(), - fuel_tx::TxPointer::new(0u32.into(), 0), - contract_id, - )) - .add_output(fuel_tx::Output::Contract( - fuel_tx::output::contract::Contract { - input_index, - balance_root: fuel_tx::Bytes32::zeroed(), - state_root: fuel_tx::Bytes32::zeroed(), - }, - )) - } - fn add_contracts(&mut self, contract_ids: Vec) -> &mut Self { - for contract_id in contract_ids { - self.add_contract(contract_id); - } - self - } - fn add_inputs(&mut self, inputs: Vec) -> &mut Self { - for input in inputs { - self.add_input(input); - } - self - } - async fn fund( - &mut self, - address: Address, - provider: Provider, - signature_witness_index: u16, - ) -> Result<&mut Self> { - let asset_id = *provider.base_asset_id(); - let wallet = Wallet::from_address(Bech32Address::from(address), Some(provider)); - - let amount = 1_000_000; - let filter = None; - let inputs: Vec<_> = wallet - .get_spendable_resources(asset_id, amount, filter) - .await? - .into_iter() - .map(|coin_type| match coin_type { - CoinType::Coin(coin) => create_coin_input(coin, signature_witness_index), - CoinType::Message(message) => { - create_coin_message_input(message, signature_witness_index) - } - }) - .collect(); - let output = Output::change(wallet.address().into(), 0, asset_id); - - self.add_inputs(inputs).add_output(output); - - Ok(self) - } - async fn finalize_signed( - &mut self, - provider: Provider, - default_sign: bool, - signing_key: Option, - wallet_mode: &WalletSelectionMode, - ) -> Result { - let chain_info = provider.chain_info().await?; - let params = chain_info.consensus_parameters; - let signing_key = - select_secret_key(wallet_mode, default_sign, signing_key, &provider, 1).await?; - // Get the address - let address = if let Some(key) = signing_key { - Address::from(*key.public_key().hash()) - } else { - // TODO: Remove this path https://github.com/FuelLabs/sway/issues/6071 - Address::from(prompt_address()?) - }; - - // Insert dummy witness for signature - let signature_witness_index = self.witnesses().len().try_into()?; - self.add_witness(Witness::default()); - - // Add input coin and output change - self.fund( - address, - provider, - signature_witness_index, - ) - .await.map_err(|e| if e.to_string().contains("not enough coins to fit the target") { - anyhow::anyhow!("Deployment failed due to insufficient funds. Please be sure to have enough coins to pay for deployment transaction.") - } else { - e - })?; - - let mut tx = self.finalize_without_signature_inner(); - - let signature = if let Some(signing_key) = signing_key { - let message = Message::from_bytes(*tx.id(¶ms.chain_id())); - Signature::sign(&signing_key, &message) - } else { - prompt_signature(tx.id(¶ms.chain_id()))? - }; - - let witness = Witness::from(signature.as_ref()); - tx.replace_witness(signature_witness_index, witness); - tx.precompute(¶ms.chain_id()) - .map_err(anyhow::Error::msg)?; - - Ok(tx) - } -} - -pub trait TransactionExt { - fn replace_witness(&mut self, witness_index: u16, witness: Witness) -> &mut Self; -} - -impl TransactionExt for T { - fn replace_witness(&mut self, index: u16, witness: Witness) -> &mut Self { - self.witnesses_mut()[index as usize] = witness; - self - } -} - #[cfg(test)] mod tests { use super::*; - use std::collections::BTreeMap; - use std::collections::HashMap; + use fuels::types::bech32::Bech32Address; + use std::collections::{BTreeMap, HashMap}; #[test] fn test_format_base_asset_account_balances() { diff --git a/forc-plugins/forc-client/tests/deploy.rs b/forc-plugins/forc-client/tests/deploy.rs index 0a31fb91ccb..9457bd6815c 100644 --- a/forc-plugins/forc-client/tests/deploy.rs +++ b/forc-plugins/forc-client/tests/deploy.rs @@ -2,7 +2,7 @@ use forc::cli::shared::Pkg; use forc_client::{ cmd, op::{deploy, DeployedContract}, - util::tx::update_proxy_contract_target, + util::{account::ForcClientAccount, tx::update_proxy_contract_target}, NodeTarget, }; use forc_pkg::manifest::Proxy; @@ -597,16 +597,13 @@ async fn test_non_owner_fails_to_set_target() { let dummy_contract_id_target = ContractId::default(); abigen!(Contract(name = "ProxyContract", abi = "{\"programType\":\"contract\",\"specVersion\":\"1\",\"encodingVersion\":\"1\",\"concreteTypes\":[{\"type\":\"()\",\"concreteTypeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"},{\"type\":\"enum standards::src5::AccessError\",\"concreteTypeId\":\"3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d\",\"metadataTypeId\":1},{\"type\":\"enum standards::src5::State\",\"concreteTypeId\":\"192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c\",\"metadataTypeId\":2},{\"type\":\"enum std::option::Option\",\"concreteTypeId\":\"0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8\",\"metadataTypeId\":4,\"typeArguments\":[\"29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54\"]},{\"type\":\"enum sway_libs::ownership::errors::InitializationError\",\"concreteTypeId\":\"1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893\",\"metadataTypeId\":5},{\"type\":\"enum sway_libs::upgradability::errors::SetProxyOwnerError\",\"concreteTypeId\":\"3c6e90ae504df6aad8b34a93ba77dc62623e00b777eecacfa034a8ac6e890c74\",\"metadataTypeId\":6},{\"type\":\"str\",\"concreteTypeId\":\"8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a\"},{\"type\":\"struct std::contract_id::ContractId\",\"concreteTypeId\":\"29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54\",\"metadataTypeId\":9},{\"type\":\"struct sway_libs::upgradability::events::ProxyOwnerSet\",\"concreteTypeId\":\"96dd838b44f99d8ccae2a7948137ab6256c48ca4abc6168abc880de07fba7247\",\"metadataTypeId\":10},{\"type\":\"struct sway_libs::upgradability::events::ProxyTargetSet\",\"concreteTypeId\":\"1ddc0adda1270a016c08ffd614f29f599b4725407c8954c8b960bdf651a9a6c8\",\"metadataTypeId\":11}],\"metadataTypes\":[{\"type\":\"b256\",\"metadataTypeId\":0},{\"type\":\"enum standards::src5::AccessError\",\"metadataTypeId\":1,\"components\":[{\"name\":\"NotOwner\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"}]},{\"type\":\"enum standards::src5::State\",\"metadataTypeId\":2,\"components\":[{\"name\":\"Uninitialized\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"},{\"name\":\"Initialized\",\"typeId\":3},{\"name\":\"Revoked\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"}]},{\"type\":\"enum std::identity::Identity\",\"metadataTypeId\":3,\"components\":[{\"name\":\"Address\",\"typeId\":8},{\"name\":\"ContractId\",\"typeId\":9}]},{\"type\":\"enum std::option::Option\",\"metadataTypeId\":4,\"components\":[{\"name\":\"None\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"},{\"name\":\"Some\",\"typeId\":7}],\"typeParameters\":[7]},{\"type\":\"enum sway_libs::ownership::errors::InitializationError\",\"metadataTypeId\":5,\"components\":[{\"name\":\"CannotReinitialized\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"}]},{\"type\":\"enum sway_libs::upgradability::errors::SetProxyOwnerError\",\"metadataTypeId\":6,\"components\":[{\"name\":\"CannotUninitialize\",\"typeId\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\"}]},{\"type\":\"generic T\",\"metadataTypeId\":7},{\"type\":\"struct std::address::Address\",\"metadataTypeId\":8,\"components\":[{\"name\":\"bits\",\"typeId\":0}]},{\"type\":\"struct std::contract_id::ContractId\",\"metadataTypeId\":9,\"components\":[{\"name\":\"bits\",\"typeId\":0}]},{\"type\":\"struct sway_libs::upgradability::events::ProxyOwnerSet\",\"metadataTypeId\":10,\"components\":[{\"name\":\"new_proxy_owner\",\"typeId\":2}]},{\"type\":\"struct sway_libs::upgradability::events::ProxyTargetSet\",\"metadataTypeId\":11,\"components\":[{\"name\":\"new_target\",\"typeId\":9}]}],\"functions\":[{\"inputs\":[],\"name\":\"proxy_target\",\"output\":\"0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Returns the target contract of the proxy contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Returns\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * [Option] - The new proxy contract to which all fallback calls will be passed or `None`.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Reads: `1`\"]},{\"name\":\"storage\",\"arguments\":[\"read\"]}]},{\"inputs\":[{\"name\":\"new_target\",\"concreteTypeId\":\"29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54\"}],\"name\":\"set_proxy_target\",\"output\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Change the target contract of the proxy contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Additional Information\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This method can only be called by the `proxy_owner`.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Arguments\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * `new_target`: [ContractId] - The new proxy contract to which all fallback calls will be passed.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Reverts\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * When not called by `proxy_owner`.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Reads: `1`\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Write: `1`\"]},{\"name\":\"storage\",\"arguments\":[\"read\",\"write\"]}]},{\"inputs\":[],\"name\":\"proxy_owner\",\"output\":\"192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Returns the owner of the proxy contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Returns\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * [State] - Represents the state of ownership for this contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Reads: `1`\"]},{\"name\":\"storage\",\"arguments\":[\"read\"]}]},{\"inputs\":[],\"name\":\"initialize_proxy\",\"output\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Initializes the proxy contract.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Additional Information\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This method sets the storage values using the values of the configurable constants `INITIAL_TARGET` and `INITIAL_OWNER`.\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This then allows methods that write to storage to be called.\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This method can only be called once.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Reverts\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * When `storage::SRC14.proxy_owner` is not [State::Uninitialized].\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Writes: `2`\"]},{\"name\":\"storage\",\"arguments\":[\"write\"]}]},{\"inputs\":[{\"name\":\"new_proxy_owner\",\"concreteTypeId\":\"192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c\"}],\"name\":\"set_proxy_owner\",\"output\":\"2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d\",\"attributes\":[{\"name\":\"doc-comment\",\"arguments\":[\" Changes proxy ownership to the passed State.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Additional Information\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" This method can be used to transfer ownership between Identities or to revoke ownership.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Arguments\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * `new_proxy_owner`: [State] - The new state of the proxy ownership.\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Reverts\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * When the sender is not the current proxy owner.\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * When the new state of the proxy ownership is [State::Uninitialized].\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" # Number of Storage Accesses\"]},{\"name\":\"doc-comment\",\"arguments\":[\"\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Reads: `1`\"]},{\"name\":\"doc-comment\",\"arguments\":[\" * Writes: `1`\"]},{\"name\":\"storage\",\"arguments\":[\"write\"]}]}],\"loggedTypes\":[{\"logId\":\"4571204900286667806\",\"concreteTypeId\":\"3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d\"},{\"logId\":\"2151606668983994881\",\"concreteTypeId\":\"1ddc0adda1270a016c08ffd614f29f599b4725407c8954c8b960bdf651a9a6c8\"},{\"logId\":\"2161305517876418151\",\"concreteTypeId\":\"1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893\"},{\"logId\":\"4354576968059844266\",\"concreteTypeId\":\"3c6e90ae504df6aad8b34a93ba77dc62623e00b777eecacfa034a8ac6e890c74\"},{\"logId\":\"10870989709723147660\",\"concreteTypeId\":\"96dd838b44f99d8ccae2a7948137ab6256c48ca4abc6168abc880de07fba7247\"},{\"logId\":\"10098701174489624218\",\"concreteTypeId\":\"8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a\"}],\"messagesTypes\":[],\"configurables\":[{\"name\":\"INITIAL_TARGET\",\"concreteTypeId\":\"0d79387ad3bacdc3b7aad9da3a96f4ce60d9a1b6002df254069ad95a3931d5c8\",\"offset\":13368},{\"name\":\"INITIAL_OWNER\",\"concreteTypeId\":\"192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c\",\"offset\":13320}]}",)); + let wallet = WalletUnlocked::new_from_private_key(attacker_secret_key, Some(provider.clone())); + let attacker_account = ForcClientAccount::Wallet(wallet); // Try to change target of the proxy with a random wallet which is not the owner of the proxy. - let res = update_proxy_contract_target( - &provider, - attacker_secret_key, - proxy_id, - dummy_contract_id_target, - ) - .await - .err() - .unwrap(); + let res = update_proxy_contract_target(&attacker_account, proxy_id, dummy_contract_id_target) + .await + .err() + .unwrap(); node.kill().unwrap(); assert!(res From 7ee092dcf3caf49027e50b43d0deaaa306703c89 Mon Sep 17 00:00:00 2001 From: Joshua Batty Date: Wed, 25 Sep 2024 23:44:04 +1000 Subject: [PATCH 038/115] chore: bump to v0.64.0 (#6584) ## Description ~~waiting on #6578~~ This release contains no API changes and along with bug fixes, upgrades support for fuel-core to 0.36 and fuels SDK to 0.66.5. --- Cargo.lock | 68 +++++++++++++++++++++++++++--------------------------- Cargo.toml | 2 +- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 495478e3d1f..b0c7e8122fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2678,7 +2678,7 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "forc" -version = "0.63.6" +version = "0.64.0" dependencies = [ "annotate-snippets", "ansi_term", @@ -2689,7 +2689,7 @@ dependencies = [ "completest-pty", "forc-pkg", "forc-test", - "forc-tracing 0.63.6", + "forc-tracing 0.64.0", "forc-util", "fs_extra", "fuel-asm", @@ -2715,7 +2715,7 @@ dependencies = [ [[package]] name = "forc-client" -version = "0.63.6" +version = "0.64.0" dependencies = [ "anyhow", "async-trait", @@ -2727,7 +2727,7 @@ dependencies = [ "dialoguer", "forc", "forc-pkg", - "forc-tracing 0.63.6", + "forc-tracing 0.64.0", "forc-tx", "forc-util", "forc-wallet", @@ -2761,13 +2761,13 @@ dependencies = [ [[package]] name = "forc-crypto" -version = "0.63.6" +version = "0.64.0" dependencies = [ "anyhow", "async-trait", "atty", "clap 4.5.16", - "forc-tracing 0.63.6", + "forc-tracing 0.64.0", "forc-util", "fuel-core-types", "fuel-crypto", @@ -2787,7 +2787,7 @@ dependencies = [ [[package]] name = "forc-debug" -version = "0.63.6" +version = "0.64.0" dependencies = [ "anyhow", "clap 4.5.16", @@ -2795,7 +2795,7 @@ dependencies = [ "escargot", "forc-pkg", "forc-test", - "forc-tracing 0.63.6", + "forc-tracing 0.64.0", "fuel-core-client", "fuel-types", "fuel-vm", @@ -2813,7 +2813,7 @@ dependencies = [ [[package]] name = "forc-doc" -version = "0.63.6" +version = "0.64.0" dependencies = [ "anyhow", "clap 4.5.16", @@ -2821,7 +2821,7 @@ dependencies = [ "dir_indexer", "expect-test", "forc-pkg", - "forc-tracing 0.63.6", + "forc-tracing 0.64.0", "forc-util", "horrorshow", "include_dir", @@ -2838,12 +2838,12 @@ dependencies = [ [[package]] name = "forc-fmt" -version = "0.63.6" +version = "0.64.0" dependencies = [ "anyhow", "clap 4.5.16", "forc-pkg", - "forc-tracing 0.63.6", + "forc-tracing 0.64.0", "forc-util", "prettydiff 0.7.0", "sway-core", @@ -2855,7 +2855,7 @@ dependencies = [ [[package]] name = "forc-lsp" -version = "0.63.6" +version = "0.64.0" dependencies = [ "anyhow", "clap 4.5.16", @@ -2866,13 +2866,13 @@ dependencies = [ [[package]] name = "forc-pkg" -version = "0.63.6" +version = "0.64.0" dependencies = [ "ansi_term", "anyhow", "byte-unit", "cid", - "forc-tracing 0.63.6", + "forc-tracing 0.64.0", "forc-util", "fuel-abi-types", "futures", @@ -2903,7 +2903,7 @@ dependencies = [ [[package]] name = "forc-test" -version = "0.63.6" +version = "0.64.0" dependencies = [ "anyhow", "forc-pkg", @@ -2930,7 +2930,7 @@ dependencies = [ [[package]] name = "forc-tracing" -version = "0.63.6" +version = "0.64.0" dependencies = [ "ansi_term", "tracing", @@ -2940,7 +2940,7 @@ dependencies = [ [[package]] name = "forc-tx" -version = "0.63.6" +version = "0.64.0" dependencies = [ "anyhow", "clap 4.5.16", @@ -2955,7 +2955,7 @@ dependencies = [ [[package]] name = "forc-util" -version = "0.63.6" +version = "0.64.0" dependencies = [ "annotate-snippets", "ansi_term", @@ -2963,7 +2963,7 @@ dependencies = [ "clap 4.5.16", "dirs 5.0.1", "fd-lock", - "forc-tracing 0.63.6", + "forc-tracing 0.64.0", "fuel-tx", "hex", "paste", @@ -7642,7 +7642,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sway-ast" -version = "0.63.6" +version = "0.64.0" dependencies = [ "extension-trait", "num-bigint", @@ -7654,7 +7654,7 @@ dependencies = [ [[package]] name = "sway-core" -version = "0.63.6" +version = "0.64.0" dependencies = [ "clap 4.5.16", "derivative", @@ -7699,7 +7699,7 @@ dependencies = [ [[package]] name = "sway-error" -version = "0.63.6" +version = "0.64.0" dependencies = [ "either", "in_definite", @@ -7713,7 +7713,7 @@ dependencies = [ [[package]] name = "sway-ir" -version = "0.63.6" +version = "0.64.0" dependencies = [ "anyhow", "downcast-rs", @@ -7732,7 +7732,7 @@ dependencies = [ [[package]] name = "sway-ir-macros" -version = "0.63.6" +version = "0.64.0" dependencies = [ "itertools 0.13.0", "proc-macro2", @@ -7742,7 +7742,7 @@ dependencies = [ [[package]] name = "sway-lsp" -version = "0.63.6" +version = "0.64.0" dependencies = [ "anyhow", "assert-json-diff", @@ -7753,7 +7753,7 @@ dependencies = [ "dirs 4.0.0", "fd-lock", "forc-pkg", - "forc-tracing 0.63.6", + "forc-tracing 0.64.0", "forc-util", "futures", "indexmap 2.5.0", @@ -7792,7 +7792,7 @@ dependencies = [ [[package]] name = "sway-lsp-test-utils" -version = "0.63.6" +version = "0.64.0" dependencies = [ "assert-json-diff", "futures", @@ -7807,7 +7807,7 @@ dependencies = [ [[package]] name = "sway-parse" -version = "0.63.6" +version = "0.64.0" dependencies = [ "assert_matches", "extension-trait", @@ -7825,7 +7825,7 @@ dependencies = [ [[package]] name = "sway-types" -version = "0.63.6" +version = "0.64.0" dependencies = [ "bytecount", "fuel-asm", @@ -7844,7 +7844,7 @@ dependencies = [ [[package]] name = "sway-utils" -version = "0.63.6" +version = "0.64.0" dependencies = [ "serde", "walkdir", @@ -7852,11 +7852,11 @@ dependencies = [ [[package]] name = "swayfmt" -version = "0.63.6" +version = "0.64.0" dependencies = [ "anyhow", "difference", - "forc-tracing 0.63.6", + "forc-tracing 0.64.0", "indoc", "paste", "prettydiff 0.6.4", @@ -8140,7 +8140,7 @@ dependencies = [ "forc-client", "forc-pkg", "forc-test", - "forc-tracing 0.63.6", + "forc-tracing 0.64.0", "fuel-vm", "futures", "gag", diff --git a/Cargo.toml b/Cargo.toml index 0ecc97ccb14..ad00532b0bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ exclude = [ [workspace.package] edition = "2021" -version = "0.63.6" +version = "0.64.0" authors = ["Fuel Labs "] homepage = "https://fuel.network/" license = "Apache-2.0" From ed58e1e8bdfea8ae10c90498ca9f5f98553491af Mon Sep 17 00:00:00 2001 From: IGI-111 Date: Wed, 25 Sep 2024 16:35:15 +0200 Subject: [PATCH 039/115] Fix verify_tag.sh script to use workspace version (#6587) ## Description Update CI script to work with https://github.com/FuelLabs/sway/commit/ab1e030f984768f8e85531cb7d121dce79b1ef5b ## 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. --- .github/workflows/ci.yml | 23 +---------------------- .github/workflows/scripts/verify_tag.sh | 2 +- 2 files changed, 2 insertions(+), 23 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 786a6cebbbd..2178ed40bb1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -643,28 +643,7 @@ jobs: - name: Verify tag version run: | cargo install toml-cli - ./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} forc/Cargo.toml - ./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} forc-pkg/Cargo.toml - ./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} forc-plugins/forc-client/Cargo.toml - ./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} forc-plugins/forc-debug/Cargo.toml - ./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} forc-plugins/forc-doc/Cargo.toml - ./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} forc-plugins/forc-fmt/Cargo.toml - ./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} forc-plugins/forc-lsp/Cargo.toml - ./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} forc-plugins/forc-tx/Cargo.toml - ./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} forc-plugins/forc-crypto/Cargo.toml - ./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} forc-test/Cargo.toml - ./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} forc-tracing/Cargo.toml - ./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} forc-util/Cargo.toml - ./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} sway-ast/Cargo.toml - ./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} sway-core/Cargo.toml - ./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} sway-error/Cargo.toml - ./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} sway-ir/Cargo.toml - ./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} sway-ir/sway-ir-macros/Cargo.toml - ./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} sway-lsp/Cargo.toml - ./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} sway-parse/Cargo.toml - ./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} sway-types/Cargo.toml - ./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} sway-utils/Cargo.toml - ./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} swayfmt/Cargo.toml + ./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} Cargo.toml - name: Notify if Job Fails uses: ravsamhq/notify-slack-action@v2 diff --git a/.github/workflows/scripts/verify_tag.sh b/.github/workflows/scripts/verify_tag.sh index e029f651988..b833ffce74f 100755 --- a/.github/workflows/scripts/verify_tag.sh +++ b/.github/workflows/scripts/verify_tag.sh @@ -25,7 +25,7 @@ fi # strip preceeding 'v' if it exists on tag REF=${REF/#v} -TOML_VERSION=$(toml get $MANIFEST package.version | tr -d '"') +TOML_VERSION=$(toml get $MANIFEST workspace.package.version | tr -d '"') if [ "$TOML_VERSION" != "$REF" ]; then err "Crate version $TOML_VERSION, doesn't match tag version $REF" From 2156bfbbee01ffb85bfca2aae8f185f8e7c715a4 Mon Sep 17 00:00:00 2001 From: Sophie Dankel <47993817+sdankel@users.noreply.github.com> Date: Wed, 25 Sep 2024 15:18:01 -0700 Subject: [PATCH 040/115] ci: add versions to cargo workspace (#6588) ## Description This should [unblock](https://github.com/FuelLabs/sway/actions/runs/11035362451/job/30652169645#step:4:22) releases. [Cargo doesn't use the workspace version for path dependencies](https://github.com/rust-lang/cargo/issues/11133), so we still have to specify the versions. This is also how it's done in [fuel-core](https://github.com/FuelLabs/fuel-core/blob/master/Cargo.toml). This is actually nice because it means we could in the future bump the versions of the dependencies separately, all from within the one file. ## Checklist - [ ] 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. - [ ] 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). - [ ] I have requested a review from the relevant team or maintainers. --- Cargo.toml | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ad00532b0bc..bf11ce66ef7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,34 +45,34 @@ repository = "https://github.com/FuelLabs/sway" # Internal dependencies in order to propagate `workspace.version` # -forc = { path = "forc/" } -forc-pkg = { path = "forc-pkg/" } -forc-test = { path = "forc-test/" } -forc-tracing = { path = "forc-tracing/" } -forc-util = { path = "forc-util/" } +forc = { path = "forc/", version = "0.64.0" } +forc-pkg = { path = "forc-pkg/", version = "0.64.0" } +forc-test = { path = "forc-test/", version = "0.64.0" } +forc-tracing = { path = "forc-tracing/", version = "0.64.0" } +forc-util = { path = "forc-util/", version = "0.64.0" } # Forc plugins -forc-plugins = { path = "forc-plugins/" } -forc-client = { path = "forc-plugins/forc-client/" } -forc-crypto = { path = "forc-plugins/forc-crypto/" } -forc-debug = { path = "forc-plugins/forc-debug/" } -forc-doc = { path = "forc-plugins/forc-doc/" } -forc-fmt = { path = "forc-plugins/forc-fmt/" } -forc-lsp = { path = "forc-plugins/forc-lsp/" } -forc-tx = { path = "forc-plugins/forc-tx/" } +forc-plugins = { path = "forc-plugins/", version = "0.64.0" } +forc-client = { path = "forc-plugins/forc-client/", version = "0.64.0" } +forc-crypto = { path = "forc-plugins/forc-crypto/", version = "0.64.0" } +forc-debug = { path = "forc-plugins/forc-debug/", version = "0.64.0" } +forc-doc = { path = "forc-plugins/forc-doc/", version = "0.64.0" } +forc-fmt = { path = "forc-plugins/forc-fmt/", version = "0.64.0" } +forc-lsp = { path = "forc-plugins/forc-lsp/", version = "0.64.0" } +forc-tx = { path = "forc-plugins/forc-tx/", version = "0.64.0" } -sway-ast = { path = "sway-ast/" } -sway-core = { path = "sway-core/" } -sway-error = { path = "sway-error/" } -sway-lsp = { path = "sway-lsp/" } -sway-parse = { path = "sway-parse/" } -sway-types = { path = "sway-types/" } -sway-utils = { path = "sway-utils/" } -swayfmt = { path = "swayfmt/" } +sway-ast = { path = "sway-ast/", version = "0.64.0" } +sway-core = { path = "sway-core/", version = "0.64.0" } +sway-error = { path = "sway-error/", version = "0.64.0" } +sway-lsp = { path = "sway-lsp/", version = "0.64.0" } +sway-parse = { path = "sway-parse/", version = "0.64.0" } +sway-types = { path = "sway-types/", version = "0.64.0" } +sway-utils = { path = "sway-utils/", version = "0.64.0" } +swayfmt = { path = "swayfmt/", version = "0.64.0" } # Sway IR -sway-ir = { path = "sway-ir/" } -sway-ir-macros = { path = "sway-ir/sway-ir-macros" } +sway-ir = { path = "sway-ir/", version = "0.64.0" } +sway-ir-macros = { path = "sway-ir/sway-ir-macros", version = "0.64.0" } # # External Fuel dependencies From 6fe4223693d05fdcb6334709c021d96542cb18d7 Mon Sep 17 00:00:00 2001 From: Marcos Henrich Date: Thu, 26 Sep 2024 18:21:13 +0100 Subject: [PATCH 041/115] Proof that #5046 is fixed. (#6583) ## Description The reproduction reported in #5046 is throwing the expected error. Closes #5046. ## 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 --- .../should_fail/missing_hash_trait/Forc.lock | 13 +++++++++++ .../should_fail/missing_hash_trait/Forc.toml | 9 ++++++++ .../missing_hash_trait/src/main.sw | 22 +++++++++++++++++++ .../should_fail/missing_hash_trait/test.toml | 5 +++++ 4 files changed, 49 insertions(+) create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/missing_hash_trait/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/missing_hash_trait/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/missing_hash_trait/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/missing_hash_trait/test.toml diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/missing_hash_trait/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_fail/missing_hash_trait/Forc.lock new file mode 100644 index 00000000000..d0ea2d085b5 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/missing_hash_trait/Forc.lock @@ -0,0 +1,13 @@ +[[package]] +name = "core" +source = "path+from-root-6B977435DD9C5058" + +[[package]] +name = "missing_hash_trait" +source = "member" +dependencies = ["std"] + +[[package]] +name = "std" +source = "path+from-root-6B977435DD9C5058" +dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/missing_hash_trait/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/missing_hash_trait/Forc.toml new file mode 100644 index 00000000000..69067b7baaa --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/missing_hash_trait/Forc.toml @@ -0,0 +1,9 @@ +[project] +authors = ["Fuel Labs "] +license = "Apache-2.0" +name = "missing_hash_trait" +entry = "main.sw" +implicit-std = false + +[dependencies] +std = { path = "../../../../../../sway-lib-std" } \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/missing_hash_trait/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/missing_hash_trait/src/main.sw new file mode 100644 index 00000000000..478ee462af3 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/missing_hash_trait/src/main.sw @@ -0,0 +1,22 @@ +contract; + +struct MyStruct { + val: u64 +} + +abi MyContract { + #[storage(read, write)] + fn test_function(); +} + +storage { + my_map: StorageMap = StorageMap:: {}, +} + +impl MyContract for Contract { + #[storage(read, write)] + fn test_function() { + let my_struct = MyStruct { val: 1 }; + storage.my_map.insert(my_struct, 2) + } +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/missing_hash_trait/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/missing_hash_trait/test.toml new file mode 100644 index 00000000000..50547fb25c4 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/missing_hash_trait/test.toml @@ -0,0 +1,5 @@ +category = "fail" + +# check: $()storage.my_map.insert(my_struct, 2) +# nextln: $()Trait "Hash" is not implemented for type "MyStruct". + From 344f1c55c9eeba281fa68f5c7c2348d24fa6e4bf Mon Sep 17 00:00:00 2001 From: Sophie Dankel <47993817+sdankel@users.noreply.github.com> Date: Thu, 26 Sep 2024 14:04:41 -0700 Subject: [PATCH 042/115] fix: proxy deployments for contracts with storage (#6591) ## Description Fixes an issue where storage access wasn't working for proxied contracts. The fix is passing the combined storage slots to the proxy contract. ## Checklist - [ ] 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. - [ ] 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). - [ ] I have requested a review from the relevant team or maintainers. --- forc-plugins/forc-client/src/op/deploy.rs | 11 +++-- .../test/data/standalone_contract/src/main.sw | 21 +++++++++ .../standalone_contract-abi.json | 36 ++++++++++++++ .../data/standalone_contract_b/.gitignore | 2 - .../test/data/standalone_contract_b/Forc.toml | 9 ---- .../data/standalone_contract_b/src/main.sw | 11 ----- forc-plugins/forc-client/tests/deploy.rs | 47 +++++++++++++++++-- 7 files changed, 108 insertions(+), 29 deletions(-) delete mode 100644 forc-plugins/forc-client/test/data/standalone_contract_b/.gitignore delete mode 100644 forc-plugins/forc-client/test/data/standalone_contract_b/Forc.toml delete mode 100644 forc-plugins/forc-client/test/data/standalone_contract_b/src/main.sw diff --git a/forc-plugins/forc-client/src/op/deploy.rs b/forc-plugins/forc-client/src/op/deploy.rs index e6070e0af85..a5c71a41f79 100644 --- a/forc-plugins/forc-client/src/op/deploy.rs +++ b/forc-plugins/forc-client/src/op/deploy.rs @@ -200,6 +200,7 @@ async fn deploy_chunked( async fn deploy_new_proxy( command: &cmd::Deploy, pkg_name: &str, + pkg_storage_slots: &[StorageSlot], impl_contract: &fuel_tx::ContractId, provider: &Provider, account: &ForcClientAccount, @@ -208,9 +209,11 @@ async fn deploy_new_proxy( let proxy_dir_output = create_proxy_contract(pkg_name)?; let address = account.address(); - let storage_path = proxy_dir_output.join("proxy-storage_slots.json"); - let storage_configuration = - StorageConfiguration::default().add_slot_overrides_from_file(storage_path)?; + // Add the combined storage slots from the original contract and the proxy contract. + let proxy_storage_path = proxy_dir_output.join("proxy-storage_slots.json"); + let storage_configuration = StorageConfiguration::default() + .add_slot_overrides(pkg_storage_slots.iter().cloned()) + .add_slot_overrides_from_file(proxy_storage_path)?; let configurables = ProxyContractConfigurables::default() .with_INITIAL_TARGET(Some(*impl_contract))? @@ -391,10 +394,12 @@ pub async fn deploy(command: cmd::Deploy) -> Result> { address: None, }) => { let pkg_name = &pkg.descriptor.name; + let pkg_storage_slots = &pkg.storage_slots; // Deploy a new proxy contract. let deployed_proxy_contract = deploy_new_proxy( &command, pkg_name, + pkg_storage_slots, &deployed_contract_id, &provider, &account, diff --git a/forc-plugins/forc-client/test/data/standalone_contract/src/main.sw b/forc-plugins/forc-client/test/data/standalone_contract/src/main.sw index 7d4a75493c6..49e0ac20ae2 100644 --- a/forc-plugins/forc-client/test/data/standalone_contract/src/main.sw +++ b/forc-plugins/forc-client/test/data/standalone_contract/src/main.sw @@ -1,11 +1,32 @@ contract; +storage { + value: u8 = 5, +} + abi MyContract { fn test_function() -> bool; + + #[storage(read)] + fn test_function_read() -> u8; + + #[storage(read, write)] + fn test_function_write(value: u8) -> u8; } impl MyContract for Contract { fn test_function() -> bool { true } + + #[storage(read)] + fn test_function_read() -> u8 { + storage.value.read() + } + + #[storage(read, write)] + fn test_function_write(value: u8) -> u8 { + storage.value.write(value); + storage.value.read() + } } diff --git a/forc-plugins/forc-client/test/data/standalone_contract/standalone_contract-abi.json b/forc-plugins/forc-client/test/data/standalone_contract/standalone_contract-abi.json index a2d797817fc..0dfb6f2fad7 100644 --- a/forc-plugins/forc-client/test/data/standalone_contract/standalone_contract-abi.json +++ b/forc-plugins/forc-client/test/data/standalone_contract/standalone_contract-abi.json @@ -6,6 +6,10 @@ { "type": "bool", "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "type": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" } ], "metadataTypes": [], @@ -15,6 +19,38 @@ "name": "test_function", "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", "attributes": null + }, + { + "inputs": [], + "name": "test_function_read", + "output": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "value", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "name": "test_function_write", + "output": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] } ], "loggedTypes": [], diff --git a/forc-plugins/forc-client/test/data/standalone_contract_b/.gitignore b/forc-plugins/forc-client/test/data/standalone_contract_b/.gitignore deleted file mode 100644 index 77d3844f58c..00000000000 --- a/forc-plugins/forc-client/test/data/standalone_contract_b/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/forc-plugins/forc-client/test/data/standalone_contract_b/Forc.toml b/forc-plugins/forc-client/test/data/standalone_contract_b/Forc.toml deleted file mode 100644 index e61b046039b..00000000000 --- a/forc-plugins/forc-client/test/data/standalone_contract_b/Forc.toml +++ /dev/null @@ -1,9 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -implicit-std = false -license = "Apache-2.0" -name = "standalone_contract_b" - -[dependencies] -std = { path = "../../../../../sway-lib-std/" } diff --git a/forc-plugins/forc-client/test/data/standalone_contract_b/src/main.sw b/forc-plugins/forc-client/test/data/standalone_contract_b/src/main.sw deleted file mode 100644 index 7d4a75493c6..00000000000 --- a/forc-plugins/forc-client/test/data/standalone_contract_b/src/main.sw +++ /dev/null @@ -1,11 +0,0 @@ -contract; - -abi MyContract { - fn test_function() -> bool; -} - -impl MyContract for Contract { - fn test_function() -> bool { - true - } -} diff --git a/forc-plugins/forc-client/tests/deploy.rs b/forc-plugins/forc-client/tests/deploy.rs index 9457bd6815c..eb3c8e259a8 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( - "50fe882cbef5f3da6da82509a66b7e5e0a64a40d70164861c01c908a332198ae", + "4ea5fa100cd7c8972bc8925ed6f8ccfb6bf1e16f79c3642c3a503c73b7d18de2", ) .unwrap(), proxy: None, @@ -383,7 +383,7 @@ async fn test_deploy_submit_only() { node.kill().unwrap(); let expected = vec![DeployedContract { id: ContractId::from_str( - "50fe882cbef5f3da6da82509a66b7e5e0a64a40d70164861c01c908a332198ae", + "4ea5fa100cd7c8972bc8925ed6f8ccfb6bf1e16f79c3642c3a503c73b7d18de2", ) .unwrap(), proxy: None, @@ -428,12 +428,12 @@ async fn test_deploy_fresh_proxy() { node.kill().unwrap(); let impl_contract = DeployedContract { id: ContractId::from_str( - "50fe882cbef5f3da6da82509a66b7e5e0a64a40d70164861c01c908a332198ae", + "4ea5fa100cd7c8972bc8925ed6f8ccfb6bf1e16f79c3642c3a503c73b7d18de2", ) .unwrap(), proxy: Some( ContractId::from_str( - "8eae70214f55d25a65608bd288a5863e7187fcf65705143ee1a45fd228dacc19", + "deb633128bceadcd4eb4fe546089f6653727348b60228638a7f9d55d0b6da1ae", ) .unwrap(), ), @@ -491,6 +491,25 @@ async fn test_proxy_contract_re_routes_call() { )); let impl_contract_a = ImplementationContract::new(proxy_contract_id, wallet_unlocked.clone()); + + // Test storage functions + let res = impl_contract_a + .methods() + .test_function_read() + .with_contract_ids(&[impl_contract_id.into()]) + .call() + .await + .unwrap(); + assert_eq!(res.value, 5); + let res = impl_contract_a + .methods() + .test_function_write(8) + .with_contract_ids(&[impl_contract_id.into()]) + .call() + .await + .unwrap(); + assert_eq!(res.value, 8); + let res = impl_contract_a .methods() .test_function() @@ -525,6 +544,26 @@ async fn test_proxy_contract_re_routes_call() { let impl_contract_id_after_update = contract_ids[0].id; assert!(impl_contract_id != impl_contract_id_after_update); let impl_contract_a = ImplementationContract::new(proxy_contract_after_update, wallet_unlocked); + + // Test storage functions + let res = impl_contract_a + .methods() + .test_function_read() + .with_contract_ids(&[impl_contract_id_after_update.into()]) + .call() + .await + .unwrap(); + // Storage should be preserved from the previous target contract. + assert_eq!(res.value, 8); + let res = impl_contract_a + .methods() + .test_function_write(9) + .with_contract_ids(&[impl_contract_id_after_update.into()]) + .call() + .await + .unwrap(); + assert_eq!(res.value, 9); + let res = impl_contract_a .methods() .test_function() From f14af85025b4ba36451b918ce6723740c7986cbe Mon Sep 17 00:00:00 2001 From: Cameron Carstens Date: Sun, 29 Sep 2024 14:01:31 +0545 Subject: [PATCH 043/115] Update single and multi asset example in docs hub (#6594) ## Description The single and multi asset examples in the docs hub do not use the latest versions of the SRC3 and SRC20 standard. This has been updated to follow the specifications. ## 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. --- .../blockchain-development/native_assets.md | 128 ++++++++++++++---- 1 file changed, 99 insertions(+), 29 deletions(-) diff --git a/docs/book/src/blockchain-development/native_assets.md b/docs/book/src/blockchain-development/native_assets.md index 49b1b0bef79..bc589ccda85 100644 --- a/docs/book/src/blockchain-development/native_assets.md +++ b/docs/book/src/blockchain-development/native_assets.md @@ -199,18 +199,27 @@ It implements the [SRC-20; Native Asset](https://github.com/FuelLabs/sway-standa // ERC20 equivalent in Sway. contract; -use src3::SRC3; -use src5::{SRC5, State, AccessError}; -use src20::SRC20; +use standards::{ + src3::SRC3, + src5::{ + SRC5, + State, + AccessError, + }, + src20::{ + SetDecimalsEvent, + SetNameEvent, + SetSymbolEvent, + SRC20, + TotalSupplyEvent, + }, +}; use std::{ asset::{ burn, mint_to, }, - call_frames::{ - contract_id, - msg_asset_id, - }, + call_frames::msg_asset_id, constants::DEFAULT_SUB_ID, context::msg_amount, string::String, @@ -282,14 +291,21 @@ impl SRC5 for Contract { // Mint and Burn Standard impl SRC3 for Contract { #[storage(read, write)] - fn mint(recipient: Identity, sub_id: SubId, amount: u64) { - require(sub_id == DEFAULT_SUB_ID, "incorrect-sub-id"); + fn mint(recipient: Identity, sub_id: Option, amount: u64) { + require(sub_id.is_some() && sub_id.unwrap() == DEFAULT_SUB_ID, "incorrect-sub-id"); require_access_owner(); + let new_supply = storage.total_supply.read() + amount; storage .total_supply - .write(amount + storage.total_supply.read()); + .write(new_supply); mint_to(recipient, DEFAULT_SUB_ID, amount); + + TotalSupplyEvent::new( + AssetId::default(), + new_supply, + msg_sender().unwrap() + ).log(); } #[storage(read, write)] @@ -302,10 +318,17 @@ impl SRC3 for Contract { ); require_access_owner(); + let new_supply = storage.total_supply.read() - amount; storage .total_supply - .write(storage.total_supply.read() - amount); + .write(new_supply); burn(DEFAULT_SUB_ID, amount); + + TotalSupplyEvent::new( + AssetId::default(), + new_supply, + msg_sender().unwrap() + ).log(); } } @@ -329,6 +352,24 @@ fn require_access_owner() { AccessError::NotOwner, ); } + +abi EmitSRC20Events { + fn emit_src20_events(); +} + +impl EmitSRC20Events for Contract { + fn emit_src20_events() { + // Metadata that is stored as a configurable should only be emitted once. + let asset = AssetId::default(); + let sender = msg_sender().unwrap(); + let name = Some(String::from_ascii_str(from_str_array(NAME))); + let symbol = Some(String::from_ascii_str(from_str_array(SYMBOL))); + + SetNameEvent::new(asset, name, sender).log(); + SetSymbolEvent::new(asset, symbol, sender).log(); + SetDecimalsEvent::new(asset, DECIMALS, sender).log(); + } +} ``` ## Multi Native Asset Example @@ -341,18 +382,27 @@ It implements the [SRC-20; Native Asset](https://github.com/FuelLabs/sway-standa // ERC1155 equivalent in Sway. contract; -use src5::{SRC5, State, AccessError}; -use src20::SRC20; -use src3::SRC3; +use standards::{ + src5::{ + SRC5, + State, + AccessError + }, + src20::{ + SetDecimalsEvent, + SetNameEvent, + SetSymbolEvent, + SRC20, + TotalSupplyEvent, + } + src3::SRC3, +}; use std::{ asset::{ burn, mint_to, }, - call_frames::{ - contract_id, - msg_asset_id, - }, + call_frames::msg_asset_id, hash::{ Hash, }, @@ -401,28 +451,42 @@ impl SRC20 for Contract { // Mint and Burn Standard impl SRC3 for Contract { #[storage(read, write)] - fn mint(recipient: Identity, sub_id: SubId, amount: u64) { + fn mint(recipient: Identity, sub_id: Option, amount: u64) { + require(sub_id.is_some(), "Error: SubId is None"); require_access_owner(); - let asset_id = AssetId::new(contract_id(), sub_id); + + let asset_id = AssetId::new(ContractId::this(), sub_id.unwrap()); let supply = storage.total_supply.get(asset_id).try_read(); if supply.is_none() { storage.total_assets.write(storage.total_assets.try_read().unwrap_or(0) + 1); } - let current_supply = supply.unwrap_or(0); - storage.total_supply.insert(asset_id, current_supply + amount); + let new_supply = supply.unwrap_or(0) + amount; + storage.total_supply.insert(asset_id, new_supply); mint_to(recipient, sub_id, amount); + + TotalSupplyEvent::new( + asset_id, + new_supply, + msg_sender().unwrap() + ).log(); } #[storage(read, write)] fn burn(sub_id: SubId, amount: u64) { require_access_owner(); - let asset_id = AssetId::new(contract_id(), sub_id); + let asset_id = AssetId::new(ContractId::this(), sub_id); require(this_balance(asset_id) >= amount, "not-enough-coins"); let supply = storage.total_supply.get(asset_id).try_read(); - let current_supply = supply.unwrap_or(0); - storage.total_supply.insert(asset_id, current_supply - amount); + let new_supply = supply.unwrap_or(0) - amount; + storage.total_supply.insert(asset_id, new_supply); burn(sub_id, amount); + + TotalSupplyEvent::new( + asset_id, + new_supply, + msg_sender().unwrap() + ).log(); } } @@ -431,10 +495,10 @@ abi MultiAsset { fn constructor(owner_: Identity); #[storage(read, write)] - fn set_name(asset: AssetId, name: String); + fn set_name(asset: AssetId, name: Option); #[storage(read, write)] - fn set_symbol(asset: AssetId, symbol: String); + fn set_symbol(asset: AssetId, symbol: Option); #[storage(read, write)] fn set_decimals(asset: AssetId, decimals: u8); @@ -448,23 +512,29 @@ impl MultiAsset for Contract { } #[storage(read, write)] - fn set_name(asset: AssetId, name: String) { + fn set_name(asset: AssetId, name: Option) { require_access_owner(); storage.name.insert(asset, StorageString {}); storage.name.get(asset).write_slice(name); + + SetNameEvent::new(asset, name, msg_sender().unwrap()).log(); } #[storage(read, write)] - fn set_symbol(asset: AssetId, symbol: String) { + fn set_symbol(asset: AssetId, symbol: Option) { require_access_owner(); storage.symbol.insert(asset, StorageString {}); storage.symbol.get(asset).write_slice(symbol); + + SetSymbolEvent::new(asset, symbol, msg_sender().unwrap()).log(); } #[storage(read, write)] fn set_decimals(asset: AssetId, decimals: u8) { require_access_owner(); storage.decimals.insert(asset, decimals); + + SetDecimalsEvent::new(asset, decimals, msg_sender().unwrap()).log(); } } From 6ba98da794fc6389c173f70f93d90ea661e23313 Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite Date: Sun, 29 Sep 2024 11:49:28 +0100 Subject: [PATCH 044/115] fix code snippet for old diagnostics (#6507) ## Description This PR solves a small bug when calculating the code snippets of some diagnostics. ![image](https://github.com/user-attachments/assets/57c792ed-701d-4294-9a1e-bbdcbd524979) ## 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. - [ ] 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 --- forc-util/src/lib.rs | 123 +++++++++++++----- .../array_wrong_elements_types/stdout.snap | 21 +-- .../insufficient_type_info/test.toml | 4 + .../type_check_analyze_errors/stdout.snap | 5 +- 4 files changed, 112 insertions(+), 41 deletions(-) diff --git a/forc-util/src/lib.rs b/forc-util/src/lib.rs index a630f741023..7cf7f45b2b4 100644 --- a/forc-util/src/lib.rs +++ b/forc-util/src/lib.rs @@ -716,43 +716,104 @@ fn construct_window<'a>( let total_lines_of_highlight = end.line - start.line; debug_assert!(total_lines_in_input >= total_lines_of_highlight); - let mut current_line = 0; - let mut lines_to_start_of_snippet = 0; - let mut calculated_start_ix = None; - let mut calculated_end_ix = None; - let mut pos = 0; - for character in input.chars() { + let mut current_line = 1usize; + + let mut chars = input.char_indices().map(|(char_offset, character)| { + let r = (current_line, char_offset); if character == '\n' { - current_line += 1 + current_line += 1; } + r + }); - if current_line + NUM_LINES_BUFFER >= start.line && calculated_start_ix.is_none() { - calculated_start_ix = Some(pos); - lines_to_start_of_snippet = current_line; - } + // Find the first char of the first line + let first_char = chars + .by_ref() + .find(|(current_line, _)| current_line + NUM_LINES_BUFFER >= start.line); - if current_line >= end.line + NUM_LINES_BUFFER && calculated_end_ix.is_none() { - calculated_end_ix = Some(pos); - } + // Find the last char of the last line + let last_char = chars + .by_ref() + .find(|(current_line, _)| *current_line > end.line + NUM_LINES_BUFFER) + .map(|x| x.1); - if calculated_start_ix.is_some() && calculated_end_ix.is_some() { - break; + // this releases the borrow of `current_line` + drop(chars); + + let (first_char_line, first_char_offset, last_char_offset) = match (first_char, last_char) { + // has first and last + (Some((first_char_line, first_char_offset)), Some(last_char_offset)) => { + (first_char_line, first_char_offset, last_char_offset) } - pos += character.len_utf8(); + // has first and no last + (Some((first_char_line, first_char_offset)), None) => { + (first_char_line, first_char_offset, input.len()) + } + // others + _ => (current_line, input.len(), input.len()), + }; + + // adjust indices to be inside the returned window + start.line = first_char_line; + *start_ix = start_ix.saturating_sub(first_char_offset); + *end_ix = end_ix.saturating_sub(first_char_offset); + + &input[first_char_offset..last_char_offset] +} + +#[test] +fn ok_construct_window() { + fn t( + start_line: usize, + start_col: usize, + end_line: usize, + end_col: usize, + start_char: usize, + end_char: usize, + input: &str, + ) -> (usize, usize, &str) { + let mut s = LineCol { + line: start_line, + col: start_col, + }; + let mut start = start_char; + let mut end = end_char; + let r = construct_window( + &mut s, + LineCol { + line: end_line, + col: end_col, + }, + &mut start, + &mut end, + input, + ); + (start, end, r) } - let calculated_start_ix = calculated_start_ix.unwrap_or(0); - let calculated_end_ix = calculated_end_ix.unwrap_or(input.len()); - let start_ix_bytes = *start_ix - std::cmp::min(calculated_start_ix, *start_ix); - let end_ix_bytes = *end_ix - std::cmp::min(calculated_start_ix, *end_ix); - // We want the start_ix and end_ix in terms of chars and not bytes, so translate. - *start_ix = input[calculated_start_ix..(calculated_start_ix + start_ix_bytes)] - .chars() - .count(); - *end_ix = input[calculated_start_ix..(calculated_start_ix + end_ix_bytes)] - .chars() - .count(); - - start.line = lines_to_start_of_snippet; - &input[calculated_start_ix..calculated_end_ix] + // Invalid Empty file + assert_eq!(t(0, 0, 0, 0, 0, 0, ""), (0, 0, "")); + + // Valid Empty File + assert_eq!(t(1, 1, 1, 1, 0, 0, ""), (0, 0, "")); + + // One line, error after the last char + assert_eq!(t(1, 7, 1, 7, 6, 6, "script"), (6, 6, "script")); + + // 01 23 45 67 89 AB CD E + let eight_lines = "1\n2\n3\n4\n5\n6\n7\n8"; + + assert_eq!(t(1, 1, 1, 1, 0, 1, eight_lines), (0, 1, "1\n2\n3\n")); + assert_eq!(t(2, 1, 2, 1, 2, 3, eight_lines), (2, 3, "1\n2\n3\n4\n")); + assert_eq!(t(3, 1, 3, 1, 4, 5, eight_lines), (4, 5, "1\n2\n3\n4\n5\n")); + assert_eq!(t(4, 1, 4, 1, 6, 7, eight_lines), (4, 5, "2\n3\n4\n5\n6\n")); + assert_eq!(t(5, 1, 5, 1, 8, 9, eight_lines), (4, 5, "3\n4\n5\n6\n7\n")); + assert_eq!(t(6, 1, 6, 1, 10, 11, eight_lines), (4, 5, "4\n5\n6\n7\n8")); + assert_eq!(t(7, 1, 7, 1, 12, 13, eight_lines), (4, 5, "5\n6\n7\n8")); + assert_eq!(t(8, 1, 8, 1, 14, 15, eight_lines), (4, 5, "6\n7\n8")); + + // Invalid lines + assert_eq!(t(9, 1, 9, 1, 14, 15, eight_lines), (2, 3, "7\n8")); + assert_eq!(t(10, 1, 10, 1, 14, 15, eight_lines), (0, 1, "8")); + assert_eq!(t(11, 1, 11, 1, 14, 15, eight_lines), (0, 0, "")); } diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/stdout.snap index 3df03eb69cf..3a28c876aaf 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/stdout.snap @@ -12,7 +12,7 @@ stderr: error --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:41:27 | -39 | +39 | // unexpected Option 40 | let a = [None, Some(1), Some(1u8)]; 41 | let _b: Option = a[1]; | ^^^^ Mismatched types. @@ -27,7 +27,7 @@ ____ error --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:45:18 | -43 | +43 | // unexpected u8 44 | let a = [8, 256u16, 8u8]; 45 | let b: u32 = a[2]; | ^^^^ Mismatched types. @@ -42,7 +42,7 @@ ____ error --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:9:22 | - 7 | + 7 | fn main() { 8 | // unexpected u16 9 | let a: [u8;1] = [1u16]; | ^^^^ Mismatched types. @@ -65,13 +65,14 @@ expected: u8 found: u16. 13 | let a = [1, 2u8, 3u16, 4u32, 5u64]; +14 | | ____ error --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:13:22 | -11 | +11 | // unexpected u16 12 | let _ = [1u8, 1u16]; 13 | let a = [1, 2u8, 3u16, 4u32, 5u64]; | ^^^^ Mismatched types. @@ -86,7 +87,7 @@ ____ error --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:13:28 | -11 | +11 | // unexpected u16 12 | let _ = [1u8, 1u16]; 13 | let a = [1, 2u8, 3u16, 4u32, 5u64]; | ^^^^ Mismatched types. @@ -101,7 +102,7 @@ ____ error --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:13:34 | -11 | +11 | // unexpected u16 12 | let _ = [1u8, 1u16]; 13 | let a = [1, 2u8, 3u16, 4u32, 5u64]; | ^^^^ Mismatched types. @@ -221,7 +222,7 @@ ____ error --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:32:20 | -30 | +30 | // unexpected str 31 | let _ = [1, "", 1u16]; 32 | let _ = [1, 2, "hello"]; | ^^^^^^^ Mismatched types. @@ -236,7 +237,7 @@ ____ error --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:33:25 | -31 | +31 | let _ = [1, "", 1u16]; 32 | let _ = [1, 2, "hello"]; 33 | let _ = [1, return, "", 1u16]; | ^^ Mismatched types. @@ -244,13 +245,14 @@ expected: u16 found: str. 34 | let _ = [1, "", return, 1u16]; +35 | | ____ error --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:34:17 | -32 | +32 | let _ = [1, 2, "hello"]; 33 | let _ = [1, return, "", 1u16]; 34 | let _ = [1, "", return, 1u16]; | ^^ Mismatched types. @@ -288,6 +290,7 @@ expected: u16 found: u8. 45 | let b: u32 = a[2]; +46 | | ____ diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/insufficient_type_info/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/insufficient_type_info/test.toml index 04cf3e244a3..27dfeaece54 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/insufficient_type_info/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/insufficient_type_info/test.toml @@ -8,6 +8,10 @@ category = "fail" # check: $()None::; # nextln: $()Could not find symbol "T" in this scope. +# check: $()error +# check: $()None::; +# nextln: $()Unknown type name "T" + # check: $()error # check: $()foo() # nextln: $()Cannot infer type for type parameter "T". Insufficient type information provided. Try annotating its type. diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/stdout.snap index 976078dcd1b..858d27be7e6 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/stdout.snap @@ -12,11 +12,12 @@ stderr: error --> test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/src/main.sw:5:14 | -3 | +3 | fn main() { 4 | // 0x100 does not fit into a u8 5 | let _a = 0x100; | ^^^^^ Literal would overflow because its value does not fit into "u8" 6 | Vec::::new().push(_a); +7 | | ____ @@ -28,6 +29,7 @@ error 9 | let _a = 0x10000; | ^^^^^^^ Literal would overflow because its value does not fit into "u16" 10 | Vec::::new().push(_a); +11 | | ____ @@ -39,6 +41,7 @@ error 13 | let _a = 0x100000000; | ^^^^^^^^^^^ Literal would overflow because its value does not fit into "u32" 14 | Vec::::new().push(_a); +15 | | ____ From c5f363b8bc8bc65aa66df9a9afa9145eb4889167 Mon Sep 17 00:00:00 2001 From: IGI-111 Date: Mon, 30 Sep 2024 18:59:59 +0900 Subject: [PATCH 045/115] Fix release check script to check new version specs (#6592) ## Description Refactor `verify_tag.sh` to check all the places where lockstep versions are present in new workspace configuration. ## 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. Co-authored-by: Joshua Batty --- .github/workflows/ci.yml | 2 +- .github/workflows/scripts/verify_tag.sh | 72 ++++++++++++++++++------- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2178ed40bb1..1f5630d1fdd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -643,7 +643,7 @@ jobs: - name: Verify tag version run: | cargo install toml-cli - ./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} Cargo.toml + ./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} - name: Notify if Job Fails uses: ravsamhq/notify-slack-action@v2 diff --git a/.github/workflows/scripts/verify_tag.sh b/.github/workflows/scripts/verify_tag.sh index b833ffce74f..6277011a708 100755 --- a/.github/workflows/scripts/verify_tag.sh +++ b/.github/workflows/scripts/verify_tag.sh @@ -6,30 +6,66 @@ err() { } status() { - WIDTH=12 - printf "\e[32m\e[1m%${WIDTH}s\e[0m %s\n" "$1" "$2" + local width=12 + printf "\e[32m\e[1m%${width}s\e[0m %s\n" "$1" "$2" +} + +get_toml_version () { + local toml_path="$1" + + local manifest="Cargo.toml" + echo $(toml get $manifest $toml_path | tr -d '"') +} + +check_version () { + local ref=$1 + local toml_path=$2 + + # strip preceeding 'v' if it exists on tag + ref=${ref/#v} + + local toml_version=$(get_toml_version "$toml_path") + + if [ "$toml_version" != "$ref" ]; then + err "Crate version $toml_version for $toml_path, doesn't match tag version $ref" + exit 1 + else + status "Crate version for $toml_path matches tag $toml_version" + fi } REF=$1 -MANIFEST=$2 if [ -z "$REF" ]; then err "Expected ref to be set" exit 1 fi -if [ -z "$MANIFEST" ]; then - err "Expected manifest to be set" - exit 1 -fi - -# strip preceeding 'v' if it exists on tag -REF=${REF/#v} -TOML_VERSION=$(toml get $MANIFEST workspace.package.version | tr -d '"') - -if [ "$TOML_VERSION" != "$REF" ]; then - err "Crate version $TOML_VERSION, doesn't match tag version $REF" - exit 1 -else - status "Crate version matches tag $TOML_VERSION" -fi +for toml_path in \ + "workspace.package.version" \ + "workspace.dependencies.forc.version" \ + "workspace.dependencies.forc-pkg.version" \ + "workspace.dependencies.forc-test.version" \ + "workspace.dependencies.forc-tracing.version" \ + "workspace.dependencies.forc-util.version" \ + "workspace.dependencies.forc-plugins.version" \ + "workspace.dependencies.forc-client.version" \ + "workspace.dependencies.forc-crypto.version" \ + "workspace.dependencies.forc-debug.version" \ + "workspace.dependencies.forc-doc.version" \ + "workspace.dependencies.forc-fmt.version" \ + "workspace.dependencies.forc-lsp.version" \ + "workspace.dependencies.forc-tx.version" \ + "workspace.dependencies.sway-ast.version" \ + "workspace.dependencies.sway-core.version" \ + "workspace.dependencies.sway-error.version" \ + "workspace.dependencies.sway-lsp.version" \ + "workspace.dependencies.sway-parse.version" \ + "workspace.dependencies.sway-types.version" \ + "workspace.dependencies.sway-utils.version" \ + "workspace.dependencies.swayfmt.version" \ + "workspace.dependencies.sway-ir.version" \ + "workspace.dependencies.sway-ir-macros.version" \ +; do + check_version $REF $toml_path +done From 069ae4ab0d1cfd756e8ddb7e6a8ab4556d626706 Mon Sep 17 00:00:00 2001 From: Sophie Dankel <47993817+sdankel@users.noreply.github.com> Date: Mon, 30 Sep 2024 18:04:22 -0700 Subject: [PATCH 046/115] fix: Capture more declarations for sway autocomplete (#6598) ## Description I noticed that autocomplete wasn't working for some function declarations. It was because sometimes function declarations in the token map are stored as `TyDecl::FunctionDecl(decl)` and sometimes as `TypedAstToken::TypedFunctionDeclaration(TyFunctionDecl {..})` This PR expands the matching for declarations to make autocomplete work in more cases. ## Checklist - [ ] 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. - [ ] 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). - [ ] I have requested a review from the relevant team or maintainers. --- .../code_actions/diagnostic/auto_import.rs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/sway-lsp/src/capabilities/code_actions/diagnostic/auto_import.rs b/sway-lsp/src/capabilities/code_actions/diagnostic/auto_import.rs index 06aecd9a80d..22889c6eea6 100644 --- a/sway-lsp/src/capabilities/code_actions/diagnostic/auto_import.rs +++ b/sway-lsp/src/capabilities/code_actions/diagnostic/auto_import.rs @@ -118,6 +118,27 @@ pub(crate) fn get_call_paths_for_name<'s>( trait_decl.call_path.to_import_path(ctx.engines, &namespace); Some(call_path) } + TyDecl::FunctionDecl(decl) => { + let function_decl = ctx.engines.de().get_function(&decl.decl_id); + let call_path = function_decl + .call_path + .to_import_path(ctx.engines, &namespace); + Some(call_path) + } + TyDecl::ConstantDecl(decl) => { + let constant_decl = ctx.engines.de().get_constant(&decl.decl_id); + let call_path = constant_decl + .call_path + .to_import_path(ctx.engines, &namespace); + Some(call_path) + } + TyDecl::TypeAliasDecl(decl) => { + let type_alias_decl = ctx.engines.de().get_type_alias(&decl.decl_id); + let call_path = type_alias_decl + .call_path + .to_import_path(ctx.engines, &namespace); + Some(call_path) + } _ => None, }; } From d39958053db1942b3a2134ec799626583822b320 Mon Sep 17 00:00:00 2001 From: IGI-111 Date: Tue, 1 Oct 2024 12:04:07 +0900 Subject: [PATCH 047/115] Formalize code freeze (#6600) --- .github/CODEOWNERS | 61 ++++++++++++++++--------------- sway-lsp/tests/integration/lsp.rs | 4 +- 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index bdb38dc2c31..7fb8f888450 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,36 +1,37 @@ -# Everything else -* @FuelLabs/leads +* @Voxelot @mchristopher @luizstacio +# # Everything else +# * @FuelLabs/leads -# Documentation -/docs/ @FuelLabs/tooling @FuelLabs/sway-compiler @FuelLabs/swayex @FuelLabs/Devrel +# # Documentation +# /docs/ @FuelLabs/tooling @FuelLabs/sway-compiler @FuelLabs/swayex @FuelLabs/Devrel -# Sway files and standard library -/examples/ @FuelLabs/sway-compiler @FuelLabs/swayex -/sway-lib-core/ @FuelLabs/sway-compiler @FuelLabs/swayex -/sway-lib-std/ @FuelLabs/sway-compiler @FuelLabs/swayex +# # Sway files and standard library +# /examples/ @FuelLabs/sway-compiler @FuelLabs/swayex +# /sway-lib-core/ @FuelLabs/sway-compiler @FuelLabs/swayex +# /sway-lib-std/ @FuelLabs/sway-compiler @FuelLabs/swayex -# Tooling -/forc/ @FuelLabs/tooling -/forc-pkg/ @FuelLabs/tooling -/forc-plugins/ @FuelLabs/tooling -/forc-test/ @FuelLabs/tooling -/forc-tracing/ @FuelLabs/tooling -/forc-util/ @FuelLabs/tooling -/sway-lsp/ @FuelLabs/tooling -/swayfmt/ @FuelLabs/tooling +# # Tooling +# /forc/ @FuelLabs/tooling +# /forc-pkg/ @FuelLabs/tooling +# /forc-plugins/ @FuelLabs/tooling +# /forc-test/ @FuelLabs/tooling +# /forc-tracing/ @FuelLabs/tooling +# /forc-util/ @FuelLabs/tooling +# /sway-lsp/ @FuelLabs/tooling +# /swayfmt/ @FuelLabs/tooling -# Compiler -/sway-ast/ @FuelLabs/sway-compiler -/sway-core/ @FuelLabs/sway-compiler -/sway-error/ @FuelLabs/sway-compiler -/sway-ir/ @FuelLabs/sway-compiler -/sway-parse/ @FuelLabs/sway-compiler -/sway-types/ @FuelLabs/sway-compiler -/sway-utils/ @FuelLabs/sway-compiler -/templates/ @FuelLabs/sway-compiler -/test/ @FuelLabs/sway-compiler +# # Compiler +# /sway-ast/ @FuelLabs/sway-compiler +# /sway-core/ @FuelLabs/sway-compiler +# /sway-error/ @FuelLabs/sway-compiler +# /sway-ir/ @FuelLabs/sway-compiler +# /sway-parse/ @FuelLabs/sway-compiler +# /sway-types/ @FuelLabs/sway-compiler +# /sway-utils/ @FuelLabs/sway-compiler +# /templates/ @FuelLabs/sway-compiler +# /test/ @FuelLabs/sway-compiler -# Root lockfile and deployment scripts -Cargo.lock @FuelLabs/leads -/deployment/ @FuelLabs/leads +# # Root lockfile and deployment scripts +# Cargo.lock @FuelLabs/leads +# /deployment/ @FuelLabs/leads diff --git a/sway-lsp/tests/integration/lsp.rs b/sway-lsp/tests/integration/lsp.rs index 7f26570846a..b187510b5fb 100644 --- a/sway-lsp/tests/integration/lsp.rs +++ b/sway-lsp/tests/integration/lsp.rs @@ -640,8 +640,8 @@ pub(crate) async fn rename_request<'a>( new_name: rename.new_name.to_string(), work_done_progress_params: Default::default(), }; - let worspace_edit = request::handle_rename(server, params).await.unwrap(); - worspace_edit.unwrap() + let workspace_edit = request::handle_rename(server, params).await.unwrap(); + workspace_edit.unwrap() } pub fn create_did_change_params( From 347c83473a04db699dad1d467724f9fa6c0c18c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaya=20G=C3=B6kalp?= Date: Sat, 5 Oct 2024 23:12:36 -0700 Subject: [PATCH 048/115] feat: add blob deployments for scripts and predicates (#6607) ## Description This PR adds support for deploying executables, namely predicates and scripts. Before this PR executing `forc-deploy` on a script or predicate was an hard error. With this PR we are enabling the deployment of them via converting them to a loader which loads the original bytecode deployed as a blob. The loader binaries are serialized to disk under `out` folder for both predicates and scripts. For predicates we also save the root of the loader additionally. Every output related to generated `loader` is suffixed with `-loader` so that it can be distinguished easily. --------- Co-authored-by: Joshua Batty Co-authored-by: Sophie Dankel <47993817+sdankel@users.noreply.github.com> --- Cargo.lock | 98 ++--- Cargo.toml | 17 +- .../src/forc/plugins/forc_client/index.md | 23 +- forc-plugins/forc-client/src/op/deploy.rs | 318 +++++++++++++---- forc-plugins/forc-client/src/op/mod.rs | 2 +- .../test/data/deployed_predicate/.gitignore | 2 + .../test/data/deployed_predicate/Forc.lock | 13 + .../test/data/deployed_predicate/Forc.toml | 8 + .../deployed_predicate-abi.json | 128 +++++++ .../test/data/deployed_predicate/src/main.sw | 53 +++ .../test/data/deployed_script/.gitignore | 2 + .../test/data/deployed_script/Forc.toml | 8 + .../deployed_script/deployed_script-abi.json | 312 ++++++++++++++++ .../test/data/deployed_script/src/main.sw | 72 ++++ forc-plugins/forc-client/tests/deploy.rs | 337 ++++++++++++++++-- forc-plugins/forc-tx/Cargo.toml | 2 +- forc-util/Cargo.toml | 2 +- test/src/e2e_vm_tests/harness.rs | 25 +- test/src/sdk-harness/Cargo.lock | 321 +++++++++-------- test/src/sdk-harness/Cargo.toml | 8 +- 20 files changed, 1447 insertions(+), 304 deletions(-) create mode 100644 forc-plugins/forc-client/test/data/deployed_predicate/.gitignore create mode 100644 forc-plugins/forc-client/test/data/deployed_predicate/Forc.lock create mode 100644 forc-plugins/forc-client/test/data/deployed_predicate/Forc.toml create mode 100644 forc-plugins/forc-client/test/data/deployed_predicate/deployed_predicate-abi.json create mode 100644 forc-plugins/forc-client/test/data/deployed_predicate/src/main.sw create mode 100644 forc-plugins/forc-client/test/data/deployed_script/.gitignore create mode 100644 forc-plugins/forc-client/test/data/deployed_script/Forc.toml create mode 100644 forc-plugins/forc-client/test/data/deployed_script/deployed_script-abi.json create mode 100644 forc-plugins/forc-client/test/data/deployed_script/src/main.sw diff --git a/Cargo.lock b/Cargo.lock index b0c7e8122fe..f9d6234bdc1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2508,9 +2508,9 @@ checksum = "b90ca2580b73ab6a1f724b76ca11ab632df820fd6040c336200d2c1df7b3c82c" [[package]] name = "eventsource-client" -version = "0.12.2" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c80c6714d1a380314fcb11a22eeff022e1e1c9642f0bb54e15dc9cb29f37b29" +checksum = "43ddc25e1ad2cc0106d5e2d967397b4fb2068a66677ee9b0eea4600e5cfe8fb4" dependencies = [ "futures", "hyper 0.14.30", @@ -2982,9 +2982,9 @@ dependencies = [ [[package]] name = "forc-wallet" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c595f65f380e2f63332ef84c4473ea4418407d32631acc49637f50d5495acb18" +checksum = "1ed8ee5063d7acc9b7dbdc5bdd43171e2bdcee5171b54939d1876f1b4fb01f6b" dependencies = [ "anyhow", "clap 4.5.16", @@ -3064,9 +3064,9 @@ dependencies = [ [[package]] name = "fuel-asm" -version = "0.57.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b29ea55a794c00d0dfaad06f11720a05fa928603f812dca1c38163f2b240860a" +checksum = "79ca07227658105bdf873556dea09fa7fbfe792fbc084b4b9568f5ba3d64c411" dependencies = [ "bitflags 2.6.0", "fuel-types", @@ -3076,9 +3076,9 @@ dependencies = [ [[package]] name = "fuel-core-chain-config" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a4c5a71702426b8354bff2010131c0abb4a4f0b608cc7a6dfd72f9e785ba478" +checksum = "cd1eca1d12daf8ad0f2479d7fff9405d94b6467496e5319e5f8b99cbdabdd58b" dependencies = [ "anyhow", "bech32", @@ -3096,11 +3096,12 @@ dependencies = [ [[package]] name = "fuel-core-client" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5770dbda6220e641eb57ee204dd5914fa15170afe3009473f57cdf15e2339fd8" +checksum = "9dbd88f285afdf061e409b712ecef49e2fe9ba235288cc76e8de8f05d50b6876" dependencies = [ "anyhow", + "base64 0.22.1", "cynic", "derive_more 0.99.18", "eventsource-client", @@ -3120,9 +3121,9 @@ dependencies = [ [[package]] name = "fuel-core-metrics" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f671e9e813b81873ef07e1cfe8697ba3f9fd0f05313879ed0933446da4c1c14" +checksum = "dfc199e165e600f241cab86129766b26bab78572a701a39bc40a5fdb669961a8" dependencies = [ "parking_lot 0.12.3", "pin-project-lite", @@ -3133,9 +3134,9 @@ dependencies = [ [[package]] name = "fuel-core-poa" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b698e7c184ab4acbaabe7bad73fdc7dfc9ebfc3a6856b1d719a4fd4c1921873" +checksum = "49c4f3e5fa1e916793609bdb9a52142077a84a793272379a04cf24375aa94e6f" dependencies = [ "anyhow", "async-trait", @@ -3152,9 +3153,9 @@ dependencies = [ [[package]] name = "fuel-core-services" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "998a4f9d057bf3efe43be574bd200ef64c3318007fd04523ce6bd51cc7bb963c" +checksum = "739dca83db1eb86651db3833f088f52afcd3f181cfca40e5725074aceb3ea49d" dependencies = [ "anyhow", "async-trait", @@ -3167,9 +3168,9 @@ dependencies = [ [[package]] name = "fuel-core-storage" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1daa7422e48120b1623b53fe1a1152d11314f30fb290a73dc80f7e128c1f9014" +checksum = "6255d852b6866199d103233e1eef2e7ded141019bc782b5b211fcf001727c34b" dependencies = [ "anyhow", "derive_more 0.99.18", @@ -3189,9 +3190,9 @@ dependencies = [ [[package]] name = "fuel-core-types" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aa1c54f09cc7c29a11ca1129f73105745f8374a192e3e24040c10822871d83f" +checksum = "33a4e9b2de06381e1ad598cd1030344993fee7401331ca9955d0a1860cc0484c" dependencies = [ "anyhow", "bs58", @@ -3207,9 +3208,9 @@ dependencies = [ [[package]] name = "fuel-crypto" -version = "0.57.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2661b2a6c43e811be4892250513a6f4c46a69cc7092a1e5b240f49697f08292e" +checksum = "f53b06525aa7754bf7c3ef23daf15fd798ae990a82f8b7b813d25cedfeacfe5c" dependencies = [ "coins-bip32", "coins-bip39", @@ -3228,9 +3229,9 @@ dependencies = [ [[package]] name = "fuel-derive" -version = "0.57.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03509567813a351ca60d8507b2ac476b06c1590f2e9edbe72bc205bb04e0af12" +checksum = "c8e34d6eec30d04506607cc0bc85fc97c57c964580cd233fd557e346c5273535" dependencies = [ "proc-macro2", "quote", @@ -3287,9 +3288,9 @@ dependencies = [ [[package]] name = "fuel-merkle" -version = "0.57.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24938ee8a5e9efe71994203527dffb4c81872aa2953de0c347ad38696527b58a" +checksum = "7a9fa3708405eba32fd2b947b827dc52484377ba6a238260b03a07b642395e6c" dependencies = [ "derive_more 0.99.18", "digest 0.10.7", @@ -3302,15 +3303,15 @@ dependencies = [ [[package]] name = "fuel-storage" -version = "0.57.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4283f9cabc26a1154a31268e79de1e0f317d57231b4dc8d7282efb22e49d2ed3" +checksum = "f6f678f1c900d0632d77e15d4a4946048d4d517fefeba72607390c03288ca127" [[package]] name = "fuel-tx" -version = "0.57.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f9e8fdda6abfe83cf1456a11eabf1de66d682176fb097f2f950704cc50c26" +checksum = "1e3065c12eecc9121514694f4b01009c9a83d8842af11c43ec9e2bbc0a7f36cb" dependencies = [ "bitflags 2.6.0", "derivative", @@ -3324,16 +3325,15 @@ dependencies = [ "postcard", "rand", "serde", - "serde_json", "strum 0.24.1", "strum_macros 0.24.3", ] [[package]] name = "fuel-types" -version = "0.57.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f196060a10db0293cdfca455f7e2f3a7914f46f25e0fbc2d28cf0a11e835a86" +checksum = "a93d5f3fd028d874d8927be439fcdea01cb04499049bc68a874c73dd0c7e32b7" dependencies = [ "fuel-derive", "hex", @@ -3343,9 +3343,9 @@ dependencies = [ [[package]] name = "fuel-vm" -version = "0.57.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6f4e0cc4ae65d00df6f3dcae90b81dd21135b45b932a79e368f35d255df12a1" +checksum = "cb0562398978e501e8ee2caeb747a2852cc4a8c5fff250eb58e38f1c03217311" dependencies = [ "anyhow", "async-trait", @@ -3377,9 +3377,9 @@ dependencies = [ [[package]] name = "fuels" -version = "0.66.5" +version = "0.66.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaf7ca0443308f4c3d3e9dd7ed67cb18369ae63d208302056d6d5f3a09efb031" +checksum = "921a8ea521744e600e0a34236adff7524ecf34bd940c2a018315d0212c140d7b" dependencies = [ "fuel-core-client", "fuel-crypto", @@ -3393,9 +3393,9 @@ dependencies = [ [[package]] name = "fuels-accounts" -version = "0.66.5" +version = "0.66.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ea69afa418ba67b9572a5b4cb612b80ee2113c9f755e93acf7adc9fc1454d1" +checksum = "2da8bad87e947fc448c44c22e4c90a4af49d61de08722b1d1774d977b2071047" dependencies = [ "async-trait", "chrono", @@ -3418,9 +3418,9 @@ dependencies = [ [[package]] name = "fuels-code-gen" -version = "0.66.5" +version = "0.66.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8d1949debe40c9eb731a93b22a50da560007d85f6f7983679d217c01b9dc867" +checksum = "9fdc5f9dcdf330f5ef5f367dbc2334e72151e9ae46a4ee9f21d43a5e859be11b" dependencies = [ "Inflector", "fuel-abi-types", @@ -3434,9 +3434,9 @@ dependencies = [ [[package]] name = "fuels-core" -version = "0.66.5" +version = "0.66.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e720a87a7c99fcc5477cbb251738406de752a10eb237e15c79c1d99b64f4679f" +checksum = "629212e8278d57aa1a6f846ca0ca1e3428fb6da2d43e368931ff1494a0a6b5ce" dependencies = [ "async-trait", "bech32", @@ -3462,9 +3462,9 @@ dependencies = [ [[package]] name = "fuels-macros" -version = "0.66.5" +version = "0.66.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7b391259fceb75331bcbde2878cd9765b579e9167abd818641205b4c96b9a" +checksum = "562bf012adedfb492431f4bfd5be4ccbf2171ab7d5247c5953a6be3ea8036072" dependencies = [ "fuels-code-gen", "itertools 0.12.1", @@ -3475,9 +3475,9 @@ dependencies = [ [[package]] name = "fuels-programs" -version = "0.66.5" +version = "0.66.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf719a68184ad4999c24dd53cf68bdd247d02fe16a9d67ccba177c8e44771b9" +checksum = "30a366e6a78e1c104fe1cb14439199833987fe76ecd46ee2b46fe05868a3366d" dependencies = [ "async-trait", "fuel-abi-types", @@ -3494,9 +3494,9 @@ dependencies = [ [[package]] name = "fuels-test-helpers" -version = "0.66.5" +version = "0.66.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a615a59644d3cfce8dc1089db0764b4cca2bcea42b2a08eca826e2b8f892936" +checksum = "7705708c0fe28a874c44635b77c3e120a3422c8a24fdc45f07dc8c21ee9ca6fb" dependencies = [ "fuel-core-chain-config", "fuel-core-client", diff --git a/Cargo.toml b/Cargo.toml index bf11ce66ef7..da1286e8d99 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -86,23 +86,24 @@ fuel-abi-types = "0.7" # Although ALL verions are "X.Y", we need the complete semver for # fuel-core-client as the GitHub Actions workflow parses this value to pull down # the correct tarball -fuel-core-client = { version = "0.36.0", default-features = false } -fuel-core-types = { version = "0.36", default-features = false } +fuel-core-client = { version = "0.37.0", default-features = false } +fuel-core-types = { version = "0.37", default-features = false } # Dependencies from the `fuels-rs` repository: + fuels = "0.66" fuels-core = "0.66" fuels-accounts = "0.66" # Dependencies from the `fuel-vm` repository: -fuel-asm = "0.57" -fuel-crypto = "0.57" -fuel-types = "0.57" -fuel-tx = "0.57" -fuel-vm = "0.57" +fuel-asm = "0.58" +fuel-crypto = "0.58" +fuel-types = "0.58" +fuel-tx = "0.58" +fuel-vm = "0.58" # Dependencies from the `forc-wallet` repository: -forc-wallet = "0.9" +forc-wallet = "0.10" # # External dependencies diff --git a/docs/book/src/forc/plugins/forc_client/index.md b/docs/book/src/forc/plugins/forc_client/index.md index 23c668b18d4..454cbc9f622 100644 --- a/docs/book/src/forc/plugins/forc_client/index.md +++ b/docs/book/src/forc/plugins/forc_client/index.md @@ -179,4 +179,25 @@ If an `address` is present, `forc` calls into that contract to update its `targe ## Large Contracts -For contracts over 100KB, `forc-deploy` will split the contract into chunks and deploy the contract with multiple transactions using the Rust SDK's [loader contract](https://github.com/FuelLabs/fuels-rs/blob/master/docs/src/deploying/large_contracts.md) functionality. Chunks that have already been deployed will be reused on subsequent deployments. +For contracts over the maximum contract size limit defined by the network, `forc-deploy` will split the contract into chunks and deploy the contract with multiple transactions using the Rust SDK's [loader contract](https://github.com/FuelLabs/fuels-rs/blob/master/docs/src/deploying/large_contracts.md) functionality. Chunks that have already been deployed will be reused on subsequent deployments. + +## Deploying Scripts and Predicates + +`forc deploy` now supports deploying scripts and predicates in addition to contracts. These are deployed as blobs with generated loaders for efficiency. + +Scripts and predicates are deployed automatically when you run `forc deploy` on a project that contains them. The deployment process differs slightly from contract deployment: + +1. For scripts and predicates, the bytecode is uploaded as a blob. +2. A loader is generated that can load and execute the blob. +3. The loader bytecode is saved in the project's output directory. + +After deployment, you'll find new files in your project's output directory: + +- For scripts: `-loader.bin` +- For predicates: `-loader.bin` and `-loader-root` + +The loader files contain the bytecode necessary to load and execute your script or predicate from the deployed blob. + +This new deployment method allows for more efficient storage and execution of scripts and predicates on the Fuel network. + +Note: Contracts are still deployed directly, not as blobs given that the contract size is under the maximum contract size limit defined by network. diff --git a/forc-plugins/forc-client/src/op/deploy.rs b/forc-plugins/forc-client/src/op/deploy.rs index a5c71a41f79..af3c1e6e737 100644 --- a/forc-plugins/forc-client/src/op/deploy.rs +++ b/forc-plugins/forc-client/src/op/deploy.rs @@ -13,8 +13,8 @@ use crate::{ }, }; use anyhow::{bail, Context, Result}; -use forc_pkg::manifest::GenericManifestFile; use forc_pkg::{self as pkg, PackageManifestFile}; +use forc_pkg::{manifest::GenericManifestFile, MemberFilter}; use forc_tracing::{println_action_green, println_warning}; use forc_util::default_output_directory; use forc_wallet::utils::default_wallet_path; @@ -25,7 +25,10 @@ use fuel_tx::{Salt, Transaction}; use fuel_vm::prelude::*; use fuels::{ macros::abigen, - programs::contract::{LoadConfiguration, StorageConfiguration}, + programs::{ + contract::{LoadConfiguration, StorageConfiguration}, + executable::Executable, + }, types::{bech32::Bech32ContractId, transaction_builders::Blob}, }; use fuels_accounts::{provider::Provider, Account, ViewOnlyAccount}; @@ -43,12 +46,22 @@ use std::{ use sway_core::language::parsed::TreeType; use sway_core::BuildTarget; -/// Maximum contract size allowed for a single contract. If the target +/// Default maximum contract size allowed for a single contract. If the target /// contract size is bigger than this amount, forc-deploy will automatically /// starts dividing the contract and deploy them in chunks automatically. /// The value is in bytes. const MAX_CONTRACT_SIZE: usize = 100_000; +/// Represents a deployed instance of a forc package. +/// Packages other than libraries are deployable through different mechanisms. +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum DeployedPackage { + Contract(DeployedContract), + Script(DeployedExecutable), + Predicate(DeployedExecutable), +} + +/// Represents a deployed contract on the Fuel network. #[derive(Debug, PartialEq, Eq, Clone, PartialOrd, Ord)] pub struct DeployedContract { pub id: fuel_tx::ContractId, @@ -56,6 +69,13 @@ pub struct DeployedContract { pub chunked: bool, } +/// Represents a deployed executable (script or predicate) on the Fuel network. +/// Executables are deployed as blobs with generated loaders for efficiency. +#[derive(Debug, PartialEq, Eq, Clone, PartialOrd, Ord)] +pub struct DeployedExecutable { + pub bytecode: Vec, +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct DeploymentArtifact { transaction_id: String, @@ -153,7 +173,7 @@ fn resolve_storage_slots( } /// Creates blobs from the contract to deploy contracts that are larger than -/// `MAX_CONTRACT_SIZE`. Created blobs are deployed, and a loader contract is +/// maximum contract size. Created blobs are deployed, and a loader contract is /// generated such that it loads all the deployed blobs, and provides the user /// a single contract (loader contract that loads the blobs) to call into. async fn deploy_chunked( @@ -174,10 +194,15 @@ async fn deploy_chunked( None => "".to_string(), }; + let chunk_size = chain_info + .consensus_parameters + .contract_params() + .contract_max_size() as usize; + let blobs = compiled .bytecode .bytes - .chunks(MAX_CONTRACT_SIZE) + .chunks(chunk_size) .map(|chunk| Blob::new(chunk.to_vec())) .collect(); @@ -251,27 +276,25 @@ async fn deploy_new_proxy( Ok(proxy_contract_id) } -/// Builds and deploys contract(s). If the given path corresponds to a workspace, all deployable members -/// will be built and deployed. +/// Builds and deploys contracts, scripts, and predicates from the given path or workspace. /// -/// Upon success, returns the ID of each deployed contract in order of deployment. +/// Contracts are deployed directly, while scripts and predicates are deployed as blobs with generated loaders. /// -/// When deploying a single contract, only that contract's ID is returned. -pub async fn deploy(command: cmd::Deploy) -> Result> { +/// Returns a vector of `DeployedPackage` representing all successful deployments. +pub async fn deploy(command: cmd::Deploy) -> Result> { if command.unsigned { println_warning("--unsigned flag is deprecated, please prefer using --default-signer. Assuming `--default-signer` is passed. This means your transaction will be signed by an account that is funded by fuel-core by default for testing purposes."); } - - let mut deployed_contracts = Vec::new(); let curr_dir = if let Some(ref path) = command.pkg.path { PathBuf::from(path) } else { std::env::current_dir()? }; - - let build_opts = build_opts_from_cmd(&command); + let build_opts = build_opts_from_cmd(&command, MemberFilter::default()); let built_pkgs = built_pkgs(&curr_dir, &build_opts)?; - let pkgs_to_deploy = built_pkgs + let mut deployed_packages = Vec::new(); + + let contracts_to_deploy = built_pkgs .iter() .filter(|pkg| { pkg.descriptor @@ -279,20 +302,148 @@ pub async fn deploy(command: cmd::Deploy) -> Result> { .check_program_type(&[TreeType::Contract]) .is_ok() }) + .cloned() .collect::>(); - if pkgs_to_deploy.is_empty() { - println_warning("No deployable contracts found in the current directory."); + let scripts_to_deploy = built_pkgs + .iter() + .filter(|pkg| { + pkg.descriptor + .manifest_file + .check_program_type(&[TreeType::Script]) + .is_ok() + }) + .cloned() + .collect::>(); + + let predicates_to_deploy = built_pkgs + .iter() + .filter(|pkg| { + pkg.descriptor + .manifest_file + .check_program_type(&[TreeType::Predicate]) + .is_ok() + }) + .cloned() + .collect::>(); + + if contracts_to_deploy.is_empty() + && scripts_to_deploy.is_empty() + && predicates_to_deploy.is_empty() + { + println_warning("No deployable package was found in the current directory."); + } else { + deployed_packages.extend( + deploy_contracts(&command, &contracts_to_deploy) + .await? + .into_iter() + .map(DeployedPackage::Contract), + ); + deployed_packages.extend( + deploy_executables(&command, &scripts_to_deploy) + .await? + .into_iter() + .map(DeployedPackage::Script), + ); + deployed_packages.extend( + deploy_executables(&command, &predicates_to_deploy) + .await? + .into_iter() + .map(DeployedPackage::Predicate), + ); + } + + Ok(deployed_packages) +} + +/// Builds and deploys executable (script and predicate) package(s) as blobs, +/// and generates a loader for each of them. +pub async fn deploy_executables( + command: &cmd::Deploy, + executables_to_deploy: &[Arc], +) -> Result> { + let mut deployed_executable = vec![]; + if executables_to_deploy.is_empty() { + return Ok(deployed_executable); + } + + let node_url = validate_and_get_node_url(command, executables_to_deploy).await?; + // We will have 1 transaction per executable as each deployment uses a single blob. + let tx_count = executables_to_deploy.len(); + let account = setup_deployment_account(command, &node_url, tx_count).await?; + + for pkg in executables_to_deploy { + let script = Executable::from_bytes(pkg.bytecode.bytes.clone()); + let loader = script.convert_to_loader()?; + println_action_green("Uploading", "blob containing executable bytecode."); + loader.upload_blob(account.clone()).await?; + println_action_green("Generating", "loader bytecode for the uploaded executable."); + let loader_bytecode = loader.code(); + let pkg_name = &pkg.descriptor.name; + let out_dir = pkg.descriptor.manifest_file.dir().join("out"); + let bin_path = out_dir.join(format!("{pkg_name}-loader.bin")); + std::fs::write(&bin_path, &loader_bytecode)?; + println_action_green( + "Saved", + &format!("loader bytecode at {}", bin_path.display()), + ); + // If the executable is a predicate, we also want to display and save the predicate root. + if pkg + .descriptor + .manifest_file + .program_type() + .with_context(|| { + "error while trying to retrieve program type for executable deployment." + })? + == TreeType::Predicate + { + // Calculate the root. + let root = format!("0x{}", fuel_tx::Input::predicate_owner(&loader_bytecode)); + // Root files are named in `pkg-name-root` format, since this is a + // loader we are also adding an identifier to differentiate it from + // the root of the "original" predicate. + let root_file_name = format!("{}-loader-root", &pkg_name); + let root_path = out_dir.join(root_file_name); + std::fs::write(&root_path, &root)?; + println_action_green( + "Saved", + &format!("loader root ({}) at {}", root, root_path.display()), + ); + } + let deployed = DeployedExecutable { + bytecode: loader_bytecode, + }; + deployed_executable.push(deployed); + println_action_green("Finished", &format!("deploying executable {pkg_name}")); + } + Ok(deployed_executable) +} + +/// Builds and deploys contract(s). If the given path corresponds to a workspace, all deployable members +/// will be built and deployed. +/// +/// Upon success, returns the ID of each deployed contract in order of deployment. +/// +/// When deploying a single contract, only that contract's ID is returned. +pub async fn deploy_contracts( + command: &cmd::Deploy, + contracts_to_deploy: &[Arc], +) -> Result> { + let mut deployed_contracts = Vec::new(); + + if contracts_to_deploy.is_empty() { return Ok(deployed_contracts); } let contract_salt_map = if let Some(salt_input) = &command.salt { // If we're building 1 package, we just parse the salt as a string, ie. 0x00... // If we're building >1 package, we must parse the salt as a pair of strings, ie. contract_name:0x00... - if built_pkgs.len() > 1 { + if contracts_to_deploy.len() > 1 { let map = validate_and_parse_salts( salt_input, - built_pkgs.iter().map(|b| &b.descriptor.manifest_file), + contracts_to_deploy + .iter() + .map(|b| &b.descriptor.manifest_file), )?; Some(map) @@ -310,7 +461,7 @@ pub async fn deploy(command: cmd::Deploy) -> Result> { .unwrap(); let mut contract_salt_map = ContractSaltMap::default(); contract_salt_map.insert( - built_pkgs[0] + contracts_to_deploy[0] .descriptor .manifest_file .project_name() @@ -323,23 +474,32 @@ pub async fn deploy(command: cmd::Deploy) -> Result> { None }; - // Ensure that all packages are being deployed to the same node. - let node_url = get_node_url( - &command.node, - &pkgs_to_deploy[0].descriptor.manifest_file.network, - )?; - if !pkgs_to_deploy.iter().all(|pkg| { - get_node_url(&command.node, &pkg.descriptor.manifest_file.network).ok() - == Some(node_url.clone()) - }) { - bail!("All contracts in a deployment should be deployed to the same node. Please ensure that the network specified in the Forc.toml files of all contracts is the same."); - } + let node_url = validate_and_get_node_url(command, contracts_to_deploy).await?; + let provider = Provider::connect(node_url.clone()).await?; + let max_contract_size = provider + .chain_info() + .await + .ok() + .and_then(|chain_info| { + chain_info + .consensus_parameters + .contract_params() + .contract_max_size() + .try_into() + .ok() + }) + .unwrap_or(MAX_CONTRACT_SIZE); // Confirmation step. Summarize the transaction(s) for the deployment. - let (provider, account) = - confirm_transaction_details(&pkgs_to_deploy, &command, node_url.clone()).await?; + let account = confirm_transaction_details( + contracts_to_deploy, + command, + node_url.clone(), + max_contract_size, + ) + .await?; - for pkg in pkgs_to_deploy { + for pkg in contracts_to_deploy { let salt = match (&contract_salt_map, command.default_salt) { (Some(map), false) => { if let Some(salt) = map.get(pkg.descriptor.manifest_file.project_name()) { @@ -355,13 +515,13 @@ pub async fn deploy(command: cmd::Deploy) -> Result> { } }; let bytecode_size = pkg.bytecode.bytes.len(); - let deployed_contract_id = if bytecode_size > MAX_CONTRACT_SIZE { + let deployed_contract_id = if bytecode_size > max_contract_size { // Deploy chunked let node_url = get_node_url(&command.node, &pkg.descriptor.manifest_file.network)?; let provider = Provider::connect(node_url).await?; deploy_chunked( - &command, + command, pkg, salt, &account, @@ -370,7 +530,7 @@ pub async fn deploy(command: cmd::Deploy) -> Result> { ) .await? } else { - deploy_pkg(&command, pkg, salt, &provider, &account).await? + deploy_pkg(command, pkg, salt, &provider, &account).await? }; let proxy_id = match &pkg.descriptor.manifest_file.proxy { @@ -397,7 +557,7 @@ pub async fn deploy(command: cmd::Deploy) -> Result> { let pkg_storage_slots = &pkg.storage_slots; // Deploy a new proxy contract. let deployed_proxy_contract = deploy_new_proxy( - &command, + command, pkg_name, pkg_storage_slots, &deployed_contract_id, @@ -420,7 +580,7 @@ pub async fn deploy(command: cmd::Deploy) -> Result> { let deployed_contract = DeployedContract { id: deployed_contract_id, proxy: proxy_id, - chunked: bytecode_size > MAX_CONTRACT_SIZE, + chunked: bytecode_size > max_contract_size, }; deployed_contracts.push(deployed_contract); } @@ -429,10 +589,11 @@ pub async fn deploy(command: cmd::Deploy) -> Result> { /// Prompt the user to confirm the transactions required for deployment, as well as the signing key. async fn confirm_transaction_details( - pkgs_to_deploy: &[&Arc], + pkgs_to_deploy: &[Arc], command: &cmd::Deploy, node_url: String, -) -> Result<(Provider, ForcClientAccount)> { + max_contract_size: usize, +) -> Result { // Confirmation step. Summarize the transaction(s) for the deployment. let mut tx_count = 0; let tx_summary = pkgs_to_deploy @@ -455,8 +616,8 @@ async fn confirm_transaction_details( }; let pkg_bytecode_len = pkg.bytecode.bytes.len(); - let blob_text = if pkg_bytecode_len > MAX_CONTRACT_SIZE { - let number_of_blobs = pkg_bytecode_len.div_ceil(MAX_CONTRACT_SIZE); + let blob_text = if pkg_bytecode_len > max_contract_size { + let number_of_blobs = pkg_bytecode_len.div_ceil(max_contract_size); tx_count += number_of_blobs; &format!(" + {number_of_blobs} blobs") } else { @@ -474,31 +635,12 @@ async fn confirm_transaction_details( println_action_green("Confirming", &format!("transactions [{tx_summary}]")); println_action_green("", &format!("Network: {node_url}")); - let provider = Provider::connect(node_url.clone()).await?; - - let wallet_mode = if command.default_signer || command.signing_key.is_some() { - SignerSelectionMode::Manual - } else if let Some(arn) = &command.aws_kms_signer { - SignerSelectionMode::AwsSigner(arn.clone()) - } else { - println_action_green("", &format!("Wallet: {}", default_wallet_path().display())); - let password = prompt_forc_wallet_password()?; - SignerSelectionMode::ForcWallet(password) - }; + let account = setup_deployment_account(command, &node_url, tx_count).await?; // TODO: Display the estimated gas cost of the transaction(s). // https://github.com/FuelLabs/sway/issues/6277 - let account = select_account( - &wallet_mode, - command.default_signer || command.unsigned, - command.signing_key, - &provider, - tx_count, - ) - .await?; - - Ok((provider.clone(), account)) + Ok(account) } /// Deploy a single pkg given deploy command and the manifest file @@ -632,7 +774,7 @@ fn tx_policies_from_cmd(cmd: &cmd::Deploy) -> TxPolicies { tx_policies } -fn build_opts_from_cmd(cmd: &cmd::Deploy) -> pkg::BuildOpts { +fn build_opts_from_cmd(cmd: &cmd::Deploy, member_filter: pkg::MemberFilter) -> pkg::BuildOpts { pkg::BuildOpts { pkg: pkg::PkgOpts { path: cmd.pkg.path.clone(), @@ -665,7 +807,7 @@ fn build_opts_from_cmd(cmd: &cmd::Deploy) -> pkg::BuildOpts { debug_outfile: cmd.build_output.debug_file.clone(), build_target: BuildTarget::default(), tests: false, - member_filter: pkg::MemberFilter::only_contracts(), + member_filter, experimental: ExperimentalFlags { new_encoding: !cmd.no_encoding_v1, }, @@ -715,6 +857,50 @@ fn create_deployment_artifact( deployment_artifact.to_file(&output_dir, pkg_name, contract_id) } +/// Validates that all packages are being deployed to the same node and returns the node URL. +async fn validate_and_get_node_url( + command: &cmd::Deploy, + packages: &[Arc], +) -> Result { + let node_url = get_node_url(&command.node, &packages[0].descriptor.manifest_file.network)?; + if !packages.iter().all(|pkg| { + get_node_url(&command.node, &pkg.descriptor.manifest_file.network).ok() + == Some(node_url.clone()) + }) { + bail!("All packages in a deployment should be deployed to the same node. Please ensure that the network specified in the Forc.toml files of all packages is the same."); + } + Ok(node_url) +} + +/// Sets up and returns the account for deployment. +async fn setup_deployment_account( + command: &cmd::Deploy, + node_url: &str, + tx_count: usize, +) -> Result { + let provider = Provider::connect(node_url).await?; + + let wallet_mode = if command.default_signer || command.signing_key.is_some() { + SignerSelectionMode::Manual + } else if let Some(arn) = &command.aws_kms_signer { + SignerSelectionMode::AwsSigner(arn.clone()) + } else { + println_action_green("", &format!("Wallet: {}", default_wallet_path().display())); + let password = prompt_forc_wallet_password()?; + SignerSelectionMode::ForcWallet(password) + }; + + let account = select_account( + &wallet_mode, + command.default_signer || command.unsigned, + command.signing_key, + &provider, + tx_count, + ) + .await?; + + Ok(account) +} #[cfg(test)] mod test { use super::*; diff --git a/forc-plugins/forc-client/src/op/mod.rs b/forc-plugins/forc-client/src/op/mod.rs index 44a1b055551..f11f8c63b7c 100644 --- a/forc-plugins/forc-client/src/op/mod.rs +++ b/forc-plugins/forc-client/src/op/mod.rs @@ -2,6 +2,6 @@ mod deploy; mod run; mod submit; -pub use deploy::{deploy, DeployedContract}; +pub use deploy::{deploy, DeployedContract, DeployedExecutable, DeployedPackage}; pub use run::run; pub use submit::submit; diff --git a/forc-plugins/forc-client/test/data/deployed_predicate/.gitignore b/forc-plugins/forc-client/test/data/deployed_predicate/.gitignore new file mode 100644 index 00000000000..77d3844f58c --- /dev/null +++ b/forc-plugins/forc-client/test/data/deployed_predicate/.gitignore @@ -0,0 +1,2 @@ +out +target diff --git a/forc-plugins/forc-client/test/data/deployed_predicate/Forc.lock b/forc-plugins/forc-client/test/data/deployed_predicate/Forc.lock new file mode 100644 index 00000000000..2be3d70a3ca --- /dev/null +++ b/forc-plugins/forc-client/test/data/deployed_predicate/Forc.lock @@ -0,0 +1,13 @@ +[[package]] +name = "core" +source = "path+from-root-661979F06117CBCE" + +[[package]] +name = "deployed_predicate" +source = "member" +dependencies = ["std"] + +[[package]] +name = "std" +source = "path+from-root-661979F06117CBCE" +dependencies = ["core"] diff --git a/forc-plugins/forc-client/test/data/deployed_predicate/Forc.toml b/forc-plugins/forc-client/test/data/deployed_predicate/Forc.toml new file mode 100644 index 00000000000..68b7cb9dff1 --- /dev/null +++ b/forc-plugins/forc-client/test/data/deployed_predicate/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "deployed_predicate" + +[dependencies] +std = { path = "../../../../../sway-lib-std/" } diff --git a/forc-plugins/forc-client/test/data/deployed_predicate/deployed_predicate-abi.json b/forc-plugins/forc-client/test/data/deployed_predicate/deployed_predicate-abi.json new file mode 100644 index 00000000000..f38d1dbedd6 --- /dev/null +++ b/forc-plugins/forc-client/test/data/deployed_predicate/deployed_predicate-abi.json @@ -0,0 +1,128 @@ +{ + "programType": "predicate", + "specVersion": "1", + "encodingVersion": "1", + "concreteTypes": [ + { + "type": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "type": "enum EnumWithGeneric", + "concreteTypeId": "37cd1cba311039a851ac8bfa614cc41359b4ad95c8656fcef2e8f504fe7a1272", + "metadataTypeId": 1, + "typeArguments": [ + "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + ] + }, + { + "type": "struct StructWithGeneric", + "concreteTypeId": "563310524b4f4447a10d0e50556310253dfb3b5eb4b29c3773222b737c8b7075", + "metadataTypeId": 3, + "typeArguments": [ + "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + ] + }, + { + "type": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "metadataTypes": [ + { + "type": "()", + "metadataTypeId": 0 + }, + { + "type": "enum EnumWithGeneric", + "metadataTypeId": 1, + "components": [ + { + "name": "VariantOne", + "typeId": 2 + }, + { + "name": "VariantTwo", + "typeId": 0 + } + ], + "typeParameters": [ + 2 + ] + }, + { + "type": "generic D", + "metadataTypeId": 2 + }, + { + "type": "struct StructWithGeneric", + "metadataTypeId": 3, + "components": [ + { + "name": "field_1", + "typeId": 2 + }, + { + "name": "field_2", + "typeId": 4 + } + ], + "typeParameters": [ + 2 + ] + }, + { + "type": "u64", + "metadataTypeId": 4 + } + ], + "functions": [ + { + "inputs": [ + { + "name": "switch", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "name": "u_8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + }, + { + "name": "some_struct", + "concreteTypeId": "563310524b4f4447a10d0e50556310253dfb3b5eb4b29c3773222b737c8b7075" + }, + { + "name": "some_enum", + "concreteTypeId": "37cd1cba311039a851ac8bfa614cc41359b4ad95c8656fcef2e8f504fe7a1272" + } + ], + "name": "main", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "attributes": null + } + ], + "loggedTypes": [], + "messagesTypes": [], + "configurables": [ + { + "name": "BOOL", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "offset": 1896 + }, + { + "name": "U8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "offset": 1936 + }, + { + "name": "STRUCT", + "concreteTypeId": "563310524b4f4447a10d0e50556310253dfb3b5eb4b29c3773222b737c8b7075", + "offset": 1920 + }, + { + "name": "ENUM", + "concreteTypeId": "37cd1cba311039a851ac8bfa614cc41359b4ad95c8656fcef2e8f504fe7a1272", + "offset": 1904 + } + ] +} \ No newline at end of file diff --git a/forc-plugins/forc-client/test/data/deployed_predicate/src/main.sw b/forc-plugins/forc-client/test/data/deployed_predicate/src/main.sw new file mode 100644 index 00000000000..f33b61faf40 --- /dev/null +++ b/forc-plugins/forc-client/test/data/deployed_predicate/src/main.sw @@ -0,0 +1,53 @@ +predicate; + +#[allow(dead_code)] +enum EnumWithGeneric { + VariantOne: D, + VariantTwo: (), +} + +struct StructWithGeneric { + field_1: D, + field_2: u64, +} + +impl Eq for EnumWithGeneric +where + D: Eq, +{ + fn eq(self, other: Self) -> bool { + match (self, other) { + (EnumWithGeneric::VariantOne(d1), EnumWithGeneric::VariantOne(d2)) => d1 == d2, + (EnumWithGeneric::VariantTwo, EnumWithGeneric::VariantTwo) => true, + _ => false, + } + } +} + +impl Eq for StructWithGeneric +where + D: Eq, +{ + fn eq(self, other: Self) -> bool { + self.field_1 == other.field_1 && self.field_2 == other.field_2 + } +} + +configurable { + BOOL: bool = true, + U8: u8 = 8, + STRUCT: StructWithGeneric = StructWithGeneric { + field_1: 8, + field_2: 16, + }, + ENUM: EnumWithGeneric = EnumWithGeneric::VariantOne(true), +} + +fn main( + switch: bool, + u_8: u8, + some_struct: StructWithGeneric, + some_enum: EnumWithGeneric, +) -> bool { + switch == BOOL && u_8 == U8 && some_struct == STRUCT && some_enum == ENUM +} diff --git a/forc-plugins/forc-client/test/data/deployed_script/.gitignore b/forc-plugins/forc-client/test/data/deployed_script/.gitignore new file mode 100644 index 00000000000..77d3844f58c --- /dev/null +++ b/forc-plugins/forc-client/test/data/deployed_script/.gitignore @@ -0,0 +1,2 @@ +out +target diff --git a/forc-plugins/forc-client/test/data/deployed_script/Forc.toml b/forc-plugins/forc-client/test/data/deployed_script/Forc.toml new file mode 100644 index 00000000000..3eb3cdf653b --- /dev/null +++ b/forc-plugins/forc-client/test/data/deployed_script/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "deployed_script" + +[dependencies] +std = { path = "../../../../../sway-lib-std/" } diff --git a/forc-plugins/forc-client/test/data/deployed_script/deployed_script-abi.json b/forc-plugins/forc-client/test/data/deployed_script/deployed_script-abi.json new file mode 100644 index 00000000000..7689a658d2a --- /dev/null +++ b/forc-plugins/forc-client/test/data/deployed_script/deployed_script-abi.json @@ -0,0 +1,312 @@ +{ + "programType": "script", + "specVersion": "1", + "encodingVersion": "1", + "concreteTypes": [ + { + "type": "((bool, u8, u16, u32, u64, u256, b256, str[4], (u8, bool), [u32; 3], struct StructWithGeneric, enum EnumWithGeneric), bool, u64, u8)", + "concreteTypeId": "25fbba860b8a1983ebcfa3f135136266a7edb7ca3a7e1f8ec988135c12a9f873", + "metadataTypeId": 2 + }, + { + "type": "(u8, bool)", + "concreteTypeId": "e0128f7be9902d1fe16326cafe703b52038064a7997b03ebfc1c9dd607e1536c", + "metadataTypeId": 1 + }, + { + "type": "[u32; 3]", + "concreteTypeId": "d9fac01ab38fe10950758ae9604da330d6406a71fda3ef1ea818121261132d56", + "metadataTypeId": 4 + }, + { + "type": "b256", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "type": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "type": "enum EnumWithGeneric", + "concreteTypeId": "37cd1cba311039a851ac8bfa614cc41359b4ad95c8656fcef2e8f504fe7a1272", + "metadataTypeId": 5, + "typeArguments": [ + "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + ] + }, + { + "type": "str[4]", + "concreteTypeId": "94f0fa95c830be5e4f711963e83259fe7e8bc723278ab6ec34449e791a99b53a" + }, + { + "type": "struct StructWithGeneric", + "concreteTypeId": "563310524b4f4447a10d0e50556310253dfb3b5eb4b29c3773222b737c8b7075", + "metadataTypeId": 7, + "typeArguments": [ + "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + ] + }, + { + "type": "u16", + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + }, + { + "type": "u256", + "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e" + }, + { + "type": "u32", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "type": "u64", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "type": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "metadataTypes": [ + { + "type": "()", + "metadataTypeId": 0 + }, + { + "type": "(_, _)", + "metadataTypeId": 1, + "components": [ + { + "name": "__tuple_element", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + }, + { + "name": "__tuple_element", + "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + ] + }, + { + "type": "(_, _, _, _)", + "metadataTypeId": 2, + "components": [ + { + "name": "__tuple_element", + "typeId": 3 + }, + { + "name": "__tuple_element", + "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "name": "__tuple_element", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "__tuple_element", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + }, + { + "type": "(_, _, _, _, _, _, _, _, _, _, _, _)", + "metadataTypeId": 3, + "components": [ + { + "name": "__tuple_element", + "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "name": "__tuple_element", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + }, + { + "name": "__tuple_element", + "typeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + }, + { + "name": "__tuple_element", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "__tuple_element", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "__tuple_element", + "typeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e" + }, + { + "name": "__tuple_element", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "name": "__tuple_element", + "typeId": "94f0fa95c830be5e4f711963e83259fe7e8bc723278ab6ec34449e791a99b53a" + }, + { + "name": "__tuple_element", + "typeId": 1 + }, + { + "name": "__tuple_element", + "typeId": 4 + }, + { + "name": "__tuple_element", + "typeId": 7, + "typeArguments": [ + { + "name": "", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + }, + { + "name": "__tuple_element", + "typeId": 5, + "typeArguments": [ + { + "name": "", + "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + ] + } + ] + }, + { + "type": "[_; 3]", + "metadataTypeId": 4, + "components": [ + { + "name": "__array_element", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ] + }, + { + "type": "enum EnumWithGeneric", + "metadataTypeId": 5, + "components": [ + { + "name": "VariantOne", + "typeId": 6 + }, + { + "name": "VariantTwo", + "typeId": 0 + } + ], + "typeParameters": [ + 6 + ] + }, + { + "type": "generic D", + "metadataTypeId": 6 + }, + { + "type": "struct StructWithGeneric", + "metadataTypeId": 7, + "components": [ + { + "name": "field_1", + "typeId": 6 + }, + { + "name": "field_2", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "typeParameters": [ + 6 + ] + } + ], + "functions": [ + { + "inputs": [ + { + "name": "a", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "contract_addr", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ], + "name": "main", + "output": "25fbba860b8a1983ebcfa3f135136266a7edb7ca3a7e1f8ec988135c12a9f873", + "attributes": null + } + ], + "loggedTypes": [ + { + "logId": "14454674236531057292", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "messagesTypes": [], + "configurables": [ + { + "name": "BOOL", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "offset": 8560 + }, + { + "name": "U8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "offset": 8672 + }, + { + "name": "U16", + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", + "offset": 8616 + }, + { + "name": "U32", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", + "offset": 8656 + }, + { + "name": "U64", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "offset": 8664 + }, + { + "name": "U256", + "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", + "offset": 8624 + }, + { + "name": "B256", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "offset": 8528 + }, + { + "name": "STR_4", + "concreteTypeId": "94f0fa95c830be5e4f711963e83259fe7e8bc723278ab6ec34449e791a99b53a", + "offset": 8600 + }, + { + "name": "TUPLE", + "concreteTypeId": "e0128f7be9902d1fe16326cafe703b52038064a7997b03ebfc1c9dd607e1536c", + "offset": 8608 + }, + { + "name": "ARRAY", + "concreteTypeId": "d9fac01ab38fe10950758ae9604da330d6406a71fda3ef1ea818121261132d56", + "offset": 8512 + }, + { + "name": "STRUCT", + "concreteTypeId": "563310524b4f4447a10d0e50556310253dfb3b5eb4b29c3773222b737c8b7075", + "offset": 8584 + }, + { + "name": "ENUM", + "concreteTypeId": "37cd1cba311039a851ac8bfa614cc41359b4ad95c8656fcef2e8f504fe7a1272", + "offset": 8568 + } + ] +} \ No newline at end of file diff --git a/forc-plugins/forc-client/test/data/deployed_script/src/main.sw b/forc-plugins/forc-client/test/data/deployed_script/src/main.sw new file mode 100644 index 00000000000..c47105d4d74 --- /dev/null +++ b/forc-plugins/forc-client/test/data/deployed_script/src/main.sw @@ -0,0 +1,72 @@ +script; + +use std::logging::log; + +#[allow(dead_code)] +enum EnumWithGeneric { + VariantOne: D, + VariantTwo: (), +} + +struct StructWithGeneric { + field_1: D, + field_2: u64, +} + +abi MyContract { + fn test_function() -> bool; + + #[storage(read)] + fn test_function_read() -> u8; + + #[storage(read, write)] + fn test_function_write(value: u8) -> u8; +} + +configurable { + BOOL: bool = true, + U8: u8 = 8, + U16: u16 = 16, + U32: u32 = 32, + U64: u64 = 63, + U256: u256 = 0x0000000000000000000000000000000000000000000000000000000000000008u256, + B256: b256 = 0x0101010101010101010101010101010101010101010101010101010101010101, + STR_4: str[4] = __to_str_array("fuel"), + TUPLE: (u8, bool) = (8, true), + ARRAY: [u32; 3] = [253, 254, 255], + STRUCT: StructWithGeneric = StructWithGeneric { + field_1: 8, + field_2: 16, + }, + ENUM: EnumWithGeneric = EnumWithGeneric::VariantOne(true), +} + +fn get_configurables() -> (bool, u8, u16, u32, u64, u256, b256, str[4], (u8, bool), [u32; 3], StructWithGeneric, EnumWithGeneric) { + (BOOL, U8, U16, U32, U64, U256, B256, STR_4, TUPLE, ARRAY, STRUCT, ENUM) +} + +fn basic_function_with_input(a: u32) -> bool { + if a % 2 == 0 { + true + }else { + false + } +} + +fn basic_function_without_input() -> u64 { + let a = 100; + let b = 25; + a*b +} + +fn main(a: u32, contract_addr: b256) -> ((bool, u8, u16, u32, u64, u256, b256, str[4], (u8, bool), [u32; 3], StructWithGeneric, EnumWithGeneric), bool, u64, u8) { + log(U8); + let configs = get_configurables(); + let with_in = basic_function_with_input(a); + let without_in = basic_function_without_input(); + + let contract_instance = abi(MyContract, contract_addr); + let from_contract = contract_instance.test_function_read(); + + return (configs, with_in, without_in, from_contract); +} diff --git a/forc-plugins/forc-client/tests/deploy.rs b/forc-plugins/forc-client/tests/deploy.rs index eb3c8e259a8..d751afbf662 100644 --- a/forc-plugins/forc-client/tests/deploy.rs +++ b/forc-plugins/forc-client/tests/deploy.rs @@ -1,7 +1,7 @@ use forc::cli::shared::Pkg; use forc_client::{ cmd, - op::{deploy, DeployedContract}, + op::{deploy, DeployedContract, DeployedExecutable, DeployedPackage}, util::{account::ForcClientAccount, tx::update_proxy_contract_target}, NodeTarget, }; @@ -10,9 +10,9 @@ use fuel_crypto::SecretKey; use fuel_tx::{ContractId, Salt}; use fuels::{ macros::abigen, - types::{transaction::TxPolicies, AsciiString, Bits256}, + types::{transaction::TxPolicies, AsciiString, Bits256, SizedAsciiString}, }; -use fuels_accounts::{provider::Provider, wallet::WalletUnlocked, Account}; +use fuels_accounts::{provider::Provider, wallet::WalletUnlocked, Account, ViewOnlyAccount}; use portpicker::Port; use rand::thread_rng; use rexpect::spawn; @@ -71,6 +71,37 @@ fn copy_dir(source: &Path, dest: &Path) -> anyhow::Result<()> { Ok(()) } +/// Tries to get an `DeployedContract` out of the given `DeployedPackage`. +/// Panics otherwise. +fn expect_deployed_contract(deployed_package: DeployedPackage) -> DeployedContract { + if let DeployedPackage::Contract(contract) = deployed_package { + contract + } else { + println!("{deployed_package:?}"); + panic!("expected deployed package to be a contract") + } +} + +/// Tries to get a script (`DeployedExecutable`) out of given deployed package. +/// Panics otherwise. +fn expect_deployed_script(deployed_package: DeployedPackage) -> DeployedExecutable { + if let DeployedPackage::Script(script) = deployed_package { + script + } else { + panic!("expected deployed package to be a script") + } +} + +/// Tries to get a predicate (`DeployedExecutable`) out of given deployed package. +/// Panics otherwise. +fn expect_deployed_predicate(deployed_package: DeployedPackage) -> DeployedExecutable { + if let DeployedPackage::Predicate(predicate) = deployed_package { + predicate + } else { + panic!("expected deployed package to be a predicate") + } +} + fn patch_manifest_file_with_path_std(manifest_dir: &Path) -> anyhow::Result<()> { let toml_path = manifest_dir.join(sway_utils::constants::MANIFEST_FILE_NAME); let toml_content = fs::read_to_string(&toml_path).unwrap(); @@ -339,14 +370,14 @@ async fn test_simple_deploy() { }; let contract_ids = deploy(cmd).await.unwrap(); node.kill().unwrap(); - let expected = vec![DeployedContract { + let expected = vec![DeployedPackage::Contract(DeployedContract { id: ContractId::from_str( "4ea5fa100cd7c8972bc8925ed6f8ccfb6bf1e16f79c3642c3a503c73b7d18de2", ) .unwrap(), proxy: None, chunked: false, - }]; + })]; assert_eq!(contract_ids, expected) } @@ -381,14 +412,14 @@ async fn test_deploy_submit_only() { }; let contract_ids = deploy(cmd).await.unwrap(); node.kill().unwrap(); - let expected = vec![DeployedContract { + let expected = vec![DeployedPackage::Contract(DeployedContract { id: ContractId::from_str( "4ea5fa100cd7c8972bc8925ed6f8ccfb6bf1e16f79c3642c3a503c73b7d18de2", ) .unwrap(), proxy: None, chunked: false, - }]; + })]; assert_eq!(contract_ids, expected) } @@ -426,7 +457,7 @@ async fn test_deploy_fresh_proxy() { }; let contract_ids = deploy(cmd).await.unwrap(); node.kill().unwrap(); - let impl_contract = DeployedContract { + let impl_contract = DeployedPackage::Contract(DeployedContract { id: ContractId::from_str( "4ea5fa100cd7c8972bc8925ed6f8ccfb6bf1e16f79c3642c3a503c73b7d18de2", ) @@ -438,7 +469,7 @@ async fn test_deploy_fresh_proxy() { .unwrap(), ), chunked: false, - }; + }); let expected = vec![impl_contract]; assert_eq!(contract_ids, expected) @@ -475,10 +506,10 @@ async fn test_proxy_contract_re_routes_call() { default_signer: true, ..Default::default() }; - let contract_ids = deploy(cmd).await.unwrap(); + let deployed_contract = expect_deployed_contract(deploy(cmd).await.unwrap().remove(0)); // At this point we deployed a contract with proxy. - let proxy_contract_id = contract_ids[0].proxy.unwrap(); - let impl_contract_id = contract_ids[0].id; + let proxy_contract_id = deployed_contract.proxy.unwrap(); + let impl_contract_id = deployed_contract.id; // Make a contract call into proxy contract, and check if the initial // contract returns a true. let provider = Provider::connect(&node_url).await.unwrap(); @@ -537,11 +568,11 @@ async fn test_proxy_contract_re_routes_call() { default_signer: true, ..Default::default() }; - let contract_ids = deploy(cmd).await.unwrap(); + let deployed_contract = expect_deployed_contract(deploy(cmd).await.unwrap().remove(0)); // proxy contract id should be the same. - let proxy_contract_after_update = contract_ids[0].proxy.unwrap(); + let proxy_contract_after_update = deployed_contract.proxy.unwrap(); assert_eq!(proxy_contract_id, proxy_contract_after_update); - let impl_contract_id_after_update = contract_ids[0].id; + let impl_contract_id_after_update = deployed_contract.id; assert!(impl_contract_id != impl_contract_id_after_update); let impl_contract_a = ImplementationContract::new(proxy_contract_after_update, wallet_unlocked); @@ -606,9 +637,9 @@ async fn test_non_owner_fails_to_set_target() { default_signer: true, ..Default::default() }; - let contract_id = deploy(cmd).await.unwrap(); + let contract_id = expect_deployed_contract(deploy(cmd).await.unwrap().remove(0)); // Proxy contract's id. - let proxy_id = contract_id.first().and_then(|f| f.proxy).unwrap(); + let proxy_id = contract_id.proxy.unwrap(); // Create and fund an owner account and an attacker account. let provider = Provider::connect(&node_url).await.unwrap(); @@ -709,7 +740,7 @@ async fn chunked_deploy() { default_signer: true, ..Default::default() }; - let deployed_contract = deploy(cmd).await.unwrap().remove(0); + let deployed_contract = expect_deployed_contract(deploy(cmd).await.unwrap().remove(0)); node.kill().unwrap(); assert!(deployed_contract.chunked); @@ -741,7 +772,7 @@ async fn chunked_deploy_re_routes_calls() { default_signer: true, ..Default::default() }; - let deployed_contract = deploy(cmd).await.unwrap().remove(0); + let deployed_contract = expect_deployed_contract(deploy(cmd).await.unwrap().remove(0)); let provider = Provider::connect(&node_url).await.unwrap(); let secret_key = SecretKey::from_str(forc_client::constants::DEFAULT_PRIVATE_KEY).unwrap(); @@ -783,7 +814,7 @@ async fn chunked_deploy_with_proxy_re_routes_call() { default_signer: true, ..Default::default() }; - let deployed_contract = deploy(cmd).await.unwrap().remove(0); + let deployed_contract = expect_deployed_contract(deploy(cmd).await.unwrap().remove(0)); let provider = Provider::connect(&node_url).await.unwrap(); let secret_key = SecretKey::from_str(forc_client::constants::DEFAULT_PRIVATE_KEY).unwrap(); @@ -793,3 +824,269 @@ async fn chunked_deploy_with_proxy_re_routes_call() { node.kill().unwrap(); } + +#[tokio::test] +async fn can_deploy_script() { + let (mut node, port) = run_node(); + let tmp_dir = tempdir().unwrap(); + let project_dir = test_data_path().join("deployed_script"); + copy_dir(&project_dir, tmp_dir.path()).unwrap(); + patch_manifest_file_with_path_std(tmp_dir.path()).unwrap(); + + let node_url = format!("http://127.0.0.1:{}/v1/graphql", port); + let target = NodeTarget { + node_url: Some(node_url.clone()), + target: None, + testnet: false, + }; + let pkg = Pkg { + path: Some(tmp_dir.path().display().to_string()), + ..Default::default() + }; + let cmd = cmd::Deploy { + pkg, + salt: Some(vec![format!("{}", Salt::default())]), + node: target, + default_signer: true, + ..Default::default() + }; + + expect_deployed_script(deploy(cmd).await.unwrap().remove(0)); + node.kill().unwrap(); +} + +#[tokio::test] +async fn deploy_script_calls() { + let (mut node, port) = run_node(); + let tmp_dir = tempdir().unwrap(); + let project_dir = test_data_path().join("deployed_script"); + copy_dir(&project_dir, tmp_dir.path()).unwrap(); + patch_manifest_file_with_path_std(tmp_dir.path()).unwrap(); + + let node_url = format!("http://127.0.0.1:{}/v1/graphql", port); + let target = NodeTarget { + node_url: Some(node_url.clone()), + target: None, + testnet: false, + }; + let pkg = Pkg { + path: Some(tmp_dir.path().display().to_string()), + ..Default::default() + }; + let cmd = cmd::Deploy { + pkg, + salt: Some(vec![format!("{}", Salt::default())]), + node: target, + default_signer: true, + ..Default::default() + }; + + expect_deployed_script(deploy(cmd).await.unwrap().remove(0)); + + // Deploy the contract the script is going to be calling. + let contract_tmp_dir = tempdir().unwrap(); + let project_dir = test_data_path().join("standalone_contract"); + copy_dir(&project_dir, contract_tmp_dir.path()).unwrap(); + patch_manifest_file_with_path_std(contract_tmp_dir.path()).unwrap(); + + let pkg = Pkg { + path: Some(contract_tmp_dir.path().display().to_string()), + ..Default::default() + }; + + let node_url = format!("http://127.0.0.1:{}/v1/graphql", port); + let target = NodeTarget { + node_url: Some(node_url.clone()), + target: None, + testnet: false, + }; + let cmd = cmd::Deploy { + pkg, + salt: Some(vec![format!("{}", Salt::default())]), + node: target, + default_signer: true, + ..Default::default() + }; + let deployed_packages = deploy(cmd).await.unwrap().remove(0); + let contract = expect_deployed_contract(deployed_packages); + let contract_id = contract.id; + + abigen!(Script( + name = "MyScript", + abi = "forc-plugins/forc-client/test/data/deployed_script/deployed_script-abi.json" + )); + + let provider = Provider::connect(&node_url).await.unwrap(); + let secret_key = SecretKey::from_str(forc_client::constants::DEFAULT_PRIVATE_KEY).unwrap(); + let wallet_unlocked = WalletUnlocked::new_from_private_key(secret_key, Some(provider)); + + let loader_path = tmp_dir.path().join("out/deployed_script-loader.bin"); + let instance = MyScript::new(wallet_unlocked, &loader_path.display().to_string()); + + let contract_id_bits256 = Bits256(contract.id.into()); + let call_handler = instance + .main(10, contract_id_bits256) + .with_contract_ids(&[contract_id.into()]) + .call() + .await + .unwrap(); + let (configs, with_input, without_input, from_contract) = call_handler.value; + let receipts = call_handler.receipts; + + assert!(configs.0); // bool + assert_eq!(configs.1, 8); // u8 + assert_eq!(configs.2, 16); // u16 + assert_eq!(configs.3, 32); // u32 + assert_eq!(configs.4, 63); // u64 + assert_eq!(configs.5, 8.into()); // u256 + assert_eq!( + configs.6, + Bits256::from_hex_str("0x0101010101010101010101010101010101010101010101010101010101010101") + .unwrap() + ); // b256 + assert_eq!( + configs.7, + SizedAsciiString::new("fuel".to_string()).unwrap() + ); // str[4] + assert_eq!(configs.8, (8, true)); // tuple + assert_eq!(configs.9, [253, 254, 255]); // array + + let expected_struct = StructWithGeneric { + field_1: 8, + field_2: 16, + }; + assert_eq!(configs.10, expected_struct); // struct + + let expected_enum = EnumWithGeneric::VariantOne(true); + assert_eq!(configs.11, expected_enum); // enum + + assert!(with_input); // 10 % 2 == 0 + assert_eq!(without_input, 2500); // 25 * 100 = 2500 + + assert_eq!(from_contract, 5); + + receipts.iter().find(|receipt| { + if let fuel_tx::Receipt::LogData { data, .. } = receipt { + *data == Some(vec![0x08]) + } else { + false + } + }); + + node.kill().unwrap(); +} + +#[tokio::test] +async fn can_deploy_predicates() { + let (mut node, port) = run_node(); + let tmp_dir = tempdir().unwrap(); + let project_dir = test_data_path().join("deployed_predicate"); + copy_dir(&project_dir, tmp_dir.path()).unwrap(); + patch_manifest_file_with_path_std(tmp_dir.path()).unwrap(); + + let node_url = format!("http://127.0.0.1:{}/v1/graphql", port); + let target = NodeTarget { + node_url: Some(node_url.clone()), + target: None, + testnet: false, + }; + let pkg = Pkg { + path: Some(tmp_dir.path().display().to_string()), + ..Default::default() + }; + let cmd = cmd::Deploy { + pkg, + salt: Some(vec![format!("{}", Salt::default())]), + node: target, + default_signer: true, + ..Default::default() + }; + + expect_deployed_predicate(deploy(cmd).await.unwrap().remove(0)); + node.kill().unwrap(); +} + +#[tokio::test] +async fn deployed_predicate_call() { + let (mut node, port) = run_node(); + let tmp_dir = tempdir().unwrap(); + let project_dir = test_data_path().join("deployed_predicate"); + copy_dir(&project_dir, tmp_dir.path()).unwrap(); + patch_manifest_file_with_path_std(tmp_dir.path()).unwrap(); + + let node_url = format!("http://127.0.0.1:{}/v1/graphql", port); + let target = NodeTarget { + node_url: Some(node_url.clone()), + target: None, + testnet: false, + }; + let pkg = Pkg { + path: Some(tmp_dir.path().display().to_string()), + ..Default::default() + }; + let cmd = cmd::Deploy { + pkg, + salt: Some(vec![format!("{}", Salt::default())]), + node: target, + default_signer: true, + ..Default::default() + }; + expect_deployed_predicate(deploy(cmd).await.unwrap().remove(0)); + + abigen!(Predicate( + name = "MyPredicate", + abi = "forc-plugins/forc-client/test/data/deployed_predicate/deployed_predicate-abi.json" + )); + + let provider = Provider::connect(&node_url).await.unwrap(); + let base_asset_id = *provider.base_asset_id(); + let secret_key = SecretKey::from_str(forc_client::constants::DEFAULT_PRIVATE_KEY).unwrap(); + let wallet_unlocked = WalletUnlocked::new_from_private_key(secret_key, Some(provider.clone())); + let loader_path = tmp_dir.path().join("out/deployed_predicate-loader.bin"); + let strct = StructWithGeneric { + field_1: 8, + field_2: 16, + }; + let enm = EnumWithGeneric::VariantOne(true); + let encoded_data = MyPredicateEncoder::default() + .encode_data(true, 8, strct, enm) + .unwrap(); + let predicate: fuels::prelude::Predicate = + fuels::prelude::Predicate::load_from(&loader_path.display().to_string()) + .unwrap() + .with_data(encoded_data) + .with_provider(provider); + + // lock some amount under the predicate + wallet_unlocked + .transfer( + predicate.address(), + 500, + base_asset_id, + TxPolicies::default(), + ) + .await + .unwrap(); + + // Check predicate balance. + let balance = predicate.get_asset_balance(&base_asset_id).await.unwrap(); + assert_eq!(balance, 500); + + // Try to spend it + let amount_to_unlock = 300; + predicate + .transfer( + wallet_unlocked.address(), + amount_to_unlock, + base_asset_id, + TxPolicies::default(), + ) + .await + .unwrap(); + + // Check predicate balance again. + let balance = predicate.get_asset_balance(&base_asset_id).await.unwrap(); + assert_eq!(balance, 200); + + node.kill().unwrap(); +} diff --git a/forc-plugins/forc-tx/Cargo.toml b/forc-plugins/forc-tx/Cargo.toml index a6a552585a6..91fee672cf3 100644 --- a/forc-plugins/forc-tx/Cargo.toml +++ b/forc-plugins/forc-tx/Cargo.toml @@ -20,7 +20,7 @@ anyhow.workspace = true clap = { workspace = true, features = ["derive", "env"] } devault.workspace = true forc-util.workspace = true -fuel-tx = { workspace = true, features = ["random", "serde", "test-helpers"] } +fuel-tx = { workspace = true, features = ["random", "test-helpers"] } fuel-types = { workspace = true, features = ["serde"] } serde.workspace = true serde_json.workspace = true diff --git a/forc-util/Cargo.toml b/forc-util/Cargo.toml index 47e702cec70..f224c3028cb 100644 --- a/forc-util/Cargo.toml +++ b/forc-util/Cargo.toml @@ -16,7 +16,7 @@ clap = { workspace = true, features = ["cargo", "derive", "env"] } dirs.workspace = true fd-lock.workspace = true forc-tracing.workspace = true -fuel-tx = { workspace = true, features = ["serde"], optional = true } +fuel-tx = { workspace = true, optional = true } hex.workspace = true paste.workspace = true regex.workspace = true diff --git a/test/src/e2e_vm_tests/harness.rs b/test/src/e2e_vm_tests/harness.rs index e2a3236db07..6c3f7c307d9 100644 --- a/test/src/e2e_vm_tests/harness.rs +++ b/test/src/e2e_vm_tests/harness.rs @@ -2,7 +2,7 @@ use anyhow::{anyhow, bail, Result}; use colored::Colorize; use forc_client::{ cmd::{Deploy as DeployCommand, Run as RunCommand}, - op::{deploy, run}, + op::{deploy, run, DeployedPackage}, NodeTarget, }; use forc_pkg::{ @@ -67,7 +67,7 @@ pub(crate) async fn deploy_contract(file_name: &str, run_config: &RunConfig) -> println!(" Deploying {} ...", file_name.bold()); let manifest_dir = env!("CARGO_MANIFEST_DIR"); - deploy(DeployCommand { + let deployed_packages = deploy(DeployCommand { pkg: forc_client::cmd::deploy::Pkg { path: Some(format!( "{manifest_dir}/src/e2e_vm_tests/test_programs/{file_name}" @@ -85,13 +85,20 @@ pub(crate) async fn deploy_contract(file_name: &str, run_config: &RunConfig) -> no_encoding_v1: !run_config.experimental.new_encoding, ..Default::default() }) - .await - .map(|contract_ids| { - contract_ids - .first() - .map(|contract_id| contract_id.id) - .unwrap() - }) + .await?; + + deployed_packages + .into_iter() + .map(|deployed_pkg| { + if let DeployedPackage::Contract(deployed_contract) = deployed_pkg { + Some(deployed_contract.id) + } else { + None + } + }) + .next() + .flatten() + .ok_or_else(|| anyhow!("expected to find at least one deployed contract.")) } /// Run a given project against a node. Assumes the node is running at localhost:4000. diff --git a/test/src/sdk-harness/Cargo.lock b/test/src/sdk-harness/Cargo.lock index 23af427650a..a6bed9abb7b 100644 --- a/test/src/sdk-harness/Cargo.lock +++ b/test/src/sdk-harness/Cargo.lock @@ -236,9 +236,9 @@ checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" [[package]] name = "async-graphql" -version = "7.0.6" +version = "7.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf338d20ba5bab309f55ce8df95d65ee19446f7737f06f4a64593ab2c6b546ad" +checksum = "0ba6d24703c5adc5ba9116901b92ee4e4c0643c01a56c4fd303f3818638d7449" dependencies = [ "async-graphql-derive", "async-graphql-parser", @@ -248,6 +248,7 @@ dependencies = [ "base64 0.22.1", "bytes", "fnv", + "futures-timer", "futures-util", "http 1.1.0", "indexmap 2.2.6", @@ -268,13 +269,13 @@ dependencies = [ [[package]] name = "async-graphql-derive" -version = "7.0.6" +version = "7.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc51fd6b7102acda72bc94e8ae1543844d5688ff394a6cf7c21f2a07fe2d64e4" +checksum = "a94c2d176893486bd37cd1b6defadd999f7357bf5804e92f510c08bcf16c538f" dependencies = [ "Inflector", "async-graphql-parser", - "darling 0.20.8", + "darling 0.20.10", "proc-macro-crate", "proc-macro2", "quote", @@ -285,9 +286,9 @@ dependencies = [ [[package]] name = "async-graphql-parser" -version = "7.0.6" +version = "7.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75361eefd64e39f89bead4cb45fddbaf60ddb0e7b15fb7c852b6088bcd63071f" +checksum = "79272bdbf26af97866e149f05b2b546edb5c00e51b5f916289931ed233e208ad" dependencies = [ "async-graphql-value", "pest", @@ -297,9 +298,9 @@ dependencies = [ [[package]] name = "async-graphql-value" -version = "7.0.6" +version = "7.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1f665d2d52b41c4ed1f01c43f3ef27a2fe0af2452ed5c8bc7ac9b1a8719afaa" +checksum = "ef5ec94176a12a8cbe985cd73f2e54dc9c702c88c766bdef12f1f3a67cedbee1" dependencies = [ "bytes", "indexmap 2.2.6", @@ -1191,12 +1192,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.8" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ - "darling_core 0.20.8", - "darling_macro 0.20.8", + "darling_core 0.20.10", + "darling_macro 0.20.10", ] [[package]] @@ -1215,15 +1216,15 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.8" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "strsim 0.10.0", + "strsim 0.11.1", "syn 2.0.63", ] @@ -1240,11 +1241,11 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.8" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ - "darling_core 0.20.8", + "darling_core 0.20.10", "quote", "syn 2.0.63", ] @@ -1594,9 +1595,9 @@ dependencies = [ [[package]] name = "eventsource-client" -version = "0.12.2" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c80c6714d1a380314fcb11a22eeff022e1e1c9642f0bb54e15dc9cb29f37b29" +checksum = "43ddc25e1ad2cc0106d5e2d967397b4fb2068a66677ee9b0eea4600e5cfe8fb4" dependencies = [ "futures", "hyper", @@ -1706,21 +1707,32 @@ dependencies = [ [[package]] name = "fuel-asm" -version = "0.57.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b29ea55a794c00d0dfaad06f11720a05fa928603f812dca1c38163f2b240860a" +checksum = "79ca07227658105bdf873556dea09fa7fbfe792fbc084b4b9568f5ba3d64c411" dependencies = [ "bitflags 2.5.0", - "fuel-types 0.57.0", + "fuel-types 0.58.0", "serde", "strum 0.24.1", ] +[[package]] +name = "fuel-compression" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3af97bfc2c2b4f0a7f471141663557f13462d7ac278922b01ebaf2127e7515f3" +dependencies = [ + "fuel-derive 0.58.0", + "fuel-types 0.58.0", + "serde", +] + [[package]] name = "fuel-core" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a36ed389d86361845a354d4d0e80620e811c575f937840a11c616e6e409021f8" +checksum = "e8bc5d6df88c21c821bf56dfa0bbd148c18b5153551c4119e5497ab7b90b3d22" dependencies = [ "anyhow", "async-graphql", @@ -1730,6 +1742,7 @@ dependencies = [ "derive_more", "enum-iterator", "fuel-core-chain-config", + "fuel-core-compression", "fuel-core-consensus-module", "fuel-core-database", "fuel-core-executor", @@ -1742,13 +1755,14 @@ dependencies = [ "fuel-core-services", "fuel-core-storage", "fuel-core-txpool", - "fuel-core-types 0.36.0", + "fuel-core-types 0.37.0", "fuel-core-upgradable-executor", "futures", "hex", "hyper", "indicatif", "itertools 0.12.1", + "paste", "rand", "serde", "serde_json", @@ -1766,15 +1780,15 @@ dependencies = [ [[package]] name = "fuel-core-chain-config" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a4c5a71702426b8354bff2010131c0abb4a4f0b608cc7a6dfd72f9e785ba478" +checksum = "cd1eca1d12daf8ad0f2479d7fff9405d94b6467496e5319e5f8b99cbdabdd58b" dependencies = [ "anyhow", "bech32", "derivative", "fuel-core-storage", - "fuel-core-types 0.36.0", + "fuel-core-types 0.37.0", "itertools 0.12.1", "postcard", "rand", @@ -1786,15 +1800,16 @@ dependencies = [ [[package]] name = "fuel-core-client" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5770dbda6220e641eb57ee204dd5914fa15170afe3009473f57cdf15e2339fd8" +checksum = "9dbd88f285afdf061e409b712ecef49e2fe9ba235288cc76e8de8f05d50b6876" dependencies = [ "anyhow", + "base64 0.22.1", "cynic", "derive_more", "eventsource-client", - "fuel-core-types 0.36.0", + "fuel-core-types 0.37.0", "futures", "hex", "hyper-rustls", @@ -1808,40 +1823,55 @@ dependencies = [ "tracing", ] +[[package]] +name = "fuel-core-compression" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25fdfc8202216391d0dfc87922eaf2576100c618ed67a8244212ca58dd1b2171" +dependencies = [ + "anyhow", + "fuel-core-types 0.37.0", + "paste", + "rand", + "serde", + "strum 0.25.0", + "strum_macros 0.25.3", +] + [[package]] name = "fuel-core-consensus-module" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f97a3fc636d057db88cf7087aa996de9825335980092c4e894749674d599f7d" +checksum = "a95b4d2df8d8099839f3f3c00429c1af5271783d24007481711c37f579bfd4da" dependencies = [ "anyhow", "fuel-core-chain-config", "fuel-core-poa", "fuel-core-storage", - "fuel-core-types 0.36.0", + "fuel-core-types 0.37.0", ] [[package]] name = "fuel-core-database" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5844c2cf72d4a29d512bcb295f5528c9b8ddbf8ecbf82c3f41001451f5f4ec6f" +checksum = "b466baa45ea41ca9141b3e4ff2b5387f10d274f484561755f9b0d9c953892083" dependencies = [ "anyhow", "derive_more", "fuel-core-storage", - "fuel-core-types 0.36.0", + "fuel-core-types 0.37.0", ] [[package]] name = "fuel-core-executor" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e46400b0e816da2efeee58e5822dfe7ffc1218516456159939968a59417a20af" +checksum = "71858c962367af3c3e5c651c2ea62f1d268d7bc77e6326cd4a206d74a58d0dec" dependencies = [ "anyhow", "fuel-core-storage", - "fuel-core-types 0.36.0", + "fuel-core-types 0.37.0", "hex", "parking_lot", "serde", @@ -1850,16 +1880,16 @@ dependencies = [ [[package]] name = "fuel-core-gas-price-service" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "390c5c33743633c1c70eaa5aaef27f87ad2ab9a79adba7a321c4899fad4c53ee" +checksum = "e33755cb67a3892c5dd058b0f2c022d0f16adebf6bb29a94814794044fbb6a67" dependencies = [ "anyhow", "async-trait", "enum-iterator", "fuel-core-services", "fuel-core-storage", - "fuel-core-types 0.36.0", + "fuel-core-types 0.37.0", "fuel-gas-price-algorithm", "futures", "num_enum", @@ -1875,15 +1905,15 @@ dependencies = [ [[package]] name = "fuel-core-importer" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d6710d343bf04f100f8c3bd4324ce60164e7ca3a8c167915a907180abf23332" +checksum = "7fc8cea1fabe1a51bdabce436d7040d29b3a4d14c0429289060d0a754a1b1a46" dependencies = [ "anyhow", "derive_more", "fuel-core-metrics", "fuel-core-storage", - "fuel-core-types 0.36.0", + "fuel-core-types 0.37.0", "parking_lot", "rayon", "tokio", @@ -1892,9 +1922,9 @@ dependencies = [ [[package]] name = "fuel-core-metrics" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f671e9e813b81873ef07e1cfe8697ba3f9fd0f05313879ed0933446da4c1c14" +checksum = "dfc199e165e600f241cab86129766b26bab78572a701a39bc40a5fdb669961a8" dependencies = [ "parking_lot", "pin-project-lite", @@ -1905,9 +1935,9 @@ dependencies = [ [[package]] name = "fuel-core-p2p" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2453df795ce5e9a22f7ac10bc3436974612d0d698dcb918b2179c5e24b4bfb4a" +checksum = "42ae4fa0826f148c13248db4fe634d2ba7a297bbd424e7288c6e1d881a50f662" dependencies = [ "anyhow", "async-trait", @@ -1915,7 +1945,7 @@ dependencies = [ "fuel-core-metrics", "fuel-core-services", "fuel-core-storage", - "fuel-core-types 0.36.0", + "fuel-core-types 0.37.0", "futures", "hex", "hickory-resolver", @@ -1939,16 +1969,16 @@ dependencies = [ [[package]] name = "fuel-core-poa" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b698e7c184ab4acbaabe7bad73fdc7dfc9ebfc3a6856b1d719a4fd4c1921873" +checksum = "49c4f3e5fa1e916793609bdb9a52142077a84a793272379a04cf24375aa94e6f" dependencies = [ "anyhow", "async-trait", "fuel-core-chain-config", "fuel-core-services", "fuel-core-storage", - "fuel-core-types 0.36.0", + "fuel-core-types 0.37.0", "serde", "serde_json", "tokio", @@ -1958,15 +1988,15 @@ dependencies = [ [[package]] name = "fuel-core-producer" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff23a51239988a9aaf451afa05a1ca7920b4e900319d511bd40bf1e04e414ce1" +checksum = "642d4a10f1df444a09944ae547f1782ca865ac4705ea9cefe0821c5a8e4b3081" dependencies = [ "anyhow", "async-trait", "derive_more", "fuel-core-storage", - "fuel-core-types 0.36.0", + "fuel-core-types 0.37.0", "tokio", "tokio-rayon", "tracing", @@ -1974,9 +2004,9 @@ dependencies = [ [[package]] name = "fuel-core-services" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "998a4f9d057bf3efe43be574bd200ef64c3318007fd04523ce6bd51cc7bb963c" +checksum = "739dca83db1eb86651db3833f088f52afcd3f181cfca40e5725074aceb3ea49d" dependencies = [ "anyhow", "async-trait", @@ -1989,15 +2019,15 @@ dependencies = [ [[package]] name = "fuel-core-storage" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1daa7422e48120b1623b53fe1a1152d11314f30fb290a73dc80f7e128c1f9014" +checksum = "6255d852b6866199d103233e1eef2e7ded141019bc782b5b211fcf001727c34b" dependencies = [ "anyhow", "derive_more", "enum-iterator", - "fuel-core-types 0.36.0", - "fuel-vm 0.57.0", + "fuel-core-types 0.37.0", + "fuel-vm 0.58.0", "impl-tools", "itertools 0.12.1", "mockall", @@ -2013,9 +2043,9 @@ dependencies = [ [[package]] name = "fuel-core-txpool" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5d2c7d515be53c36070fadbae61a59025ef4a41d20d38e7f2ad71237c4dded" +checksum = "e7b4667213fa8aca461f49c9b305f1f2abda2848a2da5323999d82e3dc76a723" dependencies = [ "anyhow", "async-trait", @@ -2023,10 +2053,12 @@ dependencies = [ "fuel-core-metrics", "fuel-core-services", "fuel-core-storage", - "fuel-core-types 0.36.0", + "fuel-core-types 0.37.0", + "futures", "mockall", "num-rational", "parking_lot", + "rayon", "tokio", "tokio-rayon", "tokio-stream", @@ -2051,15 +2083,15 @@ dependencies = [ [[package]] name = "fuel-core-types" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aa1c54f09cc7c29a11ca1129f73105745f8374a192e3e24040c10822871d83f" +checksum = "33a4e9b2de06381e1ad598cd1030344993fee7401331ca9955d0a1860cc0484c" dependencies = [ "anyhow", "bs58", "derivative", "derive_more", - "fuel-vm 0.57.0", + "fuel-vm 0.58.0", "rand", "secrecy", "serde", @@ -2069,15 +2101,15 @@ dependencies = [ [[package]] name = "fuel-core-upgradable-executor" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89c636782a522cc49f9e5d43e29b15632a5db930959b8bca9dbf8a6adac76415" +checksum = "768bf8bbb7d27d13b5055ad7b755609e027b5a322b3b21790fac7a478685ba14" dependencies = [ "anyhow", "derive_more", "fuel-core-executor", "fuel-core-storage", - "fuel-core-types 0.36.0", + "fuel-core-types 0.37.0", "fuel-core-wasm-executor", "parking_lot", "postcard", @@ -2087,15 +2119,15 @@ dependencies = [ [[package]] name = "fuel-core-wasm-executor" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52d69a92fba4ccba773b207dd740f04893dbdd0c76dffbebddfebb13c69eea0c" +checksum = "385ce8e704a7370ec5230ba3bd7d986cbe66174f400160b54cf76799a578609e" dependencies = [ "anyhow", "fuel-core-executor", "fuel-core-storage", "fuel-core-types 0.35.0", - "fuel-core-types 0.36.0", + "fuel-core-types 0.37.0", "postcard", "serde", "serde_json", @@ -2119,15 +2151,15 @@ dependencies = [ [[package]] name = "fuel-crypto" -version = "0.57.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2661b2a6c43e811be4892250513a6f4c46a69cc7092a1e5b240f49697f08292e" +checksum = "f53b06525aa7754bf7c3ef23daf15fd798ae990a82f8b7b813d25cedfeacfe5c" dependencies = [ "coins-bip32", "coins-bip39", "ecdsa", "ed25519-dalek", - "fuel-types 0.57.0", + "fuel-types 0.58.0", "k256", "lazy_static", "p256", @@ -2152,9 +2184,9 @@ dependencies = [ [[package]] name = "fuel-derive" -version = "0.57.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03509567813a351ca60d8507b2ac476b06c1590f2e9edbe72bc205bb04e0af12" +checksum = "c8e34d6eec30d04506607cc0bc85fc97c57c964580cd233fd557e346c5273535" dependencies = [ "proc-macro2", "quote", @@ -2164,9 +2196,9 @@ dependencies = [ [[package]] name = "fuel-gas-price-algorithm" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a69655b9d140ad98d3e8a333e64814876c63ffe6097fd80e68cdd427514912d" +checksum = "15d4a5847c09db9159ea66bc75bdfe59c4d6139d8b24c1a8026f253f011409bc" dependencies = [ "serde", "thiserror", @@ -2189,13 +2221,13 @@ dependencies = [ [[package]] name = "fuel-merkle" -version = "0.57.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24938ee8a5e9efe71994203527dffb4c81872aa2953de0c347ad38696527b58a" +checksum = "7a9fa3708405eba32fd2b947b827dc52484377ba6a238260b03a07b642395e6c" dependencies = [ "derive_more", "digest 0.10.7", - "fuel-storage 0.57.0", + "fuel-storage 0.58.0", "hashbrown 0.13.2", "hex", "serde", @@ -2210,9 +2242,9 @@ checksum = "4c1b711f28553ddc5f3546711bd220e144ce4c1af7d9e9a1f70b2f20d9f5b791" [[package]] name = "fuel-storage" -version = "0.57.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4283f9cabc26a1154a31268e79de1e0f317d57231b4dc8d7282efb22e49d2ed3" +checksum = "f6f678f1c900d0632d77e15d4a4946048d4d517fefeba72607390c03288ca127" [[package]] name = "fuel-tx" @@ -2238,23 +2270,23 @@ dependencies = [ [[package]] name = "fuel-tx" -version = "0.57.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f9e8fdda6abfe83cf1456a11eabf1de66d682176fb097f2f950704cc50c26" +checksum = "1e3065c12eecc9121514694f4b01009c9a83d8842af11c43ec9e2bbc0a7f36cb" dependencies = [ "bitflags 2.5.0", "derivative", "derive_more", - "fuel-asm 0.57.0", - "fuel-crypto 0.57.0", - "fuel-merkle 0.57.0", - "fuel-types 0.57.0", + "fuel-asm 0.58.0", + "fuel-compression", + "fuel-crypto 0.58.0", + "fuel-merkle 0.58.0", + "fuel-types 0.58.0", "hashbrown 0.14.5", "itertools 0.10.5", "postcard", "rand", "serde", - "serde_json", "strum 0.24.1", "strum_macros 0.24.3", ] @@ -2272,11 +2304,11 @@ dependencies = [ [[package]] name = "fuel-types" -version = "0.57.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f196060a10db0293cdfca455f7e2f3a7914f46f25e0fbc2d28cf0a11e835a86" +checksum = "a93d5f3fd028d874d8927be439fcdea01cb04499049bc68a874c73dd0c7e32b7" dependencies = [ - "fuel-derive 0.57.0", + "fuel-derive 0.58.0", "hex", "rand", "serde", @@ -2315,9 +2347,9 @@ dependencies = [ [[package]] name = "fuel-vm" -version = "0.57.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6f4e0cc4ae65d00df6f3dcae90b81dd21135b45b932a79e368f35d255df12a1" +checksum = "cb0562398978e501e8ee2caeb747a2852cc4a8c5fff250eb58e38f1c03217311" dependencies = [ "anyhow", "async-trait", @@ -2326,12 +2358,13 @@ dependencies = [ "derivative", "derive_more", "ethnum", - "fuel-asm 0.57.0", - "fuel-crypto 0.57.0", - "fuel-merkle 0.57.0", - "fuel-storage 0.57.0", - "fuel-tx 0.57.0", - "fuel-types 0.57.0", + "fuel-asm 0.58.0", + "fuel-compression", + "fuel-crypto 0.58.0", + "fuel-merkle 0.58.0", + "fuel-storage 0.58.0", + "fuel-tx 0.58.0", + "fuel-types 0.58.0", "hashbrown 0.14.5", "itertools 0.10.5", "libm", @@ -2349,13 +2382,13 @@ dependencies = [ [[package]] name = "fuels" -version = "0.66.5" +version = "0.66.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaf7ca0443308f4c3d3e9dd7ed67cb18369ae63d208302056d6d5f3a09efb031" +checksum = "921a8ea521744e600e0a34236adff7524ecf34bd940c2a018315d0212c140d7b" dependencies = [ "fuel-core-client", - "fuel-crypto 0.57.0", - "fuel-tx 0.57.0", + "fuel-crypto 0.58.0", + "fuel-tx 0.58.0", "fuels-accounts", "fuels-core", "fuels-macros", @@ -2365,19 +2398,19 @@ dependencies = [ [[package]] name = "fuels-accounts" -version = "0.66.5" +version = "0.66.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ea69afa418ba67b9572a5b4cb612b80ee2113c9f755e93acf7adc9fc1454d1" +checksum = "2da8bad87e947fc448c44c22e4c90a4af49d61de08722b1d1774d977b2071047" dependencies = [ "async-trait", "chrono", "elliptic-curve", "eth-keystore", "fuel-core-client", - "fuel-core-types 0.36.0", - "fuel-crypto 0.57.0", - "fuel-tx 0.57.0", - "fuel-types 0.57.0", + "fuel-core-types 0.37.0", + "fuel-crypto 0.58.0", + "fuel-tx 0.58.0", + "fuel-types 0.58.0", "fuels-core", "itertools 0.12.1", "rand", @@ -2390,9 +2423,9 @@ dependencies = [ [[package]] name = "fuels-code-gen" -version = "0.66.5" +version = "0.66.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8d1949debe40c9eb731a93b22a50da560007d85f6f7983679d217c01b9dc867" +checksum = "9fdc5f9dcdf330f5ef5f367dbc2334e72151e9ae46a4ee9f21d43a5e859be11b" dependencies = [ "Inflector", "fuel-abi-types", @@ -2406,22 +2439,22 @@ dependencies = [ [[package]] name = "fuels-core" -version = "0.66.5" +version = "0.66.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e720a87a7c99fcc5477cbb251738406de752a10eb237e15c79c1d99b64f4679f" +checksum = "629212e8278d57aa1a6f846ca0ca1e3428fb6da2d43e368931ff1494a0a6b5ce" dependencies = [ "async-trait", "bech32", "chrono", "fuel-abi-types", - "fuel-asm 0.57.0", + "fuel-asm 0.58.0", "fuel-core-chain-config", "fuel-core-client", - "fuel-core-types 0.36.0", - "fuel-crypto 0.57.0", - "fuel-tx 0.57.0", - "fuel-types 0.57.0", - "fuel-vm 0.57.0", + "fuel-core-types 0.37.0", + "fuel-crypto 0.58.0", + "fuel-tx 0.58.0", + "fuel-types 0.58.0", + "fuel-vm 0.58.0", "fuels-macros", "hex", "itertools 0.12.1", @@ -2434,9 +2467,9 @@ dependencies = [ [[package]] name = "fuels-macros" -version = "0.66.5" +version = "0.66.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7b391259fceb75331bcbde2878cd9765b579e9167abd818641205b4c96b9a" +checksum = "562bf012adedfb492431f4bfd5be4ccbf2171ab7d5247c5953a6be3ea8036072" dependencies = [ "fuels-code-gen", "itertools 0.12.1", @@ -2447,15 +2480,15 @@ dependencies = [ [[package]] name = "fuels-programs" -version = "0.66.5" +version = "0.66.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf719a68184ad4999c24dd53cf68bdd247d02fe16a9d67ccba177c8e44771b9" +checksum = "30a366e6a78e1c104fe1cb14439199833987fe76ecd46ee2b46fe05868a3366d" dependencies = [ "async-trait", "fuel-abi-types", - "fuel-asm 0.57.0", - "fuel-tx 0.57.0", - "fuel-types 0.57.0", + "fuel-asm 0.58.0", + "fuel-tx 0.58.0", + "fuel-types 0.58.0", "fuels-accounts", "fuels-core", "itertools 0.12.1", @@ -2466,19 +2499,19 @@ dependencies = [ [[package]] name = "fuels-test-helpers" -version = "0.66.5" +version = "0.66.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a615a59644d3cfce8dc1089db0764b4cca2bcea42b2a08eca826e2b8f892936" +checksum = "7705708c0fe28a874c44635b77c3e120a3422c8a24fdc45f07dc8c21ee9ca6fb" dependencies = [ "fuel-core", "fuel-core-chain-config", "fuel-core-client", "fuel-core-poa", "fuel-core-services", - "fuel-core-types 0.36.0", - "fuel-crypto 0.57.0", - "fuel-tx 0.57.0", - "fuel-types 0.57.0", + "fuel-core-types 0.37.0", + "fuel-crypto 0.58.0", + "fuel-tx 0.58.0", + "fuel-types 0.58.0", "fuels-accounts", "fuels-core", "futures", @@ -4356,9 +4389,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.10" +version = "2.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" +checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9" dependencies = [ "memchr", "thiserror", @@ -5304,7 +5337,7 @@ version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2" dependencies = [ - "darling 0.20.8", + "darling 0.20.10", "proc-macro2", "quote", "syn 2.0.63", @@ -5702,7 +5735,7 @@ dependencies = [ "assert_matches", "fuel-core", "fuel-core-client", - "fuel-vm 0.57.0", + "fuel-vm 0.58.0", "fuels", "hex", "paste", diff --git a/test/src/sdk-harness/Cargo.toml b/test/src/sdk-harness/Cargo.toml index 071e3fe3374..778acf33105 100644 --- a/test/src/sdk-harness/Cargo.toml +++ b/test/src/sdk-harness/Cargo.toml @@ -10,15 +10,15 @@ publish = false assert_matches = "1.5" # Dependencies from the `fuel-core` repository: -fuel-core = { version = "0.36", default-features = false } +fuel-core = { version = "0.37", default-features = false } # Using full semver as the workspace Cargo.toml (see the comment there) -fuel-core-client = { version = "0.36.0", default-features = false } +fuel-core-client = { version = "0.37.0", default-features = false } # Dependencies from the `fuel-vm` repository: -fuel-vm = { version = "0.57", features = ["random"] } +fuel-vm = { version = "0.58", features = ["random"] } # Dependencies from the `fuels-rs` repository: -fuels = { version = "0.66", features = ["fuel-core-lib"] } +fuels = { version = "0.66.6", features = ["fuel-core-lib"] } hex = "0.4" paste = "1.0" From 32d1cc91dc3cf8fbda12fe217e563b139feef8a7 Mon Sep 17 00:00:00 2001 From: Joshua Batty Date: Sun, 6 Oct 2024 17:49:06 +1100 Subject: [PATCH 049/115] chore: bump to 0.65.0 (#6610) ## Description Adds blob deployments for scripts and predicates. Supports fuels 0.66.6 and fuel-core 0.37.0. --- Cargo.lock | 68 +++++++++++++++++++++++++++--------------------------- Cargo.toml | 48 +++++++++++++++++++------------------- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f9d6234bdc1..ccc06355650 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2678,7 +2678,7 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "forc" -version = "0.64.0" +version = "0.65.0" dependencies = [ "annotate-snippets", "ansi_term", @@ -2689,7 +2689,7 @@ dependencies = [ "completest-pty", "forc-pkg", "forc-test", - "forc-tracing 0.64.0", + "forc-tracing 0.65.0", "forc-util", "fs_extra", "fuel-asm", @@ -2715,7 +2715,7 @@ dependencies = [ [[package]] name = "forc-client" -version = "0.64.0" +version = "0.65.0" dependencies = [ "anyhow", "async-trait", @@ -2727,7 +2727,7 @@ dependencies = [ "dialoguer", "forc", "forc-pkg", - "forc-tracing 0.64.0", + "forc-tracing 0.65.0", "forc-tx", "forc-util", "forc-wallet", @@ -2761,13 +2761,13 @@ dependencies = [ [[package]] name = "forc-crypto" -version = "0.64.0" +version = "0.65.0" dependencies = [ "anyhow", "async-trait", "atty", "clap 4.5.16", - "forc-tracing 0.64.0", + "forc-tracing 0.65.0", "forc-util", "fuel-core-types", "fuel-crypto", @@ -2787,7 +2787,7 @@ dependencies = [ [[package]] name = "forc-debug" -version = "0.64.0" +version = "0.65.0" dependencies = [ "anyhow", "clap 4.5.16", @@ -2795,7 +2795,7 @@ dependencies = [ "escargot", "forc-pkg", "forc-test", - "forc-tracing 0.64.0", + "forc-tracing 0.65.0", "fuel-core-client", "fuel-types", "fuel-vm", @@ -2813,7 +2813,7 @@ dependencies = [ [[package]] name = "forc-doc" -version = "0.64.0" +version = "0.65.0" dependencies = [ "anyhow", "clap 4.5.16", @@ -2821,7 +2821,7 @@ dependencies = [ "dir_indexer", "expect-test", "forc-pkg", - "forc-tracing 0.64.0", + "forc-tracing 0.65.0", "forc-util", "horrorshow", "include_dir", @@ -2838,12 +2838,12 @@ dependencies = [ [[package]] name = "forc-fmt" -version = "0.64.0" +version = "0.65.0" dependencies = [ "anyhow", "clap 4.5.16", "forc-pkg", - "forc-tracing 0.64.0", + "forc-tracing 0.65.0", "forc-util", "prettydiff 0.7.0", "sway-core", @@ -2855,7 +2855,7 @@ dependencies = [ [[package]] name = "forc-lsp" -version = "0.64.0" +version = "0.65.0" dependencies = [ "anyhow", "clap 4.5.16", @@ -2866,13 +2866,13 @@ dependencies = [ [[package]] name = "forc-pkg" -version = "0.64.0" +version = "0.65.0" dependencies = [ "ansi_term", "anyhow", "byte-unit", "cid", - "forc-tracing 0.64.0", + "forc-tracing 0.65.0", "forc-util", "fuel-abi-types", "futures", @@ -2903,7 +2903,7 @@ dependencies = [ [[package]] name = "forc-test" -version = "0.64.0" +version = "0.65.0" dependencies = [ "anyhow", "forc-pkg", @@ -2930,7 +2930,7 @@ dependencies = [ [[package]] name = "forc-tracing" -version = "0.64.0" +version = "0.65.0" dependencies = [ "ansi_term", "tracing", @@ -2940,7 +2940,7 @@ dependencies = [ [[package]] name = "forc-tx" -version = "0.64.0" +version = "0.65.0" dependencies = [ "anyhow", "clap 4.5.16", @@ -2955,7 +2955,7 @@ dependencies = [ [[package]] name = "forc-util" -version = "0.64.0" +version = "0.65.0" dependencies = [ "annotate-snippets", "ansi_term", @@ -2963,7 +2963,7 @@ dependencies = [ "clap 4.5.16", "dirs 5.0.1", "fd-lock", - "forc-tracing 0.64.0", + "forc-tracing 0.65.0", "fuel-tx", "hex", "paste", @@ -7642,7 +7642,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sway-ast" -version = "0.64.0" +version = "0.65.0" dependencies = [ "extension-trait", "num-bigint", @@ -7654,7 +7654,7 @@ dependencies = [ [[package]] name = "sway-core" -version = "0.64.0" +version = "0.65.0" dependencies = [ "clap 4.5.16", "derivative", @@ -7699,7 +7699,7 @@ dependencies = [ [[package]] name = "sway-error" -version = "0.64.0" +version = "0.65.0" dependencies = [ "either", "in_definite", @@ -7713,7 +7713,7 @@ dependencies = [ [[package]] name = "sway-ir" -version = "0.64.0" +version = "0.65.0" dependencies = [ "anyhow", "downcast-rs", @@ -7732,7 +7732,7 @@ dependencies = [ [[package]] name = "sway-ir-macros" -version = "0.64.0" +version = "0.65.0" dependencies = [ "itertools 0.13.0", "proc-macro2", @@ -7742,7 +7742,7 @@ dependencies = [ [[package]] name = "sway-lsp" -version = "0.64.0" +version = "0.65.0" dependencies = [ "anyhow", "assert-json-diff", @@ -7753,7 +7753,7 @@ dependencies = [ "dirs 4.0.0", "fd-lock", "forc-pkg", - "forc-tracing 0.64.0", + "forc-tracing 0.65.0", "forc-util", "futures", "indexmap 2.5.0", @@ -7792,7 +7792,7 @@ dependencies = [ [[package]] name = "sway-lsp-test-utils" -version = "0.64.0" +version = "0.65.0" dependencies = [ "assert-json-diff", "futures", @@ -7807,7 +7807,7 @@ dependencies = [ [[package]] name = "sway-parse" -version = "0.64.0" +version = "0.65.0" dependencies = [ "assert_matches", "extension-trait", @@ -7825,7 +7825,7 @@ dependencies = [ [[package]] name = "sway-types" -version = "0.64.0" +version = "0.65.0" dependencies = [ "bytecount", "fuel-asm", @@ -7844,7 +7844,7 @@ dependencies = [ [[package]] name = "sway-utils" -version = "0.64.0" +version = "0.65.0" dependencies = [ "serde", "walkdir", @@ -7852,11 +7852,11 @@ dependencies = [ [[package]] name = "swayfmt" -version = "0.64.0" +version = "0.65.0" dependencies = [ "anyhow", "difference", - "forc-tracing 0.64.0", + "forc-tracing 0.65.0", "indoc", "paste", "prettydiff 0.6.4", @@ -8140,7 +8140,7 @@ dependencies = [ "forc-client", "forc-pkg", "forc-test", - "forc-tracing 0.64.0", + "forc-tracing 0.65.0", "fuel-vm", "futures", "gag", diff --git a/Cargo.toml b/Cargo.toml index da1286e8d99..245f9d10cf8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ exclude = [ [workspace.package] edition = "2021" -version = "0.64.0" +version = "0.65.0" authors = ["Fuel Labs "] homepage = "https://fuel.network/" license = "Apache-2.0" @@ -45,34 +45,34 @@ repository = "https://github.com/FuelLabs/sway" # Internal dependencies in order to propagate `workspace.version` # -forc = { path = "forc/", version = "0.64.0" } -forc-pkg = { path = "forc-pkg/", version = "0.64.0" } -forc-test = { path = "forc-test/", version = "0.64.0" } -forc-tracing = { path = "forc-tracing/", version = "0.64.0" } -forc-util = { path = "forc-util/", version = "0.64.0" } +forc = { path = "forc/", version = "0.65.0" } +forc-pkg = { path = "forc-pkg/", version = "0.65.0" } +forc-test = { path = "forc-test/", version = "0.65.0" } +forc-tracing = { path = "forc-tracing/", version = "0.65.0" } +forc-util = { path = "forc-util/", version = "0.65.0" } # Forc plugins -forc-plugins = { path = "forc-plugins/", version = "0.64.0" } -forc-client = { path = "forc-plugins/forc-client/", version = "0.64.0" } -forc-crypto = { path = "forc-plugins/forc-crypto/", version = "0.64.0" } -forc-debug = { path = "forc-plugins/forc-debug/", version = "0.64.0" } -forc-doc = { path = "forc-plugins/forc-doc/", version = "0.64.0" } -forc-fmt = { path = "forc-plugins/forc-fmt/", version = "0.64.0" } -forc-lsp = { path = "forc-plugins/forc-lsp/", version = "0.64.0" } -forc-tx = { path = "forc-plugins/forc-tx/", version = "0.64.0" } +forc-plugins = { path = "forc-plugins/", version = "0.65.0" } +forc-client = { path = "forc-plugins/forc-client/", version = "0.65.0" } +forc-crypto = { path = "forc-plugins/forc-crypto/", version = "0.65.0" } +forc-debug = { path = "forc-plugins/forc-debug/", version = "0.65.0" } +forc-doc = { path = "forc-plugins/forc-doc/", version = "0.65.0" } +forc-fmt = { path = "forc-plugins/forc-fmt/", version = "0.65.0" } +forc-lsp = { path = "forc-plugins/forc-lsp/", version = "0.65.0" } +forc-tx = { path = "forc-plugins/forc-tx/", version = "0.65.0" } -sway-ast = { path = "sway-ast/", version = "0.64.0" } -sway-core = { path = "sway-core/", version = "0.64.0" } -sway-error = { path = "sway-error/", version = "0.64.0" } -sway-lsp = { path = "sway-lsp/", version = "0.64.0" } -sway-parse = { path = "sway-parse/", version = "0.64.0" } -sway-types = { path = "sway-types/", version = "0.64.0" } -sway-utils = { path = "sway-utils/", version = "0.64.0" } -swayfmt = { path = "swayfmt/", version = "0.64.0" } +sway-ast = { path = "sway-ast/", version = "0.65.0" } +sway-core = { path = "sway-core/", version = "0.65.0" } +sway-error = { path = "sway-error/", version = "0.65.0" } +sway-lsp = { path = "sway-lsp/", version = "0.65.0" } +sway-parse = { path = "sway-parse/", version = "0.65.0" } +sway-types = { path = "sway-types/", version = "0.65.0" } +sway-utils = { path = "sway-utils/", version = "0.65.0" } +swayfmt = { path = "swayfmt/", version = "0.65.0" } # Sway IR -sway-ir = { path = "sway-ir/", version = "0.64.0" } -sway-ir-macros = { path = "sway-ir/sway-ir-macros", version = "0.64.0" } +sway-ir = { path = "sway-ir/", version = "0.65.0" } +sway-ir-macros = { path = "sway-ir/sway-ir-macros", version = "0.65.0" } # # External Fuel dependencies From 53615b43997f3a040240640a03c000f4ba815f6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaya=20G=C3=B6kalp?= Date: Sun, 6 Oct 2024 07:40:30 -0700 Subject: [PATCH 050/115] feat: generate a loader abi of loaders generated for predicates and scripts (#6611) ## Description Thanks a lot to @hal3e for helping debug this. With this PR, there will be an additional abi in the `out` folder for predicates and scripts that are deployed as loaders following the `{package_name}-loader-abi.json` naming convention. This PR adds `loader-abi.json` file generation capability to forc. To do so forc needs to have the old (original) and new (loader) data offsets of the script/predicate. After getting it the difference should be applied to all configurable slots to find out the new locations of the configurable slots inside the loader binary. Basically enables backwards compatibility with the older sdk releases. Since forc can now generate a loader abi with correct configurable offsets, it can be used to load the script as it is, (without the newer loader stuff) and everything will be still working. --- Cargo.lock | 15 +- forc-plugins/forc-client/Cargo.toml | 1 + forc-plugins/forc-client/src/op/deploy.rs | 143 +++++++- .../deployed_script-loader-abi.json | 312 ++++++++++++++++++ .../data/deployed_script/deployed_script.bin | Bin 0 -> 8784 bytes forc-plugins/forc-client/tests/deploy.rs | 205 ++++++++++++ 6 files changed, 669 insertions(+), 7 deletions(-) create mode 100644 forc-plugins/forc-client/test/data/deployed_script/deployed_script-loader-abi.json create mode 100644 forc-plugins/forc-client/test/data/deployed_script/deployed_script.bin diff --git a/Cargo.lock b/Cargo.lock index ccc06355650..cb617fba612 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2744,6 +2744,7 @@ dependencies = [ "hex", "k256", "portpicker", + "pretty_assertions", "rand", "regex", "rexpect 0.5.0", @@ -5952,12 +5953,12 @@ dependencies = [ [[package]] name = "pretty_assertions" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" dependencies = [ "diff", - "yansi", + "yansi 1.0.1", ] [[package]] @@ -7350,7 +7351,7 @@ dependencies = [ "thiserror", "tokio", "version_check", - "yansi", + "yansi 0.5.1", ] [[package]] @@ -9469,6 +9470,12 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + [[package]] name = "zerocopy" version = "0.7.35" diff --git a/forc-plugins/forc-client/Cargo.toml b/forc-plugins/forc-client/Cargo.toml index f63bb0b99c9..ee1b03ea173 100644 --- a/forc-plugins/forc-client/Cargo.toml +++ b/forc-plugins/forc-client/Cargo.toml @@ -48,6 +48,7 @@ tracing.workspace = true [dev-dependencies] portpicker = "0.1.1" +pretty_assertions = "1.4.1" rexpect = "0.5" tempfile = "3" diff --git a/forc-plugins/forc-client/src/op/deploy.rs b/forc-plugins/forc-client/src/op/deploy.rs index af3c1e6e737..ddaf6a8c54d 100644 --- a/forc-plugins/forc-client/src/op/deploy.rs +++ b/forc-plugins/forc-client/src/op/deploy.rs @@ -18,18 +18,22 @@ use forc_pkg::{manifest::GenericManifestFile, MemberFilter}; use forc_tracing::{println_action_green, println_warning}; use forc_util::default_output_directory; use forc_wallet::utils::default_wallet_path; +use fuel_abi_types::abi::program::Configurable; use fuel_core_client::client::types::{ChainInfo, TransactionStatus}; use fuel_core_client::client::FuelClient; use fuel_crypto::fuel_types::ChainId; use fuel_tx::{Salt, Transaction}; -use fuel_vm::prelude::*; +use fuel_vm::{consts::WORD_SIZE, fuel_asm::op, prelude::*}; use fuels::{ macros::abigen, programs::{ contract::{LoadConfiguration, StorageConfiguration}, executable::Executable, }, - types::{bech32::Bech32ContractId, transaction_builders::Blob}, + types::{ + bech32::Bech32ContractId, + transaction_builders::{Blob, BlobId}, + }, }; use fuels_accounts::{provider::Provider, Account, ViewOnlyAccount}; use fuels_core::types::{transaction::TxPolicies, transaction_builders::CreateTransactionBuilder}; @@ -43,8 +47,8 @@ use std::{ sync::Arc, time::Duration, }; -use sway_core::language::parsed::TreeType; use sway_core::BuildTarget; +use sway_core::{asm_generation::ProgramABI, language::parsed::TreeType}; /// Default maximum contract size allowed for a single contract. If the target /// contract size is bigger than this amount, forc-deploy will automatically @@ -356,6 +360,103 @@ pub async fn deploy(command: cmd::Deploy) -> Result> { Ok(deployed_packages) } +/// Calculates the loader data offset. Returns a `None` if the original `binary` +/// does not have a data section (no configurables and no args). Otherwise +/// returns the new offset of the data section. +fn loader_data_offset(binary: &[u8], blob_id: &BlobId) -> Result> { + // The following code is taken from SDK, and once they expose the offsets + // we will no longer need to maintain this duplicate version here. + + // The final code is going to have this structure (if the data section is non-empty): + // 1. loader instructions + // 2. blob id + // 3. length_of_data_section + // 4. the data_section (updated with configurables as needed) + const BLOB_ID_SIZE: u16 = 32; + const REG_ADDRESS_OF_DATA_AFTER_CODE: u8 = 0x10; + const REG_START_OF_LOADED_CODE: u8 = 0x11; + const REG_GENERAL_USE: u8 = 0x12; + let get_instructions = |num_of_instructions| { + // There are 3 main steps: + // 1. Load the blob content into memory + // 2. Load the data section right after the blob + // 3. Jump to the beginning of the memory where the blob was loaded + [ + // 1. Load the blob content into memory + // Find the start of the hardcoded blob ID, which is located after the loader code ends. + op::move_(REG_ADDRESS_OF_DATA_AFTER_CODE, RegId::PC), + // hold the address of the blob ID. + op::addi( + REG_ADDRESS_OF_DATA_AFTER_CODE, + REG_ADDRESS_OF_DATA_AFTER_CODE, + num_of_instructions * Instruction::SIZE as u16, + ), + // The code is going to be loaded from the current value of SP onwards, save + // the location into REG_START_OF_LOADED_CODE so we can jump into it at the end. + op::move_(REG_START_OF_LOADED_CODE, RegId::SP), + // REG_GENERAL_USE to hold the size of the blob. + op::bsiz(REG_GENERAL_USE, REG_ADDRESS_OF_DATA_AFTER_CODE), + // Push the blob contents onto the stack. + op::ldc(REG_ADDRESS_OF_DATA_AFTER_CODE, 0, REG_GENERAL_USE, 1), + // Move on to the data section length + op::addi( + REG_ADDRESS_OF_DATA_AFTER_CODE, + REG_ADDRESS_OF_DATA_AFTER_CODE, + BLOB_ID_SIZE, + ), + // load the size of the data section into REG_GENERAL_USE + op::lw(REG_GENERAL_USE, REG_ADDRESS_OF_DATA_AFTER_CODE, 0), + // after we have read the length of the data section, we move the pointer to the actual + // data by skipping WORD_SIZE B. + op::addi( + REG_ADDRESS_OF_DATA_AFTER_CODE, + REG_ADDRESS_OF_DATA_AFTER_CODE, + WORD_SIZE as u16, + ), + // load the data section of the executable + op::ldc(REG_ADDRESS_OF_DATA_AFTER_CODE, 0, REG_GENERAL_USE, 2), + // Jump into the memory where the contract is loaded. + // What follows is called _jmp_mem by the sway compiler. + // Subtract the address contained in IS because jmp will add it back. + op::sub( + REG_START_OF_LOADED_CODE, + REG_START_OF_LOADED_CODE, + RegId::IS, + ), + // jmp will multiply by 4, so we need to divide to cancel that out. + op::divi(REG_START_OF_LOADED_CODE, REG_START_OF_LOADED_CODE, 4), + // Jump to the start of the contract we loaded. + op::jmp(REG_START_OF_LOADED_CODE), + ] + }; + + let offset = extract_data_offset(binary)?; + + if binary.len() < offset { + anyhow::bail!("data sectio offset is out of bounds"); + } + + let data_section = binary[offset..].to_vec(); + + if !data_section.is_empty() { + let num_of_instructions = u16::try_from(get_instructions(0).len()) + .expect("to never have more than u16::MAX instructions"); + + let instruction_bytes = get_instructions(num_of_instructions) + .into_iter() + .flat_map(|instruction| instruction.to_bytes()); + + let blob_bytes = blob_id.iter().copied(); + + let loader_offset = + instruction_bytes.count() + blob_bytes.count() + data_section.len().to_be_bytes().len(); + + Ok(Some(loader_offset)) + } else { + Ok(None) + } +} + /// Builds and deploys executable (script and predicate) package(s) as blobs, /// and generates a loader for each of them. pub async fn deploy_executables( @@ -387,6 +488,29 @@ pub async fn deploy_executables( "Saved", &format!("loader bytecode at {}", bin_path.display()), ); + if let Some(loader_data_section_offset) = + loader_data_offset(&pkg.bytecode.bytes, &BlobId::default())? + { + if let ProgramABI::Fuel(mut fuel_abi) = pkg.program_abi.clone() { + println_action_green("Generating", "loader abi for the uploaded executable."); + let json_abi_path = out_dir.join(format!("{pkg_name}-loader-abi.json")); + let original_data_section = extract_data_offset(&pkg.bytecode.bytes).unwrap(); + let offset_shift = original_data_section - loader_data_section_offset; + // if there are configurables in the abi we need to shift them by `offset_shift`. + let configurables = fuel_abi.configurables.clone().map(|configs| { + configs + .into_iter() + .map(|config| Configurable { + offset: config.offset - offset_shift as u64, + ..config.clone() + }) + .collect() + }); + fuel_abi.configurables = configurables; + let json_string = serde_json::to_string_pretty(&fuel_abi)?; + std::fs::write(json_abi_path, json_string)?; + } + } // If the executable is a predicate, we also want to display and save the predicate root. if pkg .descriptor @@ -419,6 +543,19 @@ pub async fn deploy_executables( Ok(deployed_executable) } +fn extract_data_offset(binary: &[u8]) -> Result { + if binary.len() < 16 { + anyhow::bail!( + "given binary is too short to contain a data offset, len: {}", + binary.len() + ); + } + + let data_offset: [u8; 8] = binary[8..16].try_into().expect("checked above"); + + Ok(u64::from_be_bytes(data_offset) as usize) +} + /// Builds and deploys contract(s). If the given path corresponds to a workspace, all deployable members /// will be built and deployed. /// diff --git a/forc-plugins/forc-client/test/data/deployed_script/deployed_script-loader-abi.json b/forc-plugins/forc-client/test/data/deployed_script/deployed_script-loader-abi.json new file mode 100644 index 00000000000..81b65c43cd7 --- /dev/null +++ b/forc-plugins/forc-client/test/data/deployed_script/deployed_script-loader-abi.json @@ -0,0 +1,312 @@ +{ + "programType": "script", + "specVersion": "1", + "encodingVersion": "1", + "concreteTypes": [ + { + "type": "((bool, u8, u16, u32, u64, u256, b256, str[4], (u8, bool), [u32; 3], struct StructWithGeneric, enum EnumWithGeneric), bool, u64, u8)", + "concreteTypeId": "25fbba860b8a1983ebcfa3f135136266a7edb7ca3a7e1f8ec988135c12a9f873", + "metadataTypeId": 2 + }, + { + "type": "(u8, bool)", + "concreteTypeId": "e0128f7be9902d1fe16326cafe703b52038064a7997b03ebfc1c9dd607e1536c", + "metadataTypeId": 1 + }, + { + "type": "[u32; 3]", + "concreteTypeId": "d9fac01ab38fe10950758ae9604da330d6406a71fda3ef1ea818121261132d56", + "metadataTypeId": 4 + }, + { + "type": "b256", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "type": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "type": "enum EnumWithGeneric", + "concreteTypeId": "37cd1cba311039a851ac8bfa614cc41359b4ad95c8656fcef2e8f504fe7a1272", + "metadataTypeId": 5, + "typeArguments": [ + "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + ] + }, + { + "type": "str[4]", + "concreteTypeId": "94f0fa95c830be5e4f711963e83259fe7e8bc723278ab6ec34449e791a99b53a" + }, + { + "type": "struct StructWithGeneric", + "concreteTypeId": "563310524b4f4447a10d0e50556310253dfb3b5eb4b29c3773222b737c8b7075", + "metadataTypeId": 7, + "typeArguments": [ + "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + ] + }, + { + "type": "u16", + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + }, + { + "type": "u256", + "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e" + }, + { + "type": "u32", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "type": "u64", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "type": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "metadataTypes": [ + { + "type": "()", + "metadataTypeId": 0 + }, + { + "type": "(_, _)", + "metadataTypeId": 1, + "components": [ + { + "name": "__tuple_element", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + }, + { + "name": "__tuple_element", + "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + ] + }, + { + "type": "(_, _, _, _)", + "metadataTypeId": 2, + "components": [ + { + "name": "__tuple_element", + "typeId": 3 + }, + { + "name": "__tuple_element", + "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "name": "__tuple_element", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "__tuple_element", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + }, + { + "type": "(_, _, _, _, _, _, _, _, _, _, _, _)", + "metadataTypeId": 3, + "components": [ + { + "name": "__tuple_element", + "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "name": "__tuple_element", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + }, + { + "name": "__tuple_element", + "typeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + }, + { + "name": "__tuple_element", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "__tuple_element", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "__tuple_element", + "typeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e" + }, + { + "name": "__tuple_element", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "name": "__tuple_element", + "typeId": "94f0fa95c830be5e4f711963e83259fe7e8bc723278ab6ec34449e791a99b53a" + }, + { + "name": "__tuple_element", + "typeId": 1 + }, + { + "name": "__tuple_element", + "typeId": 4 + }, + { + "name": "__tuple_element", + "typeId": 7, + "typeArguments": [ + { + "name": "", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + }, + { + "name": "__tuple_element", + "typeId": 5, + "typeArguments": [ + { + "name": "", + "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + ] + } + ] + }, + { + "type": "[_; 3]", + "metadataTypeId": 4, + "components": [ + { + "name": "__array_element", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ] + }, + { + "type": "enum EnumWithGeneric", + "metadataTypeId": 5, + "components": [ + { + "name": "VariantOne", + "typeId": 6 + }, + { + "name": "VariantTwo", + "typeId": 0 + } + ], + "typeParameters": [ + 6 + ] + }, + { + "type": "generic D", + "metadataTypeId": 6 + }, + { + "type": "struct StructWithGeneric", + "metadataTypeId": 7, + "components": [ + { + "name": "field_1", + "typeId": 6 + }, + { + "name": "field_2", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "typeParameters": [ + 6 + ] + } + ], + "functions": [ + { + "inputs": [ + { + "name": "a", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "contract_addr", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ], + "name": "main", + "output": "25fbba860b8a1983ebcfa3f135136266a7edb7ca3a7e1f8ec988135c12a9f873", + "attributes": null + } + ], + "loggedTypes": [ + { + "logId": "14454674236531057292", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "messagesTypes": [], + "configurables": [ + { + "name": "BOOL", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "offset": 136 + }, + { + "name": "U8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "offset": 248 + }, + { + "name": "U16", + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", + "offset": 192 + }, + { + "name": "U32", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", + "offset": 232 + }, + { + "name": "U64", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "offset": 240 + }, + { + "name": "U256", + "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", + "offset": 200 + }, + { + "name": "B256", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "offset": 104 + }, + { + "name": "STR_4", + "concreteTypeId": "94f0fa95c830be5e4f711963e83259fe7e8bc723278ab6ec34449e791a99b53a", + "offset": 176 + }, + { + "name": "TUPLE", + "concreteTypeId": "e0128f7be9902d1fe16326cafe703b52038064a7997b03ebfc1c9dd607e1536c", + "offset": 184 + }, + { + "name": "ARRAY", + "concreteTypeId": "d9fac01ab38fe10950758ae9604da330d6406a71fda3ef1ea818121261132d56", + "offset": 88 + }, + { + "name": "STRUCT", + "concreteTypeId": "563310524b4f4447a10d0e50556310253dfb3b5eb4b29c3773222b737c8b7075", + "offset": 160 + }, + { + "name": "ENUM", + "concreteTypeId": "37cd1cba311039a851ac8bfa614cc41359b4ad95c8656fcef2e8f504fe7a1272", + "offset": 144 + } + ] +} \ No newline at end of file diff --git a/forc-plugins/forc-client/test/data/deployed_script/deployed_script.bin b/forc-plugins/forc-client/test/data/deployed_script/deployed_script.bin new file mode 100644 index 0000000000000000000000000000000000000000..0daa7de8f3e5707f28d74b70d11d1f5b4395c5af GIT binary patch literal 8784 zcmcgxZ){sv6~A_z#_2lsjV7D-s&=nZI*c@gMY}2EOW(sWc5p&&mV~CPo?Wfo3{0En zC0#lMGtfZ=`w*sWWC)>bAe6yAyrhovZ$d_zAV?tmfe-xx@&uDoZASjEp_B>2@7(*I z-^+`gw)~6KzVqI__uO-S=bU@aJyz=xHo=&miN7OyYOCy1wzk;!82cH2x6b%q*gjs> znYMY1jel76^AD?m3FdzTV+zJJjD@z3wH?D)1Y4x>rQPS3*3sa495HzJL4Ja$5_@Hd(t!ZIL2}qBONYy#$LkMw6)(Wp0Rn1 z&0s8ub+3BHeuuGHjFIlId&aJ+?{VO|ufj)`rq1YWFOOg5=^FbIkFLz-6D$}ux(Y@AF1&QpIhtdm>Z&XrwtBWmV?+gB=;>vTJPJT%k}dc_IhA+MbLzo!Gos_2Dw(QK$kg( z=VGNb&pn@)JQrpio~v1#XUgDy9$(D@Z^Fisaba1|v7RzdUY@bPr_$zAsRzx8RNS1z zdcV@&Rp=f(S~x$ze2A-d%<~^Sb+&x>IAh^M6S{gj$N13Yb=dtvUT1q0<2X}d6FSWU zHf7juGhNF)o33RF>6-R+9$%<9G8T1PM#xvSzeCq25)DIF~RbEppD}?j}{f+`VHXvP2hTw$LE8N zti^FblRw4RBu)Np@C3aB*D7Q}jF7A=OvqB8hZFnJo7P&@~25R*DE3A!)|SeS%?$#cNuTfpSo zkjK$IT6AQMuU%^BVDKC;xpcZ8F*meS&W|HL2D^b1Wl(WNU5e(@4h zHScgc8=`h|Akm$dk0T>RE; zemJw%rHrfVkkNF>SZ~cU@Pfs2%Hg@DGJ?t3qC%KTb1N=b~ zx+1}BtB2Wr>QDu7WCr0&!GnDPU5N$sbSy&o2k%{t_jE1Nrj9Dsxid;J*-7hASA~VX zq6PqM`KS6mqqw@Y$)0ygy|L#2_81&3D}!C-^dMu(7$=?Yc!5FBYdV{O-rtA*pWS2( zICR)JNDQEVvdYpi#?%j>|255?-(k%^v3#|4-&%W@y%u+(+%~@%sxm%8{(wE-QIPlaZF<56 zUvT*j**QUWw&!~=*)MdbdZk9^lF8u%S~yyCXq;E%53p-ay%w=`ysL?vx|*D2>d>_C z?UbR(I*9mE{SGn1@gjU$epd|mD)12Bhl;=#t?A$p$i8e z`8&<^=)aHVKtAOm_#);gYM;XBjJ9+RxpcN|(~w8XQr+Qe*!ye5_W<-$2ap3%Ga(o1 z>VQJA=ev*LJM?w=jLq9^ckb2oI(EO}(zgS;^fuAAhjQM5VaUN*=K({}ZFxxd^m~dQ zd(b(6^D>}MFt#uK9%S|42K}u2k-1;sMr-Jd9Vrrqx>#@Ykq=4Q!IQi2wC&r_*~XLN zBxS`(p0l8WSZfk1JJ!QLG%seY{lnMe!mFu&K+ihi)kOb$gx`$7Z-6Dv=r+Pn=t^VoA03(cKfT_Zak(3?YO^5+ug)Dxl3fnRy7AoFx(&}m zMi=><-|{)Po!sYDv-m*WLUzI#O*P1MbBV8J%MN_(9FY*T^f5Xs?0g|<$N#fUe5P@B z!sa)Dpw-EHm{XZa1_VxP7Dt}LIlG1T@g>1WmocWKrZN zS;J`Fb>FpQcHO5+3A?`L(GqH!#ToG~?gG@KRK)$!v;SKbp9toPy8!NrnxKs?^d#$t z(L=kKN}A6d_XQq+F1@@@f1M}vC;5Q>3g`N(d{n={vwDa>rk~J<*@O-j-24X(|D259bC=Ix2^fuHeymALPHHxMsJgPBBU31yjVyL znNw6tQ2z(Ef118?Llb+TUx*&*^o4YdKLbp@0=XQYi(jq+6VXcs&RIbdR-oaFrZZN= zowunkT5&j^X&qIDAUXwhtvr>{x>ozFS^OEQM!-V{^o&KUL5o9^wm_*`=BU2*na zGQp=|b8j3^GT-0j`X%&u7OB629#2=<>lc&EAE0>W$%QF_fB)Gsa2&z!0;7n#^(OlL z(u&Uv<`cHC*W#vFOMTg)Qi$$l==JH4Pm{G#q)D%jy=(EIeJwsE*@u9Aapyp9xnzQ0 z#Nk)Ww&v#(`37g^w2R-mpe4U{@I$X-F)O}_{zQZOBq2+-7>V+eSTogujHE2CVXWB7%q$7 zWMbO#L$O(w@9TUEJ~PQ<+B(%|i1kYN4BfK}s3kk9>b0D_hayi|_fS{9VyKyBy*191 zu={W~-A6*$6|%^qtA?h{psF@La;T|NOR2O}qQ7t^}s*7y--L*)Ah6TA?zZcm6Habt zu6hu59uju|#9KRIPP|Evu;3XjmT`8r0^Z zg$xSmi#o8;-#H=e<#XGs(!^dA_c*@=-(_Jt!?qpeImk(NL=6ht?S<`bL9W<`ZyNQ$ zy2rX(*-!pnbJEP_GvGh=8PWfPAK>?zG1B!C?0FmPiJYh$fRFSFACdQ?SwZ7|=nSQ-@|g`CrrFref-UBmYbjA1mDG znE?C(H(~>RlCWo;h@F69pn-^U0(%5-zZO0V-@-YOxdms%KKPc~F4-2oHRJde6TTH^ z;_n~$|DX7`MQ^_A{m~@XpUE;bk4&C>jL4up!5*;2TRe!3<{CR;^QCWF`1`H+ yWB!SAPfesBnSA`=i7!6!cshUX%vsl}UC8xUhF=?a?6v2K7yZepd#B{Hv-mHji(0z? literal 0 HcmV?d00001 diff --git a/forc-plugins/forc-client/tests/deploy.rs b/forc-plugins/forc-client/tests/deploy.rs index d751afbf662..adb83853318 100644 --- a/forc-plugins/forc-client/tests/deploy.rs +++ b/forc-plugins/forc-client/tests/deploy.rs @@ -1090,3 +1090,208 @@ async fn deployed_predicate_call() { node.kill().unwrap(); } + +/// Generates a script instance using SDK, and returns the result as a string. +async fn call_with_sdk_generated_overrides(node_url: &str, contract_id: ContractId) -> String { + let project_dir = test_data_path().join("deployed_script"); + abigen!(Script( + name = "MyScript", + abi = "forc-plugins/forc-client/test/data/deployed_script/deployed_script-abi.json" + )); + let provider = Provider::connect(&node_url).await.unwrap(); + let secret_key = SecretKey::from_str(forc_client::constants::DEFAULT_PRIVATE_KEY).unwrap(); + let wallet_unlocked = WalletUnlocked::new_from_private_key(secret_key, Some(provider.clone())); + let bin_dir = project_dir.join("deployed_script.bin"); + let script_instance = MyScript::new(wallet_unlocked, bin_dir.display().to_string().as_str()); + + let strc = StructWithGeneric { + field_1: 1u8, + field_2: 2, + }; + let encoded = MyScriptConfigurables::default() + .with_BOOL(false) + .unwrap() + .with_U8(1) + .unwrap() + .with_U16(2) + .unwrap() + .with_U32(3) + .unwrap() + .with_U64(4) + .unwrap() + .with_U256(5.into()) + .unwrap() + .with_B256(Bits256::zeroed()) + .unwrap() + .with_ARRAY([1, 2, 3]) + .unwrap() + .with_STRUCT(strc) + .unwrap() + .with_ENUM(EnumWithGeneric::VariantTwo) + .unwrap(); + + let mut script_instance_with_configs = script_instance.with_configurables(encoded); + + let loader_from_sdk = script_instance_with_configs + .convert_into_loader() + .await + .unwrap(); + + let contract_ids_bits256 = Bits256(contract_id.into()); + format!( + "{:?}", + loader_from_sdk + .main(10, contract_ids_bits256) + .with_contract_ids(&[contract_id.into()]) + .call() + .await + .unwrap() + .value + ) +} + +/// Generates a script instance using the shifted abi, and returns the result as a string. +async fn call_with_forc_generated_overrides(node_url: &str, contract_id: ContractId) -> String { + let provider = Provider::connect(&node_url).await.unwrap(); + let secret_key = SecretKey::from_str(forc_client::constants::DEFAULT_PRIVATE_KEY).unwrap(); + let wallet_unlocked = WalletUnlocked::new_from_private_key(secret_key, Some(provider.clone())); + let tmp_dir = tempdir().unwrap(); + let project_dir = test_data_path().join("deployed_script"); + copy_dir(&project_dir, tmp_dir.path()).unwrap(); + patch_manifest_file_with_path_std(tmp_dir.path()).unwrap(); + + let target = NodeTarget { + node_url: Some(node_url.to_string()), + target: None, + testnet: false, + }; + let pkg = Pkg { + path: Some(tmp_dir.path().display().to_string()), + ..Default::default() + }; + let cmd = cmd::Deploy { + pkg, + salt: Some(vec![format!("{}", Salt::default())]), + node: target, + default_signer: true, + ..Default::default() + }; + + expect_deployed_script(deploy(cmd).await.unwrap().remove(0)); + + // Since `abigen!` macro does not allow for dynamic paths, we need to + // pre-generate the loader bin and abi and read them from project dir. Here + // we are ensuring forc-deploy indeed generated the files we are basing our + // tests below. + let generated_loader_abi_path = tmp_dir.path().join("out/deployed_script-loader-abi.json"); + let generated_loader_abi = fs::read_to_string(generated_loader_abi_path).unwrap(); + + // this path is basically, `forc-plugins/forc-client/test/data/deployed_script/deployed_script-loader-abi.json`. + let used_loader_abi_path = project_dir.join("deployed_script-loader-abi.json"); + let used_loader_abi = fs::read_to_string(used_loader_abi_path).unwrap(); + + assert_eq!(generated_loader_abi, used_loader_abi); + + let generated_loader_bin = tmp_dir.path().join("out/deployed_script-loader.bin"); + abigen!(Script( + name = "MyScript", + abi = "forc-plugins/forc-client/test/data/deployed_script/deployed_script-loader-abi.json" + )); + let forc_generated_script_instance = MyScript::new( + wallet_unlocked, + generated_loader_bin.display().to_string().as_str(), + ); + let strc = StructWithGeneric { + field_1: 1u8, + field_2: 2, + }; + let encoded = MyScriptConfigurables::default() + .with_BOOL(false) + .unwrap() + .with_U8(1) + .unwrap() + .with_U16(2) + .unwrap() + .with_U32(3) + .unwrap() + .with_U64(4) + .unwrap() + .with_U256(5.into()) + .unwrap() + .with_B256(Bits256::zeroed()) + .unwrap() + .with_ARRAY([1, 2, 3]) + .unwrap() + .with_STRUCT(strc) + .unwrap() + .with_ENUM(EnumWithGeneric::VariantTwo) + .unwrap(); + + let forc_generated_script_with_configs = + forc_generated_script_instance.with_configurables(encoded); + let contract_ids_bits256 = Bits256(contract_id.into()); + format!( + "{:?}", + forc_generated_script_with_configs + .main(10, contract_ids_bits256) + .with_contract_ids(&[contract_id.into()]) + .call() + .await + .unwrap() + .value + ) +} + +#[tokio::test] +async fn offset_shifted_abi_works() { + // To test if offset shifted abi works or not, we generate a loader + // contract using sdk and give a configurable override, and call the + // main function. + + // We also create the shited abi using forc-deploy and create a script + // instance using this new shifted abi, and generate a normal script out of + // the loader binary generated again by forc-deploy. + + // We then override the configurables with the same values as sdk flow on + // this script, generated with loader abi and bin coming from forc-deploy. + + // If returned value is equal, than the configurables work correctly. + let (mut node, port) = run_node(); + // Deploy the contract the script is going to be calling. + let contract_tmp_dir = tempdir().unwrap(); + let project_dir = test_data_path().join("standalone_contract"); + copy_dir(&project_dir, contract_tmp_dir.path()).unwrap(); + patch_manifest_file_with_path_std(contract_tmp_dir.path()).unwrap(); + + let pkg = Pkg { + path: Some(contract_tmp_dir.path().display().to_string()), + ..Default::default() + }; + + let node_url = format!("http://127.0.0.1:{}/v1/graphql", port); + let target = NodeTarget { + node_url: Some(node_url.clone()), + target: None, + testnet: false, + }; + let cmd = cmd::Deploy { + pkg, + salt: Some(vec![format!("{}", Salt::default())]), + node: target, + default_signer: true, + ..Default::default() + }; + let deployed_packages = deploy(cmd).await.unwrap().remove(0); + let contract = expect_deployed_contract(deployed_packages); + let contract_id = contract.id; + // Generating the sdk loader bytecode with configurables. + let loader_with_configs_from_sdk = + call_with_sdk_generated_overrides(&node_url, contract_id).await; + + // Genearating the forc-deploy loader bytecode and loader abi. + let loader_with_configs_from_forc = + call_with_forc_generated_overrides(&node_url, contract_id).await; + pretty_assertions::assert_eq!(loader_with_configs_from_forc, loader_with_configs_from_sdk); + + node.kill().unwrap() +} From 3a9c171cd43611d7ccad94ab66a5093c6634717b Mon Sep 17 00:00:00 2001 From: Joshua Batty Date: Mon, 7 Oct 2024 03:15:27 +1100 Subject: [PATCH 051/115] chore: bump to v0.65.1 (#6612) ## Description waiting on #6611 Co-authored-by: Brandon Kite --- Cargo.lock | 68 +++++++++++++++++++++++++++--------------------------- Cargo.toml | 48 +++++++++++++++++++------------------- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cb617fba612..ce2f1fa66c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2678,7 +2678,7 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "forc" -version = "0.65.0" +version = "0.65.1" dependencies = [ "annotate-snippets", "ansi_term", @@ -2689,7 +2689,7 @@ dependencies = [ "completest-pty", "forc-pkg", "forc-test", - "forc-tracing 0.65.0", + "forc-tracing 0.65.1", "forc-util", "fs_extra", "fuel-asm", @@ -2715,7 +2715,7 @@ dependencies = [ [[package]] name = "forc-client" -version = "0.65.0" +version = "0.65.1" dependencies = [ "anyhow", "async-trait", @@ -2727,7 +2727,7 @@ dependencies = [ "dialoguer", "forc", "forc-pkg", - "forc-tracing 0.65.0", + "forc-tracing 0.65.1", "forc-tx", "forc-util", "forc-wallet", @@ -2762,13 +2762,13 @@ dependencies = [ [[package]] name = "forc-crypto" -version = "0.65.0" +version = "0.65.1" dependencies = [ "anyhow", "async-trait", "atty", "clap 4.5.16", - "forc-tracing 0.65.0", + "forc-tracing 0.65.1", "forc-util", "fuel-core-types", "fuel-crypto", @@ -2788,7 +2788,7 @@ dependencies = [ [[package]] name = "forc-debug" -version = "0.65.0" +version = "0.65.1" dependencies = [ "anyhow", "clap 4.5.16", @@ -2796,7 +2796,7 @@ dependencies = [ "escargot", "forc-pkg", "forc-test", - "forc-tracing 0.65.0", + "forc-tracing 0.65.1", "fuel-core-client", "fuel-types", "fuel-vm", @@ -2814,7 +2814,7 @@ dependencies = [ [[package]] name = "forc-doc" -version = "0.65.0" +version = "0.65.1" dependencies = [ "anyhow", "clap 4.5.16", @@ -2822,7 +2822,7 @@ dependencies = [ "dir_indexer", "expect-test", "forc-pkg", - "forc-tracing 0.65.0", + "forc-tracing 0.65.1", "forc-util", "horrorshow", "include_dir", @@ -2839,12 +2839,12 @@ dependencies = [ [[package]] name = "forc-fmt" -version = "0.65.0" +version = "0.65.1" dependencies = [ "anyhow", "clap 4.5.16", "forc-pkg", - "forc-tracing 0.65.0", + "forc-tracing 0.65.1", "forc-util", "prettydiff 0.7.0", "sway-core", @@ -2856,7 +2856,7 @@ dependencies = [ [[package]] name = "forc-lsp" -version = "0.65.0" +version = "0.65.1" dependencies = [ "anyhow", "clap 4.5.16", @@ -2867,13 +2867,13 @@ dependencies = [ [[package]] name = "forc-pkg" -version = "0.65.0" +version = "0.65.1" dependencies = [ "ansi_term", "anyhow", "byte-unit", "cid", - "forc-tracing 0.65.0", + "forc-tracing 0.65.1", "forc-util", "fuel-abi-types", "futures", @@ -2904,7 +2904,7 @@ dependencies = [ [[package]] name = "forc-test" -version = "0.65.0" +version = "0.65.1" dependencies = [ "anyhow", "forc-pkg", @@ -2931,7 +2931,7 @@ dependencies = [ [[package]] name = "forc-tracing" -version = "0.65.0" +version = "0.65.1" dependencies = [ "ansi_term", "tracing", @@ -2941,7 +2941,7 @@ dependencies = [ [[package]] name = "forc-tx" -version = "0.65.0" +version = "0.65.1" dependencies = [ "anyhow", "clap 4.5.16", @@ -2956,7 +2956,7 @@ dependencies = [ [[package]] name = "forc-util" -version = "0.65.0" +version = "0.65.1" dependencies = [ "annotate-snippets", "ansi_term", @@ -2964,7 +2964,7 @@ dependencies = [ "clap 4.5.16", "dirs 5.0.1", "fd-lock", - "forc-tracing 0.65.0", + "forc-tracing 0.65.1", "fuel-tx", "hex", "paste", @@ -7643,7 +7643,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sway-ast" -version = "0.65.0" +version = "0.65.1" dependencies = [ "extension-trait", "num-bigint", @@ -7655,7 +7655,7 @@ dependencies = [ [[package]] name = "sway-core" -version = "0.65.0" +version = "0.65.1" dependencies = [ "clap 4.5.16", "derivative", @@ -7700,7 +7700,7 @@ dependencies = [ [[package]] name = "sway-error" -version = "0.65.0" +version = "0.65.1" dependencies = [ "either", "in_definite", @@ -7714,7 +7714,7 @@ dependencies = [ [[package]] name = "sway-ir" -version = "0.65.0" +version = "0.65.1" dependencies = [ "anyhow", "downcast-rs", @@ -7733,7 +7733,7 @@ dependencies = [ [[package]] name = "sway-ir-macros" -version = "0.65.0" +version = "0.65.1" dependencies = [ "itertools 0.13.0", "proc-macro2", @@ -7743,7 +7743,7 @@ dependencies = [ [[package]] name = "sway-lsp" -version = "0.65.0" +version = "0.65.1" dependencies = [ "anyhow", "assert-json-diff", @@ -7754,7 +7754,7 @@ dependencies = [ "dirs 4.0.0", "fd-lock", "forc-pkg", - "forc-tracing 0.65.0", + "forc-tracing 0.65.1", "forc-util", "futures", "indexmap 2.5.0", @@ -7793,7 +7793,7 @@ dependencies = [ [[package]] name = "sway-lsp-test-utils" -version = "0.65.0" +version = "0.65.1" dependencies = [ "assert-json-diff", "futures", @@ -7808,7 +7808,7 @@ dependencies = [ [[package]] name = "sway-parse" -version = "0.65.0" +version = "0.65.1" dependencies = [ "assert_matches", "extension-trait", @@ -7826,7 +7826,7 @@ dependencies = [ [[package]] name = "sway-types" -version = "0.65.0" +version = "0.65.1" dependencies = [ "bytecount", "fuel-asm", @@ -7845,7 +7845,7 @@ dependencies = [ [[package]] name = "sway-utils" -version = "0.65.0" +version = "0.65.1" dependencies = [ "serde", "walkdir", @@ -7853,11 +7853,11 @@ dependencies = [ [[package]] name = "swayfmt" -version = "0.65.0" +version = "0.65.1" dependencies = [ "anyhow", "difference", - "forc-tracing 0.65.0", + "forc-tracing 0.65.1", "indoc", "paste", "prettydiff 0.6.4", @@ -8141,7 +8141,7 @@ dependencies = [ "forc-client", "forc-pkg", "forc-test", - "forc-tracing 0.65.0", + "forc-tracing 0.65.1", "fuel-vm", "futures", "gag", diff --git a/Cargo.toml b/Cargo.toml index 245f9d10cf8..0fae0608eef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ exclude = [ [workspace.package] edition = "2021" -version = "0.65.0" +version = "0.65.1" authors = ["Fuel Labs "] homepage = "https://fuel.network/" license = "Apache-2.0" @@ -45,34 +45,34 @@ repository = "https://github.com/FuelLabs/sway" # Internal dependencies in order to propagate `workspace.version` # -forc = { path = "forc/", version = "0.65.0" } -forc-pkg = { path = "forc-pkg/", version = "0.65.0" } -forc-test = { path = "forc-test/", version = "0.65.0" } -forc-tracing = { path = "forc-tracing/", version = "0.65.0" } -forc-util = { path = "forc-util/", version = "0.65.0" } +forc = { path = "forc/", version = "0.65.1" } +forc-pkg = { path = "forc-pkg/", version = "0.65.1" } +forc-test = { path = "forc-test/", version = "0.65.1" } +forc-tracing = { path = "forc-tracing/", version = "0.65.1" } +forc-util = { path = "forc-util/", version = "0.65.1" } # Forc plugins -forc-plugins = { path = "forc-plugins/", version = "0.65.0" } -forc-client = { path = "forc-plugins/forc-client/", version = "0.65.0" } -forc-crypto = { path = "forc-plugins/forc-crypto/", version = "0.65.0" } -forc-debug = { path = "forc-plugins/forc-debug/", version = "0.65.0" } -forc-doc = { path = "forc-plugins/forc-doc/", version = "0.65.0" } -forc-fmt = { path = "forc-plugins/forc-fmt/", version = "0.65.0" } -forc-lsp = { path = "forc-plugins/forc-lsp/", version = "0.65.0" } -forc-tx = { path = "forc-plugins/forc-tx/", version = "0.65.0" } +forc-plugins = { path = "forc-plugins/", version = "0.65.1" } +forc-client = { path = "forc-plugins/forc-client/", version = "0.65.1" } +forc-crypto = { path = "forc-plugins/forc-crypto/", version = "0.65.1" } +forc-debug = { path = "forc-plugins/forc-debug/", version = "0.65.1" } +forc-doc = { path = "forc-plugins/forc-doc/", version = "0.65.1" } +forc-fmt = { path = "forc-plugins/forc-fmt/", version = "0.65.1" } +forc-lsp = { path = "forc-plugins/forc-lsp/", version = "0.65.1" } +forc-tx = { path = "forc-plugins/forc-tx/", version = "0.65.1" } -sway-ast = { path = "sway-ast/", version = "0.65.0" } -sway-core = { path = "sway-core/", version = "0.65.0" } -sway-error = { path = "sway-error/", version = "0.65.0" } -sway-lsp = { path = "sway-lsp/", version = "0.65.0" } -sway-parse = { path = "sway-parse/", version = "0.65.0" } -sway-types = { path = "sway-types/", version = "0.65.0" } -sway-utils = { path = "sway-utils/", version = "0.65.0" } -swayfmt = { path = "swayfmt/", version = "0.65.0" } +sway-ast = { path = "sway-ast/", version = "0.65.1" } +sway-core = { path = "sway-core/", version = "0.65.1" } +sway-error = { path = "sway-error/", version = "0.65.1" } +sway-lsp = { path = "sway-lsp/", version = "0.65.1" } +sway-parse = { path = "sway-parse/", version = "0.65.1" } +sway-types = { path = "sway-types/", version = "0.65.1" } +sway-utils = { path = "sway-utils/", version = "0.65.1" } +swayfmt = { path = "swayfmt/", version = "0.65.1" } # Sway IR -sway-ir = { path = "sway-ir/", version = "0.65.0" } -sway-ir-macros = { path = "sway-ir/sway-ir-macros", version = "0.65.0" } +sway-ir = { path = "sway-ir/", version = "0.65.1" } +sway-ir-macros = { path = "sway-ir/sway-ir-macros", version = "0.65.1" } # # External Fuel dependencies From b465e19284c86504989eff535ddb135d1097c854 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaya=20G=C3=B6kalp?= Date: Mon, 7 Oct 2024 05:10:36 -0700 Subject: [PATCH 052/115] fix: pin forc-deploy to use 100kb blob size by default (#6616) ## Description Pins forc-deploy chunk sizes to 100kb to fix errors while deploying chunked contracts. To unblock an ecosystem project, the PR is marked critical. --- .../src/forc/plugins/forc_client/index.md | 4 +-- forc-plugins/forc-client/src/op/deploy.rs | 28 ++++--------------- 2 files changed, 7 insertions(+), 25 deletions(-) diff --git a/docs/book/src/forc/plugins/forc_client/index.md b/docs/book/src/forc/plugins/forc_client/index.md index 454cbc9f622..13800088b96 100644 --- a/docs/book/src/forc/plugins/forc_client/index.md +++ b/docs/book/src/forc/plugins/forc_client/index.md @@ -179,7 +179,7 @@ If an `address` is present, `forc` calls into that contract to update its `targe ## Large Contracts -For contracts over the maximum contract size limit defined by the network, `forc-deploy` will split the contract into chunks and deploy the contract with multiple transactions using the Rust SDK's [loader contract](https://github.com/FuelLabs/fuels-rs/blob/master/docs/src/deploying/large_contracts.md) functionality. Chunks that have already been deployed will be reused on subsequent deployments. +For contracts over the maximum contract size limit (currently `100kB`) defined by the network, `forc-deploy` will split the contract into chunks and deploy the contract with multiple transactions using the Rust SDK's [loader contract](https://github.com/FuelLabs/fuels-rs/blob/master/docs/src/deploying/large_contracts.md) functionality. Chunks that have already been deployed will be reused on subsequent deployments. ## Deploying Scripts and Predicates @@ -200,4 +200,4 @@ The loader files contain the bytecode necessary to load and execute your script This new deployment method allows for more efficient storage and execution of scripts and predicates on the Fuel network. -Note: Contracts are still deployed directly, not as blobs given that the contract size is under the maximum contract size limit defined by network. +Note: Contracts are still deployed directly, not as blobs given that the contract size is under the maximum contract size limit defined by network (currently `100kB`). diff --git a/forc-plugins/forc-client/src/op/deploy.rs b/forc-plugins/forc-client/src/op/deploy.rs index ddaf6a8c54d..798fd788826 100644 --- a/forc-plugins/forc-client/src/op/deploy.rs +++ b/forc-plugins/forc-client/src/op/deploy.rs @@ -53,7 +53,7 @@ use sway_core::{asm_generation::ProgramABI, language::parsed::TreeType}; /// Default maximum contract size allowed for a single contract. If the target /// contract size is bigger than this amount, forc-deploy will automatically /// starts dividing the contract and deploy them in chunks automatically. -/// The value is in bytes. +/// The value is in bytes const MAX_CONTRACT_SIZE: usize = 100_000; /// Represents a deployed instance of a forc package. @@ -198,15 +198,10 @@ async fn deploy_chunked( None => "".to_string(), }; - let chunk_size = chain_info - .consensus_parameters - .contract_params() - .contract_max_size() as usize; - let blobs = compiled .bytecode .bytes - .chunks(chunk_size) + .chunks(MAX_CONTRACT_SIZE) .map(|chunk| Blob::new(chunk.to_vec())) .collect(); @@ -613,26 +608,13 @@ pub async fn deploy_contracts( let node_url = validate_and_get_node_url(command, contracts_to_deploy).await?; let provider = Provider::connect(node_url.clone()).await?; - let max_contract_size = provider - .chain_info() - .await - .ok() - .and_then(|chain_info| { - chain_info - .consensus_parameters - .contract_params() - .contract_max_size() - .try_into() - .ok() - }) - .unwrap_or(MAX_CONTRACT_SIZE); // Confirmation step. Summarize the transaction(s) for the deployment. let account = confirm_transaction_details( contracts_to_deploy, command, node_url.clone(), - max_contract_size, + MAX_CONTRACT_SIZE, ) .await?; @@ -652,7 +634,7 @@ pub async fn deploy_contracts( } }; let bytecode_size = pkg.bytecode.bytes.len(); - let deployed_contract_id = if bytecode_size > max_contract_size { + let deployed_contract_id = if bytecode_size > MAX_CONTRACT_SIZE { // Deploy chunked let node_url = get_node_url(&command.node, &pkg.descriptor.manifest_file.network)?; let provider = Provider::connect(node_url).await?; @@ -717,7 +699,7 @@ pub async fn deploy_contracts( let deployed_contract = DeployedContract { id: deployed_contract_id, proxy: proxy_id, - chunked: bytecode_size > max_contract_size, + chunked: bytecode_size > MAX_CONTRACT_SIZE, }; deployed_contracts.push(deployed_contract); } From 66bb430395daf5b8f7205f7b9d8d008e2e812d54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaya=20G=C3=B6kalp?= Date: Mon, 7 Oct 2024 05:37:45 -0700 Subject: [PATCH 053/115] chore: bump to v0.65.2 (#6617) ## Description releases v0.65.2 --- Cargo.lock | 68 +++++++++++++++++++++++++++--------------------------- Cargo.toml | 48 +++++++++++++++++++------------------- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ce2f1fa66c7..88b6b8e6464 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2678,7 +2678,7 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "forc" -version = "0.65.1" +version = "0.65.2" dependencies = [ "annotate-snippets", "ansi_term", @@ -2689,7 +2689,7 @@ dependencies = [ "completest-pty", "forc-pkg", "forc-test", - "forc-tracing 0.65.1", + "forc-tracing 0.65.2", "forc-util", "fs_extra", "fuel-asm", @@ -2715,7 +2715,7 @@ dependencies = [ [[package]] name = "forc-client" -version = "0.65.1" +version = "0.65.2" dependencies = [ "anyhow", "async-trait", @@ -2727,7 +2727,7 @@ dependencies = [ "dialoguer", "forc", "forc-pkg", - "forc-tracing 0.65.1", + "forc-tracing 0.65.2", "forc-tx", "forc-util", "forc-wallet", @@ -2762,13 +2762,13 @@ dependencies = [ [[package]] name = "forc-crypto" -version = "0.65.1" +version = "0.65.2" dependencies = [ "anyhow", "async-trait", "atty", "clap 4.5.16", - "forc-tracing 0.65.1", + "forc-tracing 0.65.2", "forc-util", "fuel-core-types", "fuel-crypto", @@ -2788,7 +2788,7 @@ dependencies = [ [[package]] name = "forc-debug" -version = "0.65.1" +version = "0.65.2" dependencies = [ "anyhow", "clap 4.5.16", @@ -2796,7 +2796,7 @@ dependencies = [ "escargot", "forc-pkg", "forc-test", - "forc-tracing 0.65.1", + "forc-tracing 0.65.2", "fuel-core-client", "fuel-types", "fuel-vm", @@ -2814,7 +2814,7 @@ dependencies = [ [[package]] name = "forc-doc" -version = "0.65.1" +version = "0.65.2" dependencies = [ "anyhow", "clap 4.5.16", @@ -2822,7 +2822,7 @@ dependencies = [ "dir_indexer", "expect-test", "forc-pkg", - "forc-tracing 0.65.1", + "forc-tracing 0.65.2", "forc-util", "horrorshow", "include_dir", @@ -2839,12 +2839,12 @@ dependencies = [ [[package]] name = "forc-fmt" -version = "0.65.1" +version = "0.65.2" dependencies = [ "anyhow", "clap 4.5.16", "forc-pkg", - "forc-tracing 0.65.1", + "forc-tracing 0.65.2", "forc-util", "prettydiff 0.7.0", "sway-core", @@ -2856,7 +2856,7 @@ dependencies = [ [[package]] name = "forc-lsp" -version = "0.65.1" +version = "0.65.2" dependencies = [ "anyhow", "clap 4.5.16", @@ -2867,13 +2867,13 @@ dependencies = [ [[package]] name = "forc-pkg" -version = "0.65.1" +version = "0.65.2" dependencies = [ "ansi_term", "anyhow", "byte-unit", "cid", - "forc-tracing 0.65.1", + "forc-tracing 0.65.2", "forc-util", "fuel-abi-types", "futures", @@ -2904,7 +2904,7 @@ dependencies = [ [[package]] name = "forc-test" -version = "0.65.1" +version = "0.65.2" dependencies = [ "anyhow", "forc-pkg", @@ -2931,7 +2931,7 @@ dependencies = [ [[package]] name = "forc-tracing" -version = "0.65.1" +version = "0.65.2" dependencies = [ "ansi_term", "tracing", @@ -2941,7 +2941,7 @@ dependencies = [ [[package]] name = "forc-tx" -version = "0.65.1" +version = "0.65.2" dependencies = [ "anyhow", "clap 4.5.16", @@ -2956,7 +2956,7 @@ dependencies = [ [[package]] name = "forc-util" -version = "0.65.1" +version = "0.65.2" dependencies = [ "annotate-snippets", "ansi_term", @@ -2964,7 +2964,7 @@ dependencies = [ "clap 4.5.16", "dirs 5.0.1", "fd-lock", - "forc-tracing 0.65.1", + "forc-tracing 0.65.2", "fuel-tx", "hex", "paste", @@ -7643,7 +7643,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sway-ast" -version = "0.65.1" +version = "0.65.2" dependencies = [ "extension-trait", "num-bigint", @@ -7655,7 +7655,7 @@ dependencies = [ [[package]] name = "sway-core" -version = "0.65.1" +version = "0.65.2" dependencies = [ "clap 4.5.16", "derivative", @@ -7700,7 +7700,7 @@ dependencies = [ [[package]] name = "sway-error" -version = "0.65.1" +version = "0.65.2" dependencies = [ "either", "in_definite", @@ -7714,7 +7714,7 @@ dependencies = [ [[package]] name = "sway-ir" -version = "0.65.1" +version = "0.65.2" dependencies = [ "anyhow", "downcast-rs", @@ -7733,7 +7733,7 @@ dependencies = [ [[package]] name = "sway-ir-macros" -version = "0.65.1" +version = "0.65.2" dependencies = [ "itertools 0.13.0", "proc-macro2", @@ -7743,7 +7743,7 @@ dependencies = [ [[package]] name = "sway-lsp" -version = "0.65.1" +version = "0.65.2" dependencies = [ "anyhow", "assert-json-diff", @@ -7754,7 +7754,7 @@ dependencies = [ "dirs 4.0.0", "fd-lock", "forc-pkg", - "forc-tracing 0.65.1", + "forc-tracing 0.65.2", "forc-util", "futures", "indexmap 2.5.0", @@ -7793,7 +7793,7 @@ dependencies = [ [[package]] name = "sway-lsp-test-utils" -version = "0.65.1" +version = "0.65.2" dependencies = [ "assert-json-diff", "futures", @@ -7808,7 +7808,7 @@ dependencies = [ [[package]] name = "sway-parse" -version = "0.65.1" +version = "0.65.2" dependencies = [ "assert_matches", "extension-trait", @@ -7826,7 +7826,7 @@ dependencies = [ [[package]] name = "sway-types" -version = "0.65.1" +version = "0.65.2" dependencies = [ "bytecount", "fuel-asm", @@ -7845,7 +7845,7 @@ dependencies = [ [[package]] name = "sway-utils" -version = "0.65.1" +version = "0.65.2" dependencies = [ "serde", "walkdir", @@ -7853,11 +7853,11 @@ dependencies = [ [[package]] name = "swayfmt" -version = "0.65.1" +version = "0.65.2" dependencies = [ "anyhow", "difference", - "forc-tracing 0.65.1", + "forc-tracing 0.65.2", "indoc", "paste", "prettydiff 0.6.4", @@ -8141,7 +8141,7 @@ dependencies = [ "forc-client", "forc-pkg", "forc-test", - "forc-tracing 0.65.1", + "forc-tracing 0.65.2", "fuel-vm", "futures", "gag", diff --git a/Cargo.toml b/Cargo.toml index 0fae0608eef..69d4008bc12 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ exclude = [ [workspace.package] edition = "2021" -version = "0.65.1" +version = "0.65.2" authors = ["Fuel Labs "] homepage = "https://fuel.network/" license = "Apache-2.0" @@ -45,34 +45,34 @@ repository = "https://github.com/FuelLabs/sway" # Internal dependencies in order to propagate `workspace.version` # -forc = { path = "forc/", version = "0.65.1" } -forc-pkg = { path = "forc-pkg/", version = "0.65.1" } -forc-test = { path = "forc-test/", version = "0.65.1" } -forc-tracing = { path = "forc-tracing/", version = "0.65.1" } -forc-util = { path = "forc-util/", version = "0.65.1" } +forc = { path = "forc/", version = "0.65.2" } +forc-pkg = { path = "forc-pkg/", version = "0.65.2" } +forc-test = { path = "forc-test/", version = "0.65.2" } +forc-tracing = { path = "forc-tracing/", version = "0.65.2" } +forc-util = { path = "forc-util/", version = "0.65.2" } # Forc plugins -forc-plugins = { path = "forc-plugins/", version = "0.65.1" } -forc-client = { path = "forc-plugins/forc-client/", version = "0.65.1" } -forc-crypto = { path = "forc-plugins/forc-crypto/", version = "0.65.1" } -forc-debug = { path = "forc-plugins/forc-debug/", version = "0.65.1" } -forc-doc = { path = "forc-plugins/forc-doc/", version = "0.65.1" } -forc-fmt = { path = "forc-plugins/forc-fmt/", version = "0.65.1" } -forc-lsp = { path = "forc-plugins/forc-lsp/", version = "0.65.1" } -forc-tx = { path = "forc-plugins/forc-tx/", version = "0.65.1" } +forc-plugins = { path = "forc-plugins/", version = "0.65.2" } +forc-client = { path = "forc-plugins/forc-client/", version = "0.65.2" } +forc-crypto = { path = "forc-plugins/forc-crypto/", version = "0.65.2" } +forc-debug = { path = "forc-plugins/forc-debug/", version = "0.65.2" } +forc-doc = { path = "forc-plugins/forc-doc/", version = "0.65.2" } +forc-fmt = { path = "forc-plugins/forc-fmt/", version = "0.65.2" } +forc-lsp = { path = "forc-plugins/forc-lsp/", version = "0.65.2" } +forc-tx = { path = "forc-plugins/forc-tx/", version = "0.65.2" } -sway-ast = { path = "sway-ast/", version = "0.65.1" } -sway-core = { path = "sway-core/", version = "0.65.1" } -sway-error = { path = "sway-error/", version = "0.65.1" } -sway-lsp = { path = "sway-lsp/", version = "0.65.1" } -sway-parse = { path = "sway-parse/", version = "0.65.1" } -sway-types = { path = "sway-types/", version = "0.65.1" } -sway-utils = { path = "sway-utils/", version = "0.65.1" } -swayfmt = { path = "swayfmt/", version = "0.65.1" } +sway-ast = { path = "sway-ast/", version = "0.65.2" } +sway-core = { path = "sway-core/", version = "0.65.2" } +sway-error = { path = "sway-error/", version = "0.65.2" } +sway-lsp = { path = "sway-lsp/", version = "0.65.2" } +sway-parse = { path = "sway-parse/", version = "0.65.2" } +sway-types = { path = "sway-types/", version = "0.65.2" } +sway-utils = { path = "sway-utils/", version = "0.65.2" } +swayfmt = { path = "swayfmt/", version = "0.65.2" } # Sway IR -sway-ir = { path = "sway-ir/", version = "0.65.1" } -sway-ir-macros = { path = "sway-ir/sway-ir-macros", version = "0.65.1" } +sway-ir = { path = "sway-ir/", version = "0.65.2" } +sway-ir-macros = { path = "sway-ir/sway-ir-macros", version = "0.65.2" } # # External Fuel dependencies From f5fd2e63a6ed0f947dd3f978cc15f6d788f53843 Mon Sep 17 00:00:00 2001 From: Joshua Batty Date: Wed, 9 Oct 2024 09:18:36 +1100 Subject: [PATCH 054/115] revert to original code owners before the freeze (#6622) ## Description This was added in #6600. Reverting this back to the original code owners now after having a chat with Mike. ## Checklist - [ ] 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. - [ ] 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). - [ ] I have requested a review from the relevant team or maintainers. --- .github/CODEOWNERS | 61 +++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 7fb8f888450..bdb38dc2c31 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,37 +1,36 @@ -* @Voxelot @mchristopher @luizstacio -# # Everything else -# * @FuelLabs/leads +# Everything else +* @FuelLabs/leads -# # Documentation -# /docs/ @FuelLabs/tooling @FuelLabs/sway-compiler @FuelLabs/swayex @FuelLabs/Devrel +# Documentation +/docs/ @FuelLabs/tooling @FuelLabs/sway-compiler @FuelLabs/swayex @FuelLabs/Devrel -# # Sway files and standard library -# /examples/ @FuelLabs/sway-compiler @FuelLabs/swayex -# /sway-lib-core/ @FuelLabs/sway-compiler @FuelLabs/swayex -# /sway-lib-std/ @FuelLabs/sway-compiler @FuelLabs/swayex +# Sway files and standard library +/examples/ @FuelLabs/sway-compiler @FuelLabs/swayex +/sway-lib-core/ @FuelLabs/sway-compiler @FuelLabs/swayex +/sway-lib-std/ @FuelLabs/sway-compiler @FuelLabs/swayex -# # Tooling -# /forc/ @FuelLabs/tooling -# /forc-pkg/ @FuelLabs/tooling -# /forc-plugins/ @FuelLabs/tooling -# /forc-test/ @FuelLabs/tooling -# /forc-tracing/ @FuelLabs/tooling -# /forc-util/ @FuelLabs/tooling -# /sway-lsp/ @FuelLabs/tooling -# /swayfmt/ @FuelLabs/tooling +# Tooling +/forc/ @FuelLabs/tooling +/forc-pkg/ @FuelLabs/tooling +/forc-plugins/ @FuelLabs/tooling +/forc-test/ @FuelLabs/tooling +/forc-tracing/ @FuelLabs/tooling +/forc-util/ @FuelLabs/tooling +/sway-lsp/ @FuelLabs/tooling +/swayfmt/ @FuelLabs/tooling -# # Compiler -# /sway-ast/ @FuelLabs/sway-compiler -# /sway-core/ @FuelLabs/sway-compiler -# /sway-error/ @FuelLabs/sway-compiler -# /sway-ir/ @FuelLabs/sway-compiler -# /sway-parse/ @FuelLabs/sway-compiler -# /sway-types/ @FuelLabs/sway-compiler -# /sway-utils/ @FuelLabs/sway-compiler -# /templates/ @FuelLabs/sway-compiler -# /test/ @FuelLabs/sway-compiler +# Compiler +/sway-ast/ @FuelLabs/sway-compiler +/sway-core/ @FuelLabs/sway-compiler +/sway-error/ @FuelLabs/sway-compiler +/sway-ir/ @FuelLabs/sway-compiler +/sway-parse/ @FuelLabs/sway-compiler +/sway-types/ @FuelLabs/sway-compiler +/sway-utils/ @FuelLabs/sway-compiler +/templates/ @FuelLabs/sway-compiler +/test/ @FuelLabs/sway-compiler -# # Root lockfile and deployment scripts -# Cargo.lock @FuelLabs/leads -# /deployment/ @FuelLabs/leads +# Root lockfile and deployment scripts +Cargo.lock @FuelLabs/leads +/deployment/ @FuelLabs/leads From 98d821b6ed404a7018453db8530eda03fde44067 Mon Sep 17 00:00:00 2001 From: Sophie Dankel <47993817+sdankel@users.noreply.github.com> Date: Mon, 14 Oct 2024 21:00:25 -0700 Subject: [PATCH 055/115] add new target to forc (#6621) ## Description ## Checklist - [ ] 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. - [ ] 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). - [ ] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: Alfie John Co-authored-by: Joshua Batty --- .../src/forc/plugins/forc_client/index.md | 18 ++-- forc-plugins/forc-client/src/cmd/deploy.rs | 2 +- forc-plugins/forc-client/src/constants.rs | 14 +-- forc-plugins/forc-client/src/lib.rs | 18 ++-- forc-plugins/forc-client/src/op/deploy.rs | 6 +- forc-plugins/forc-client/src/util/node_url.rs | 86 +++++++------------ forc-plugins/forc-client/src/util/target.rs | 67 +++++---------- forc-plugins/forc-client/src/util/tx.rs | 19 ++-- forc-plugins/forc-client/tests/deploy.rs | 16 ++++ 9 files changed, 115 insertions(+), 131 deletions(-) diff --git a/docs/book/src/forc/plugins/forc_client/index.md b/docs/book/src/forc/plugins/forc_client/index.md index 13800088b96..feb436af788 100644 --- a/docs/book/src/forc/plugins/forc_client/index.md +++ b/docs/book/src/forc/plugins/forc_client/index.md @@ -92,24 +92,30 @@ By default `--default-signer` flag would sign your transactions with the followi 0xde97d8624a438121b86a1956544bd72ed68cd69f2c99555b08b1e8c51ffd511c ``` -## Interacting with the testnet +## Selecting a target network -To interact with the latest testnet, use the `--testnet` flag. When this flag is passed, transactions created by `forc-deploy` will be sent to the latest `testnet`. +By default, `local` is used for the target network. To interact with the latest testnet, use the `--testnet` flag. When this flag is passed, transactions created by `forc-deploy` will be sent to the latest `testnet`: ```sh forc-deploy --testnet ``` -It is also possible to pass the exact node URL while using `forc-deploy` or `forc-run` which can be done using `--node-url` flag. +The same can be done to target mainnet: ```sh -forc-deploy --node-url https://beta-3.fuel.network +forc-deploy --mainnet ``` -Another alternative is the `--target` option, which provides useful aliases to all targets. For example if you want to deploy to `beta-5` you can use: +It is also possible to pass the exact node URL while using `forc-deploy` or `forc-run` which can be done using `--node-url` flag: ```sh -forc-deploy --target beta-5 +forc-deploy --node-url https://mainnet.fuel.network +``` + +Another alternative is the `--target` option, which provides useful aliases to all targets. For example if you want to deploy to `testnet` you can use: + +```sh +forc-deploy --target testnet ``` Since deploying and running projects on the testnet cost gas, you will need coins to pay for them. You can get some using the [testnet faucet](https://faucet-testnet.fuel.network/). diff --git a/forc-plugins/forc-client/src/cmd/deploy.rs b/forc-plugins/forc-client/src/cmd/deploy.rs index 5553a2fe06b..87428dfbca7 100644 --- a/forc-plugins/forc-client/src/cmd/deploy.rs +++ b/forc-plugins/forc-client/src/cmd/deploy.rs @@ -10,7 +10,7 @@ forc_util::cli_examples! { super::Command { [ Deploy a single contract => "forc deploy bc09bfa7a11a04ce42b0a5abf04fd437387ee49bf4561d575177e2946468b408" ] [ Deploy a single contract from a different path => "forc deploy bc09bfa7a11a04ce42b0a5abf04fd437387ee49bf4561d575177e2946468b408 --path {path}" ] - [ Deploy to a custom network => "forc deploy --node-url https://beta-5.fuel.network/graphql" ] + [ Deploy to a custom network => "forc deploy --node-url https://testnet.fuel.network/graphql" ] } } diff --git a/forc-plugins/forc-client/src/constants.rs b/forc-plugins/forc-client/src/constants.rs index f6e1faa4201..1b195f733e6 100644 --- a/forc-plugins/forc-client/src/constants.rs +++ b/forc-plugins/forc-client/src/constants.rs @@ -1,20 +1,12 @@ /// Default to localhost to favour the common case of testing. pub const NODE_URL: &str = sway_utils::constants::DEFAULT_NODE_URL; -pub const BETA_2_ENDPOINT_URL: &str = "https://node-beta-2.fuel.network"; -pub const BETA_3_ENDPOINT_URL: &str = "https://beta-3.fuel.network"; -pub const BETA_4_ENDPOINT_URL: &str = "https://beta-4.fuel.network"; -pub const BETA_5_ENDPOINT_URL: &str = "https://beta-5.fuel.network"; -pub const DEVNET_ENDPOINT_URL: &str = "https://devnet.fuel.network"; pub const TESTNET_ENDPOINT_URL: &str = "https://testnet.fuel.network"; +pub const MAINNET_ENDPOINT_URL: &str = "https://mainnet.fuel.network"; -pub const BETA_2_FAUCET_URL: &str = "https://faucet-beta-2.fuel.network"; -pub const BETA_3_FAUCET_URL: &str = "https://faucet-beta-3.fuel.network"; -pub const BETA_4_FAUCET_URL: &str = "https://faucet-beta-4.fuel.network"; -pub const BETA_5_FAUCET_URL: &str = "https://faucet-beta-5.fuel.network"; -pub const DEVNET_FAUCET_URL: &str = "https://faucet-devnet.fuel.network"; pub const TESTNET_FAUCET_URL: &str = "https://faucet-testnet.fuel.network"; -pub const TESTNET_EXPLORER_URL: &str = "https://app.fuel.network"; +pub const TESTNET_EXPLORER_URL: &str = "https://app-testnet.fuel.network"; +pub const MAINNET_EXPLORER_URL: &str = "https://app.fuel.network"; /// Default PrivateKey to sign transactions submitted to local node. pub const DEFAULT_PRIVATE_KEY: &str = diff --git a/forc-plugins/forc-client/src/lib.rs b/forc-plugins/forc-client/src/lib.rs index cce5e5ab95e..a4db6b262a1 100644 --- a/forc-plugins/forc-client/src/lib.rs +++ b/forc-plugins/forc-client/src/lib.rs @@ -14,19 +14,27 @@ pub struct NodeTarget { /// If unspecified, checks the manifest's `network` table, then falls back /// to `http://127.0.0.1:4000` /// - /// You can also use `--target` or `--testnet` to specify the Fuel node. + /// You can also use `--target`, `--testnet`, or `--mainnet` to specify the Fuel node. #[clap(long, env = "FUEL_NODE_URL")] pub node_url: Option, + /// Use preset configurations for deploying to a specific target. /// - /// You can also use `--node-url` or `--testnet` to specify the Fuel node. + /// You can also use `--node-url`, `--testnet`, or `--mainnet` to specify the Fuel node. /// - /// Possible values are: [beta-1, beta-2, beta-3, beta-4, local] + /// Possible values are: [local, testnet, mainnet] #[clap(long)] pub target: Option, - /// Use preset configuration for the latest testnet. + + /// Use preset configuration for testnet. /// - /// You can also use `--node-url` or `--target` to specify the Fuel node. + /// You can also use `--node-url`, `--target`, or `--mainnet` to specify the Fuel node. #[clap(long)] pub testnet: bool, + + /// Use preset configuration for mainnet. + /// + /// You can also use `--node-url`, `--target`, or `--testnet` to specify the Fuel node. + #[clap(long)] + pub mainnet: bool, } diff --git a/forc-plugins/forc-client/src/op/deploy.rs b/forc-plugins/forc-client/src/op/deploy.rs index 798fd788826..cdc5d35162c 100644 --- a/forc-plugins/forc-client/src/op/deploy.rs +++ b/forc-plugins/forc-client/src/op/deploy.rs @@ -192,7 +192,7 @@ async fn deploy_chunked( let storage_slots = resolve_storage_slots(command, compiled)?; let chain_info = provider.chain_info().await?; - let target = Target::from_str(&chain_info.name).unwrap_or(Target::testnet()); + let target = Target::from_str(&chain_info.name).unwrap_or_default(); let contract_url = match target.explorer_url() { Some(explorer_url) => format!("{explorer_url}/contract/0x"), None => "".to_string(), @@ -257,7 +257,7 @@ async fn deploy_new_proxy( .into(); let chain_info = provider.chain_info().await?; - let target = Target::from_str(&chain_info.name).unwrap_or(Target::testnet()); + let target = Target::from_str(&chain_info.name).unwrap_or_default(); let contract_url = match target.explorer_url() { Some(explorer_url) => format!("{explorer_url}/contract/0x"), None => "".to_string(), @@ -948,7 +948,7 @@ fn create_deployment_artifact( let contract_id = ContractId::from_str(&deployment_artifact.contract_id).unwrap(); let pkg_name = manifest.project_name(); - let target = Target::from_str(&chain_info.name).unwrap_or(Target::testnet()); + let target = Target::from_str(&chain_info.name).unwrap_or_default(); let (contract_url, block_url) = match target.explorer_url() { Some(explorer_url) => ( format!("{explorer_url}/contract/0x"), diff --git a/forc-plugins/forc-client/src/util/node_url.rs b/forc-plugins/forc-client/src/util/node_url.rs index b7fe3f8bf39..58e9dcd87e1 100644 --- a/forc-plugins/forc-client/src/util/node_url.rs +++ b/forc-plugins/forc-client/src/util/node_url.rs @@ -12,18 +12,22 @@ pub fn get_node_url( ) -> Result { let node_url = match ( node_target.testnet, + node_target.mainnet, node_target.target.clone(), node_target.node_url.clone(), ) { - (true, None, None) => Target::testnet().target_url(), - (false, Some(target), None) => target.target_url(), - (false, None, Some(node_url)) => node_url, - (false, None, None) => manifest_network + (true, false, None, None) => Target::testnet().target_url(), + (false, true, None, None) => Target::mainnet().target_url(), + (false, false, Some(target), None) => target.target_url(), + (false, false, None, Some(node_url)) => node_url, + (false, false, None, None) => manifest_network .as_ref() .map(|nw| &nw.url[..]) .unwrap_or(crate::constants::NODE_URL) .to_string(), - _ => bail!("Only one of `--testnet`, `--target`, or `--node-url` should be specified"), + _ => bail!( + "Only one of `--testnet`, `--mainnet`, `--target`, or `--node-url` should be specified" + ), }; Ok(node_url) @@ -35,6 +39,7 @@ fn test_get_node_url_testnet() { target: None, node_url: None, testnet: true, + mainnet: false, }; let actual = get_node_url(&input, &None).unwrap(); @@ -42,63 +47,41 @@ fn test_get_node_url_testnet() { } #[test] -fn test_get_node_url_target_devnet() { +fn test_get_node_url_mainnet() { let input = NodeTarget { - target: Some(Target::Devnet), - node_url: None, - testnet: false, - }; - let actual = get_node_url(&input, &None).unwrap(); - assert_eq!("https://devnet.fuel.network", actual); -} - -#[test] -fn test_get_node_url_target_testnet() { - let input = NodeTarget { - target: Some(Target::Testnet), + target: None, node_url: None, testnet: false, + mainnet: true, }; let actual = get_node_url(&input, &None).unwrap(); - assert_eq!("https://testnet.fuel.network", actual); + assert_eq!("https://mainnet.fuel.network", actual); } #[test] -fn test_get_node_url_beta5() { +fn test_get_node_url_target_mainnet() { let input = NodeTarget { - target: Some(Target::Beta5), + target: Some(Target::Mainnet), node_url: None, testnet: false, + mainnet: false, }; let actual = get_node_url(&input, &None).unwrap(); - assert_eq!("https://beta-5.fuel.network", actual); + assert_eq!("https://mainnet.fuel.network", actual); } #[test] -fn test_get_node_url_beta4() { - let input = NodeTarget { - target: None, - node_url: Some("https://beta-4.fuel.network".to_string()), - testnet: false, - }; - let actual = get_node_url(&input, &None).unwrap(); - assert_eq!("https://beta-4.fuel.network", actual); -} - -#[test] -fn test_get_node_url_url_beta4_manifest() { - let network = Network { - url: "https://beta-4.fuel.network".to_string(), - }; +fn test_get_node_url_target_testnet() { let input = NodeTarget { - target: None, + target: Some(Target::Testnet), node_url: None, testnet: false, + mainnet: false, }; - let actual = get_node_url(&input, &Some(network)).unwrap(); - assert_eq!("https://beta-4.fuel.network", actual); + let actual = get_node_url(&input, &None).unwrap(); + assert_eq!("https://testnet.fuel.network", actual); } #[test] @@ -107,29 +90,20 @@ fn test_get_node_url_default() { target: None, node_url: None, testnet: false, + mainnet: false, }; let actual = get_node_url(&input, &None).unwrap(); assert_eq!("http://127.0.0.1:4000", actual); } -#[test] -fn test_get_node_url_beta3() { - let input = NodeTarget { - target: Some(Target::Beta3), - node_url: None, - testnet: false, - }; - let actual = get_node_url(&input, &None).unwrap(); - assert_eq!("https://beta-3.fuel.network", actual); -} - #[test] fn test_get_node_url_local() { let input = NodeTarget { target: Some(Target::Local), node_url: None, testnet: false, + mainnet: false, }; let actual = get_node_url(&input, &None).unwrap(); assert_eq!("http://127.0.0.1:4000", actual); @@ -137,26 +111,28 @@ fn test_get_node_url_local() { #[test] #[should_panic( - expected = "Only one of `--testnet`, `--target`, or `--node-url` should be specified" + expected = "Only one of `--testnet`, `--mainnet`, `--target`, or `--node-url` should be specified" )] fn test_get_node_url_local_testnet() { let input = NodeTarget { target: Some(Target::Local), node_url: None, testnet: true, + mainnet: false, }; get_node_url(&input, &None).unwrap(); } #[test] #[should_panic( - expected = "Only one of `--testnet`, `--target`, or `--node-url` should be specified" + expected = "Only one of `--testnet`, `--mainnet`, `--target`, or `--node-url` should be specified" )] fn test_get_node_url_same_url() { let input = NodeTarget { - target: Some(Target::Beta3), - node_url: Some("beta-3.fuel.network".to_string()), + target: Some(Target::Testnet), + node_url: Some("testnet.fuel.network".to_string()), testnet: false, + mainnet: false, }; get_node_url(&input, &None).unwrap(); } diff --git a/forc-plugins/forc-client/src/util/target.rs b/forc-plugins/forc-client/src/util/target.rs index 86b9b947666..3982f91ce07 100644 --- a/forc-plugins/forc-client/src/util/target.rs +++ b/forc-plugins/forc-client/src/util/target.rs @@ -1,8 +1,6 @@ use crate::constants::{ - BETA_2_ENDPOINT_URL, BETA_2_FAUCET_URL, BETA_3_ENDPOINT_URL, BETA_3_FAUCET_URL, - BETA_4_ENDPOINT_URL, BETA_4_FAUCET_URL, BETA_5_ENDPOINT_URL, BETA_5_FAUCET_URL, - DEVNET_ENDPOINT_URL, DEVNET_FAUCET_URL, NODE_URL, TESTNET_ENDPOINT_URL, TESTNET_EXPLORER_URL, - TESTNET_FAUCET_URL, + MAINNET_ENDPOINT_URL, MAINNET_EXPLORER_URL, NODE_URL, TESTNET_ENDPOINT_URL, + TESTNET_EXPLORER_URL, TESTNET_FAUCET_URL, }; use anyhow::{bail, Result}; use serde::{Deserialize, Serialize}; @@ -11,12 +9,8 @@ use std::str::FromStr; #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)] /// Possible target values that forc-client can interact with. pub enum Target { - Beta2, - Beta3, - Beta4, - Beta5, - Devnet, Testnet, + Mainnet, Local, } @@ -29,12 +23,8 @@ impl Default for Target { impl Target { pub fn target_url(&self) -> String { let url = match self { - Target::Beta2 => BETA_2_ENDPOINT_URL, - Target::Beta3 => BETA_3_ENDPOINT_URL, - Target::Beta4 => BETA_4_ENDPOINT_URL, - Target::Beta5 => BETA_5_ENDPOINT_URL, - Target::Devnet => DEVNET_ENDPOINT_URL, Target::Testnet => TESTNET_ENDPOINT_URL, + Target::Mainnet => MAINNET_ENDPOINT_URL, Target::Local => NODE_URL, }; url.to_string() @@ -42,36 +32,37 @@ impl Target { pub fn from_target_url(target_url: &str) -> Option { match target_url { - BETA_2_ENDPOINT_URL => Some(Target::Beta2), - BETA_3_ENDPOINT_URL => Some(Target::Beta3), - BETA_4_ENDPOINT_URL => Some(Target::Beta4), - BETA_5_ENDPOINT_URL => Some(Target::Beta5), - DEVNET_ENDPOINT_URL => Some(Target::Devnet), TESTNET_ENDPOINT_URL => Some(Target::Testnet), + MAINNET_ENDPOINT_URL => Some(Target::Mainnet), NODE_URL => Some(Target::Local), _ => None, } } + pub fn local() -> Self { + Target::Local + } + pub fn testnet() -> Self { Target::Testnet } - pub fn faucet_url(&self) -> String { + pub fn mainnet() -> Self { + Target::Mainnet + } + + pub fn faucet_url(&self) -> Option { match self { - Target::Beta2 => BETA_2_FAUCET_URL.to_string(), - Target::Beta3 => BETA_3_FAUCET_URL.to_string(), - Target::Beta4 => BETA_4_FAUCET_URL.to_string(), - Target::Beta5 => BETA_5_FAUCET_URL.to_string(), - Target::Devnet => DEVNET_FAUCET_URL.to_string(), - Target::Testnet => TESTNET_FAUCET_URL.to_string(), - Target::Local => "http://localhost:3000".to_string(), + Target::Testnet => Some(TESTNET_FAUCET_URL.to_string()), + Target::Mainnet => None, + Target::Local => Some("http://localhost:3000".to_string()), } } pub fn explorer_url(&self) -> Option { match self { - Target::Testnet | Target::Devnet => Some(TESTNET_EXPLORER_URL.to_string()), + Target::Testnet => Some(TESTNET_EXPLORER_URL.to_string()), + Target::Mainnet => Some(MAINNET_EXPLORER_URL.to_string()), _ => None, } } @@ -82,21 +73,13 @@ impl FromStr for Target { fn from_str(s: &str) -> Result { match s { - "beta-2" => Ok(Target::Beta2), - "beta-3" => Ok(Target::Beta3), - "beta-4" => Ok(Target::Beta4), - "beta-5" => Ok(Target::Beta5), - "devnet" => Ok(Target::Devnet), "testnet" => Ok(Target::Testnet), + "mainnet" => Ok(Target::Mainnet), "local" => Ok(Target::Local), _ => bail!( - "'{s}' is not a valid target name. Possible values: '{}', '{}', '{}', '{}', '{}', '{}', '{}'", - Target::Beta2, - Target::Beta3, - Target::Beta4, - Target::Beta5, - Target::Devnet, + "'{s}' is not a valid target name. Possible values: '{}', '{}', '{}'", Target::Testnet, + Target::Mainnet, Target::Local ), } @@ -106,12 +89,8 @@ impl FromStr for Target { impl std::fmt::Display for Target { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let s = match self { - Target::Beta2 => "beta-2", - Target::Beta3 => "beta-3", - Target::Beta4 => "beta-4", - Target::Beta5 => "beta-5", - Target::Devnet => "devnet", Target::Testnet => "testnet", + Target::Mainnet => "mainnet", Target::Local => "local", }; write!(f, "{}", s) diff --git a/forc-plugins/forc-client/src/util/tx.rs b/forc-plugins/forc-client/src/util/tx.rs index d5a002e809f..d1ceb751194 100644 --- a/forc-plugins/forc-client/src/util/tx.rs +++ b/forc-plugins/forc-client/src/util/tx.rs @@ -181,12 +181,19 @@ pub(crate) async fn select_account( let first_account = accounts .get(&0) .ok_or_else(|| anyhow::anyhow!("No account derived for this wallet"))?; - let target = Target::from_str(&chain_info.name).unwrap_or(Target::testnet()); - let faucet_link = format!("{}/?address={first_account}", target.faucet_url()); - anyhow::bail!("Your wallet does not have any funds to pay for the transaction.\ - \n\nIf you are interacting with a testnet consider using the faucet.\ - \n-> {target} network faucet: {faucet_link}\ - \nIf you are interacting with a local node, consider providing a chainConfig which funds your account.") + let target = Target::from_str(&chain_info.name).unwrap_or_default(); + let message = if let Some(faucet_url) = target.faucet_url() { + format!( + "Your wallet does not have any funds to pay for the transaction.\ + \n\nIf you are interacting with a testnet, consider using the faucet.\ + \n-> {target} network faucet: {}/?address={first_account}\ + \nIf you are interacting with a local node, consider providing a chainConfig which funds your account.", + faucet_url + ) + } else { + "Your wallet does not have any funds to pay for the transaction.".to_string() + }; + anyhow::bail!(message) } let selections = format_base_asset_account_balances(&accounts, &account_balances, base_asset_id); diff --git a/forc-plugins/forc-client/tests/deploy.rs b/forc-plugins/forc-client/tests/deploy.rs index adb83853318..e1f416062ff 100644 --- a/forc-plugins/forc-client/tests/deploy.rs +++ b/forc-plugins/forc-client/tests/deploy.rs @@ -360,6 +360,7 @@ async fn test_simple_deploy() { node_url: Some(node_url), target: None, testnet: false, + mainnet: false, }; let cmd = cmd::Deploy { pkg, @@ -401,6 +402,7 @@ async fn test_deploy_submit_only() { node_url: Some(node_url), target: None, testnet: false, + mainnet: false, }; let cmd = cmd::Deploy { pkg, @@ -447,6 +449,7 @@ async fn test_deploy_fresh_proxy() { node_url: Some(node_url), target: None, testnet: false, + mainnet: false, }; let cmd = cmd::Deploy { pkg, @@ -498,6 +501,7 @@ async fn test_proxy_contract_re_routes_call() { node_url: Some(node_url.clone()), target: None, testnet: false, + mainnet: false, }; let cmd = cmd::Deploy { pkg, @@ -555,6 +559,7 @@ async fn test_proxy_contract_re_routes_call() { node_url: Some(node_url.clone()), target: None, testnet: false, + mainnet: false, }; let pkg = Pkg { path: Some(tmp_dir.path().display().to_string()), @@ -629,6 +634,7 @@ async fn test_non_owner_fails_to_set_target() { node_url: Some(node_url.clone()), target: None, testnet: false, + mainnet: false, }; let cmd = cmd::Deploy { pkg, @@ -732,6 +738,7 @@ async fn chunked_deploy() { node_url: Some(node_url), target: None, testnet: false, + mainnet: false, }; let cmd = cmd::Deploy { pkg, @@ -764,6 +771,7 @@ async fn chunked_deploy_re_routes_calls() { node_url: Some(node_url.clone()), target: None, testnet: false, + mainnet: false, }; let cmd = cmd::Deploy { pkg, @@ -806,6 +814,7 @@ async fn chunked_deploy_with_proxy_re_routes_call() { node_url: Some(node_url.clone()), target: None, testnet: false, + mainnet: false, }; let cmd = cmd::Deploy { pkg, @@ -838,6 +847,7 @@ async fn can_deploy_script() { node_url: Some(node_url.clone()), target: None, testnet: false, + mainnet: false, }; let pkg = Pkg { path: Some(tmp_dir.path().display().to_string()), @@ -868,6 +878,7 @@ async fn deploy_script_calls() { node_url: Some(node_url.clone()), target: None, testnet: false, + mainnet: false, }; let pkg = Pkg { path: Some(tmp_dir.path().display().to_string()), @@ -899,6 +910,7 @@ async fn deploy_script_calls() { node_url: Some(node_url.clone()), target: None, testnet: false, + mainnet: false, }; let cmd = cmd::Deploy { pkg, @@ -989,6 +1001,7 @@ async fn can_deploy_predicates() { node_url: Some(node_url.clone()), target: None, testnet: false, + mainnet: false, }; let pkg = Pkg { path: Some(tmp_dir.path().display().to_string()), @@ -1019,6 +1032,7 @@ async fn deployed_predicate_call() { node_url: Some(node_url.clone()), target: None, testnet: false, + mainnet: false, }; let pkg = Pkg { path: Some(tmp_dir.path().display().to_string()), @@ -1164,6 +1178,7 @@ async fn call_with_forc_generated_overrides(node_url: &str, contract_id: Contrac node_url: Some(node_url.to_string()), target: None, testnet: false, + mainnet: false, }; let pkg = Pkg { path: Some(tmp_dir.path().display().to_string()), @@ -1273,6 +1288,7 @@ async fn offset_shifted_abi_works() { node_url: Some(node_url.clone()), target: None, testnet: false, + mainnet: false, }; let cmd = cmd::Deploy { pkg, From 7c7f27b85aa3a15b6c85345becb821caf580d14e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaya=20G=C3=B6kalp?= Date: Tue, 15 Oct 2024 02:19:14 -0700 Subject: [PATCH 056/115] feat: bump fuel-core to v0.40.0 and sdk to v0.66.9 + show checksum addresses in forc-deploy (#6630) ## Description Bumps fuel-core v0.40.0 and SDK to 0.66.9. Also updates the account selection phase of forc-deploy to show check sum encoded address. image --- Cargo.lock | 98 ++++--- Cargo.toml | 12 +- forc-plugins/forc-client/src/util/target.rs | 8 +- forc-plugins/forc-client/src/util/tx.rs | 35 ++- test/src/sdk-harness/Cargo.lock | 308 +++++++++++--------- test/src/sdk-harness/Cargo.toml | 6 +- 6 files changed, 266 insertions(+), 201 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 88b6b8e6464..d084c00dcf0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2983,9 +2983,9 @@ dependencies = [ [[package]] name = "forc-wallet" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ed8ee5063d7acc9b7dbdc5bdd43171e2bdcee5171b54939d1876f1b4fb01f6b" +checksum = "4e6ad4498ecab72fa7c5e134ade0137279d1b8f4a6df50963bb3803fdeb69dac" dependencies = [ "anyhow", "clap 4.5.16", @@ -3065,9 +3065,9 @@ dependencies = [ [[package]] name = "fuel-asm" -version = "0.58.0" +version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79ca07227658105bdf873556dea09fa7fbfe792fbc084b4b9568f5ba3d64c411" +checksum = "5f325971bf9047ec70004f80a989e03456316bc19cbef3ff3a39a38b192ab56e" dependencies = [ "bitflags 2.6.0", "fuel-types", @@ -3077,9 +3077,9 @@ dependencies = [ [[package]] name = "fuel-core-chain-config" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd1eca1d12daf8ad0f2479d7fff9405d94b6467496e5319e5f8b99cbdabdd58b" +checksum = "990db3029efd3766c4ae7c92a53c159ae66abf6f568ac6a3d58354f11400e6e2" dependencies = [ "anyhow", "bech32", @@ -3097,9 +3097,9 @@ dependencies = [ [[package]] name = "fuel-core-client" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dbd88f285afdf061e409b712ecef49e2fe9ba235288cc76e8de8f05d50b6876" +checksum = "f09b3a35e82226d77b10653829beb508dc4bcf698fbdaa96610faf894e794444" dependencies = [ "anyhow", "base64 0.22.1", @@ -3122,22 +3122,25 @@ dependencies = [ [[package]] name = "fuel-core-metrics" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc199e165e600f241cab86129766b26bab78572a701a39bc40a5fdb669961a8" +checksum = "94a1c3eb92040d95d27f7c658801bb5c04ad4aaf67de380cececbeed5aab6e61" dependencies = [ + "once_cell", "parking_lot 0.12.3", "pin-project-lite", "prometheus-client", "regex", + "strum 0.25.0", + "strum_macros 0.25.3", "tracing", ] [[package]] name = "fuel-core-poa" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49c4f3e5fa1e916793609bdb9a52142077a84a793272379a04cf24375aa94e6f" +checksum = "2f6f78fa31dc56b9458e3ca9a7058b4bea381e16e49fcab0db49923be8a30f9c" dependencies = [ "anyhow", "async-trait", @@ -3154,24 +3157,25 @@ dependencies = [ [[package]] name = "fuel-core-services" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "739dca83db1eb86651db3833f088f52afcd3f181cfca40e5725074aceb3ea49d" +checksum = "8312b598da4b9a6503c9263c1c2a7ea58d34ab1f86e7f345490e12d309fb29bb" dependencies = [ "anyhow", "async-trait", "fuel-core-metrics", "futures", "parking_lot 0.12.3", + "pin-project-lite", "tokio", "tracing", ] [[package]] name = "fuel-core-storage" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6255d852b6866199d103233e1eef2e7ded141019bc782b5b211fcf001727c34b" +checksum = "bda9242ebc9e8ef3251b9eae85f4ce5cdb376348baa30925606f3ce602db7ec5" dependencies = [ "anyhow", "derive_more 0.99.18", @@ -3191,9 +3195,9 @@ dependencies = [ [[package]] name = "fuel-core-types" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33a4e9b2de06381e1ad598cd1030344993fee7401331ca9955d0a1860cc0484c" +checksum = "6ee3a95b189bf729d21354a761862bb481298cbd883550adc3fef1bc7beb0b67" dependencies = [ "anyhow", "bs58", @@ -3209,9 +3213,9 @@ dependencies = [ [[package]] name = "fuel-crypto" -version = "0.58.0" +version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f53b06525aa7754bf7c3ef23daf15fd798ae990a82f8b7b813d25cedfeacfe5c" +checksum = "65e318850ca64890ff123a99b6b866954ef49da94ab9bc6827cf6ee045568585" dependencies = [ "coins-bip32", "coins-bip39", @@ -3230,9 +3234,9 @@ dependencies = [ [[package]] name = "fuel-derive" -version = "0.58.0" +version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e34d6eec30d04506607cc0bc85fc97c57c964580cd233fd557e346c5273535" +checksum = "ab0bc46a3552964bae5169e79b383761a54bd115ea66951a1a7a229edcefa55a" dependencies = [ "proc-macro2", "quote", @@ -3289,9 +3293,9 @@ dependencies = [ [[package]] name = "fuel-merkle" -version = "0.58.0" +version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a9fa3708405eba32fd2b947b827dc52484377ba6a238260b03a07b642395e6c" +checksum = "c79eca6a452311c70978a5df796c0f99f27e474b69719e0db4c1d82e68800d07" dependencies = [ "derive_more 0.99.18", "digest 0.10.7", @@ -3304,15 +3308,15 @@ dependencies = [ [[package]] name = "fuel-storage" -version = "0.58.0" +version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f678f1c900d0632d77e15d4a4946048d4d517fefeba72607390c03288ca127" +checksum = "2d0c46b5d76b3e11197bd31e036cd8b1cb46c4d822cacc48836638080c6d2b76" [[package]] name = "fuel-tx" -version = "0.58.0" +version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e3065c12eecc9121514694f4b01009c9a83d8842af11c43ec9e2bbc0a7f36cb" +checksum = "6723bb8710ba2b70516ac94d34459593225870c937670fb3afaf82e0354667ac" dependencies = [ "bitflags 2.6.0", "derivative", @@ -3332,9 +3336,9 @@ dependencies = [ [[package]] name = "fuel-types" -version = "0.58.0" +version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a93d5f3fd028d874d8927be439fcdea01cb04499049bc68a874c73dd0c7e32b7" +checksum = "982265415a99b5bd6277bc24194a233bb2e18764df11c937b3dbb11a02c9e545" dependencies = [ "fuel-derive", "hex", @@ -3344,9 +3348,9 @@ dependencies = [ [[package]] name = "fuel-vm" -version = "0.58.0" +version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0562398978e501e8ee2caeb747a2852cc4a8c5fff250eb58e38f1c03217311" +checksum = "54b5362d7d072c72eec20581f67fc5400090c356a7f3ae77c79880b3b177b667" dependencies = [ "anyhow", "async-trait", @@ -3378,9 +3382,9 @@ dependencies = [ [[package]] name = "fuels" -version = "0.66.6" +version = "0.66.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "921a8ea521744e600e0a34236adff7524ecf34bd940c2a018315d0212c140d7b" +checksum = "6ed08053e72bdb285d5a167c27a7a0d10f1dc4e27d1e6e5296dd2a67813bd13f" dependencies = [ "fuel-core-client", "fuel-crypto", @@ -3394,12 +3398,13 @@ dependencies = [ [[package]] name = "fuels-accounts" -version = "0.66.6" +version = "0.66.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da8bad87e947fc448c44c22e4c90a4af49d61de08722b1d1774d977b2071047" +checksum = "49fee90e8f3a4fc9392a6cde3010c561fa50da0f805d66fdb659eaa4d5d8a504" dependencies = [ "async-trait", "chrono", + "cynic", "elliptic-curve", "eth-keystore", "fuel-core-client", @@ -3419,9 +3424,9 @@ dependencies = [ [[package]] name = "fuels-code-gen" -version = "0.66.6" +version = "0.66.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fdc5f9dcdf330f5ef5f367dbc2334e72151e9ae46a4ee9f21d43a5e859be11b" +checksum = "f857b7ff658400506ca6be57bb84fedda44b566e78f5f0a8d0782242f41615c0" dependencies = [ "Inflector", "fuel-abi-types", @@ -3435,9 +3440,9 @@ dependencies = [ [[package]] name = "fuels-core" -version = "0.66.6" +version = "0.66.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "629212e8278d57aa1a6f846ca0ca1e3428fb6da2d43e368931ff1494a0a6b5ce" +checksum = "baccbdd81e624f57950dcb136b32b853c520dd954badf26b9f58de33f3d71c7e" dependencies = [ "async-trait", "bech32", @@ -3457,15 +3462,16 @@ dependencies = [ "postcard", "serde", "serde_json", + "sha2 0.10.8", "thiserror", "uint", ] [[package]] name = "fuels-macros" -version = "0.66.6" +version = "0.66.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562bf012adedfb492431f4bfd5be4ccbf2171ab7d5247c5953a6be3ea8036072" +checksum = "5da75294c5e9da312bdc49239736699ee84ea9c5bfbc19a61a8ee588a1247aa1" dependencies = [ "fuels-code-gen", "itertools 0.12.1", @@ -3476,9 +3482,9 @@ dependencies = [ [[package]] name = "fuels-programs" -version = "0.66.6" +version = "0.66.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a366e6a78e1c104fe1cb14439199833987fe76ecd46ee2b46fe05868a3366d" +checksum = "32675ed1c08edd28ddb648dfae0c60a1946d4368a69ddfa6434f2316e33f0520" dependencies = [ "async-trait", "fuel-abi-types", @@ -3495,9 +3501,9 @@ dependencies = [ [[package]] name = "fuels-test-helpers" -version = "0.66.6" +version = "0.66.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7705708c0fe28a874c44635b77c3e120a3422c8a24fdc45f07dc8c21ee9ca6fb" +checksum = "02176c0fb1bf8cf58b8a9e5372efb650324740abcd4847b45bd0b041a0f133a2" dependencies = [ "fuel-core-chain-config", "fuel-core-client", diff --git a/Cargo.toml b/Cargo.toml index 69d4008bc12..2f335a5031b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -86,14 +86,14 @@ fuel-abi-types = "0.7" # Although ALL verions are "X.Y", we need the complete semver for # fuel-core-client as the GitHub Actions workflow parses this value to pull down # the correct tarball -fuel-core-client = { version = "0.37.0", default-features = false } -fuel-core-types = { version = "0.37", default-features = false } +fuel-core-client = { version = "0.40.0", default-features = false } +fuel-core-types = { version = "0.40", default-features = false } # Dependencies from the `fuels-rs` repository: -fuels = "0.66" -fuels-core = "0.66" -fuels-accounts = "0.66" +fuels = "0.66.9" +fuels-core = "0.66.9" +fuels-accounts = "0.66.9" # Dependencies from the `fuel-vm` repository: fuel-asm = "0.58" @@ -103,7 +103,7 @@ fuel-tx = "0.58" fuel-vm = "0.58" # Dependencies from the `forc-wallet` repository: -forc-wallet = "0.10" +forc-wallet = "0.11" # # External dependencies diff --git a/forc-plugins/forc-client/src/util/target.rs b/forc-plugins/forc-client/src/util/target.rs index 3982f91ce07..bbc5679e844 100644 --- a/forc-plugins/forc-client/src/util/target.rs +++ b/forc-plugins/forc-client/src/util/target.rs @@ -73,8 +73,8 @@ impl FromStr for Target { fn from_str(s: &str) -> Result { match s { - "testnet" => Ok(Target::Testnet), - "mainnet" => Ok(Target::Mainnet), + "Fuel Sepolia Testnet" => Ok(Target::Testnet), + "Ignition" => Ok(Target::Mainnet), "local" => Ok(Target::Local), _ => bail!( "'{s}' is not a valid target name. Possible values: '{}', '{}', '{}'", @@ -89,8 +89,8 @@ impl FromStr for Target { impl std::fmt::Display for Target { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let s = match self { - Target::Testnet => "testnet", - Target::Mainnet => "mainnet", + Target::Testnet => "Fuel Sepolia Testnet", + Target::Mainnet => "Ignition", Target::Local => "local", }; write!(f, "{}", s) diff --git a/forc-plugins/forc-client/src/util/tx.rs b/forc-plugins/forc-client/src/util/tx.rs index d1ceb751194..e9f8b220121 100644 --- a/forc-plugins/forc-client/src/util/tx.rs +++ b/forc-plugins/forc-client/src/util/tx.rs @@ -15,7 +15,9 @@ use forc_wallet::{ }; use fuel_crypto::SecretKey; use fuel_tx::{AssetId, ContractId}; -use fuels::{macros::abigen, programs::responses::CallResponse}; +use fuels::{ + macros::abigen, programs::responses::CallResponse, types::checksum_address::checksum_encode, +}; use fuels_accounts::{ provider::Provider, wallet::{Wallet, WalletUnlocked}, @@ -139,7 +141,7 @@ pub fn format_base_asset_account_balances( accounts_map: &AccountsMap, account_balances: &AccountBalances, base_asset_id: &AssetId, -) -> Vec { +) -> Result> { accounts_map .iter() .zip(account_balances) @@ -148,10 +150,12 @@ pub fn format_base_asset_account_balances( .get(&base_asset_id.to_string()) .copied() .unwrap_or(0); + let raw_addr = format!("0x{address}"); + let checksum_addr = checksum_encode(&raw_addr)?; let eth_amount = base_asset_amount as f64 / 1_000_000_000.0; - format!("[{ix}] {address} - {eth_amount} ETH") + Ok(format!("[{ix}] {checksum_addr} - {eth_amount} ETH")) }) - .collect() + .collect::>>() } // TODO: Simplify the function signature once https://github.com/FuelLabs/sway/issues/6071 is closed. @@ -196,7 +200,7 @@ pub(crate) async fn select_account( anyhow::bail!(message) } let selections = - format_base_asset_account_balances(&accounts, &account_balances, base_asset_id); + format_base_asset_account_balances(&accounts, &account_balances, base_asset_id)?; let mut account_index; loop { @@ -210,7 +214,14 @@ pub(crate) async fn select_account( if accounts.contains_key(&account_index) { break; } - let options: Vec = accounts.keys().map(|key| key.to_string()).collect(); + let options: Vec = accounts + .keys() + .map(|key| { + let raw_addr = format!("0x{key}"); + let checksum_addr = checksum_encode(&raw_addr)?; + Ok(checksum_addr) + }) + .collect::>>()?; println_warning(&format!( "\"{}\" is not a valid account.\nPlease choose a valid option from {}", account_index, @@ -287,6 +298,7 @@ mod tests { ) .expect("address1") .into(); + let address2: fuel_tx::Address = Bech32Address::from_str( "fuel1x9f3ysyk7fmey5ac23s2p4rwg4gjye2kke3nu3pvrs5p4qc4m4qqwx56k3", ) @@ -308,13 +320,18 @@ mod tests { balance2.insert("other_asset".to_string(), 3_000_000_000); account_balances.push(balance2); + let address1_expected = + "0x6B32DF5954e1BaDEAFFEFD2c0fc5E594dcff3713aaE3Dd18B7d966624B010027"; + let address2_expected = + "0x3153124096f2779253B85460a0D46e4551226556b6633E442c1C281a8315dd40"; let expected = vec![ - format!("[0] {address1} - 1.5 ETH"), - format!("[1] {address2} - 0 ETH"), + format!("[0] {address1_expected} - 1.5 ETH"), + format!("[1] {address2_expected} - 0 ETH"), ]; let result = - format_base_asset_account_balances(&accounts_map, &account_balances, &base_asset_id); + format_base_asset_account_balances(&accounts_map, &account_balances, &base_asset_id) + .unwrap(); assert_eq!(result, expected); } } diff --git a/test/src/sdk-harness/Cargo.lock b/test/src/sdk-harness/Cargo.lock index a6bed9abb7b..dad11fa0e14 100644 --- a/test/src/sdk-harness/Cargo.lock +++ b/test/src/sdk-harness/Cargo.lock @@ -449,7 +449,7 @@ dependencies = [ "sync_wrapper", "tokio", "tower", - "tower-http", + "tower-http 0.3.5", "tower-layer", "tower-service", ] @@ -1646,6 +1646,12 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + [[package]] name = "float-cmp" version = "0.9.0" @@ -1707,35 +1713,36 @@ dependencies = [ [[package]] name = "fuel-asm" -version = "0.58.0" +version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79ca07227658105bdf873556dea09fa7fbfe792fbc084b4b9568f5ba3d64c411" +checksum = "5f325971bf9047ec70004f80a989e03456316bc19cbef3ff3a39a38b192ab56e" dependencies = [ "bitflags 2.5.0", - "fuel-types 0.58.0", + "fuel-types 0.58.2", "serde", "strum 0.24.1", ] [[package]] name = "fuel-compression" -version = "0.58.0" +version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3af97bfc2c2b4f0a7f471141663557f13462d7ac278922b01ebaf2127e7515f3" +checksum = "24e42841f56f76ed759b3f516e5188d5c42de47015bee951651660c13b6dfa6c" dependencies = [ - "fuel-derive 0.58.0", - "fuel-types 0.58.0", + "fuel-derive 0.58.2", + "fuel-types 0.58.2", "serde", ] [[package]] name = "fuel-core" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8bc5d6df88c21c821bf56dfa0bbd148c18b5153551c4119e5497ab7b90b3d22" +checksum = "9d5873aa1178f6fafdd967ddee2214a78be8be0c612a9c695889d31b5c1ede44" dependencies = [ "anyhow", "async-graphql", + "async-graphql-value", "async-trait", "axum", "clap", @@ -1755,7 +1762,7 @@ dependencies = [ "fuel-core-services", "fuel-core-storage", "fuel-core-txpool", - "fuel-core-types 0.37.0", + "fuel-core-types 0.40.0", "fuel-core-upgradable-executor", "futures", "hex", @@ -1773,22 +1780,23 @@ dependencies = [ "tokio-rayon", "tokio-stream", "tokio-util", - "tower-http", + "tower", + "tower-http 0.4.4", "tracing", "uuid 1.8.0", ] [[package]] name = "fuel-core-chain-config" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd1eca1d12daf8ad0f2479d7fff9405d94b6467496e5319e5f8b99cbdabdd58b" +checksum = "990db3029efd3766c4ae7c92a53c159ae66abf6f568ac6a3d58354f11400e6e2" dependencies = [ "anyhow", "bech32", "derivative", "fuel-core-storage", - "fuel-core-types 0.37.0", + "fuel-core-types 0.40.0", "itertools 0.12.1", "postcard", "rand", @@ -1800,16 +1808,16 @@ dependencies = [ [[package]] name = "fuel-core-client" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dbd88f285afdf061e409b712ecef49e2fe9ba235288cc76e8de8f05d50b6876" +checksum = "f09b3a35e82226d77b10653829beb508dc4bcf698fbdaa96610faf894e794444" dependencies = [ "anyhow", "base64 0.22.1", "cynic", "derive_more", "eventsource-client", - "fuel-core-types 0.37.0", + "fuel-core-types 0.40.0", "futures", "hex", "hyper-rustls", @@ -1825,12 +1833,12 @@ dependencies = [ [[package]] name = "fuel-core-compression" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25fdfc8202216391d0dfc87922eaf2576100c618ed67a8244212ca58dd1b2171" +checksum = "0b6ed44f8fcd0f1ff5983510e49835149b39afb8226257f6397db17a0ca0558d" dependencies = [ "anyhow", - "fuel-core-types 0.37.0", + "fuel-core-types 0.40.0", "paste", "rand", "serde", @@ -1840,38 +1848,38 @@ dependencies = [ [[package]] name = "fuel-core-consensus-module" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a95b4d2df8d8099839f3f3c00429c1af5271783d24007481711c37f579bfd4da" +checksum = "61161b1016ffb1a4f0d629534dd0b165bdaf146ce5037ccd5c8e8c9ec740d52f" dependencies = [ "anyhow", "fuel-core-chain-config", "fuel-core-poa", "fuel-core-storage", - "fuel-core-types 0.37.0", + "fuel-core-types 0.40.0", ] [[package]] name = "fuel-core-database" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b466baa45ea41ca9141b3e4ff2b5387f10d274f484561755f9b0d9c953892083" +checksum = "ceae011a49cbccb0e9b043c67f7e64dfd2f4d41233de34aff11d23646e98f5d8" dependencies = [ "anyhow", "derive_more", "fuel-core-storage", - "fuel-core-types 0.37.0", + "fuel-core-types 0.40.0", ] [[package]] name = "fuel-core-executor" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71858c962367af3c3e5c651c2ea62f1d268d7bc77e6326cd4a206d74a58d0dec" +checksum = "db57f06af045fafa81b76ca11318d47579e41babb0839fb0955ae7cf32e58a1f" dependencies = [ "anyhow", "fuel-core-storage", - "fuel-core-types 0.37.0", + "fuel-core-types 0.40.0", "hex", "parking_lot", "serde", @@ -1880,19 +1888,20 @@ dependencies = [ [[package]] name = "fuel-core-gas-price-service" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33755cb67a3892c5dd058b0f2c022d0f16adebf6bb29a94814794044fbb6a67" +checksum = "eea974f842be1ca7783df7eec770b5865c3babd50a10a5d8f107bdac65419c45" dependencies = [ "anyhow", "async-trait", "enum-iterator", "fuel-core-services", "fuel-core-storage", - "fuel-core-types 0.37.0", + "fuel-core-types 0.40.0", "fuel-gas-price-algorithm", "futures", "num_enum", + "parking_lot", "reqwest", "serde", "strum 0.25.0", @@ -1905,15 +1914,15 @@ dependencies = [ [[package]] name = "fuel-core-importer" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fc8cea1fabe1a51bdabce436d7040d29b3a4d14c0429289060d0a754a1b1a46" +checksum = "2a6a75d87da09380dc6f706ec0eb4171cb1309fef6a4c8b709025769a1903235" dependencies = [ "anyhow", "derive_more", "fuel-core-metrics", "fuel-core-storage", - "fuel-core-types 0.37.0", + "fuel-core-types 0.40.0", "parking_lot", "rayon", "tokio", @@ -1922,22 +1931,25 @@ dependencies = [ [[package]] name = "fuel-core-metrics" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc199e165e600f241cab86129766b26bab78572a701a39bc40a5fdb669961a8" +checksum = "94a1c3eb92040d95d27f7c658801bb5c04ad4aaf67de380cececbeed5aab6e61" dependencies = [ + "once_cell", "parking_lot", "pin-project-lite", "prometheus-client", "regex", + "strum 0.25.0", + "strum_macros 0.25.3", "tracing", ] [[package]] name = "fuel-core-p2p" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ae4fa0826f148c13248db4fe634d2ba7a297bbd424e7288c6e1d881a50f662" +checksum = "db5c996b4d392a5f1991b4d2fcc2fe570dc846f8a763a30105cd7b3c8d08e747" dependencies = [ "anyhow", "async-trait", @@ -1945,7 +1957,7 @@ dependencies = [ "fuel-core-metrics", "fuel-core-services", "fuel-core-storage", - "fuel-core-types 0.37.0", + "fuel-core-types 0.40.0", "futures", "hex", "hickory-resolver", @@ -1969,16 +1981,16 @@ dependencies = [ [[package]] name = "fuel-core-poa" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49c4f3e5fa1e916793609bdb9a52142077a84a793272379a04cf24375aa94e6f" +checksum = "2f6f78fa31dc56b9458e3ca9a7058b4bea381e16e49fcab0db49923be8a30f9c" dependencies = [ "anyhow", "async-trait", "fuel-core-chain-config", "fuel-core-services", "fuel-core-storage", - "fuel-core-types 0.37.0", + "fuel-core-types 0.40.0", "serde", "serde_json", "tokio", @@ -1988,15 +2000,15 @@ dependencies = [ [[package]] name = "fuel-core-producer" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642d4a10f1df444a09944ae547f1782ca865ac4705ea9cefe0821c5a8e4b3081" +checksum = "7739b2019df5b9d5042ba2d9f7036c6feee105a0e441d8bcfd933221da5be635" dependencies = [ "anyhow", "async-trait", "derive_more", "fuel-core-storage", - "fuel-core-types 0.37.0", + "fuel-core-types 0.40.0", "tokio", "tokio-rayon", "tracing", @@ -2004,30 +2016,32 @@ dependencies = [ [[package]] name = "fuel-core-services" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "739dca83db1eb86651db3833f088f52afcd3f181cfca40e5725074aceb3ea49d" +checksum = "8312b598da4b9a6503c9263c1c2a7ea58d34ab1f86e7f345490e12d309fb29bb" dependencies = [ "anyhow", "async-trait", "fuel-core-metrics", "futures", "parking_lot", + "pin-project-lite", + "rayon", "tokio", "tracing", ] [[package]] name = "fuel-core-storage" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6255d852b6866199d103233e1eef2e7ded141019bc782b5b211fcf001727c34b" +checksum = "bda9242ebc9e8ef3251b9eae85f4ce5cdb376348baa30925606f3ce602db7ec5" dependencies = [ "anyhow", "derive_more", "enum-iterator", - "fuel-core-types 0.37.0", - "fuel-vm 0.58.0", + "fuel-core-types 0.40.0", + "fuel-vm 0.58.2", "impl-tools", "itertools 0.12.1", "mockall", @@ -2043,24 +2057,21 @@ dependencies = [ [[package]] name = "fuel-core-txpool" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7b4667213fa8aca461f49c9b305f1f2abda2848a2da5323999d82e3dc76a723" +checksum = "34cde90da8d814046018c5341129bffdbc51e6721e69ada9a393b3d4c16be14b" dependencies = [ "anyhow", "async-trait", "derive_more", - "fuel-core-metrics", "fuel-core-services", "fuel-core-storage", - "fuel-core-types 0.37.0", + "fuel-core-types 0.40.0", "futures", - "mockall", "num-rational", "parking_lot", - "rayon", + "petgraph", "tokio", - "tokio-rayon", "tokio-stream", "tracing", ] @@ -2083,15 +2094,15 @@ dependencies = [ [[package]] name = "fuel-core-types" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33a4e9b2de06381e1ad598cd1030344993fee7401331ca9955d0a1860cc0484c" +checksum = "6ee3a95b189bf729d21354a761862bb481298cbd883550adc3fef1bc7beb0b67" dependencies = [ "anyhow", "bs58", "derivative", "derive_more", - "fuel-vm 0.58.0", + "fuel-vm 0.58.2", "rand", "secrecy", "serde", @@ -2101,15 +2112,15 @@ dependencies = [ [[package]] name = "fuel-core-upgradable-executor" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "768bf8bbb7d27d13b5055ad7b755609e027b5a322b3b21790fac7a478685ba14" +checksum = "620b671cd011ee14c846628ca0d913b770923b36fd87d44dd7ba70f1a8db0eec" dependencies = [ "anyhow", "derive_more", "fuel-core-executor", "fuel-core-storage", - "fuel-core-types 0.37.0", + "fuel-core-types 0.40.0", "fuel-core-wasm-executor", "parking_lot", "postcard", @@ -2119,15 +2130,15 @@ dependencies = [ [[package]] name = "fuel-core-wasm-executor" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "385ce8e704a7370ec5230ba3bd7d986cbe66174f400160b54cf76799a578609e" +checksum = "b44366541d35be9ea11ed88ed54629c64e91c309ca5fbf861fd909d443ca7575" dependencies = [ "anyhow", "fuel-core-executor", "fuel-core-storage", "fuel-core-types 0.35.0", - "fuel-core-types 0.37.0", + "fuel-core-types 0.40.0", "postcard", "serde", "serde_json", @@ -2151,15 +2162,15 @@ dependencies = [ [[package]] name = "fuel-crypto" -version = "0.58.0" +version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f53b06525aa7754bf7c3ef23daf15fd798ae990a82f8b7b813d25cedfeacfe5c" +checksum = "65e318850ca64890ff123a99b6b866954ef49da94ab9bc6827cf6ee045568585" dependencies = [ "coins-bip32", "coins-bip39", "ecdsa", "ed25519-dalek", - "fuel-types 0.58.0", + "fuel-types 0.58.2", "k256", "lazy_static", "p256", @@ -2184,9 +2195,9 @@ dependencies = [ [[package]] name = "fuel-derive" -version = "0.58.0" +version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e34d6eec30d04506607cc0bc85fc97c57c964580cd233fd557e346c5273535" +checksum = "ab0bc46a3552964bae5169e79b383761a54bd115ea66951a1a7a229edcefa55a" dependencies = [ "proc-macro2", "quote", @@ -2196,9 +2207,9 @@ dependencies = [ [[package]] name = "fuel-gas-price-algorithm" -version = "0.37.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15d4a5847c09db9159ea66bc75bdfe59c4d6139d8b24c1a8026f253f011409bc" +checksum = "7b51715a07bb4a099ca4c658796c7a732f3edb3dfb2cec3407769081c949dc0b" dependencies = [ "serde", "thiserror", @@ -2221,13 +2232,13 @@ dependencies = [ [[package]] name = "fuel-merkle" -version = "0.58.0" +version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a9fa3708405eba32fd2b947b827dc52484377ba6a238260b03a07b642395e6c" +checksum = "c79eca6a452311c70978a5df796c0f99f27e474b69719e0db4c1d82e68800d07" dependencies = [ "derive_more", "digest 0.10.7", - "fuel-storage 0.58.0", + "fuel-storage 0.58.2", "hashbrown 0.13.2", "hex", "serde", @@ -2242,9 +2253,9 @@ checksum = "4c1b711f28553ddc5f3546711bd220e144ce4c1af7d9e9a1f70b2f20d9f5b791" [[package]] name = "fuel-storage" -version = "0.58.0" +version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f678f1c900d0632d77e15d4a4946048d4d517fefeba72607390c03288ca127" +checksum = "2d0c46b5d76b3e11197bd31e036cd8b1cb46c4d822cacc48836638080c6d2b76" [[package]] name = "fuel-tx" @@ -2270,18 +2281,18 @@ dependencies = [ [[package]] name = "fuel-tx" -version = "0.58.0" +version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e3065c12eecc9121514694f4b01009c9a83d8842af11c43ec9e2bbc0a7f36cb" +checksum = "6723bb8710ba2b70516ac94d34459593225870c937670fb3afaf82e0354667ac" dependencies = [ "bitflags 2.5.0", "derivative", "derive_more", - "fuel-asm 0.58.0", + "fuel-asm 0.58.2", "fuel-compression", - "fuel-crypto 0.58.0", - "fuel-merkle 0.58.0", - "fuel-types 0.58.0", + "fuel-crypto 0.58.2", + "fuel-merkle 0.58.2", + "fuel-types 0.58.2", "hashbrown 0.14.5", "itertools 0.10.5", "postcard", @@ -2304,11 +2315,11 @@ dependencies = [ [[package]] name = "fuel-types" -version = "0.58.0" +version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a93d5f3fd028d874d8927be439fcdea01cb04499049bc68a874c73dd0c7e32b7" +checksum = "982265415a99b5bd6277bc24194a233bb2e18764df11c937b3dbb11a02c9e545" dependencies = [ - "fuel-derive 0.58.0", + "fuel-derive 0.58.2", "hex", "rand", "serde", @@ -2347,9 +2358,9 @@ dependencies = [ [[package]] name = "fuel-vm" -version = "0.58.0" +version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0562398978e501e8ee2caeb747a2852cc4a8c5fff250eb58e38f1c03217311" +checksum = "54b5362d7d072c72eec20581f67fc5400090c356a7f3ae77c79880b3b177b667" dependencies = [ "anyhow", "async-trait", @@ -2358,13 +2369,13 @@ dependencies = [ "derivative", "derive_more", "ethnum", - "fuel-asm 0.58.0", + "fuel-asm 0.58.2", "fuel-compression", - "fuel-crypto 0.58.0", - "fuel-merkle 0.58.0", - "fuel-storage 0.58.0", - "fuel-tx 0.58.0", - "fuel-types 0.58.0", + "fuel-crypto 0.58.2", + "fuel-merkle 0.58.2", + "fuel-storage 0.58.2", + "fuel-tx 0.58.2", + "fuel-types 0.58.2", "hashbrown 0.14.5", "itertools 0.10.5", "libm", @@ -2382,13 +2393,13 @@ dependencies = [ [[package]] name = "fuels" -version = "0.66.6" +version = "0.66.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "921a8ea521744e600e0a34236adff7524ecf34bd940c2a018315d0212c140d7b" +checksum = "6ed08053e72bdb285d5a167c27a7a0d10f1dc4e27d1e6e5296dd2a67813bd13f" dependencies = [ "fuel-core-client", - "fuel-crypto 0.58.0", - "fuel-tx 0.58.0", + "fuel-crypto 0.58.2", + "fuel-tx 0.58.2", "fuels-accounts", "fuels-core", "fuels-macros", @@ -2398,19 +2409,20 @@ dependencies = [ [[package]] name = "fuels-accounts" -version = "0.66.6" +version = "0.66.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da8bad87e947fc448c44c22e4c90a4af49d61de08722b1d1774d977b2071047" +checksum = "49fee90e8f3a4fc9392a6cde3010c561fa50da0f805d66fdb659eaa4d5d8a504" dependencies = [ "async-trait", "chrono", + "cynic", "elliptic-curve", "eth-keystore", "fuel-core-client", - "fuel-core-types 0.37.0", - "fuel-crypto 0.58.0", - "fuel-tx 0.58.0", - "fuel-types 0.58.0", + "fuel-core-types 0.40.0", + "fuel-crypto 0.58.2", + "fuel-tx 0.58.2", + "fuel-types 0.58.2", "fuels-core", "itertools 0.12.1", "rand", @@ -2423,9 +2435,9 @@ dependencies = [ [[package]] name = "fuels-code-gen" -version = "0.66.6" +version = "0.66.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fdc5f9dcdf330f5ef5f367dbc2334e72151e9ae46a4ee9f21d43a5e859be11b" +checksum = "f857b7ff658400506ca6be57bb84fedda44b566e78f5f0a8d0782242f41615c0" dependencies = [ "Inflector", "fuel-abi-types", @@ -2439,37 +2451,38 @@ dependencies = [ [[package]] name = "fuels-core" -version = "0.66.6" +version = "0.66.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "629212e8278d57aa1a6f846ca0ca1e3428fb6da2d43e368931ff1494a0a6b5ce" +checksum = "baccbdd81e624f57950dcb136b32b853c520dd954badf26b9f58de33f3d71c7e" dependencies = [ "async-trait", "bech32", "chrono", "fuel-abi-types", - "fuel-asm 0.58.0", + "fuel-asm 0.58.2", "fuel-core-chain-config", "fuel-core-client", - "fuel-core-types 0.37.0", - "fuel-crypto 0.58.0", - "fuel-tx 0.58.0", - "fuel-types 0.58.0", - "fuel-vm 0.58.0", + "fuel-core-types 0.40.0", + "fuel-crypto 0.58.2", + "fuel-tx 0.58.2", + "fuel-types 0.58.2", + "fuel-vm 0.58.2", "fuels-macros", "hex", "itertools 0.12.1", "postcard", "serde", "serde_json", + "sha2 0.10.8", "thiserror", "uint", ] [[package]] name = "fuels-macros" -version = "0.66.6" +version = "0.66.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562bf012adedfb492431f4bfd5be4ccbf2171ab7d5247c5953a6be3ea8036072" +checksum = "5da75294c5e9da312bdc49239736699ee84ea9c5bfbc19a61a8ee588a1247aa1" dependencies = [ "fuels-code-gen", "itertools 0.12.1", @@ -2480,15 +2493,15 @@ dependencies = [ [[package]] name = "fuels-programs" -version = "0.66.6" +version = "0.66.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a366e6a78e1c104fe1cb14439199833987fe76ecd46ee2b46fe05868a3366d" +checksum = "32675ed1c08edd28ddb648dfae0c60a1946d4368a69ddfa6434f2316e33f0520" dependencies = [ "async-trait", "fuel-abi-types", - "fuel-asm 0.58.0", - "fuel-tx 0.58.0", - "fuel-types 0.58.0", + "fuel-asm 0.58.2", + "fuel-tx 0.58.2", + "fuel-types 0.58.2", "fuels-accounts", "fuels-core", "itertools 0.12.1", @@ -2499,19 +2512,19 @@ dependencies = [ [[package]] name = "fuels-test-helpers" -version = "0.66.6" +version = "0.66.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7705708c0fe28a874c44635b77c3e120a3422c8a24fdc45f07dc8c21ee9ca6fb" +checksum = "02176c0fb1bf8cf58b8a9e5372efb650324740abcd4847b45bd0b041a0f133a2" dependencies = [ "fuel-core", "fuel-core-chain-config", "fuel-core-client", "fuel-core-poa", "fuel-core-services", - "fuel-core-types 0.37.0", - "fuel-crypto 0.58.0", - "fuel-tx 0.58.0", - "fuel-types 0.58.0", + "fuel-core-types 0.40.0", + "fuel-crypto 0.58.2", + "fuel-tx 0.58.2", + "fuel-types 0.58.2", "fuels-accounts", "fuels-core", "futures", @@ -4398,6 +4411,16 @@ dependencies = [ "ucd-trie", ] +[[package]] +name = "petgraph" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" +dependencies = [ + "fixedbitset", + "indexmap 2.2.6", +] + [[package]] name = "pin-project" version = "1.1.5" @@ -5735,7 +5758,7 @@ dependencies = [ "assert_matches", "fuel-core", "fuel-core-client", - "fuel-vm 0.58.0", + "fuel-vm 0.58.2", "fuels", "hex", "paste", @@ -5954,6 +5977,7 @@ dependencies = [ "pin-project", "pin-project-lite", "tokio", + "tokio-util", "tower-layer", "tower-service", "tracing", @@ -5973,10 +5997,28 @@ dependencies = [ "http-body", "http-range-header", "pin-project-lite", - "tokio", "tower", "tower-layer", "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" +dependencies = [ + "bitflags 2.5.0", + "bytes", + "futures-core", + "futures-util", + "http 0.2.12", + "http-body", + "http-range-header", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", "tracing", ] diff --git a/test/src/sdk-harness/Cargo.toml b/test/src/sdk-harness/Cargo.toml index 778acf33105..3d28c7b1506 100644 --- a/test/src/sdk-harness/Cargo.toml +++ b/test/src/sdk-harness/Cargo.toml @@ -10,15 +10,15 @@ publish = false assert_matches = "1.5" # Dependencies from the `fuel-core` repository: -fuel-core = { version = "0.37", default-features = false } +fuel-core = { version = "0.40", default-features = false } # Using full semver as the workspace Cargo.toml (see the comment there) -fuel-core-client = { version = "0.37.0", default-features = false } +fuel-core-client = { version = "0.40.0", default-features = false } # Dependencies from the `fuel-vm` repository: fuel-vm = { version = "0.58", features = ["random"] } # Dependencies from the `fuels-rs` repository: -fuels = { version = "0.66.6", features = ["fuel-core-lib"] } +fuels = { version = "0.66.9", features = ["fuel-core-lib"] } hex = "0.4" paste = "1.0" From b7e59f42aebed08c2e015cbd5d0776c8953fc57f Mon Sep 17 00:00:00 2001 From: Joshua Batty Date: Tue, 15 Oct 2024 20:56:01 +1100 Subject: [PATCH 057/115] chore: bump to v0.66.0 (#6637) ## Description supports `fuel-core 0.40.0` and `fuels-rs 0.66.9` removes support for the beta channels from `forc` and adds mainnet target. #6621 ~~waiting on #6630~~ --- Cargo.lock | 68 +++++++++++++++++++++++++++--------------------------- Cargo.toml | 48 +++++++++++++++++++------------------- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d084c00dcf0..e8505d84b45 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2678,7 +2678,7 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "forc" -version = "0.65.2" +version = "0.66.0" dependencies = [ "annotate-snippets", "ansi_term", @@ -2689,7 +2689,7 @@ dependencies = [ "completest-pty", "forc-pkg", "forc-test", - "forc-tracing 0.65.2", + "forc-tracing 0.66.0", "forc-util", "fs_extra", "fuel-asm", @@ -2715,7 +2715,7 @@ dependencies = [ [[package]] name = "forc-client" -version = "0.65.2" +version = "0.66.0" dependencies = [ "anyhow", "async-trait", @@ -2727,7 +2727,7 @@ dependencies = [ "dialoguer", "forc", "forc-pkg", - "forc-tracing 0.65.2", + "forc-tracing 0.66.0", "forc-tx", "forc-util", "forc-wallet", @@ -2762,13 +2762,13 @@ dependencies = [ [[package]] name = "forc-crypto" -version = "0.65.2" +version = "0.66.0" dependencies = [ "anyhow", "async-trait", "atty", "clap 4.5.16", - "forc-tracing 0.65.2", + "forc-tracing 0.66.0", "forc-util", "fuel-core-types", "fuel-crypto", @@ -2788,7 +2788,7 @@ dependencies = [ [[package]] name = "forc-debug" -version = "0.65.2" +version = "0.66.0" dependencies = [ "anyhow", "clap 4.5.16", @@ -2796,7 +2796,7 @@ dependencies = [ "escargot", "forc-pkg", "forc-test", - "forc-tracing 0.65.2", + "forc-tracing 0.66.0", "fuel-core-client", "fuel-types", "fuel-vm", @@ -2814,7 +2814,7 @@ dependencies = [ [[package]] name = "forc-doc" -version = "0.65.2" +version = "0.66.0" dependencies = [ "anyhow", "clap 4.5.16", @@ -2822,7 +2822,7 @@ dependencies = [ "dir_indexer", "expect-test", "forc-pkg", - "forc-tracing 0.65.2", + "forc-tracing 0.66.0", "forc-util", "horrorshow", "include_dir", @@ -2839,12 +2839,12 @@ dependencies = [ [[package]] name = "forc-fmt" -version = "0.65.2" +version = "0.66.0" dependencies = [ "anyhow", "clap 4.5.16", "forc-pkg", - "forc-tracing 0.65.2", + "forc-tracing 0.66.0", "forc-util", "prettydiff 0.7.0", "sway-core", @@ -2856,7 +2856,7 @@ dependencies = [ [[package]] name = "forc-lsp" -version = "0.65.2" +version = "0.66.0" dependencies = [ "anyhow", "clap 4.5.16", @@ -2867,13 +2867,13 @@ dependencies = [ [[package]] name = "forc-pkg" -version = "0.65.2" +version = "0.66.0" dependencies = [ "ansi_term", "anyhow", "byte-unit", "cid", - "forc-tracing 0.65.2", + "forc-tracing 0.66.0", "forc-util", "fuel-abi-types", "futures", @@ -2904,7 +2904,7 @@ dependencies = [ [[package]] name = "forc-test" -version = "0.65.2" +version = "0.66.0" dependencies = [ "anyhow", "forc-pkg", @@ -2931,7 +2931,7 @@ dependencies = [ [[package]] name = "forc-tracing" -version = "0.65.2" +version = "0.66.0" dependencies = [ "ansi_term", "tracing", @@ -2941,7 +2941,7 @@ dependencies = [ [[package]] name = "forc-tx" -version = "0.65.2" +version = "0.66.0" dependencies = [ "anyhow", "clap 4.5.16", @@ -2956,7 +2956,7 @@ dependencies = [ [[package]] name = "forc-util" -version = "0.65.2" +version = "0.66.0" dependencies = [ "annotate-snippets", "ansi_term", @@ -2964,7 +2964,7 @@ dependencies = [ "clap 4.5.16", "dirs 5.0.1", "fd-lock", - "forc-tracing 0.65.2", + "forc-tracing 0.66.0", "fuel-tx", "hex", "paste", @@ -7649,7 +7649,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sway-ast" -version = "0.65.2" +version = "0.66.0" dependencies = [ "extension-trait", "num-bigint", @@ -7661,7 +7661,7 @@ dependencies = [ [[package]] name = "sway-core" -version = "0.65.2" +version = "0.66.0" dependencies = [ "clap 4.5.16", "derivative", @@ -7706,7 +7706,7 @@ dependencies = [ [[package]] name = "sway-error" -version = "0.65.2" +version = "0.66.0" dependencies = [ "either", "in_definite", @@ -7720,7 +7720,7 @@ dependencies = [ [[package]] name = "sway-ir" -version = "0.65.2" +version = "0.66.0" dependencies = [ "anyhow", "downcast-rs", @@ -7739,7 +7739,7 @@ dependencies = [ [[package]] name = "sway-ir-macros" -version = "0.65.2" +version = "0.66.0" dependencies = [ "itertools 0.13.0", "proc-macro2", @@ -7749,7 +7749,7 @@ dependencies = [ [[package]] name = "sway-lsp" -version = "0.65.2" +version = "0.66.0" dependencies = [ "anyhow", "assert-json-diff", @@ -7760,7 +7760,7 @@ dependencies = [ "dirs 4.0.0", "fd-lock", "forc-pkg", - "forc-tracing 0.65.2", + "forc-tracing 0.66.0", "forc-util", "futures", "indexmap 2.5.0", @@ -7799,7 +7799,7 @@ dependencies = [ [[package]] name = "sway-lsp-test-utils" -version = "0.65.2" +version = "0.66.0" dependencies = [ "assert-json-diff", "futures", @@ -7814,7 +7814,7 @@ dependencies = [ [[package]] name = "sway-parse" -version = "0.65.2" +version = "0.66.0" dependencies = [ "assert_matches", "extension-trait", @@ -7832,7 +7832,7 @@ dependencies = [ [[package]] name = "sway-types" -version = "0.65.2" +version = "0.66.0" dependencies = [ "bytecount", "fuel-asm", @@ -7851,7 +7851,7 @@ dependencies = [ [[package]] name = "sway-utils" -version = "0.65.2" +version = "0.66.0" dependencies = [ "serde", "walkdir", @@ -7859,11 +7859,11 @@ dependencies = [ [[package]] name = "swayfmt" -version = "0.65.2" +version = "0.66.0" dependencies = [ "anyhow", "difference", - "forc-tracing 0.65.2", + "forc-tracing 0.66.0", "indoc", "paste", "prettydiff 0.6.4", @@ -8147,7 +8147,7 @@ dependencies = [ "forc-client", "forc-pkg", "forc-test", - "forc-tracing 0.65.2", + "forc-tracing 0.66.0", "fuel-vm", "futures", "gag", diff --git a/Cargo.toml b/Cargo.toml index 2f335a5031b..42bfc9e254c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ exclude = [ [workspace.package] edition = "2021" -version = "0.65.2" +version = "0.66.0" authors = ["Fuel Labs "] homepage = "https://fuel.network/" license = "Apache-2.0" @@ -45,34 +45,34 @@ repository = "https://github.com/FuelLabs/sway" # Internal dependencies in order to propagate `workspace.version` # -forc = { path = "forc/", version = "0.65.2" } -forc-pkg = { path = "forc-pkg/", version = "0.65.2" } -forc-test = { path = "forc-test/", version = "0.65.2" } -forc-tracing = { path = "forc-tracing/", version = "0.65.2" } -forc-util = { path = "forc-util/", version = "0.65.2" } +forc = { path = "forc/", version = "0.66.0" } +forc-pkg = { path = "forc-pkg/", version = "0.66.0" } +forc-test = { path = "forc-test/", version = "0.66.0" } +forc-tracing = { path = "forc-tracing/", version = "0.66.0" } +forc-util = { path = "forc-util/", version = "0.66.0" } # Forc plugins -forc-plugins = { path = "forc-plugins/", version = "0.65.2" } -forc-client = { path = "forc-plugins/forc-client/", version = "0.65.2" } -forc-crypto = { path = "forc-plugins/forc-crypto/", version = "0.65.2" } -forc-debug = { path = "forc-plugins/forc-debug/", version = "0.65.2" } -forc-doc = { path = "forc-plugins/forc-doc/", version = "0.65.2" } -forc-fmt = { path = "forc-plugins/forc-fmt/", version = "0.65.2" } -forc-lsp = { path = "forc-plugins/forc-lsp/", version = "0.65.2" } -forc-tx = { path = "forc-plugins/forc-tx/", version = "0.65.2" } +forc-plugins = { path = "forc-plugins/", version = "0.66.0" } +forc-client = { path = "forc-plugins/forc-client/", version = "0.66.0" } +forc-crypto = { path = "forc-plugins/forc-crypto/", version = "0.66.0" } +forc-debug = { path = "forc-plugins/forc-debug/", version = "0.66.0" } +forc-doc = { path = "forc-plugins/forc-doc/", version = "0.66.0" } +forc-fmt = { path = "forc-plugins/forc-fmt/", version = "0.66.0" } +forc-lsp = { path = "forc-plugins/forc-lsp/", version = "0.66.0" } +forc-tx = { path = "forc-plugins/forc-tx/", version = "0.66.0" } -sway-ast = { path = "sway-ast/", version = "0.65.2" } -sway-core = { path = "sway-core/", version = "0.65.2" } -sway-error = { path = "sway-error/", version = "0.65.2" } -sway-lsp = { path = "sway-lsp/", version = "0.65.2" } -sway-parse = { path = "sway-parse/", version = "0.65.2" } -sway-types = { path = "sway-types/", version = "0.65.2" } -sway-utils = { path = "sway-utils/", version = "0.65.2" } -swayfmt = { path = "swayfmt/", version = "0.65.2" } +sway-ast = { path = "sway-ast/", version = "0.66.0" } +sway-core = { path = "sway-core/", version = "0.66.0" } +sway-error = { path = "sway-error/", version = "0.66.0" } +sway-lsp = { path = "sway-lsp/", version = "0.66.0" } +sway-parse = { path = "sway-parse/", version = "0.66.0" } +sway-types = { path = "sway-types/", version = "0.66.0" } +sway-utils = { path = "sway-utils/", version = "0.66.0" } +swayfmt = { path = "swayfmt/", version = "0.66.0" } # Sway IR -sway-ir = { path = "sway-ir/", version = "0.65.2" } -sway-ir-macros = { path = "sway-ir/sway-ir-macros", version = "0.65.2" } +sway-ir = { path = "sway-ir/", version = "0.66.0" } +sway-ir-macros = { path = "sway-ir/sway-ir-macros", version = "0.66.0" } # # External Fuel dependencies From 9ecfb690b129032ead19e0d7374f72de94507223 Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite Date: Tue, 15 Oct 2024 12:26:31 +0100 Subject: [PATCH 058/115] Minimal changes to remove miden deps (#6638) ## Description "miden" crate was yanked, so this is the minimal changeset to remove it as a dependency. We may still keep some `miden` stuff around. ## Checklist - [ ] 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. - [ ] 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). - [ ] I have requested a review from the relevant team or maintainers. --- .github/workflows/ci.yml | 12 - Cargo.lock | 217 +----- Cargo.toml | 8 +- forc-pkg/src/pkg.rs | 2 - sway-core/Cargo.toml | 1 - sway-core/src/asm_generation/finalized_asm.rs | 6 - sway-core/src/asm_generation/from_ir.rs | 8 - .../src/asm_generation/instruction_set.rs | 17 +- .../miden_vm/miden_vm_asm_builder.rs | 705 ------------------ .../miden_vm/miden_vm_asm_builder/miden_op.rs | 394 ---------- sway-core/src/asm_generation/miden_vm/mod.rs | 2 - sway-core/src/asm_generation/mod.rs | 2 - sway-core/src/build_config.rs | 4 - test/Cargo.toml | 1 - test/src/e2e_vm_tests/harness.rs | 20 - test/src/e2e_vm_tests/mod.rs | 7 - .../midenvm/midenvm_trivial/Forc.lock | 3 - .../midenvm/midenvm_trivial/Forc.toml | 8 - .../midenvm/midenvm_trivial/src/main.sw | 3 - .../midenvm/midenvm_trivial/test.toml | 4 - 20 files changed, 5 insertions(+), 1419 deletions(-) delete mode 100644 sway-core/src/asm_generation/miden_vm/miden_vm_asm_builder.rs delete mode 100644 sway-core/src/asm_generation/miden_vm/miden_vm_asm_builder/miden_op.rs delete mode 100644 sway-core/src/asm_generation/miden_vm/mod.rs delete mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/midenvm/midenvm_trivial/Forc.lock delete mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/midenvm/midenvm_trivial/Forc.toml delete mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/midenvm/midenvm_trivial/src/main.sw delete mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/midenvm/midenvm_trivial/test.toml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f5630d1fdd..c0a6c041059 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -384,18 +384,6 @@ jobs: - name: Cargo Run E2E Tests (EVM) run: cargo run --locked --release --bin test -- --target evm --locked --no-encoding-v1 - cargo-run-e2e-test-midenvm: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Install toolchain - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ env.RUST_VERSION }} - - uses: Swatinem/rust-cache@v2 - - name: Cargo Run E2E Tests (EVM) - run: cargo run --locked --release --bin test -- --target midenvm --locked --no-encoding-v1 - # TODO: Remove this upon merging std tests with the rest of the E2E tests. cargo-test-lib-std: runs-on: buildjet-8vcpu-ubuntu-2204 diff --git a/Cargo.lock b/Cargo.lock index e8505d84b45..9b34e4fbc7c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -943,19 +943,6 @@ dependencies = [ "wyz", ] -[[package]] -name = "blake3" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9ec96fe9a81b5e365f9db71fe00edc4fe4ca2cc7dcb7861f0603012a7caa210" -dependencies = [ - "arrayref", - "arrayvec", - "cc", - "cfg-if 1.0.0", - "constant_time_eq", -] - [[package]] name = "block-buffer" version = "0.9.0" @@ -1513,12 +1500,6 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" -[[package]] -name = "constant_time_eq" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" - [[package]] name = "convert_case" version = "0.4.0" @@ -3184,7 +3165,7 @@ dependencies = [ "fuel-vm", "impl-tools", "itertools 0.12.1", - "num_enum 0.7.3", + "num_enum", "paste", "postcard", "primitive-types", @@ -4942,100 +4923,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "miden" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8d8a25e092075f58af207e2a42bad5fbbf40c5200f13d2432a806db751a52b5" -dependencies = [ - "log", - "miden-air", - "miden-assembly", - "miden-core", - "miden-processor", - "miden-prover", - "miden-stdlib", - "miden-verifier", -] - -[[package]] -name = "miden-air" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5046ab97d8c2b7136601e9430fd0a14e7d6c6cdd648c90c1e6b39186a38b9a8b" -dependencies = [ - "miden-core", - "winter-air", -] - -[[package]] -name = "miden-assembly" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a04eec160cbd5cf3051ad16a244c3d83e648eddbd3349120dc069f6e309259dc" -dependencies = [ - "miden-core", - "num_enum 0.5.11", - "winter-crypto", -] - -[[package]] -name = "miden-core" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e75a2446684f44e61afb27bbdbf2458e8ec58c5c55d9bd202981d7cd265f7cf4" -dependencies = [ - "winter-crypto", - "winter-math", - "winter-utils", -] - -[[package]] -name = "miden-processor" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb7a467447a7d6236f3971f91f8c47c8880a01a43c29b0b08285ec50454f02ed" -dependencies = [ - "log", - "miden-core", - "winter-prover", -] - -[[package]] -name = "miden-prover" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2343eaf338770b78fe421f36a3445bb491123e0787006dfa2b98788cd6440ec6" -dependencies = [ - "log", - "miden-air", - "miden-core", - "miden-processor", - "winter-prover", -] - -[[package]] -name = "miden-stdlib" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b2a52fd1a44b136dbce7a513ebe5a407dfebc17160af8a2707383df731fc098" -dependencies = [ - "miden-assembly", - "miden-core", -] - -[[package]] -name = "miden-verifier" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d942d5b0bdcad47359d52534ef6fbccebffc0c713d2c7ca65ab603c7965c0a8b" -dependencies = [ - "miden-air", - "miden-assembly", - "miden-core", - "winter-verifier", -] - [[package]] name = "mime" version = "0.3.17" @@ -5382,34 +5269,13 @@ dependencies = [ "libc", ] -[[package]] -name = "num_enum" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" -dependencies = [ - "num_enum_derive 0.5.11", -] - [[package]] name = "num_enum" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" dependencies = [ - "num_enum_derive 0.7.3", -] - -[[package]] -name = "num_enum_derive" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" -dependencies = [ - "proc-macro-crate 1.1.3", - "proc-macro2", - "quote", - "syn 1.0.109", + "num_enum_derive", ] [[package]] @@ -7680,7 +7546,6 @@ dependencies = [ "indexmap 2.5.0", "itertools 0.13.0", "lazy_static", - "miden-core", "object", "parking_lot 0.12.3", "pest", @@ -8155,7 +8020,6 @@ dependencies = [ "hex", "insta", "libtest-mimic", - "miden", "prettydiff 0.7.0", "rand", "regex", @@ -9352,83 +9216,6 @@ version = "0.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" -[[package]] -name = "winter-air" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef91b335c5fefa4e6d3c6274de75a7744b4eecae2d7ee3778c23570f35f83396" -dependencies = [ - "winter-crypto", - "winter-fri", - "winter-math", - "winter-utils", -] - -[[package]] -name = "winter-crypto" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bd17ea728ff42185c54dfbabaafd0b442207df6b2cc60f74c607d8c01e9c4db" -dependencies = [ - "blake3", - "sha3", - "winter-math", - "winter-utils", -] - -[[package]] -name = "winter-fri" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2473f8b2c5c553e9f9d4d94b3b7a1e75806b4cdc964004f9bde4b5fc07c10c87" -dependencies = [ - "winter-crypto", - "winter-math", - "winter-utils", -] - -[[package]] -name = "winter-math" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824b459961e5d679a1eb62ec1a71c85ac25c5d3bfd126874fcd32b591202d896" -dependencies = [ - "winter-utils", -] - -[[package]] -name = "winter-prover" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831583fd662f49f23ea39427aba20a9b5ab6326230f7994e843d2bd34524411" -dependencies = [ - "log", - "winter-air", - "winter-crypto", - "winter-fri", - "winter-math", - "winter-utils", -] - -[[package]] -name = "winter-utils" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f0dbf7ca6aa5893b59928718bf1e7dbe7279bb277b5aa4c4898ddf5004f9417" - -[[package]] -name = "winter-verifier" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "922be4651b76aa80e132386a97d23788e2bc542d37b3c187a39998876a8094b6" -dependencies = [ - "winter-air", - "winter-crypto", - "winter-fri", - "winter-math", - "winter-utils", -] - [[package]] name = "wyz" version = "0.5.1" diff --git a/Cargo.toml b/Cargo.toml index 42bfc9e254c..fec9150942d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,11 +26,7 @@ members = [ "swayfmt", "test", ] -exclude = [ - "examples/*", - "swayfmt/test_macros", - "forc-test/test_data" -] +exclude = ["examples/*", "swayfmt/test_macros", "forc-test/test_data"] [workspace.package] edition = "2021" @@ -167,8 +163,6 @@ libp2p-identity = "0.2" libtest-mimic = "0.7" lsp-types = "0.94" mdbook = { version = "0.4", default-features = false } -miden = "0.3" -miden-core = "0.3" minifier = "0.3" notify = "6.1" notify-debouncer-mini = "0.4" diff --git a/forc-pkg/src/pkg.rs b/forc-pkg/src/pkg.rs index 2dbbc45f20d..9467b483b2e 100644 --- a/forc-pkg/src/pkg.rs +++ b/forc-pkg/src/pkg.rs @@ -1886,8 +1886,6 @@ pub fn compile( ProgramABI::Evm(ops) } - - BuildTarget::MidenVM => ProgramABI::MidenVM(()), }; let entries = asm_res diff --git a/sway-core/Cargo.toml b/sway-core/Cargo.toml index d1500d0dfdb..668959fab61 100644 --- a/sway-core/Cargo.toml +++ b/sway-core/Cargo.toml @@ -26,7 +26,6 @@ im.workspace = true indexmap.workspace = true itertools.workspace = true lazy_static.workspace = true -miden-core.workspace = true object = { workspace = true, features = ["write"] } parking_lot.workspace = true pest.workspace = true diff --git a/sway-core/src/asm_generation/finalized_asm.rs b/sway-core/src/asm_generation/finalized_asm.rs index 9c2d3f565ab..ce3c81e3a56 100644 --- a/sway-core/src/asm_generation/finalized_asm.rs +++ b/sway-core/src/asm_generation/finalized_asm.rs @@ -1,5 +1,4 @@ use super::instruction_set::InstructionSet; -use super::ToMidenBytecode; use super::{ fuel::{checks, data_section::DataSection}, ProgramABI, ProgramKind, @@ -78,10 +77,6 @@ impl FinalizedAsm { }) } } - InstructionSet::MidenVM { ops } => Ok(CompiledBytecode { - bytecode: ops.to_bytecode().into(), - named_data_section_entries_offsets: Default::default(), - }), } } } @@ -553,6 +548,5 @@ pub fn check_invalid_opcodes(handler: &Handler, asm: &FinalizedAsm) -> Result<() ProgramKind::Predicate => checks::check_predicate_opcodes(handler, &ops[..]), }, InstructionSet::Evm { ops: _ } => Ok(()), - InstructionSet::MidenVM { ops: _ } => Ok(()), } } diff --git a/sway-core/src/asm_generation/from_ir.rs b/sway-core/src/asm_generation/from_ir.rs index f29354c2fca..1a0435409ff 100644 --- a/sway-core/src/asm_generation/from_ir.rs +++ b/sway-core/src/asm_generation/from_ir.rs @@ -7,7 +7,6 @@ use super::{ fuel_asm_builder::FuelAsmBuilder, register_sequencer::RegisterSequencer, }, - MidenVMAsmBuilder, }; use crate::{asm_generation::ProgramKind, BuildConfig, BuildTarget}; @@ -57,13 +56,6 @@ pub fn compile_ir_context_to_finalized_asm( build_config, EvmAsmBuilder::new(kind, ir), ), - BuildTarget::MidenVM => compile( - handler, - ir, - module, - build_config, - MidenVMAsmBuilder::new(kind, ir), - ), }?; check_invalid_opcodes(handler, &finalized_asm)?; diff --git a/sway-core/src/asm_generation/instruction_set.rs b/sway-core/src/asm_generation/instruction_set.rs index 6e5f007e305..c96c3f69df0 100644 --- a/sway-core/src/asm_generation/instruction_set.rs +++ b/sway-core/src/asm_generation/instruction_set.rs @@ -4,15 +4,8 @@ use std::fmt; /// An [InstructionSet] is produced by allocating registers on an [AbstractInstructionSet]. #[derive(Clone)] pub enum InstructionSet { - Fuel { - ops: Vec, - }, - Evm { - ops: Vec, - }, - MidenVM { - ops: Vec, - }, + Fuel { ops: Vec }, + Evm { ops: Vec }, } impl fmt::Display for InstructionSet { @@ -31,12 +24,6 @@ impl fmt::Display for InstructionSet { .map(|x| format!("{x}")) .collect::>() .join("\n"), - InstructionSet::MidenVM { ops } => { - ops.iter() - .map(|x| format!("{x}")) - .collect::>() - .join("\n") - } } ) } diff --git a/sway-core/src/asm_generation/miden_vm/miden_vm_asm_builder.rs b/sway-core/src/asm_generation/miden_vm/miden_vm_asm_builder.rs deleted file mode 100644 index 87696ca002a..00000000000 --- a/sway-core/src/asm_generation/miden_vm/miden_vm_asm_builder.rs +++ /dev/null @@ -1,705 +0,0 @@ -#![allow(dead_code)] -use std::{collections::HashMap, sync::Arc}; -mod miden_op; -use indexmap::IndexMap; -pub use miden_op::MidenAsmOp; - -use crate::{ - asm_generation::{ - asm_builder::AsmBuilder, - from_ir::StateAccessType, - fuel::data_section::DataSection, - instruction_set::InstructionSet, - miden_vm::miden_vm_asm_builder::miden_op::{MidenStackValue, Push}, - FinalizedAsm, ProgramKind, - }, - asm_lang::Label, - metadata::MetadataManager, - BuildConfig, -}; - -use sway_error::{ - error::CompileError, - handler::{ErrorEmitted, Handler}, -}; -use sway_ir::{Context, *}; -use sway_types::Span; - -pub use miden_op::DirectOp; - -#[derive(Default)] -pub struct MidenVMAsmSection { - ops: Vec, -} - -/// A procedure block is used to define a frequently-used sequence of instructions. A procedure must -/// start with a proc.
{ // Call the corresponding function based on the input type. let input_owner = match input_type(iter) { Some(Input::Coin) => input_coin_owner(iter), - Some(Input::Message) => input_message_sender(iter), + Some(Input::Message) => input_message_recipient(iter), _ => None, // If not Coin or Message, loop continues. }; From 9f22fe890da825071c6bcbdb96a4457c3e64aacf Mon Sep 17 00:00:00 2001 From: SwayStar123 <46050679+SwayStar123@users.noreply.github.com> Date: Wed, 16 Oct 2024 17:19:18 +0530 Subject: [PATCH 064/115] Fix u128 log rounding errors, and overflow reverts (#6647) ## Description Same as #6163 but for u128 Ensures the reverts on overflow and unsafe math take into account the flags set ## Checklist - [ ] 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. - [ ] 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). - [ ] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: K1-R1 <77465250+K1-R1@users.noreply.github.com> --- sway-lib-std/src/u128.sw | 161 +++++++- .../stdlib/u128_log_test/src/main.sw | 8 +- .../u128_inline_tests/src/main.sw | 350 +++++++++++++++++- 3 files changed, 494 insertions(+), 25 deletions(-) diff --git a/sway-lib-std/src/u128.sw b/sway-lib-std/src/u128.sw index 94a27c98027..2018bfb0f84 100644 --- a/sway-lib-std/src/u128.sw +++ b/sway-lib-std/src/u128.sw @@ -3,9 +3,16 @@ library; use ::assert::assert; use ::convert::{From, Into}; -use ::flags::{disable_panic_on_overflow, set_flags}; +use ::flags::{ + disable_panic_on_overflow, + panic_on_overflow_enabled, + panic_on_unsafe_math_enabled, + set_flags, +}; +use ::registers::{flags, overflow}; use ::math::*; use ::result::Result::{self, *}; +use ::option::Option::{self, None, Some}; /// The 128-bit unsigned integer type. /// @@ -550,8 +557,11 @@ impl core::ops::Add for U128 { fn add(self, other: Self) -> Self { let mut upper_128 = self.upper.overflowing_add(other.upper); - // If the upper overflows, then the number cannot fit in 128 bits, so panic. - assert(upper_128.upper == 0); + if panic_on_overflow_enabled() { + // If the upper overflows, then the number cannot fit in 128 bits, so panic. + assert(upper_128.upper == 0); + } + let lower_128 = self.lower.overflowing_add(other.lower); // If overflow has occurred in the lower component addition, carry. @@ -560,8 +570,10 @@ impl core::ops::Add for U128 { upper_128 = upper_128.lower.overflowing_add(lower_128.upper); } - // If overflow has occurred in the upper component addition, panic. - assert(upper_128.upper == 0); + if panic_on_overflow_enabled() { + // If overflow has occurred in the upper component addition, panic. + assert(upper_128.upper == 0); + } Self { upper: upper_128.lower, @@ -571,10 +583,13 @@ impl core::ops::Add for U128 { } impl core::ops::Subtract for U128 { - /// Subtract a `U128` from a `U128`. Reverts of overflow. + /// Subtract a `U128` from a `U128`. Reverts on underflow. fn subtract(self, other: Self) -> Self { - // If trying to subtract a larger number, panic. - assert(!(self < other)); + // panic_on_overflow_enabled is also for underflow + if panic_on_overflow_enabled() { + // If trying to subtract a larger number, panic. + assert(!(self < other)); + } let mut upper = self.upper - other.upper; let mut lower = 0; @@ -596,7 +611,9 @@ impl core::ops::Multiply for U128 { // in case both of the `U128` upper parts are bigger than zero, // it automatically means overflow, as any `U128` value // is upper part multiplied by 2 ^ 64 + lower part - assert(self.upper == 0 || other.upper == 0); + if panic_on_unsafe_math_enabled() { + assert(self.upper == 0 || other.upper == 0); + } let mut result = self.lower.overflowing_mul(other.lower); if self.upper == 0 { @@ -616,7 +633,9 @@ impl core::ops::Divide for U128 { fn divide(self, divisor: Self) -> Self { let zero = Self::from((0, 0)); - assert(divisor != zero); + if panic_on_unsafe_math_enabled() { + assert(divisor != zero); + } if self.upper == 0 && divisor.upper == 0 { return Self::from((0, self.lower / divisor.lower)); @@ -645,6 +664,48 @@ impl core::ops::Divide for U128 { } } +fn u64_checked_add(a: u64, b: u64) -> Option { + let of = asm(a: a, b: b, res) { + add res a b; + of: u64 + }; + + if of != 0 { + return None; + } + + Some(a + b) +} + +fn u128_checked_mul(a: U128, b: U128) -> Option { + // in case both of the `U128` upper parts are bigger than zero, + // it automatically means overflow, as any `U128` value + // is upper part multiplied by 2 ^ 64 + lower part + if a.upper != 0 || b.upper != 0 { + return None + } + + let mut result = a.lower.overflowing_mul(b.lower); + + if a.upper == 0 { + match u64_checked_add(result.upper, a.lower * b.upper) { + None => return None, + Some(v) => { + result.upper = v + } + } + } else if b.upper == 0 { + match u64_checked_add(result.upper, a.upper * b.lower) { + None => return None, + Some(v) => { + result.upper = v + } + } + } + + Some(result) +} + impl Power for U128 { fn pow(self, exponent: u32) -> Self { let mut value = self; @@ -661,7 +722,10 @@ impl Power for U128 { } while exp & 1 == 0 { - value = value * value; + match u128_checked_mul(value, value) { + None => return U128::zero(), + Some(v) => value = v, + }; exp >>= 1; } @@ -672,9 +736,15 @@ impl Power for U128 { let mut acc = value; while exp > 1 { exp >>= 1; - value = value * value; + match u128_checked_mul(value, value) { + None => return U128::zero(), + Some(v) => value = v, + }; if exp & 1 == 1 { - acc = acc * value; + match u128_checked_mul(acc, value) { + None => return U128::zero(), + Some(v) => acc = v, + }; } } acc @@ -713,8 +783,14 @@ impl BinaryLogarithm for U128 { fn log2(self) -> Self { let zero = Self::from((0, 0)); let mut res = zero; - // If trying to get a log2(0), panic, as infinity is not a number. - assert(self != zero); + // If panic on unsafe math is enabled, only then revert + if panic_on_unsafe_math_enabled() { + assert(self != zero); + } else { + if self == zero { + return zero; + } + } if self.upper != 0 { res = Self::from((0, self.upper.log(2) + 64)); } else if self.lower != 0 { @@ -726,8 +802,61 @@ impl BinaryLogarithm for U128 { impl Logarithm for U128 { fn log(self, base: Self) -> Self { + let flags = disable_panic_on_overflow(); + + // If panic on unsafe math is enabled, only then revert + if panic_on_unsafe_math_enabled() { + // Logarithm is undefined for bases less than 2 + assert(base >= U128::from(2_u64)); + // Logarithm is undefined for 0 + assert(self != U128::zero()); + } else { + // Logarithm is undefined for bases less than 2 + // Logarithm is undefined for 0 + if (base < U128::from(2_u64)) || (self == U128::zero()) { + set_flags(flags); + return U128::zero(); + } + } + + // Decimals rounded to 0 + if self < base { + set_flags(flags); + return U128::zero(); + } + + // Estimating the result using change of base formula. Only an estimate because we are doing uint calculations. let self_log2 = self.log2(); let base_log2 = base.log2(); - self_log2 / base_log2 + let mut result = (self_log2 / base_log2); + + // Converting u128 to u32, this cannot fail as the result will be atmost ~128 + let parts: (u64, u64) = result.into(); + let res_u32 = asm(r1: parts.1) { + r1: u32 + }; + + // Raising the base to the power of the result + let mut pow_res = base.pow(res_u32); + let mut of = overflow(); + + // Adjusting the result until the power is less than or equal to self + // If pow_res is > than self, then there is an overestimation. If there is an overflow then there is definitely an overestimation. + while (pow_res > self) || (of > 0) { + result -= U128::from(1_u64); + + // Converting u128 to u32, this cannot fail as the result will be atmost ~128 + let parts: (u64, u64) = result.into(); + let res_u32 = asm(r1: parts.1) { + r1: u32 + }; + + pow_res = base.pow(res_u32); + of = overflow(); + }; + + set_flags(flags); + + result } } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u128_log_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u128_log_test/src/main.sw index 7d9aace3432..aa017641744 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u128_log_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u128_log_test/src/main.sw @@ -12,12 +12,12 @@ fn main() -> bool { let u_128_8: U128 = U128::from((0, 8)); let u_128_9: U128 = U128::from((0, 9)); let u_128_10: U128 = U128::from((0, 10)); - let u_128_21: U128 = U128::from((0, 21)); + let u_128_20: U128 = U128::from((0, 20)); let u_128_42: U128 = U128::from((0, 42)); let u_128_64: U128 = U128::from((0, 64)); let u_128_100: U128 = U128::from((0, 100)); let u_128_127: U128 = U128::from((0, 127)); - let u_128_max_div_2: U128 = U128::from((1, 0)); + let u64_max_times_two: U128 = U128::from((1, 0)); let u_128_max: U128 = U128::max(); @@ -29,8 +29,8 @@ fn main() -> bool { assert(u_128_100.log(u_128_9) == u_128_2); assert(u_128_max.log(u_128_2) == u_128_127); assert(u_128_max.log(u_128_9) == u_128_42); - assert(u_128_max_div_2.log(u_128_2) == u_128_64); - assert(u_128_max_div_2.log(u_128_9) == u_128_21); + assert(u64_max_times_two.log(u_128_2) == u_128_64); + assert(u64_max_times_two.log(u_128_9) == u_128_20); true } 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 c7fc8405215..4d7acda31fb 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 @@ -1,6 +1,6 @@ library; -use std::u128::U128; +use std::{u128::U128, registers::flags, flags::{set_flags, disable_panic_on_unsafe_math, disable_panic_on_overflow}}; #[test] fn u128_from_u8() { @@ -688,6 +688,8 @@ fn u128_root() { #[test] fn u128_log() { + let prior_flags = flags(); + let u_128_0: U128 = U128::from((0, 0)); let u_128_1: U128 = U128::from((0, 1)); let u_128_2: U128 = U128::from((0, 2)); @@ -696,12 +698,12 @@ fn u128_log() { let u_128_8: U128 = U128::from((0, 8)); let u_128_9: U128 = U128::from((0, 9)); let u_128_10: U128 = U128::from((0, 10)); - let u_128_21: U128 = U128::from((0, 21)); + let u_128_20: U128 = U128::from((0, 20)); let u_128_42: U128 = U128::from((0, 42)); let u_128_64: U128 = U128::from((0, 64)); let u_128_100: U128 = U128::from((0, 100)); let u_128_127: U128 = U128::from((0, 127)); - let u_128_max_div_2: U128 = U128::from((1, 0)); + let u64_max_times_two: U128 = U128::from((1, 0)); let u_128_max: U128 = U128::max(); assert(u_128_2.log(u_128_2) == u_128_1); @@ -712,8 +714,37 @@ fn u128_log() { assert(u_128_100.log(u_128_9) == u_128_2); assert(u_128_max.log(u_128_2) == u_128_127); assert(u_128_max.log(u_128_9) == u_128_42); - assert(u_128_max_div_2.log(u_128_2) == u_128_64); - assert(u_128_max_div_2.log(u_128_9) == u_128_21); + assert(u64_max_times_two.log(u_128_2) == u_128_64); + assert(u64_max_times_two.log(u_128_9) == u_128_20); + + assert(prior_flags == flags()); + + let prior_flags = disable_panic_on_unsafe_math(); + + let before_flags = flags(); + + let zero = U128::from(0_u64); + let one = U128::from(1_u64); + let three = U128::from(3_u64); + + assert(one.log(one) == zero); + assert(zero.log(three) == zero); + + assert(before_flags == flags()); + + set_flags(prior_flags); +} + +#[test(should_revert)] +fn revert_unsafe_math_u128_1log1() { + let res = U128::from(1_u64).log(U128::from(1_u64)); + log(res); +} + +#[test(should_revert)] +fn revert_unsafe_math_u128_0log_3() { + let res = U128::from(0_u64).log(U128::from(3_u64)); + log(res); } #[test] @@ -742,3 +773,312 @@ fn revert_u128_binary_log() { let _result = u_128_0.log2(); } + +#[test] +fn parity_u128_log_with_ruint() { + let prior_flags = flags(); + + // Failure cases found by comparing parity with ruint implementation of U128 + // https://docs.rs/ruint/latest/src/ruint/log.rs.html#45-89 + let a = [ + 2, 4, 4, 4, 4, 5, 5, 5, 6, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, + 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 14, 14, 15, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 29, + 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, 55, 55, 55, 56, 56, 56, 56, 56, + 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 60, 60, + 60, 60, 61, 61, 61, 62, 62, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 100, 100, 100, 100, 100, + 100, 100, 100, 100, + ]; + let b = [ + 3, 3, 5, 6, 7, 3, 6, 7, 3, 7, 3, 3, 9, 10, 11, 12, 13, 14, 15, 3, 10, 11, 12, 13, 14, 15, + 3, 11, 12, 13, 14, 15, 3, 12, 13, 14, 15, 3, 13, 14, 15, 3, 14, 15, 3, 15, 3, 3, 5, 6, 7, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 3, 5, 6, 7, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 3, 5, 6, 7, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 3, 5, 6, 7, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 3, 5, 6, 7, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 3, 5, 6, 7, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 3, 5, + 6, 7, 23, 24, 25, 26, 27, 28, 29, 30, 31, 3, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31, 3, 5, + 6, 7, 25, 26, 27, 28, 29, 30, 31, 3, 6, 7, 26, 27, 28, 29, 30, 31, 3, 6, 7, 27, 28, 29, 30, + 31, 3, 6, 7, 28, 29, 30, 31, 3, 6, 7, 29, 30, 31, 3, 6, 7, 30, 31, 3, 6, 7, 31, 3, 6, 7, 3, + 6, 7, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 6, 7, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 6, 7, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 3, 6, 7, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 7, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 7, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 3, 7, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 3, 7, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 7, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 7, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 7, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 7, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 7, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 7, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 3, 7, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 3, 7, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 7, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 3, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 56, 57, 58, + 59, 60, 61, 62, 63, 3, 57, 58, 59, 60, 61, 62, 63, 3, 58, 59, 60, 61, 62, 63, 3, 59, 60, + 61, 62, 63, 3, 60, 61, 62, 63, 3, 61, 62, 63, 3, 62, 63, 3, 63, 3, 3, 5, 6, 7, 9, 10, 11, + 12, 13, 14, 15, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, 10, 11, + 12, 13, 14, 15, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, 10, 11, 12, + 13, 14, 15, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, + 15, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, + 10, 11, 12, 13, 14, 15, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, 10, + 11, 12, 13, 14, 15, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, + 7, 9, 10, 11, 12, 13, 14, 15, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, + 10, 11, 12, 13, 14, 15, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, + 7, 10, 11, 12, 13, 14, 15, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 3, 5, 6, 7, 10, 11, 12, 13, 14, 15, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 10, 11, 12, 13, 14, 15, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 10, 11, 12, 13, 14, 15, 85, + 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 10, 11, 12, 13, + 14, 15, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 10, 11, + 12, 13, 14, 15, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 10, + 11, 12, 13, 14, 15, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 10, + 11, 12, 13, 14, 15, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 10, 11, + 12, 13, 14, 15, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 10, 11, 12, 13, + 14, 15, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 10, 11, 12, 13, 14, 15, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 10, 11, 12, 13, 14, 15, 93, 94, 95, 96, 97, + 98, 99, 100, 3, 5, 6, 7, 10, 11, 12, 13, 14, 15, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, + 10, 11, 12, 13, 14, 15, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 10, 11, 12, 13, 14, 15, 96, + 97, 98, 99, 100, 3, 5, 6, 7, 10, 11, 12, 13, 14, 15, 97, 98, 99, 100, 3, 5, 6, 7, 10, 11, + 12, 13, 14, 15, 98, 99, 100, 3, 5, 6, 7, 10, 11, 12, 13, 14, 15, 99, 100, 3, 5, 6, 7, 10, + 11, 12, 13, 14, 15, 100, 3, 5, 6, 7, 11, 12, 13, 14, 15, + ]; + let expected = [ + 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 2, 0, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 2, 1, 1, 0, 0, 0, 0, 0, 0, 2, 1, 1, 0, 0, 0, 0, 0, 3, 1, 1, 0, 0, 0, 0, 3, 1, 1, 0, + 0, 0, 3, 1, 1, 0, 0, 3, 1, 1, 0, 3, 1, 1, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 3, 0, 3, 3, 2, 2, 2, 1, 1, 1, + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, + 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, 1, 1, + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, 1, + 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, 1, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, + 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, 1, + 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 4, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 4, 2, 2, 2, 1, 1, 1, + 1, 1, 1, 0, 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, + ]; + + let mut i = 0; + + while i < 1825 { + let ai: u64 = a[i]; + let bi: u64 = b[i]; + let expected_val: u64 = expected[i]; + + let result = U128::from(ai).log(U128::from(bi)); + assert_eq(result, U128::from(expected_val)); + i += 1; + } + + assert(prior_flags == flags()); +} + +#[test] +fn u128_overflowing_add() { + let prior_flags = disable_panic_on_overflow(); + let a = U128::max(); + let b = U128::from((0, 1)); + let c = a + b; + + assert(c == U128::from((0, 0))); + + set_flags(prior_flags); +} + +#[test] +fn u128_underflowing_sub() { + let prior_flags = disable_panic_on_overflow(); + let a = U128::from((0, 1)); + let b = U128::from((0, 2)); + let c = a - b; + + assert(c == U128::max()); + + set_flags(prior_flags); +} + +#[test] +fn u128_overflowing_mul() { + let prior_flags = disable_panic_on_overflow(); + let a = U128::max(); + let b = U128::from((0, 2)); + let c = a * b; + + // 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE + assert(c == U128::from((0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFE))); + + set_flags(prior_flags); +} + +#[test] +fn u128_overflowing_pow() { + // Overflow on pow should return 0 if panic is disabled + let prior_flags = disable_panic_on_overflow(); + let a = U128::max(); + + let res = a.pow(2); + + assert(res == U128::from((0, 0))); + + set_flags(prior_flags); +} + +#[test] +fn u128_unsafemath_log2() { + let prior_flags = disable_panic_on_unsafe_math(); + // 0 is not a valid operand for log2 + let a = U128::zero(); + let res = a.log2(); + + assert(res == U128::zero()); + + set_flags(prior_flags); +} \ No newline at end of file From 31486c0b47669612acb7c64d66ecb50aea281282 Mon Sep 17 00:00:00 2001 From: Joshua Batty Date: Wed, 16 Oct 2024 23:07:23 +1100 Subject: [PATCH 065/115] chore: bump to v0.66.2 (#6643) ## Description waiting on ~~#6645~~ ~~#6647~~ ~~#6649~~ ~~#6650~~ --- Cargo.lock | 68 +++++++++---------- Cargo.toml | 48 ++++++------- .../template/Cargo.toml | 2 +- .../sway-script-test-rs/template/Cargo.toml | 2 +- templates/sway-test-rs/template/Cargo.toml | 2 +- 5 files changed, 61 insertions(+), 61 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a66b1330da7..d7bc78caa7e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2659,7 +2659,7 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "forc" -version = "0.66.1" +version = "0.66.2" dependencies = [ "annotate-snippets", "ansi_term", @@ -2670,7 +2670,7 @@ dependencies = [ "completest-pty", "forc-pkg", "forc-test", - "forc-tracing 0.66.1", + "forc-tracing 0.66.2", "forc-util", "fs_extra", "fuel-asm", @@ -2696,7 +2696,7 @@ dependencies = [ [[package]] name = "forc-client" -version = "0.66.1" +version = "0.66.2" dependencies = [ "anyhow", "async-trait", @@ -2708,7 +2708,7 @@ dependencies = [ "dialoguer", "forc", "forc-pkg", - "forc-tracing 0.66.1", + "forc-tracing 0.66.2", "forc-tx", "forc-util", "forc-wallet", @@ -2743,13 +2743,13 @@ dependencies = [ [[package]] name = "forc-crypto" -version = "0.66.1" +version = "0.66.2" dependencies = [ "anyhow", "async-trait", "atty", "clap 4.5.16", - "forc-tracing 0.66.1", + "forc-tracing 0.66.2", "forc-util", "fuel-core-types", "fuel-crypto", @@ -2769,7 +2769,7 @@ dependencies = [ [[package]] name = "forc-debug" -version = "0.66.1" +version = "0.66.2" dependencies = [ "anyhow", "clap 4.5.16", @@ -2777,7 +2777,7 @@ dependencies = [ "escargot", "forc-pkg", "forc-test", - "forc-tracing 0.66.1", + "forc-tracing 0.66.2", "fuel-core-client", "fuel-types", "fuel-vm", @@ -2795,7 +2795,7 @@ dependencies = [ [[package]] name = "forc-doc" -version = "0.66.1" +version = "0.66.2" dependencies = [ "anyhow", "clap 4.5.16", @@ -2803,7 +2803,7 @@ dependencies = [ "dir_indexer", "expect-test", "forc-pkg", - "forc-tracing 0.66.1", + "forc-tracing 0.66.2", "forc-util", "horrorshow", "include_dir", @@ -2820,12 +2820,12 @@ dependencies = [ [[package]] name = "forc-fmt" -version = "0.66.1" +version = "0.66.2" dependencies = [ "anyhow", "clap 4.5.16", "forc-pkg", - "forc-tracing 0.66.1", + "forc-tracing 0.66.2", "forc-util", "prettydiff 0.7.0", "sway-core", @@ -2837,7 +2837,7 @@ dependencies = [ [[package]] name = "forc-lsp" -version = "0.66.1" +version = "0.66.2" dependencies = [ "anyhow", "clap 4.5.16", @@ -2848,13 +2848,13 @@ dependencies = [ [[package]] name = "forc-pkg" -version = "0.66.1" +version = "0.66.2" dependencies = [ "ansi_term", "anyhow", "byte-unit", "cid", - "forc-tracing 0.66.1", + "forc-tracing 0.66.2", "forc-util", "fuel-abi-types", "futures", @@ -2885,7 +2885,7 @@ dependencies = [ [[package]] name = "forc-test" -version = "0.66.1" +version = "0.66.2" dependencies = [ "anyhow", "forc-pkg", @@ -2912,7 +2912,7 @@ dependencies = [ [[package]] name = "forc-tracing" -version = "0.66.1" +version = "0.66.2" dependencies = [ "ansi_term", "tracing", @@ -2922,7 +2922,7 @@ dependencies = [ [[package]] name = "forc-tx" -version = "0.66.1" +version = "0.66.2" dependencies = [ "anyhow", "clap 4.5.16", @@ -2937,7 +2937,7 @@ dependencies = [ [[package]] name = "forc-util" -version = "0.66.1" +version = "0.66.2" dependencies = [ "annotate-snippets", "ansi_term", @@ -2945,7 +2945,7 @@ dependencies = [ "clap 4.5.16", "dirs 5.0.1", "fd-lock", - "forc-tracing 0.66.1", + "forc-tracing 0.66.2", "fuel-tx", "hex", "paste", @@ -7515,7 +7515,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sway-ast" -version = "0.66.1" +version = "0.66.2" dependencies = [ "extension-trait", "num-bigint", @@ -7527,7 +7527,7 @@ dependencies = [ [[package]] name = "sway-core" -version = "0.66.1" +version = "0.66.2" dependencies = [ "clap 4.5.16", "derivative", @@ -7571,7 +7571,7 @@ dependencies = [ [[package]] name = "sway-error" -version = "0.66.1" +version = "0.66.2" dependencies = [ "either", "in_definite", @@ -7585,7 +7585,7 @@ dependencies = [ [[package]] name = "sway-ir" -version = "0.66.1" +version = "0.66.2" dependencies = [ "anyhow", "downcast-rs", @@ -7604,7 +7604,7 @@ dependencies = [ [[package]] name = "sway-ir-macros" -version = "0.66.1" +version = "0.66.2" dependencies = [ "itertools 0.13.0", "proc-macro2", @@ -7614,7 +7614,7 @@ dependencies = [ [[package]] name = "sway-lsp" -version = "0.66.1" +version = "0.66.2" dependencies = [ "anyhow", "assert-json-diff", @@ -7625,7 +7625,7 @@ dependencies = [ "dirs 4.0.0", "fd-lock", "forc-pkg", - "forc-tracing 0.66.1", + "forc-tracing 0.66.2", "forc-util", "futures", "indexmap 2.5.0", @@ -7664,7 +7664,7 @@ dependencies = [ [[package]] name = "sway-lsp-test-utils" -version = "0.66.1" +version = "0.66.2" dependencies = [ "assert-json-diff", "futures", @@ -7679,7 +7679,7 @@ dependencies = [ [[package]] name = "sway-parse" -version = "0.66.1" +version = "0.66.2" dependencies = [ "assert_matches", "extension-trait", @@ -7697,7 +7697,7 @@ dependencies = [ [[package]] name = "sway-types" -version = "0.66.1" +version = "0.66.2" dependencies = [ "bytecount", "fuel-asm", @@ -7716,7 +7716,7 @@ dependencies = [ [[package]] name = "sway-utils" -version = "0.66.1" +version = "0.66.2" dependencies = [ "serde", "walkdir", @@ -7724,11 +7724,11 @@ dependencies = [ [[package]] name = "swayfmt" -version = "0.66.1" +version = "0.66.2" dependencies = [ "anyhow", "difference", - "forc-tracing 0.66.1", + "forc-tracing 0.66.2", "indoc", "paste", "prettydiff 0.6.4", @@ -8012,7 +8012,7 @@ dependencies = [ "forc-client", "forc-pkg", "forc-test", - "forc-tracing 0.66.1", + "forc-tracing 0.66.2", "fuel-vm", "futures", "gag", diff --git a/Cargo.toml b/Cargo.toml index d420aecac2b..760055fc845 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ exclude = ["examples/*", "swayfmt/test_macros", "forc-test/test_data"] [workspace.package] edition = "2021" -version = "0.66.1" +version = "0.66.2" authors = ["Fuel Labs "] homepage = "https://fuel.network/" license = "Apache-2.0" @@ -41,34 +41,34 @@ repository = "https://github.com/FuelLabs/sway" # Internal dependencies in order to propagate `workspace.version` # -forc = { path = "forc/", version = "0.66.1" } -forc-pkg = { path = "forc-pkg/", version = "0.66.1" } -forc-test = { path = "forc-test/", version = "0.66.1" } -forc-tracing = { path = "forc-tracing/", version = "0.66.1" } -forc-util = { path = "forc-util/", version = "0.66.1" } +forc = { path = "forc/", version = "0.66.2" } +forc-pkg = { path = "forc-pkg/", version = "0.66.2" } +forc-test = { path = "forc-test/", version = "0.66.2" } +forc-tracing = { path = "forc-tracing/", version = "0.66.2" } +forc-util = { path = "forc-util/", version = "0.66.2" } # Forc plugins -forc-plugins = { path = "forc-plugins/", version = "0.66.1" } -forc-client = { path = "forc-plugins/forc-client/", version = "0.66.1" } -forc-crypto = { path = "forc-plugins/forc-crypto/", version = "0.66.1" } -forc-debug = { path = "forc-plugins/forc-debug/", version = "0.66.1" } -forc-doc = { path = "forc-plugins/forc-doc/", version = "0.66.1" } -forc-fmt = { path = "forc-plugins/forc-fmt/", version = "0.66.1" } -forc-lsp = { path = "forc-plugins/forc-lsp/", version = "0.66.1" } -forc-tx = { path = "forc-plugins/forc-tx/", version = "0.66.1" } +forc-plugins = { path = "forc-plugins/", version = "0.66.2" } +forc-client = { path = "forc-plugins/forc-client/", version = "0.66.2" } +forc-crypto = { path = "forc-plugins/forc-crypto/", version = "0.66.2" } +forc-debug = { path = "forc-plugins/forc-debug/", version = "0.66.2" } +forc-doc = { path = "forc-plugins/forc-doc/", version = "0.66.2" } +forc-fmt = { path = "forc-plugins/forc-fmt/", version = "0.66.2" } +forc-lsp = { path = "forc-plugins/forc-lsp/", version = "0.66.2" } +forc-tx = { path = "forc-plugins/forc-tx/", version = "0.66.2" } -sway-ast = { path = "sway-ast/", version = "0.66.1" } -sway-core = { path = "sway-core/", version = "0.66.1" } -sway-error = { path = "sway-error/", version = "0.66.1" } -sway-lsp = { path = "sway-lsp/", version = "0.66.1" } -sway-parse = { path = "sway-parse/", version = "0.66.1" } -sway-types = { path = "sway-types/", version = "0.66.1" } -sway-utils = { path = "sway-utils/", version = "0.66.1" } -swayfmt = { path = "swayfmt/", version = "0.66.1" } +sway-ast = { path = "sway-ast/", version = "0.66.2" } +sway-core = { path = "sway-core/", version = "0.66.2" } +sway-error = { path = "sway-error/", version = "0.66.2" } +sway-lsp = { path = "sway-lsp/", version = "0.66.2" } +sway-parse = { path = "sway-parse/", version = "0.66.2" } +sway-types = { path = "sway-types/", version = "0.66.2" } +sway-utils = { path = "sway-utils/", version = "0.66.2" } +swayfmt = { path = "swayfmt/", version = "0.66.2" } # Sway IR -sway-ir = { path = "sway-ir/", version = "0.66.1" } -sway-ir-macros = { path = "sway-ir/sway-ir-macros", version = "0.66.1" } +sway-ir = { path = "sway-ir/", version = "0.66.2" } +sway-ir-macros = { path = "sway-ir/sway-ir-macros", version = "0.66.2" } # # External Fuel dependencies diff --git a/templates/sway-predicate-test-rs/template/Cargo.toml b/templates/sway-predicate-test-rs/template/Cargo.toml index 39f5f4d397e..4432d7edd52 100644 --- a/templates/sway-predicate-test-rs/template/Cargo.toml +++ b/templates/sway-predicate-test-rs/template/Cargo.toml @@ -7,7 +7,7 @@ authors = ["{{authors}}"] license = "Apache-2.0" [dev-dependencies] -fuels = "0.66.1" +fuels = "0.66.2" tokio = { version = "1.12", features = ["rt", "macros"] } [[test]] diff --git a/templates/sway-script-test-rs/template/Cargo.toml b/templates/sway-script-test-rs/template/Cargo.toml index 39f5f4d397e..4432d7edd52 100644 --- a/templates/sway-script-test-rs/template/Cargo.toml +++ b/templates/sway-script-test-rs/template/Cargo.toml @@ -7,7 +7,7 @@ authors = ["{{authors}}"] license = "Apache-2.0" [dev-dependencies] -fuels = "0.66.1" +fuels = "0.66.2" tokio = { version = "1.12", features = ["rt", "macros"] } [[test]] diff --git a/templates/sway-test-rs/template/Cargo.toml b/templates/sway-test-rs/template/Cargo.toml index 39f5f4d397e..4432d7edd52 100644 --- a/templates/sway-test-rs/template/Cargo.toml +++ b/templates/sway-test-rs/template/Cargo.toml @@ -7,7 +7,7 @@ authors = ["{{authors}}"] license = "Apache-2.0" [dev-dependencies] -fuels = "0.66.1" +fuels = "0.66.2" tokio = { version = "1.12", features = ["rt", "macros"] } [[test]] From e6059a542c997bbbd243150862aabd0a0fe378c8 Mon Sep 17 00:00:00 2001 From: SwayStar123 <46050679+SwayStar123@users.noreply.github.com> Date: Thu, 17 Oct 2024 18:34:54 +0530 Subject: [PATCH 066/115] Return 0 early if divisor is 0 - U128 div (#6652) ## Description Incase panic on unsafe math is disabled, we return 0 if divisor is 0 ## Checklist - [ ] 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. - [ ] 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). - [ ] I have requested a review from the relevant team or maintainers. --- sway-lib-std/src/u128.sw | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sway-lib-std/src/u128.sw b/sway-lib-std/src/u128.sw index 2018bfb0f84..c13248c5f80 100644 --- a/sway-lib-std/src/u128.sw +++ b/sway-lib-std/src/u128.sw @@ -635,6 +635,10 @@ impl core::ops::Divide for U128 { if panic_on_unsafe_math_enabled() { assert(divisor != zero); + } else { + if divisor == zero { + return zero; + } } if self.upper == 0 && divisor.upper == 0 { From 1d2f63fa8c940f5a097184d36a76a2b4cb6f6ebb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ron=C4=8Devi=C4=87?= Date: Thu, 17 Oct 2024 22:32:12 +0200 Subject: [PATCH 067/115] Forbid `memcpyopt` if the source pointer escapes (#6655) ## Description This PR fixes the issue of the source pointer not being checked for escapes in the `memcpyopt::local_copy_prop_prememcpy`. E.g., in this example: ``` script { entry fn main() -> u64 { local u64 x local u64 y entry(): v0 = get_local ptr u64, x v1 = get_local ptr u64, y v2 = load v0 v3 = call escape(v0) // `v0` escapes here. store v2 to v1 v4 = load v1 ret u64 v4 } fn escape(a: ptr u64) -> u64 { entry(a: ptr u64): z = const u64 0 store z to a ret u64 z } } ``` after the `memcpyopt` the `store v2 to v1` got optimized away and the final return was from `v0`. It means the returned value was the one changed in `escape` and not the one taken before the call to `escape`. ## 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. - [ ] 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: K1-R1 <77465250+K1-R1@users.noreply.github.com> --- sway-ir/src/instruction.rs | 3 +- sway-ir/src/optimize/cse.rs | 2 +- sway-ir/src/optimize/memcpyopt.rs | 1 + .../memcpyopt/no_copy_prop_src_ptr_escapes.ir | 33 +++++++++++++++++++ 4 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 sway-ir/tests/memcpyopt/no_copy_prop_src_ptr_escapes.ir diff --git a/sway-ir/src/instruction.rs b/sway-ir/src/instruction.rs index 9e7b92fb5e0..cd710a609c0 100644 --- a/sway-ir/src/instruction.rs +++ b/sway-ir/src/instruction.rs @@ -385,10 +385,11 @@ impl InstOp { vals } InstOp::GetLocal(_local_var) => { - // TODO: Not sure. + // `GetLocal` returns an SSA `Value` but does not take any as an operand. vec![] } InstOp::GetConfig(_, _) => { + // `GetConfig` returns an SSA `Value` but does not take any as an operand. vec![] } InstOp::IntToPtr(v, _) => vec![*v], diff --git a/sway-ir/src/optimize/cse.rs b/sway-ir/src/optimize/cse.rs index 7423cc2fa62..3eb03ac4ccb 100644 --- a/sway-ir/src/optimize/cse.rs +++ b/sway-ir/src/optimize/cse.rs @@ -220,7 +220,7 @@ pub fn cse( } } - // Initialize all instructions and constants. Constants need special treatmemt. + // Initialize all instructions and constants. Constants need special treatment. // They don't have PartialEq implemented. So we need to value number them manually. // This map maps the hash of a constant value to all possible collisions of it. let mut const_map = FxHashMap::>::default(); diff --git a/sway-ir/src/optimize/memcpyopt.rs b/sway-ir/src/optimize/memcpyopt.rs index 8cff549530e..265db81695b 100644 --- a/sway-ir/src/optimize/memcpyopt.rs +++ b/sway-ir/src/optimize/memcpyopt.rs @@ -166,6 +166,7 @@ fn local_copy_prop_prememcpy( }) // We don't deal with symbols that escape. || escaped_symbols.contains(&dst_local) + || escaped_symbols.contains(&src_local) // We don't deal part copies. || dst_local.get_type(context) != src_local.get_type(context) // We don't replace the destination when it's an arg. diff --git a/sway-ir/tests/memcpyopt/no_copy_prop_src_ptr_escapes.ir b/sway-ir/tests/memcpyopt/no_copy_prop_src_ptr_escapes.ir new file mode 100644 index 00000000000..b72db62856f --- /dev/null +++ b/sway-ir/tests/memcpyopt/no_copy_prop_src_ptr_escapes.ir @@ -0,0 +1,33 @@ +script { + entry fn main() -> u64 { + local u64 x + local u64 y + + entry(): + v0 = get_local ptr u64, x + v1 = get_local ptr u64, y + + v2 = load v0 + v3 = call escape(v0) // `v0` escapes here. + store v2 to v1 + v4 = load v1 + + ret u64 v4 + } + + fn escape(a: ptr u64) -> u64 { + entry(a: ptr u64): + z = const u64 0 + store z to a + ret u64 z + } +} + +// The `store` instruction must not be optimized away. + +// check: v0 = get_local ptr u64, x +// check: v1 = get_local ptr u64, y +// check: v2 = load v0 +// check: v3 = call escape(v0) +// check: store v2 to v1 +// check: v4 = load v1 From fa4dac80e11ec454e37a740ef8ccbf351765c2df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ron=C4=8Devi=C4=87?= Date: Thu, 17 Oct 2024 23:09:13 +0200 Subject: [PATCH 068/115] Remove redundant `cfe(i)/cfs(i)` instructions from the allocated ASM (#6627) ## Description This PR removes redundant `cfei/cfsi` and `cfe/cfs` instructions from the allocated abstract instruction set, if the allocated/dealocated stack size is zero. Note that, in the case of `cfei/cfsi i0` the removal does not represent an optimization, because those instructions were anyhow removed at the final bytecode generation step (see #5588). The PR in this case merely synchronizes the finalized ASM with the generated bytecode, removing potential confusion caused by existence of redundant zero stack allocations in the printed final ASM. The removal of redundant `cfei/cfsi` and `cfe/cfs` instructions _must be done on the allocated instruction set_, because the register allocation could change the original allocated/dealocated size in case of spilling. Related to #5588. ## 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. --------- Co-authored-by: IGI-111 --- .../fuel/abstract_instruction_set.rs | 19 ++++++++++----- .../allocated_abstract_instruction_set.rs | 24 +++++++++++++++++++ .../asm_generation/fuel/programs/abstract.rs | 15 ++++++++---- sway-core/src/asm_lang/allocated_ops.rs | 4 ++++ test/src/ir_generation/tests/empty.sw | 3 ++- 5 files changed, 53 insertions(+), 12 deletions(-) diff --git a/sway-core/src/asm_generation/fuel/abstract_instruction_set.rs b/sway-core/src/asm_generation/fuel/abstract_instruction_set.rs index ea11591842b..32ef5a7f538 100644 --- a/sway-core/src/asm_generation/fuel/abstract_instruction_set.rs +++ b/sway-core/src/asm_generation/fuel/abstract_instruction_set.rs @@ -30,7 +30,7 @@ impl AbstractInstructionSet { .simplify_cfg() .remove_sequential_jumps() .remove_redundant_moves() - .remove_unused_ops() + .remove_redundant_ops() } /// Removes any jumps to the subsequent line. @@ -114,11 +114,18 @@ impl AbstractInstructionSet { self } - fn remove_unused_ops(mut self) -> AbstractInstructionSet { - // Just remove NOPs for now. - self.ops.retain(|op| match &op.opcode { - Either::Left(VirtualOp::NOOP) => false, - _otherwise => true, + fn remove_redundant_ops(mut self) -> AbstractInstructionSet { + self.ops.retain(|op| { + // It is easier to think in terms of operations we want to remove + // than the operations we want to retain ;-) + #[allow(clippy::match_like_matches_macro)] + // Keep the `match` for adding more ops in the future. + let remove = match &op.opcode { + Either::Left(VirtualOp::NOOP) => true, + _ => false, + }; + + !remove }); self diff --git a/sway-core/src/asm_generation/fuel/allocated_abstract_instruction_set.rs b/sway-core/src/asm_generation/fuel/allocated_abstract_instruction_set.rs index fc218425daf..0865687f5c8 100644 --- a/sway-core/src/asm_generation/fuel/allocated_abstract_instruction_set.rs +++ b/sway-core/src/asm_generation/fuel/allocated_abstract_instruction_set.rs @@ -35,6 +35,30 @@ pub struct AllocatedAbstractInstructionSet { } impl AllocatedAbstractInstructionSet { + pub(crate) fn optimize(self) -> AllocatedAbstractInstructionSet { + self.remove_redundant_ops() + } + + fn remove_redundant_ops(mut self) -> AllocatedAbstractInstructionSet { + self.ops.retain(|op| { + // It is easier to think in terms of operations we want to remove + // than the operations we want to retain ;-) + let remove = match &op.opcode { + // `cfei i0` and `cfsi i0` pairs. + Either::Left(AllocatedOpcode::CFEI(imm)) + | Either::Left(AllocatedOpcode::CFSI(imm)) => imm.value == 0u32, + // `cfe $zero` and `cfs $zero` pairs. + Either::Left(AllocatedOpcode::CFE(reg)) + | Either::Left(AllocatedOpcode::CFS(reg)) => reg.is_zero(), + _ => false, + }; + + !remove + }); + + self + } + /// Replace each PUSHA instruction with stores of all used registers to the stack, and each /// POPA with respective loads from the stack. /// diff --git a/sway-core/src/asm_generation/fuel/programs/abstract.rs b/sway-core/src/asm_generation/fuel/programs/abstract.rs index c30f72621e7..17b6240a95d 100644 --- a/sway-core/src/asm_generation/fuel/programs/abstract.rs +++ b/sway-core/src/asm_generation/fuel/programs/abstract.rs @@ -78,7 +78,7 @@ impl AbstractProgram { && self.data_section.value_pairs.is_empty() } - /// Adds prologue, globals allocation, before entries, contract method switch, and allocates virtual register + /// Adds prologue, globals allocation, before entries, contract method switch, and allocates virtual register. pub(crate) fn into_allocated_program( mut self, fallback_fn: Option, @@ -111,21 +111,21 @@ impl AbstractProgram { }) .collect(); - // Gather all functions + // Gather all functions. let all_functions = self .entries .into_iter() .map(|entry| entry.ops) .chain(self.non_entries); - // optimise and then verify these functions. + // Optimize and then verify abstract functions. let abstract_functions = all_functions .map(|instruction_set| instruction_set.optimize(&self.data_section)) .map(AbstractInstructionSet::verify) .collect::, CompileError>>()?; // Allocate the registers for each function. - let functions = abstract_functions + let allocated_functions = abstract_functions .into_iter() .map(|abstract_instruction_set| { let allocated = abstract_instruction_set.allocate_registers()?; @@ -133,7 +133,12 @@ impl AbstractProgram { }) .collect::, CompileError>>()?; - // XXX need to verify that the stack use for each function is balanced. + // Optimize allocated functions. + // TODO: Add verification. E.g., verify that the stack use for each function is balanced. + let functions = allocated_functions + .into_iter() + .map(|instruction_set| instruction_set.optimize()) + .collect::>(); Ok(AllocatedProgram { kind: self.kind, diff --git a/sway-core/src/asm_lang/allocated_ops.rs b/sway-core/src/asm_lang/allocated_ops.rs index 5590279cde7..b78ba37b2db 100644 --- a/sway-core/src/asm_lang/allocated_ops.rs +++ b/sway-core/src/asm_lang/allocated_ops.rs @@ -50,6 +50,10 @@ impl AllocatedRegister { AllocatedRegister::Constant(constant) => constant.to_reg_id(), } } + + pub fn is_zero(&self) -> bool { + matches!(self, Self::Constant(ConstantRegister::Zero)) + } } /// This enum is unfortunately a redundancy of the [fuel_asm::Opcode] and [crate::VirtualOp] enums. This variant, however, diff --git a/test/src/ir_generation/tests/empty.sw b/test/src/ir_generation/tests/empty.sw index d58938be4e3..37453757bf0 100644 --- a/test/src/ir_generation/tests/empty.sw +++ b/test/src/ir_generation/tests/empty.sw @@ -11,7 +11,8 @@ fn main() { // ::check-asm:: // The data section setup: // check: move $$$$locbase $$sp -// check: cfei i0 +// not: cfei i0 +// not: cfsi i0 // check: ret $$zero // nextln: .data // not: data_ From 029c593b5f33a5c18ed2ddf91b1db12869139c91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Matos?= Date: Thu, 17 Oct 2024 22:49:22 +0100 Subject: [PATCH 069/115] Refactor monomorphization/type resolving code out of `TypeCheckContext`. (#6615) ## Description This PR mainly refactors some common monomorphization/type resolving code out of `TypeCheckContext`, to be able to re-use this code for the symbol resolving pass as well, along with some other minor cleanups. It also helps with code quality in that this file is a big beast and so this makes it a bit more manageable to understand. Main changes: [Refactor symbol resolve from root into lexical scope.](https://github.com/FuelLabs/sway/pull/6615/commits/742067df89f25058b6aadaee7cbf8c61b8daae4d) [Refactor monomorphization/type resolving code out of TypeCheckContext.](https://github.com/FuelLabs/sway/pull/6615/commits/58c83da8a14ed648acfe09dba59cb5b513ee94e9) [Extract resolve_qualified_call_path_with_visibility_check_and_modpath to type resolver.](https://github.com/FuelLabs/sway/pull/6615/commits/d50f598d300202db7ba6f89a64a4a444d2581a12) [Extract resolve_call_path_with_visibility_check_and_modpath to type resolver.](https://github.com/FuelLabs/sway/pull/6615/commits/940a67700e2c22cc7c9388d8b786015699c55e66) [Refactor type resolver trait into functions.](https://github.com/FuelLabs/sway/pull/6615/commits/77c6a27e56b39f9dc94a8d0fb7813adea98b2111) --------- Co-authored-by: IGI-111 --- sway-core/src/decl_engine/id.rs | 35 +- sway-core/src/decl_engine/ref.rs | 19 +- sway-core/src/language/ty/ast_node.rs | 6 +- sway-core/src/language/ty/code_block.rs | 4 +- .../language/ty/declaration/configurable.rs | 8 +- .../src/language/ty/declaration/constant.rs | 8 +- .../language/ty/declaration/declaration.rs | 20 +- sway-core/src/language/ty/declaration/enum.rs | 12 +- .../src/language/ty/declaration/function.rs | 26 +- .../src/language/ty/declaration/impl_trait.rs | 8 +- .../src/language/ty/declaration/struct.rs | 12 +- .../src/language/ty/declaration/trait.rs | 29 +- .../src/language/ty/declaration/trait_fn.rs | 8 +- .../src/language/ty/declaration/trait_type.rs | 6 +- .../src/language/ty/declaration/type_alias.rs | 4 +- .../src/language/ty/declaration/variable.rs | 8 +- sway-core/src/language/ty/expression/asm.rs | 4 +- .../src/language/ty/expression/expression.rs | 6 +- .../ty/expression/expression_variant.rs | 78 +- .../ty/expression/intrinsic_function.rs | 6 +- .../language/ty/expression/reassignment.rs | 18 +- .../ty/expression/struct_exp_field.rs | 4 +- sway-core/src/semantic_analysis.rs | 1 + .../ast_node/declaration/configurable.rs | 9 +- .../ast_node/declaration/constant.rs | 9 +- .../ast_node/declaration/declaration.rs | 7 +- .../ast_node/declaration/enum.rs | 2 +- .../ast_node/declaration/function.rs | 2 +- .../function/function_parameter.rs | 2 +- .../ast_node/declaration/impl_trait.rs | 81 +- .../ast_node/declaration/struct.rs | 2 +- .../ast_node/declaration/supertrait.rs | 2 +- .../ast_node/declaration/trait.rs | 49 +- .../ast_node/declaration/trait_fn.rs | 5 +- .../ast_node/declaration/trait_type.rs | 5 +- .../ast_node/declaration/variable.rs | 2 +- .../ast_node/expression/intrinsic_function.rs | 2 +- .../match_expression/typed/typed_scrutinee.rs | 5 +- .../ast_node/expression/typed_expression.rs | 2 +- .../typed_expression/method_application.rs | 9 +- .../typed_expression/struct_instantiation.rs | 4 +- .../namespace/lexical_scope.rs | 69 +- .../src/semantic_analysis/namespace/module.rs | 12 + .../src/semantic_analysis/namespace/root.rs | 79 +- .../semantic_analysis/namespace/trait_map.rs | 43 +- .../symbol_resolve_context.rs | 36 - .../semantic_analysis/type_check_context.rs | 775 ++---------------- .../src/semantic_analysis/type_resolve.rs | 355 ++++++++ .../src/type_system/ast_elements/binding.rs | 4 +- .../ast_elements/trait_constraint.rs | 6 +- .../type_system/ast_elements/type_argument.rs | 4 +- .../ast_elements/type_parameter.rs | 6 +- sway-core/src/type_system/id.rs | 6 +- sway-core/src/type_system/mod.rs | 38 + sway-core/src/type_system/monomorphization.rs | 346 ++++++++ .../src/type_system/substitute/subst_list.rs | 92 --- .../src/type_system/substitute/subst_types.rs | 41 +- 57 files changed, 1199 insertions(+), 1242 deletions(-) create mode 100644 sway-core/src/semantic_analysis/type_resolve.rs create mode 100644 sway-core/src/type_system/monomorphization.rs delete mode 100644 sway-core/src/type_system/substitute/subst_list.rs diff --git a/sway-core/src/decl_engine/id.rs b/sway-core/src/decl_engine/id.rs index 45b241b04a7..8878b9aaa79 100644 --- a/sway-core/src/decl_engine/id.rs +++ b/sway-core/src/decl_engine/id.rs @@ -143,10 +143,10 @@ where } impl SubstTypes for DeclId { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { let decl_engine = ctx.engines.de(); let mut decl = (*decl_engine.get(self)).clone(); - if decl.subst(type_mapping, ctx).has_changes() { + if decl.subst(ctx).has_changes() { decl_engine.replace(*self, decl); HasChanges::Yes } else { @@ -155,10 +155,10 @@ impl SubstTypes for DeclId { } } impl SubstTypes for DeclId { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { let decl_engine = ctx.engines.de(); let mut decl = (*decl_engine.get(self)).clone(); - if decl.subst(type_mapping, ctx).has_changes() { + if decl.subst(ctx).has_changes() { decl_engine.replace(*self, decl); HasChanges::Yes } else { @@ -167,10 +167,10 @@ impl SubstTypes for DeclId { } } impl SubstTypes for DeclId { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { let decl_engine = ctx.engines.de(); let mut decl = (*decl_engine.get(self)).clone(); - if decl.subst(type_mapping, ctx).has_changes() { + if decl.subst(ctx).has_changes() { decl_engine.replace(*self, decl); HasChanges::Yes } else { @@ -179,10 +179,10 @@ impl SubstTypes for DeclId { } } impl SubstTypes for DeclId { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { let decl_engine = ctx.engines.de(); let mut decl = (*decl_engine.get(self)).clone(); - if decl.subst(type_mapping, ctx).has_changes() { + if decl.subst(ctx).has_changes() { decl_engine.replace(*self, decl); HasChanges::Yes } else { @@ -191,10 +191,10 @@ impl SubstTypes for DeclId { } } impl SubstTypes for DeclId { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { let decl_engine = ctx.engines.de(); let mut decl = (*decl_engine.get(self)).clone(); - if decl.subst(type_mapping, ctx).has_changes() { + if decl.subst(ctx).has_changes() { decl_engine.replace(*self, decl); HasChanges::Yes } else { @@ -203,10 +203,10 @@ impl SubstTypes for DeclId { } } impl SubstTypes for DeclId { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { let decl_engine = ctx.engines.de(); let mut decl = (*decl_engine.get(self)).clone(); - if decl.subst(type_mapping, ctx).has_changes() { + if decl.subst(ctx).has_changes() { decl_engine.replace(*self, decl); HasChanges::Yes } else { @@ -215,10 +215,10 @@ impl SubstTypes for DeclId { } } impl SubstTypes for DeclId { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { let decl_engine = ctx.engines.de(); let mut decl = (*decl_engine.get(self)).clone(); - if decl.subst(type_mapping, ctx).has_changes() { + if decl.subst(ctx).has_changes() { decl_engine.replace(*self, decl); HasChanges::Yes } else { @@ -228,10 +228,10 @@ impl SubstTypes for DeclId { } impl SubstTypes for DeclId { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { let decl_engine = ctx.engines.de(); let mut decl = (*decl_engine.get(self)).clone(); - if decl.subst(type_mapping, ctx).has_changes() { + if decl.subst(ctx).has_changes() { decl_engine.replace(*self, decl); HasChanges::Yes } else { @@ -247,12 +247,11 @@ where { pub(crate) fn subst_types_and_insert_new( &self, - type_mapping: &TypeSubstMap, ctx: &SubstTypesContext, ) -> Option> { let decl_engine = ctx.engines.de(); let mut decl = (*decl_engine.get(self)).clone(); - if decl.subst(type_mapping, ctx).has_changes() { + if decl.subst(ctx).has_changes() { Some(decl_engine.insert(decl, decl_engine.get_parsed_decl_id(self).as_ref())) } else { None diff --git a/sway-core/src/decl_engine/ref.rs b/sway-core/src/decl_engine/ref.rs index 9ad82d72883..663fd563a60 100644 --- a/sway-core/src/decl_engine/ref.rs +++ b/sway-core/src/decl_engine/ref.rs @@ -99,17 +99,15 @@ where DeclEngine: DeclEngineIndex + DeclEngineInsert + DeclEngineGetParsedDeclId, T: Named + Spanned + IsConcrete + SubstTypes + Clone + TyDeclParsedType, { - pub(crate) fn subst_types_and_insert_new( - &self, - type_mapping: &TypeSubstMap, - ctx: &SubstTypesContext, - ) -> Option { + pub(crate) fn subst_types_and_insert_new(&self, ctx: &SubstTypesContext) -> Option { let decl_engine = ctx.engines.de(); - if type_mapping.source_ids_contains_concrete_type(ctx.engines) + if ctx + .type_subst_map + .source_ids_contains_concrete_type(ctx.engines) || !decl_engine.get(&self.id).is_concrete(ctx.engines) { let mut decl = (*decl_engine.get(&self.id)).clone(); - if decl.subst(type_mapping, ctx).has_changes() { + if decl.subst(ctx).has_changes() { Some(decl_engine.insert(decl, decl_engine.get_parsed_decl_id(&self.id).as_ref())) } else { None @@ -143,12 +141,11 @@ where { pub(crate) fn subst_types_and_insert_new_with_parent( &self, - type_mapping: &TypeSubstMap, ctx: &SubstTypesContext, ) -> Option { let decl_engine = ctx.engines.de(); let mut decl = (*decl_engine.get(&self.id)).clone(); - if decl.subst(type_mapping, ctx).has_changes() { + if decl.subst(ctx).has_changes() { Some( decl_engine .insert(decl, decl_engine.get_parsed_decl_id(&self.id).as_ref()) @@ -263,10 +260,10 @@ where DeclEngine: DeclEngineIndex, T: Named + Spanned + SubstTypes + Clone, { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { let decl_engine = ctx.engines.de(); let mut decl = (*decl_engine.get(&self.id)).clone(); - if decl.subst(type_mapping, ctx).has_changes() { + if decl.subst(ctx).has_changes() { decl_engine.replace(self.id, decl); HasChanges::Yes } else { diff --git a/sway-core/src/language/ty/ast_node.rs b/sway-core/src/language/ty/ast_node.rs index fd7c2344091..59d9e942004 100644 --- a/sway-core/src/language/ty/ast_node.rs +++ b/sway-core/src/language/ty/ast_node.rs @@ -61,10 +61,10 @@ impl DebugWithEngines for TyAstNode { } impl SubstTypes for TyAstNode { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { match self.content { - TyAstNodeContent::Declaration(ref mut decl) => decl.subst(type_mapping, ctx), - TyAstNodeContent::Expression(ref mut expr) => expr.subst(type_mapping, ctx), + TyAstNodeContent::Declaration(ref mut decl) => decl.subst(ctx), + TyAstNodeContent::Expression(ref mut expr) => expr.subst(ctx), TyAstNodeContent::SideEffect(_) | TyAstNodeContent::Error(_, _) => HasChanges::No, } } diff --git a/sway-core/src/language/ty/code_block.rs b/sway-core/src/language/ty/code_block.rs index 6fcffb61a27..6ae9b0d0dea 100644 --- a/sway-core/src/language/ty/code_block.rs +++ b/sway-core/src/language/ty/code_block.rs @@ -38,8 +38,8 @@ impl HashWithEngines for TyCodeBlock { } impl SubstTypes for TyCodeBlock { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { - self.contents.subst(type_mapping, ctx) + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { + self.contents.subst(ctx) } } diff --git a/sway-core/src/language/ty/declaration/configurable.rs b/sway-core/src/language/ty/declaration/configurable.rs index bcd0220daad..da7349fc91b 100644 --- a/sway-core/src/language/ty/declaration/configurable.rs +++ b/sway-core/src/language/ty/declaration/configurable.rs @@ -89,11 +89,11 @@ impl Spanned for TyConfigurableDecl { } impl SubstTypes for TyConfigurableDecl { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { has_changes! { - self.return_type.subst(type_mapping, ctx); - self.type_ascription.subst(type_mapping, ctx); - self.value.subst(type_mapping, ctx); + self.return_type.subst(ctx); + self.type_ascription.subst(ctx); + self.value.subst(ctx); } } } diff --git a/sway-core/src/language/ty/declaration/constant.rs b/sway-core/src/language/ty/declaration/constant.rs index 4e4c0ba9f04..c8acda6b5cf 100644 --- a/sway-core/src/language/ty/declaration/constant.rs +++ b/sway-core/src/language/ty/declaration/constant.rs @@ -93,11 +93,11 @@ impl IsConcrete for TyConstantDecl { } impl SubstTypes for TyConstantDecl { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { has_changes! { - self.return_type.subst(type_mapping, ctx); - self.type_ascription.subst(type_mapping, ctx); - self.value.subst(type_mapping, ctx); + self.return_type.subst(ctx); + self.type_ascription.subst(ctx); + self.value.subst(ctx); } } } diff --git a/sway-core/src/language/ty/declaration/declaration.rs b/sway-core/src/language/ty/declaration/declaration.rs index 8038859c6ed..9bd68ec0046 100644 --- a/sway-core/src/language/ty/declaration/declaration.rs +++ b/sway-core/src/language/ty/declaration/declaration.rs @@ -250,33 +250,33 @@ impl HashWithEngines for TyDecl { } impl SubstTypes for TyDecl { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { match self { - TyDecl::VariableDecl(ref mut var_decl) => var_decl.subst(type_mapping, ctx), + TyDecl::VariableDecl(ref mut var_decl) => var_decl.subst(ctx), TyDecl::FunctionDecl(FunctionDecl { ref mut decl_id, .. - }) => decl_id.subst(type_mapping, ctx), + }) => decl_id.subst(ctx), TyDecl::TraitDecl(TraitDecl { ref mut decl_id, .. - }) => decl_id.subst(type_mapping, ctx), + }) => decl_id.subst(ctx), TyDecl::StructDecl(StructDecl { ref mut decl_id, .. - }) => decl_id.subst(type_mapping, ctx), + }) => decl_id.subst(ctx), TyDecl::EnumDecl(EnumDecl { ref mut decl_id, .. - }) => decl_id.subst(type_mapping, ctx), + }) => decl_id.subst(ctx), TyDecl::EnumVariantDecl(EnumVariantDecl { ref mut enum_ref, .. - }) => enum_ref.subst(type_mapping, ctx), + }) => enum_ref.subst(ctx), TyDecl::ImplSelfOrTrait(ImplSelfOrTrait { ref mut decl_id, .. - }) => decl_id.subst(type_mapping, ctx), + }) => decl_id.subst(ctx), TyDecl::TypeAliasDecl(TypeAliasDecl { ref mut decl_id, .. - }) => decl_id.subst(type_mapping, ctx), + }) => decl_id.subst(ctx), TyDecl::TraitTypeDecl(TraitTypeDecl { ref mut decl_id, .. - }) => decl_id.subst(type_mapping, ctx), + }) => decl_id.subst(ctx), // generics in an ABI is unsupported by design TyDecl::AbiDecl(_) | TyDecl::ConstantDecl(_) diff --git a/sway-core/src/language/ty/declaration/enum.rs b/sway-core/src/language/ty/declaration/enum.rs index 44cf87f553d..2ce5e3eae46 100644 --- a/sway-core/src/language/ty/declaration/enum.rs +++ b/sway-core/src/language/ty/declaration/enum.rs @@ -3,6 +3,7 @@ use std::{ hash::{Hash, Hasher}, }; +use monomorphization::MonomorphizeHelper; use sway_error::{ error::CompileError, handler::{ErrorEmitted, Handler}, @@ -13,7 +14,6 @@ use crate::{ engine_threading::*, has_changes, language::{parsed::EnumDeclaration, CallPath, Visibility}, - semantic_analysis::type_check_context::MonomorphizeHelper, transform, type_system::*, }; @@ -70,10 +70,10 @@ impl HashWithEngines for TyEnumDecl { } impl SubstTypes for TyEnumDecl { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { has_changes! { - self.variants.subst(type_mapping, ctx); - self.type_parameters.subst(type_mapping, ctx); + self.variants.subst(ctx); + self.type_parameters.subst(ctx); } } } @@ -186,7 +186,7 @@ impl OrdWithEngines for TyEnumVariant { } impl SubstTypes for TyEnumVariant { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { - self.type_argument.subst_inner(type_mapping, ctx) + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { + self.type_argument.subst_inner(ctx) } } diff --git a/sway-core/src/language/ty/declaration/function.rs b/sway-core/src/language/ty/declaration/function.rs index 54a2d5b0e67..8bb26f1f598 100644 --- a/sway-core/src/language/ty/declaration/function.rs +++ b/sway-core/src/language/ty/declaration/function.rs @@ -3,6 +3,7 @@ use std::{ hash::{Hash, Hasher}, }; +use monomorphization::MonomorphizeHelper; use sha2::{Digest, Sha256}; use sway_error::handler::{ErrorEmitted, Handler}; @@ -12,7 +13,6 @@ use crate::{ parsed::{FunctionDeclaration, FunctionDeclarationKind}, CallPath, }, - semantic_analysis::type_check_context::MonomorphizeHelper, transform::AttributeKind, }; @@ -220,21 +220,21 @@ impl HashWithEngines for TyFunctionDecl { } impl SubstTypes for TyFunctionDecl { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { if ctx.subst_function_body { has_changes! { - self.type_parameters.subst(type_mapping, ctx); - self.parameters.subst(type_mapping, ctx); - self.return_type.subst(type_mapping, ctx); - self.body.subst(type_mapping, ctx); - self.implementing_for_typeid.subst(type_mapping, ctx); + self.type_parameters.subst(ctx); + self.parameters.subst(ctx); + self.return_type.subst(ctx); + self.body.subst(ctx); + self.implementing_for_typeid.subst(ctx); } } else { has_changes! { - self.type_parameters.subst(type_mapping, ctx); - self.parameters.subst(type_mapping, ctx); - self.return_type.subst(type_mapping, ctx); - self.implementing_for_typeid.subst(type_mapping, ctx); + self.type_parameters.subst(ctx); + self.parameters.subst(ctx); + self.return_type.subst(ctx); + self.implementing_for_typeid.subst(ctx); } } } @@ -527,8 +527,8 @@ impl HashWithEngines for TyFunctionParameter { } impl SubstTypes for TyFunctionParameter { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { - self.type_argument.type_id.subst(type_mapping, ctx) + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { + self.type_argument.type_id.subst(ctx) } } diff --git a/sway-core/src/language/ty/declaration/impl_trait.rs b/sway-core/src/language/ty/declaration/impl_trait.rs index 42b7c04b311..0c2d25aa5fd 100644 --- a/sway-core/src/language/ty/declaration/impl_trait.rs +++ b/sway-core/src/language/ty/declaration/impl_trait.rs @@ -88,11 +88,11 @@ impl HashWithEngines for TyImplSelfOrTrait { } impl SubstTypes for TyImplSelfOrTrait { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { has_changes! { - self.impl_type_parameters.subst(type_mapping, ctx); - self.implementing_for.subst_inner(type_mapping, ctx); - self.items.subst(type_mapping, ctx); + self.impl_type_parameters.subst(ctx); + self.implementing_for.subst_inner(ctx); + self.items.subst(ctx); } } } diff --git a/sway-core/src/language/ty/declaration/struct.rs b/sway-core/src/language/ty/declaration/struct.rs index 32c4409b0d9..c4dc7e3e219 100644 --- a/sway-core/src/language/ty/declaration/struct.rs +++ b/sway-core/src/language/ty/declaration/struct.rs @@ -3,6 +3,7 @@ use std::{ hash::{Hash, Hasher}, }; +use monomorphization::MonomorphizeHelper; use sway_types::{Ident, Named, Span, Spanned}; use crate::{ @@ -10,7 +11,6 @@ use crate::{ error::module_can_be_changed, has_changes, language::{parsed::StructDeclaration, CallPath, Visibility}, - semantic_analysis::type_check_context::MonomorphizeHelper, transform, type_system::*, Namespace, @@ -68,10 +68,10 @@ impl HashWithEngines for TyStructDecl { } impl SubstTypes for TyStructDecl { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { has_changes! { - self.fields.subst(type_mapping, ctx); - self.type_parameters.subst(type_mapping, ctx); + self.fields.subst(ctx); + self.type_parameters.subst(ctx); } } } @@ -279,7 +279,7 @@ impl OrdWithEngines for TyStructField { } impl SubstTypes for TyStructField { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { - self.type_argument.subst_inner(type_mapping, ctx) + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { + self.type_argument.subst_inner(ctx) } } diff --git a/sway-core/src/language/ty/declaration/trait.rs b/sway-core/src/language/ty/declaration/trait.rs index ed6258cd71e..f0c7ee24ff3 100644 --- a/sway-core/src/language/ty/declaration/trait.rs +++ b/sway-core/src/language/ty/declaration/trait.rs @@ -3,6 +3,7 @@ use std::{ hash::{Hash, Hasher}, }; +use monomorphization::MonomorphizeHelper; use sway_error::handler::{ErrorEmitted, Handler}; use sway_types::{Ident, Named, Span, Spanned}; @@ -18,8 +19,8 @@ use crate::{ CallPath, Visibility, }, semantic_analysis::{ - type_check_context::MonomorphizeHelper, TypeCheckAnalysis, TypeCheckAnalysisContext, - TypeCheckFinalization, TypeCheckFinalizationContext, + TypeCheckAnalysis, TypeCheckAnalysisContext, TypeCheckFinalization, + TypeCheckFinalizationContext, }, transform, type_system::*, @@ -276,16 +277,16 @@ impl Spanned for TyTraitItem { } impl SubstTypes for TyTraitDecl { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { has_changes! { - self.type_parameters.subst(type_mapping, ctx); + self.type_parameters.subst(ctx); self.interface_surface .iter_mut() .fold(HasChanges::No, |has_changes, item| match item { TyTraitInterfaceItem::TraitFn(item_ref) => { if let Some(new_item_ref) = item_ref .clone() - .subst_types_and_insert_new_with_parent(type_mapping, ctx) { + .subst_types_and_insert_new_with_parent(ctx) { item_ref.replace_id(*new_item_ref.id()); HasChanges::Yes } else { @@ -295,7 +296,7 @@ impl SubstTypes for TyTraitDecl { TyTraitInterfaceItem::Constant(decl_ref) => { if let Some(new_decl_ref) = decl_ref .clone() - .subst_types_and_insert_new(type_mapping, ctx) { + .subst_types_and_insert_new(ctx) { decl_ref.replace_id(*new_decl_ref.id()); HasChanges::Yes } else{ @@ -305,7 +306,7 @@ impl SubstTypes for TyTraitDecl { TyTraitInterfaceItem::Type(decl_ref) => { if let Some(new_decl_ref) = decl_ref .clone() - .subst_types_and_insert_new(type_mapping, ctx) { + .subst_types_and_insert_new(ctx) { decl_ref.replace_id(*new_decl_ref.id()); HasChanges::Yes } else{ @@ -317,7 +318,7 @@ impl SubstTypes for TyTraitDecl { TyTraitItem::Fn(item_ref) => { if let Some(new_item_ref) = item_ref .clone() - .subst_types_and_insert_new_with_parent(type_mapping, ctx) + .subst_types_and_insert_new_with_parent(ctx) { item_ref.replace_id(*new_item_ref.id()); HasChanges::Yes @@ -328,7 +329,7 @@ impl SubstTypes for TyTraitDecl { TyTraitItem::Constant(item_ref) => { if let Some(new_decl_ref) = item_ref .clone() - .subst_types_and_insert_new_with_parent(type_mapping, ctx) + .subst_types_and_insert_new_with_parent(ctx) { item_ref.replace_id(*new_decl_ref.id()); HasChanges::Yes @@ -339,7 +340,7 @@ impl SubstTypes for TyTraitDecl { TyTraitItem::Type(item_ref) => { if let Some(new_decl_ref) = item_ref .clone() - .subst_types_and_insert_new_with_parent(type_mapping, ctx) + .subst_types_and_insert_new_with_parent(ctx) { item_ref.replace_id(*new_decl_ref.id()); HasChanges::Yes @@ -353,11 +354,11 @@ impl SubstTypes for TyTraitDecl { } impl SubstTypes for TyTraitItem { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { match self { - TyTraitItem::Fn(fn_decl) => fn_decl.subst(type_mapping, ctx), - TyTraitItem::Constant(const_decl) => const_decl.subst(type_mapping, ctx), - TyTraitItem::Type(type_decl) => type_decl.subst(type_mapping, ctx), + TyTraitItem::Fn(fn_decl) => fn_decl.subst(ctx), + TyTraitItem::Constant(const_decl) => const_decl.subst(ctx), + TyTraitItem::Type(type_decl) => type_decl.subst(ctx), } } } diff --git a/sway-core/src/language/ty/declaration/trait_fn.rs b/sway-core/src/language/ty/declaration/trait_fn.rs index ebadf1da7b6..d9572af179f 100644 --- a/sway-core/src/language/ty/declaration/trait_fn.rs +++ b/sway-core/src/language/ty/declaration/trait_fn.rs @@ -3,13 +3,13 @@ use std::{ hash::{Hash, Hasher}, }; +use monomorphization::MonomorphizeHelper; use sway_types::{Ident, Named, Span, Spanned}; use crate::{ engine_threading::*, has_changes, language::{parsed::TraitFn, ty::*, Purity}, - semantic_analysis::type_check_context::MonomorphizeHelper, transform, type_system::*, }; @@ -122,10 +122,10 @@ impl HashWithEngines for TyTraitFn { } impl SubstTypes for TyTraitFn { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { has_changes! { - self.parameters.subst(type_mapping, ctx); - self.return_type.subst(type_mapping, ctx); + self.parameters.subst(ctx); + self.return_type.subst(ctx); } } } diff --git a/sway-core/src/language/ty/declaration/trait_type.rs b/sway-core/src/language/ty/declaration/trait_type.rs index c87df54aab8..24925afa457 100644 --- a/sway-core/src/language/ty/declaration/trait_type.rs +++ b/sway-core/src/language/ty/declaration/trait_type.rs @@ -74,10 +74,10 @@ impl HashWithEngines for TyTraitType { } impl SubstTypes for TyTraitType { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { has_changes! { - self.ty.subst(type_mapping, ctx); - self.implementing_type.subst(type_mapping, ctx); + self.ty.subst(ctx); + self.implementing_type.subst(ctx); } } } diff --git a/sway-core/src/language/ty/declaration/type_alias.rs b/sway-core/src/language/ty/declaration/type_alias.rs index a6df20ca594..e2e5844de3f 100644 --- a/sway-core/src/language/ty/declaration/type_alias.rs +++ b/sway-core/src/language/ty/declaration/type_alias.rs @@ -57,8 +57,8 @@ impl HashWithEngines for TyTypeAliasDecl { } impl SubstTypes for TyTypeAliasDecl { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { - self.ty.subst(type_mapping, ctx) + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { + self.ty.subst(ctx) } } diff --git a/sway-core/src/language/ty/declaration/variable.rs b/sway-core/src/language/ty/declaration/variable.rs index e19a4fb30a8..d7eb80ad7c6 100644 --- a/sway-core/src/language/ty/declaration/variable.rs +++ b/sway-core/src/language/ty/declaration/variable.rs @@ -66,9 +66,9 @@ impl HashWithEngines for TyVariableDecl { } impl SubstTypes for TyVariableDecl { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { - self.return_type.subst(type_mapping, ctx); - self.type_ascription.subst(type_mapping, ctx); - self.body.subst(type_mapping, ctx) + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { + self.return_type.subst(ctx); + self.type_ascription.subst(ctx); + self.body.subst(ctx) } } diff --git a/sway-core/src/language/ty/expression/asm.rs b/sway-core/src/language/ty/expression/asm.rs index 874948ad626..04944125258 100644 --- a/sway-core/src/language/ty/expression/asm.rs +++ b/sway-core/src/language/ty/expression/asm.rs @@ -32,7 +32,7 @@ impl HashWithEngines for TyAsmRegisterDeclaration { } impl SubstTypes for TyAsmRegisterDeclaration { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { - self.initializer.subst(type_mapping, ctx) + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { + self.initializer.subst(ctx) } } diff --git a/sway-core/src/language/ty/expression/expression.rs b/sway-core/src/language/ty/expression/expression.rs index e4fc0fcda07..15f57369007 100644 --- a/sway-core/src/language/ty/expression/expression.rs +++ b/sway-core/src/language/ty/expression/expression.rs @@ -56,10 +56,10 @@ impl HashWithEngines for TyExpression { } impl SubstTypes for TyExpression { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { has_changes! { - self.return_type.subst(type_mapping, ctx); - self.expression.subst(type_mapping, ctx); + self.return_type.subst(ctx); + self.expression.subst(ctx); } } } diff --git a/sway-core/src/language/ty/expression/expression_variant.rs b/sway-core/src/language/ty/expression/expression_variant.rs index a71ba25c592..9908bb09f5b 100644 --- a/sway-core/src/language/ty/expression/expression_variant.rs +++ b/sway-core/src/language/ty/expression/expression_variant.rs @@ -649,7 +649,7 @@ impl HashWithEngines for TyExpressionVariant { } impl SubstTypes for TyExpressionVariant { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { use TyExpressionVariant::*; match self { Literal(..) => HasChanges::No, @@ -659,36 +659,36 @@ impl SubstTypes for TyExpressionVariant { ref mut call_path_typeid, .. } => has_changes! { - arguments.subst(type_mapping, ctx); + arguments.subst(ctx); if let Some(new_decl_ref) = fn_ref .clone() - .subst_types_and_insert_new_with_parent(type_mapping, ctx) + .subst_types_and_insert_new_with_parent(ctx) { fn_ref.replace_id(*new_decl_ref.id()); HasChanges::Yes } else { HasChanges::No }; - call_path_typeid.subst(type_mapping, ctx); + call_path_typeid.subst(ctx); }, LazyOperator { lhs, rhs, .. } => has_changes! { - lhs.subst(type_mapping, ctx); - rhs.subst(type_mapping, ctx); + lhs.subst(ctx); + rhs.subst(ctx); }, - ConstantExpression { decl, .. } => decl.subst(type_mapping, ctx), - ConfigurableExpression { decl, .. } => decl.subst(type_mapping, ctx), + ConstantExpression { decl, .. } => decl.subst(ctx), + ConfigurableExpression { decl, .. } => decl.subst(ctx), VariableExpression { .. } => HasChanges::No, - Tuple { fields } => fields.subst(type_mapping, ctx), + Tuple { fields } => fields.subst(ctx), Array { ref mut elem_type, contents, } => has_changes! { - elem_type.subst(type_mapping, ctx); - contents.subst(type_mapping, ctx); + elem_type.subst(ctx); + contents.subst(ctx); }, ArrayIndex { prefix, index } => has_changes! { - prefix.subst(type_mapping, ctx); - index.subst(type_mapping, ctx); + prefix.subst(ctx); + index.subst(ctx); }, StructExpression { struct_id, @@ -698,30 +698,30 @@ impl SubstTypes for TyExpressionVariant { } => has_changes! { if let Some(new_struct_ref) = struct_id .clone() - .subst_types_and_insert_new(type_mapping, ctx) { + .subst_types_and_insert_new(ctx) { struct_id.replace_id(*new_struct_ref.id()); HasChanges::Yes } else { HasChanges::No }; - fields.subst(type_mapping, ctx); + fields.subst(ctx); }, - CodeBlock(block) => block.subst(type_mapping, ctx), + CodeBlock(block) => block.subst(ctx), FunctionParameter => HasChanges::No, - MatchExp { desugared, .. } => desugared.subst(type_mapping, ctx), + MatchExp { desugared, .. } => desugared.subst(ctx), IfExp { condition, then, r#else, } => has_changes! { - condition.subst(type_mapping, ctx); - then.subst(type_mapping, ctx); - r#else.subst(type_mapping, ctx); + condition.subst(ctx); + then.subst(ctx); + r#else.subst(ctx); }, AsmExpression { registers, //: Vec, .. - } => registers.subst(type_mapping, ctx), + } => registers.subst(ctx), // like a variable expression but it has multiple parts, // like looking up a field in a struct StructFieldAccess { @@ -730,59 +730,59 @@ impl SubstTypes for TyExpressionVariant { ref mut resolved_type_of_parent, .. } => has_changes! { - resolved_type_of_parent.subst(type_mapping, ctx); - field_to_access.subst(type_mapping, ctx); - prefix.subst(type_mapping, ctx); + resolved_type_of_parent.subst(ctx); + field_to_access.subst(ctx); + prefix.subst(ctx); }, TupleElemAccess { prefix, ref mut resolved_type_of_parent, .. } => has_changes! { - resolved_type_of_parent.subst(type_mapping, ctx); - prefix.subst(type_mapping, ctx); + resolved_type_of_parent.subst(ctx); + prefix.subst(ctx); }, EnumInstantiation { enum_ref, contents, .. } => has_changes! { if let Some(new_enum_ref) = enum_ref .clone() - .subst_types_and_insert_new(type_mapping, ctx) + .subst_types_and_insert_new(ctx) { enum_ref.replace_id(*new_enum_ref.id()); HasChanges::Yes } else { HasChanges::No }; - contents.subst(type_mapping, ctx); + contents.subst(ctx); }, - AbiCast { address, .. } => address.subst(type_mapping, ctx), + AbiCast { address, .. } => address.subst(ctx), // storage is never generic and cannot be monomorphized StorageAccess { .. } => HasChanges::No, - IntrinsicFunction(kind) => kind.subst(type_mapping, ctx), - EnumTag { exp } => exp.subst(type_mapping, ctx), + IntrinsicFunction(kind) => kind.subst(ctx), + EnumTag { exp } => exp.subst(ctx), UnsafeDowncast { exp, variant, call_path_decl: _, } => has_changes! { - exp.subst(type_mapping, ctx); - variant.subst(type_mapping, ctx); + exp.subst(ctx); + variant.subst(ctx); }, AbiName(_) => HasChanges::No, WhileLoop { ref mut condition, ref mut body, } => { - condition.subst(type_mapping, ctx); - body.subst(type_mapping, ctx) + condition.subst(ctx); + body.subst(ctx) } - ForLoop { ref mut desugared } => desugared.subst(type_mapping, ctx), + ForLoop { ref mut desugared } => desugared.subst(ctx), Break => HasChanges::No, Continue => HasChanges::No, - Reassignment(reassignment) => reassignment.subst(type_mapping, ctx), - ImplicitReturn(expr) | Return(expr) => expr.subst(type_mapping, ctx), - Ref(exp) | Deref(exp) => exp.subst(type_mapping, ctx), + Reassignment(reassignment) => reassignment.subst(ctx), + ImplicitReturn(expr) | Return(expr) => expr.subst(ctx), + Ref(exp) | Deref(exp) => exp.subst(ctx), } } } diff --git a/sway-core/src/language/ty/expression/intrinsic_function.rs b/sway-core/src/language/ty/expression/intrinsic_function.rs index 081eeda7682..4fb4e72c3bc 100644 --- a/sway-core/src/language/ty/expression/intrinsic_function.rs +++ b/sway-core/src/language/ty/expression/intrinsic_function.rs @@ -73,10 +73,10 @@ impl HashWithEngines for TyIntrinsicFunctionKind { } impl SubstTypes for TyIntrinsicFunctionKind { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { has_changes! { - self.arguments.subst(type_mapping, ctx); - self.type_arguments.subst(type_mapping, ctx); + self.arguments.subst(ctx); + self.type_arguments.subst(ctx); } } } diff --git a/sway-core/src/language/ty/expression/reassignment.rs b/sway-core/src/language/ty/expression/reassignment.rs index 5d50e93eed2..358855a0102 100644 --- a/sway-core/src/language/ty/expression/reassignment.rs +++ b/sway-core/src/language/ty/expression/reassignment.rs @@ -114,14 +114,14 @@ impl HashWithEngines for TyReassignment { } impl SubstTypes for TyReassignmentTarget { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { has_changes! { match self { - TyReassignmentTarget::Deref(exp) => exp.subst(type_mapping, ctx), + TyReassignmentTarget::Deref(exp) => exp.subst(ctx), TyReassignmentTarget::ElementAccess { base_type, indices, .. } => { has_changes! { - base_type.subst(type_mapping, ctx); - indices.subst(type_mapping, ctx); + base_type.subst(ctx); + indices.subst(ctx); } } }; @@ -130,10 +130,10 @@ impl SubstTypes for TyReassignmentTarget { } impl SubstTypes for TyReassignment { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { has_changes! { - self.lhs.subst(type_mapping, ctx); - self.rhs.subst(type_mapping, ctx); + self.lhs.subst(ctx); + self.rhs.subst(ctx); } } } @@ -330,10 +330,10 @@ impl HashWithEngines for ProjectionKind { } impl SubstTypes for ProjectionKind { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { use ProjectionKind::*; match self { - ArrayIndex { index, .. } => index.subst(type_mapping, ctx), + ArrayIndex { index, .. } => index.subst(ctx), _ => HasChanges::No, } } diff --git a/sway-core/src/language/ty/expression/struct_exp_field.rs b/sway-core/src/language/ty/expression/struct_exp_field.rs index 103cdbaa9c7..5f879640fb3 100644 --- a/sway-core/src/language/ty/expression/struct_exp_field.rs +++ b/sway-core/src/language/ty/expression/struct_exp_field.rs @@ -33,8 +33,8 @@ impl HashWithEngines for TyStructExpressionField { } impl SubstTypes for TyStructExpressionField { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { - self.value.subst(type_mapping, ctx) + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { + self.value.subst(ctx) } } diff --git a/sway-core/src/semantic_analysis.rs b/sway-core/src/semantic_analysis.rs index 2d3bcdcc6c3..a1eb9a7f8c8 100644 --- a/sway-core/src/semantic_analysis.rs +++ b/sway-core/src/semantic_analysis.rs @@ -12,6 +12,7 @@ pub mod symbol_resolve_context; mod type_check_analysis; pub(crate) mod type_check_context; mod type_check_finalization; +pub(crate) mod type_resolve; pub use ast_node::*; pub use namespace::Namespace; pub(crate) use type_check_analysis::*; diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/configurable.rs b/sway-core/src/semantic_analysis/ast_node/declaration/configurable.rs index 3702214d9dd..6c9f5e7f404 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/configurable.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/configurable.rs @@ -17,8 +17,8 @@ use crate::{ ty::{self, TyConfigurableDecl, TyExpression}, CallPath, }, - semantic_analysis::{type_check_context::EnforceTypeArguments, *}, - Engines, SubstTypes, SubstTypesContext, TypeArgument, TypeBinding, TypeCheckTypeBinding, + semantic_analysis::*, + EnforceTypeArguments, Engines, SubstTypes, TypeArgument, TypeBinding, TypeCheckTypeBinding, TypeInfo, }; @@ -71,10 +71,7 @@ impl ty::TyConfigurableDecl { .unwrap_or_else(|err| type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None)); // this subst is required to replace associated types, namely TypeInfo::TraitType. - type_ascription.type_id.subst( - &ctx.type_subst(), - &SubstTypesContext::new(engines, !ctx.code_block_first_pass()), - ); + type_ascription.type_id.subst(&ctx.subst_ctx()); if !is_screaming_snake_case(name.as_str()) { handler.emit_warn(CompileWarning { diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/constant.rs b/sway-core/src/semantic_analysis/ast_node/declaration/constant.rs index 63ad0a9bbb7..e5cca67ecde 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/constant.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/constant.rs @@ -12,8 +12,8 @@ use crate::{ ty::{self, TyConstantDecl, TyExpression}, CallPath, }, - semantic_analysis::{type_check_context::EnforceTypeArguments, *}, - Engines, SubstTypes, SubstTypesContext, TypeInfo, + semantic_analysis::*, + EnforceTypeArguments, Engines, SubstTypes, TypeInfo, }; impl ty::TyConstantDecl { @@ -64,10 +64,7 @@ impl ty::TyConstantDecl { .unwrap_or_else(|err| type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None)); // this subst is required to replace associated types, namely TypeInfo::TraitType. - type_ascription.type_id.subst( - &ctx.type_subst(), - &SubstTypesContext::new(engines, !ctx.code_block_first_pass()), - ); + type_ascription.type_id.subst(&ctx.subst_ctx()); if !is_screaming_snake_case(name.as_str()) { handler.emit_warn(CompileWarning { diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/declaration.rs b/sway-core/src/semantic_analysis/ast_node/declaration/declaration.rs index 34f48f85491..663891261bd 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/declaration.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/declaration.rs @@ -14,10 +14,9 @@ use crate::{ }, namespace::{IsExtendingExistingImpl, IsImplSelf}, semantic_analysis::{ - symbol_collection_context::SymbolCollectionContext, - type_check_context::EnforceTypeArguments, ConstShadowingMode, GenericShadowingMode, - TypeCheckAnalysis, TypeCheckAnalysisContext, TypeCheckContext, TypeCheckFinalization, - TypeCheckFinalizationContext, + symbol_collection_context::SymbolCollectionContext, ConstShadowingMode, + GenericShadowingMode, TypeCheckAnalysis, TypeCheckAnalysisContext, TypeCheckContext, + TypeCheckFinalization, TypeCheckFinalizationContext, }, type_system::*, Engines, diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs b/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs index 7dc878e858f..58f69e92c93 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs @@ -1,7 +1,7 @@ use crate::{ decl_engine::parsed_id::ParsedDeclId, language::{parsed::*, ty, CallPath}, - semantic_analysis::{type_check_context::EnforceTypeArguments, *}, + semantic_analysis::*, type_system::*, Engines, }; diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/function.rs b/sway-core/src/semantic_analysis/ast_node/declaration/function.rs index 7ce58ac20cb..52ede5c3343 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/function.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/function.rs @@ -14,7 +14,7 @@ use crate::{ ty::{self, TyCodeBlock, TyFunctionDecl}, CallPath, Visibility, }, - semantic_analysis::{type_check_context::EnforceTypeArguments, *}, + semantic_analysis::*, type_system::*, Engines, }; diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/function/function_parameter.rs b/sway-core/src/semantic_analysis/ast_node/declaration/function/function_parameter.rs index f32fdfa4c31..00b7cb87a77 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/function/function_parameter.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/function/function_parameter.rs @@ -1,6 +1,6 @@ use crate::{ language::{parsed::FunctionParameter, ty}, - semantic_analysis::{type_check_context::EnforceTypeArguments, TypeCheckContext}, + semantic_analysis::TypeCheckContext, type_system::*, }; diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs b/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs index f47a6c055cc..033fe5cff9b 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs @@ -23,8 +23,7 @@ use crate::{ }, namespace::{IsExtendingExistingImpl, IsImplSelf, TryInsertingTraitImplOnFailure}, semantic_analysis::{ - symbol_collection_context::SymbolCollectionContext, - type_check_context::EnforceTypeArguments, AbiMode, ConstShadowingMode, + symbol_collection_context::SymbolCollectionContext, AbiMode, ConstShadowingMode, TyNodeDepGraphNodeId, TypeCheckAnalysis, TypeCheckAnalysisContext, TypeCheckContext, TypeCheckFinalization, TypeCheckFinalizationContext, }, @@ -840,10 +839,11 @@ fn type_check_trait_implementation( ty::TyTraitType::error(ctx.engines(), type_decl.as_ref().clone()) }); - type_decl.subst( + type_decl.subst(&SubstTypesContext::new( + engines, &trait_type_mapping, - &SubstTypesContext::new(engines, !ctx.code_block_first_pass()), - ); + !ctx.code_block_first_pass(), + )); // Remove this type from the checklist. let name = type_decl.name.clone(); @@ -914,10 +914,11 @@ fn type_check_trait_implementation( ) .unwrap_or_else(|_| ty::TyFunctionDecl::error(&impl_method)); - impl_method.subst( + impl_method.subst(&SubstTypesContext::new( + engines, &trait_type_mapping, - &SubstTypesContext::new(engines, !ctx.code_block_first_pass()), - ); + !ctx.code_block_first_pass(), + )); // Remove this method from the checklist. let name = impl_method.name.clone(); @@ -940,10 +941,11 @@ fn type_check_trait_implementation( ) .unwrap_or_else(|_| ty::TyConstantDecl::error(ctx.engines(), const_decl.clone())); - const_decl.subst( + const_decl.subst(&SubstTypesContext::new( + engines, &trait_type_mapping, - &SubstTypesContext::new(engines, !ctx.code_block_first_pass()), - ); + !ctx.code_block_first_pass(), + )); // Remove this constant from the checklist. let name = const_decl.call_path.suffix.clone(); @@ -1013,10 +1015,11 @@ fn type_check_trait_implementation( method.implementing_for_typeid = Some(implementing_for); method.replace_decls(&decl_mapping, handler, &mut ctx)?; - method.subst( - &type_mapping, - &SubstTypesContext::new(engines, !ctx.code_block_first_pass()), - ); + method.subst(&SubstTypesContext::new( + engines, + &trait_type_mapping, + !ctx.code_block_first_pass(), + )); all_items_refs.push(TyImplItem::Fn( decl_engine .insert( @@ -1029,10 +1032,11 @@ fn type_check_trait_implementation( TyImplItem::Constant(decl_ref) => { let mut const_decl = (*decl_engine.get_constant(decl_ref)).clone(); const_decl.replace_decls(&decl_mapping, handler, &mut ctx)?; - const_decl.subst( - &type_mapping, - &SubstTypesContext::new(engines, !ctx.code_block_first_pass()), - ); + const_decl.subst(&SubstTypesContext::new( + engines, + &trait_type_mapping, + !ctx.code_block_first_pass(), + )); all_items_refs.push(TyImplItem::Constant(decl_engine.insert( const_decl, decl_engine.get_parsed_decl_id(decl_ref.id()).as_ref(), @@ -1040,10 +1044,11 @@ fn type_check_trait_implementation( } TyImplItem::Type(decl_ref) => { let mut type_decl = (*decl_engine.get_type(decl_ref)).clone(); - type_decl.subst( - &type_mapping, - &SubstTypesContext::new(engines, !ctx.code_block_first_pass()), - ); + type_decl.subst(&SubstTypesContext::new( + engines, + &trait_type_mapping, + !ctx.code_block_first_pass(), + )); all_items_refs.push(TyImplItem::Type(decl_engine.insert( type_decl.clone(), decl_engine.get_parsed_decl_id(decl_ref.id()).as_ref(), @@ -1186,17 +1191,11 @@ fn type_check_impl_method( // this subst is required to replace associated types, namely TypeInfo::TraitType. let mut impl_method_param_type_id = impl_method_param.type_argument.type_id; - impl_method_param_type_id.subst( - &ctx.type_subst(), - &SubstTypesContext::new(engines, !ctx.code_block_first_pass()), - ); + impl_method_param_type_id.subst(&ctx.subst_ctx()); let mut impl_method_signature_param_type_id = impl_method_signature_param.type_argument.type_id; - impl_method_signature_param_type_id.subst( - &ctx.type_subst(), - &SubstTypesContext::new(engines, !ctx.code_block_first_pass()), - ); + impl_method_signature_param_type_id.subst(&ctx.subst_ctx()); if !UnifyCheck::non_dynamic_equality(engines).check( impl_method_param_type_id, @@ -1266,17 +1265,11 @@ fn type_check_impl_method( // this subst is required to replace associated types, namely TypeInfo::TraitType. let mut impl_method_return_type_id = impl_method.return_type.type_id; - impl_method_return_type_id.subst( - &ctx.type_subst(), - &SubstTypesContext::new(engines, !ctx.code_block_first_pass()), - ); + impl_method_return_type_id.subst(&ctx.subst_ctx()); let mut impl_method_signature_return_type_type_id = impl_method_signature.return_type.type_id; - impl_method_signature_return_type_type_id.subst( - &ctx.type_subst(), - &SubstTypesContext::new(engines, !ctx.code_block_first_pass()), - ); + impl_method_signature_return_type_type_id.subst(&ctx.subst_ctx()); if !UnifyCheck::non_dynamic_equality(engines).check( impl_method_return_type_id, @@ -1382,16 +1375,10 @@ fn type_check_const_decl( // this subst is required to replace associated types, namely TypeInfo::TraitType. let mut const_decl_type_id = const_decl.type_ascription.type_id; - const_decl_type_id.subst( - &ctx.type_subst(), - &SubstTypesContext::new(engines, !ctx.code_block_first_pass()), - ); + const_decl_type_id.subst(&ctx.subst_ctx()); let mut const_decl_signature_type_id = const_decl_signature.type_ascription.type_id; - const_decl_signature_type_id.subst( - &ctx.type_subst(), - &SubstTypesContext::new(engines, !ctx.code_block_first_pass()), - ); + const_decl_signature_type_id.subst(&ctx.subst_ctx()); // unify the types from the constant with the constant signature if !UnifyCheck::non_dynamic_equality(engines) diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs b/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs index 77688776b3b..0716c8f4e52 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs @@ -1,7 +1,7 @@ use crate::{ decl_engine::parsed_id::ParsedDeclId, language::{parsed::*, ty, CallPath}, - semantic_analysis::{type_check_context::EnforceTypeArguments, *}, + semantic_analysis::*, type_system::*, Engines, }; diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/supertrait.rs b/sway-core/src/semantic_analysis/ast_node/declaration/supertrait.rs index 83b9ca9ff7f..d74932eea9e 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/supertrait.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/supertrait.rs @@ -2,7 +2,7 @@ use sway_error::error::CompileError; use sway_error::handler::{ErrorEmitted, Handler}; use sway_types::{Span, Spanned}; -use crate::semantic_analysis::type_check_context::EnforceTypeArguments; +use crate::EnforceTypeArguments; use crate::{ language::{parsed, ty}, semantic_analysis::TypeCheckContext, diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs b/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs index 6beb4ea7f4f..9a0ed2942eb 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs @@ -411,10 +411,11 @@ impl TyTraitDecl { let mut method = (*decl_engine.get_function(&decl_ref)).clone(); let name = method.name.clone(); let r = if method - .subst( + .subst(&SubstTypesContext::new( + engines, &type_mapping, - &SubstTypesContext::new(engines, !ctx.code_block_first_pass()), - ) + !ctx.code_block_first_pass(), + )) .has_changes() { let new_ref = decl_engine @@ -433,10 +434,11 @@ impl TyTraitDecl { let mut const_decl = (*decl_engine.get_constant(&decl_ref)).clone(); let name = const_decl.call_path.suffix.clone(); let r = if const_decl - .subst( + .subst(&SubstTypesContext::new( + engines, &type_mapping, - &SubstTypesContext::new(engines, !ctx.code_block_first_pass()), - ) + !ctx.code_block_first_pass(), + )) .has_changes() { decl_engine.insert( @@ -452,10 +454,11 @@ impl TyTraitDecl { let mut t = (*decl_engine.get_type(&decl_ref)).clone(); let name = t.name.clone(); let r = if t - .subst( + .subst(&SubstTypesContext::new( + engines, &type_mapping, - &SubstTypesContext::new(engines, !ctx.code_block_first_pass()), - ) + !ctx.code_block_first_pass(), + )) .has_changes() { decl_engine @@ -509,10 +512,11 @@ impl TyTraitDecl { match item { ty::TyTraitInterfaceItem::TraitFn(decl_ref) => { let mut method = (*decl_engine.get_trait_fn(decl_ref)).clone(); - method.subst( + method.subst(&SubstTypesContext::new( + engines, &type_mapping, - &SubstTypesContext::new(engines, !ctx.code_block_first_pass()), - ); + !ctx.code_block_first_pass(), + )); all_items.push(TyImplItem::Fn( decl_engine .insert(method.to_dummy_func(AbiMode::NonAbi, Some(type_id)), None) @@ -540,10 +544,11 @@ impl TyTraitDecl { match item { ty::TyTraitItem::Fn(decl_ref) => { let mut method = (*decl_engine.get_function(decl_ref)).clone(); - method.subst( + method.subst(&SubstTypesContext::new( + engines, &type_mapping, - &SubstTypesContext::new(engines, !ctx.code_block_first_pass()), - ); + !ctx.code_block_first_pass(), + )); all_items.push(TyImplItem::Fn( ctx.engines .de() @@ -556,10 +561,11 @@ impl TyTraitDecl { } ty::TyTraitItem::Constant(decl_ref) => { let mut const_decl = (*decl_engine.get_constant(decl_ref)).clone(); - const_decl.subst( + const_decl.subst(&SubstTypesContext::new( + engines, &type_mapping, - &SubstTypesContext::new(engines, !ctx.code_block_first_pass()), - ); + !ctx.code_block_first_pass(), + )); all_items.push(TyImplItem::Constant(decl_engine.insert( const_decl, decl_engine.get_parsed_decl_id(decl_ref.id()).as_ref(), @@ -567,10 +573,11 @@ impl TyTraitDecl { } ty::TyTraitItem::Type(decl_ref) => { let mut type_decl = (*decl_engine.get_type(decl_ref)).clone(); - type_decl.subst( + type_decl.subst(&SubstTypesContext::new( + engines, &type_mapping, - &SubstTypesContext::new(engines, !ctx.code_block_first_pass()), - ); + !ctx.code_block_first_pass(), + )); all_items.push(TyImplItem::Type(decl_engine.insert( type_decl, decl_engine.get_parsed_decl_id(decl_ref.id()).as_ref(), diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/trait_fn.rs b/sway-core/src/semantic_analysis/ast_node/declaration/trait_fn.rs index e6b45f08919..07bd2feee81 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/trait_fn.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/trait_fn.rs @@ -6,10 +6,7 @@ use crate::{ parsed::{self, Declaration, TraitFn}, ty, CallPath, Visibility, }, - semantic_analysis::{ - symbol_collection_context::SymbolCollectionContext, - type_check_context::EnforceTypeArguments, - }, + semantic_analysis::symbol_collection_context::SymbolCollectionContext, Engines, }; use sway_error::handler::{ErrorEmitted, Handler}; diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/trait_type.rs b/sway-core/src/semantic_analysis/ast_node/declaration/trait_type.rs index c387ecdb27b..937404b3f47 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/trait_type.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/trait_type.rs @@ -11,9 +11,8 @@ use crate::{ ty::{self, TyTraitType}, }, semantic_analysis::{ - symbol_collection_context::SymbolCollectionContext, - type_check_context::EnforceTypeArguments, TypeCheckAnalysis, TypeCheckAnalysisContext, - TypeCheckContext, + symbol_collection_context::SymbolCollectionContext, TypeCheckAnalysis, + TypeCheckAnalysisContext, TypeCheckContext, }, type_system::*, Engines, diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/variable.rs b/sway-core/src/semantic_analysis/ast_node/declaration/variable.rs index 32dccb078db..3d69fb65aab 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/variable.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/variable.rs @@ -5,7 +5,7 @@ use crate::{ ty::{self, TyExpression, TyVariableDecl}, }, namespace::ResolvedDeclaration, - semantic_analysis::{type_check_context::EnforceTypeArguments, *}, + semantic_analysis::*, type_system::*, Engines, }; 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 c220ef33c1e..46e46276f25 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 @@ -13,7 +13,7 @@ use crate::{ ty::{self, TyIntrinsicFunctionKind}, Literal, }, - semantic_analysis::{type_check_context::EnforceTypeArguments, TypeCheckContext}, + semantic_analysis::TypeCheckContext, type_system::*, }; diff --git a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_scrutinee.rs b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_scrutinee.rs index 12ac36c44a6..fddb0ee7b21 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_scrutinee.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_scrutinee.rs @@ -12,10 +12,7 @@ use crate::{ ty::{self, StructAccessInfo, TyDecl, TyScrutinee, TyStructDecl, TyStructField}, CallPath, }, - semantic_analysis::{ - type_check_context::EnforceTypeArguments, TypeCheckContext, TypeCheckFinalization, - TypeCheckFinalizationContext, - }, + semantic_analysis::{TypeCheckContext, TypeCheckFinalization, TypeCheckFinalizationContext}, type_system::*, }; diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs index 24af43873ff..dd4a14f0b74 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs @@ -29,7 +29,7 @@ use crate::{ *, }, namespace::{IsExtendingExistingImpl, IsImplSelf}, - semantic_analysis::{expression::ReachableReport, type_check_context::EnforceTypeArguments, *}, + semantic_analysis::{expression::ReachableReport, *}, transform::to_parsed_lang::type_name_to_type_info_opt, type_system::*, Engines, diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs index 68de3f5f79e..7fb6d3eaff6 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs @@ -9,7 +9,7 @@ use crate::{ *, }, namespace::TryInsertingTraitImplOnFailure, - semantic_analysis::{type_check_context::EnforceTypeArguments, *}, + semantic_analysis::*, type_system::*, }; use ast_node::typed_expression::check_function_arguments_arity; @@ -659,10 +659,11 @@ pub(crate) fn type_check_method_application( vec![t.initial_type_id], vec![call_path_typeid], ); - method.subst( + method.subst(&SubstTypesContext::new( + engines, &type_subst, - &SubstTypesContext::new(engines, !ctx.code_block_first_pass()), - ); + !ctx.code_block_first_pass(), + )); } } } diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_instantiation.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_instantiation.rs index 11b1495bdc4..23ff00f7894 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_instantiation.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_instantiation.rs @@ -15,9 +15,7 @@ use crate::{ CallPath, Visibility, }, namespace::ResolvedTraitImplItem, - semantic_analysis::{ - type_check_context::EnforceTypeArguments, GenericShadowingMode, TypeCheckContext, - }, + semantic_analysis::{GenericShadowingMode, TypeCheckContext}, type_system::*, Engines, Namespace, }; diff --git a/sway-core/src/semantic_analysis/namespace/lexical_scope.rs b/sway-core/src/semantic_analysis/namespace/lexical_scope.rs index 0a85f6a3f4c..62203b13dda 100644 --- a/sway-core/src/semantic_analysis/namespace/lexical_scope.rs +++ b/sway-core/src/semantic_analysis/namespace/lexical_scope.rs @@ -18,7 +18,7 @@ use sway_error::{ error::{CompileError, ShadowingSource, StructFieldUsageContext}, handler::{ErrorEmitted, Handler}, }; -use sway_types::{span::Span, IdentUnique, Spanned}; +use sway_types::{span::Span, IdentUnique, Named, Spanned}; use std::sync::Arc; @@ -156,6 +156,50 @@ impl Items { self.symbols().keys() } + pub fn resolve_symbol( + &self, + handler: &Handler, + engines: &Engines, + symbol: &Ident, + ) -> Result { + // Check locally declared items. Any name clash with imports will have already been reported as an error. + if let Some(decl) = self.symbols.get(symbol) { + return Ok(decl.clone()); + } + + // Check item imports + if let Some((_, _, decl, _)) = self.use_item_synonyms.get(symbol) { + return Ok(decl.clone()); + } + + // Check glob imports + if let Some(decls) = self.use_glob_synonyms.get(symbol) { + if decls.len() == 1 { + return Ok(decls[0].1.clone()); + } else if decls.is_empty() { + return Err(handler.emit_err(CompileError::Internal( + "The name {symbol} was bound in a star import, but no corresponding module paths were found", + symbol.span(), + ))); + } else { + return Err(handler.emit_err(CompileError::SymbolWithMultipleBindings { + name: symbol.clone(), + paths: decls + .iter() + .map(|(path, decl, _)| get_path_for_decl(path, decl, engines)) + .collect(), + span: symbol.span(), + })); + } + } + + // Symbol not found + Err(handler.emit_err(CompileError::SymbolNotFound { + name: symbol.clone(), + span: symbol.span(), + })) + } + pub(crate) fn insert_parsed_symbol( &mut self, handler: &Handler, @@ -946,3 +990,26 @@ impl Items { Ok((symbol, parent_rover)) } } + +fn get_path_for_decl( + path: &[sway_types::BaseIdent], + decl: &ResolvedDeclaration, + engines: &Engines, +) -> String { + let mut path_names = path.iter().map(|x| x.to_string()).collect::>(); + // Add the enum name to the path if the decl is an enum variant. + match decl { + ResolvedDeclaration::Parsed(decl) => { + if let Declaration::EnumVariantDeclaration(decl) = decl { + let enum_decl = engines.pe().get_enum(&decl.enum_ref); + path_names.push(enum_decl.name().to_string()) + }; + } + ResolvedDeclaration::Typed(decl) => { + if let TyDecl::EnumVariantDecl(ty::EnumVariantDecl { enum_ref, .. }) = decl { + path_names.push(enum_ref.name().to_string()) + }; + } + } + path_names.join("::") +} diff --git a/sway-core/src/semantic_analysis/namespace/module.rs b/sway-core/src/semantic_analysis/namespace/module.rs index 36f14f2050f..77aa192b3be 100644 --- a/sway-core/src/semantic_analysis/namespace/module.rs +++ b/sway-core/src/semantic_analysis/namespace/module.rs @@ -203,6 +203,18 @@ impl Module { } } + /// Returns the root lexical scope id associated with this module. + pub fn root_lexical_scope_id(&self) -> LexicalScopeId { + 0 + } + + /// Returns the root lexical scope associated with this module. + pub fn root_lexical_scope(&self) -> &LexicalScope { + self.lexical_scopes + .get(self.root_lexical_scope_id()) + .unwrap() + } + /// Returns the current lexical scope associated with this module. pub fn current_lexical_scope(&self) -> &LexicalScope { self.lexical_scopes diff --git a/sway-core/src/semantic_analysis/namespace/root.rs b/sway-core/src/semantic_analysis/namespace/root.rs index 020c5e19111..73a57a5203b 100644 --- a/sway-core/src/semantic_analysis/namespace/root.rs +++ b/sway-core/src/semantic_analysis/namespace/root.rs @@ -18,7 +18,7 @@ use sway_error::{ error::CompileError, handler::{ErrorEmitted, Handler}, }; -use sway_types::{Named, Spanned}; +use sway_types::Spanned; use sway_utils::iter_prefixes; #[derive(Clone, Debug)] @@ -859,8 +859,12 @@ impl Root { current_mod_path.push(ident.clone()); } None => { - decl_opt = - Some(self.resolve_symbol_helper(handler, engines, ident, module)?); + decl_opt = Some( + module + .current_lexical_scope() + .items + .resolve_symbol(handler, engines, ident)?, + ); } } } @@ -874,7 +878,10 @@ impl Root { self.module .lookup_submodule(handler, engines, mod_path) .and_then(|module| { - let decl = self.resolve_symbol_helper(handler, engines, symbol, module)?; + let decl = module + .current_lexical_scope() + .items + .resolve_symbol(handler, engines, symbol)?; Ok((decl, mod_path.to_vec())) }) } @@ -1008,70 +1015,6 @@ impl Root { }, } } - - fn resolve_symbol_helper( - &self, - handler: &Handler, - engines: &Engines, - symbol: &Ident, - module: &Module, - ) -> Result { - // Check locally declared items. Any name clash with imports will have already been reported as an error. - if let Some(decl) = module.current_items().symbols.get(symbol) { - return Ok(decl.clone()); - } - // Check item imports - if let Some((_, _, decl, _)) = module.current_items().use_item_synonyms.get(symbol) { - return Ok(decl.clone()); - } - // Check glob imports - if let Some(decls) = module.current_items().use_glob_synonyms.get(symbol) { - if decls.len() == 1 { - return Ok(decls[0].1.clone()); - } else if decls.is_empty() { - return Err(handler.emit_err(CompileError::Internal( - "The name {symbol} was bound in a star import, but no corresponding module paths were found", - symbol.span(), - ))); - } else { - return Err(handler.emit_err(CompileError::SymbolWithMultipleBindings { - name: symbol.clone(), - paths: decls - .iter() - .map(|(path, decl, _)| { - let mut path_strs = - path.iter().map(|x| x.to_string()).collect::>(); - // Add the enum name to the path if the decl is an enum variant. - match decl { - ResolvedDeclaration::Parsed(decl) => { - if let Declaration::EnumVariantDeclaration(decl) = decl { - let enum_ref = engines.pe().get_enum(&decl.enum_ref); - path_strs.push(enum_ref.name().to_string()) - }; - } - ResolvedDeclaration::Typed(decl) => { - if let TyDecl::EnumVariantDecl(ty::EnumVariantDecl { - enum_ref, - .. - }) = decl - { - path_strs.push(enum_ref.name().to_string()) - }; - } - } - path_strs.join("::") - }) - .collect(), - span: symbol.span(), - })); - } - } - // Symbol not found - Err(handler.emit_err(CompileError::SymbolNotFound { - name: symbol.clone(), - span: symbol.span(), - })) - } } impl From for Root { diff --git a/sway-core/src/semantic_analysis/namespace/trait_map.rs b/sway-core/src/semantic_analysis/namespace/trait_map.rs index 47e0e884988..483f090a9ea 100644 --- a/sway-core/src/semantic_analysis/namespace/trait_map.rs +++ b/sway-core/src/semantic_analysis/namespace/trait_map.rs @@ -904,13 +904,11 @@ impl TraitMap { *map_type_id, *type_id, ); - type_id.subst( + type_id.subst(&SubstTypesContext::new( + engines, &type_mapping, - &SubstTypesContext::new( - engines, - matches!(code_block_first_pass, CodeBlockFirstPass::No), - ), - ); + matches!(code_block_first_pass, CodeBlockFirstPass::No), + )); let trait_items: TraitItems = map_trait_items .clone() .into_iter() @@ -922,16 +920,11 @@ impl TraitMap { if decl.is_trait_method_dummy && !insertable { None } else { - decl.subst( + decl.subst(&SubstTypesContext::new( + engines, &type_mapping, - &SubstTypesContext::new( - engines, - matches!( - code_block_first_pass, - CodeBlockFirstPass::No - ), - ), - ); + matches!(code_block_first_pass, CodeBlockFirstPass::No), + )); let new_ref = decl_engine .insert( decl, @@ -948,13 +941,11 @@ impl TraitMap { } ty::TyTraitItem::Constant(decl_ref) => { let mut decl = (*decl_engine.get(decl_ref.id())).clone(); - decl.subst( + decl.subst(&SubstTypesContext::new( + engines, &type_mapping, - &SubstTypesContext::new( - engines, - matches!(code_block_first_pass, CodeBlockFirstPass::No), - ), - ); + matches!(code_block_first_pass, CodeBlockFirstPass::No), + )); let new_ref = decl_engine.insert( decl, decl_engine.get_parsed_decl_id(decl_ref.id()).as_ref(), @@ -966,13 +957,11 @@ impl TraitMap { } ty::TyTraitItem::Type(decl_ref) => { let mut decl = (*decl_engine.get(decl_ref.id())).clone(); - decl.subst( + decl.subst(&SubstTypesContext::new( + engines, &type_mapping, - &SubstTypesContext::new( - engines, - matches!(code_block_first_pass, CodeBlockFirstPass::No), - ), - ); + matches!(code_block_first_pass, CodeBlockFirstPass::No), + )); let new_ref = decl_engine.insert( decl, decl_engine.get_parsed_decl_id(decl_ref.id()).as_ref(), diff --git a/sway-core/src/semantic_analysis/symbol_resolve_context.rs b/sway-core/src/semantic_analysis/symbol_resolve_context.rs index 0e88ffd543c..01bc631ec0e 100644 --- a/sway-core/src/semantic_analysis/symbol_resolve_context.rs +++ b/sway-core/src/semantic_analysis/symbol_resolve_context.rs @@ -251,39 +251,3 @@ impl<'a> SymbolResolveContext<'a> { Ok(decl) } } - -/// This type is used to denote if, during monomorphization, the compiler -/// should enforce that type arguments be provided. An example of that -/// might be this: -/// -/// ```ignore -/// struct Point { -/// x: u64, -/// y: u64 -/// } -/// -/// fn add(p1: Point, p2: Point) -> Point { -/// Point { -/// x: p1.x + p2.x, -/// y: p1.y + p2.y -/// } -/// } -/// ``` -/// -/// `EnforceTypeArguments` would require that the type annotations -/// for `p1` and `p2` contain `<...>`. This is to avoid ambiguous definitions: -/// -/// ```ignore -/// fn add(p1: Point, p2: Point) -> Point { -/// Point { -/// x: p1.x + p2.x, -/// y: p1.y + p2.y -/// } -/// } -/// ``` -#[allow(dead_code)] -#[derive(Clone, Copy)] -pub(crate) enum EnforceTypeArguments { - Yes, - No, -} diff --git a/sway-core/src/semantic_analysis/type_check_context.rs b/sway-core/src/semantic_analysis/type_check_context.rs index 66dd12166cb..3202ffaee53 100644 --- a/sway-core/src/semantic_analysis/type_check_context.rs +++ b/sway-core/src/semantic_analysis/type_check_context.rs @@ -2,13 +2,14 @@ use std::collections::{HashMap, VecDeque}; use crate::{ build_config::ExperimentalFlags, - decl_engine::{DeclEngineGet, DeclEngineGetParsedDeclId, DeclEngineInsert, DeclRefFunction}, + decl_engine::{DeclEngineGet, DeclRefFunction}, engine_threading::*, language::{ parsed::TreeType, - ty::{self, TyDecl, TyTraitItem}, + ty::{self, TyDecl}, CallPath, QualifiedCallPath, Visibility, }, + monomorphization::{monomorphize_with_modpath, MonomorphizeHelper}, namespace::{ IsExtendingExistingImpl, IsImplSelf, ModulePath, ResolvedDeclaration, ResolvedTraitImplItem, TraitMap, TryInsertingTraitImplOnFailure, @@ -18,16 +19,19 @@ use crate::{ Namespace, }, type_system::{SubstTypes, TypeArgument, TypeId, TypeInfo}, - CreateTypeId, SubstTypesContext, TraitConstraint, TypeParameter, TypeSubstMap, UnifyCheck, + EnforceTypeArguments, SubstTypesContext, TraitConstraint, TypeSubstMap, UnifyCheck, }; use sway_error::{ error::CompileError, handler::{ErrorEmitted, Handler}, }; use sway_types::{span::Span, Ident, Spanned}; -use sway_utils::iter_prefixes; -use super::{symbol_collection_context::SymbolCollectionContext, GenericShadowingMode}; +use super::{ + symbol_collection_context::SymbolCollectionContext, + type_resolve::{resolve_call_path, resolve_qualified_call_path, resolve_type}, + GenericShadowingMode, +}; /// Contextual state tracked and accumulated throughout type-checking. pub struct TypeCheckContext<'a> { @@ -527,8 +531,12 @@ impl<'a> TypeCheckContext<'a> { self.self_type } - pub(crate) fn type_subst(&self) -> TypeSubstMap { - self.type_subst.clone() + pub(crate) fn subst_ctx(&self) -> SubstTypesContext { + SubstTypesContext::new( + self.engines(), + &self.type_subst, + !self.code_block_first_pass(), + ) } pub(crate) fn abi_mode(&self) -> AbiMode { @@ -556,6 +564,11 @@ impl<'a> TypeCheckContext<'a> { self.code_block_first_pass } + /// Get the engines needed for engine threading. + pub(crate) fn engines(&self) -> &'a Engines { + self.engines + } + // Provide some convenience functions around the inner context. /// Short-hand for calling the `monomorphize` function in the type engine @@ -571,13 +584,17 @@ impl<'a> TypeCheckContext<'a> { T: MonomorphizeHelper + SubstTypes, { let mod_path = self.namespace().mod_path.clone(); - self.monomorphize_with_modpath( + monomorphize_with_modpath( handler, + self.engines(), + self.namespace(), value, type_arguments, enforce_type_arguments, call_site_span, &mod_path, + self.self_type(), + &self.subst_ctx(), ) } @@ -633,200 +650,6 @@ impl<'a> TypeCheckContext<'a> { ) } - /// Get the engines needed for engine threading. - pub(crate) fn engines(&self) -> &'a Engines { - self.engines - } - - /// Resolve the type of the given [TypeId], replacing any instances of - /// [TypeInfo::Custom] with either a monomorphized struct, monomorphized - /// enum, or a reference to a type parameter. - #[allow(clippy::too_many_arguments)] - pub(crate) fn resolve( - &mut self, - handler: &Handler, - type_id: TypeId, - span: &Span, - enforce_type_arguments: EnforceTypeArguments, - type_info_prefix: Option<&ModulePath>, - mod_path: &ModulePath, - ) -> Result { - let engines = self.engines; - let type_engine = self.engines.te(); - let module_path = type_info_prefix.unwrap_or(mod_path); - let type_id = match (*type_engine.get(type_id)).clone() { - TypeInfo::Custom { - qualified_call_path, - type_arguments, - root_type_id, - } => { - let type_decl_opt = if let Some(root_type_id) = root_type_id { - self.namespace() - .root - .resolve_call_path_and_root_type_id( - handler, - self.engines, - self.namespace().module(engines), - root_type_id, - None, - &qualified_call_path.clone().to_call_path(handler)?, - self.self_type(), - ) - .map(|decl| decl.expect_typed()) - .ok() - } else { - self.resolve_qualified_call_path_with_visibility_check_and_modpath( - handler, - module_path, - &qualified_call_path, - ) - .ok() - }; - self.type_decl_opt_to_type_id( - handler, - type_decl_opt, - &qualified_call_path.call_path, - span, - enforce_type_arguments, - mod_path, - type_arguments.clone(), - )? - } - TypeInfo::Array(mut elem_ty, n) => { - elem_ty.type_id = self - .resolve( - handler, - elem_ty.type_id, - span, - enforce_type_arguments, - None, - mod_path, - ) - .unwrap_or_else(|err| { - self.engines - .te() - .insert(self.engines, TypeInfo::ErrorRecovery(err), None) - }); - - self.engines.te().insert( - self.engines, - TypeInfo::Array(elem_ty.clone(), n.clone()), - elem_ty.span.source_id(), - ) - } - TypeInfo::Slice(mut elem_ty) => { - elem_ty.type_id = self - .resolve( - handler, - elem_ty.type_id, - span, - enforce_type_arguments, - None, - mod_path, - ) - .unwrap_or_else(|err| { - self.engines - .te() - .insert(self.engines, TypeInfo::ErrorRecovery(err), None) - }); - - self.engines.te().insert( - self.engines, - TypeInfo::Slice(elem_ty.clone()), - elem_ty.span.source_id(), - ) - } - TypeInfo::Tuple(mut type_arguments) => { - for type_argument in type_arguments.iter_mut() { - type_argument.type_id = self - .resolve( - handler, - type_argument.type_id, - span, - enforce_type_arguments, - None, - mod_path, - ) - .unwrap_or_else(|err| { - self.engines.te().insert( - self.engines, - TypeInfo::ErrorRecovery(err), - None, - ) - }); - } - - self.engines.te().insert( - self.engines, - TypeInfo::Tuple(type_arguments), - span.source_id(), - ) - } - TypeInfo::TraitType { - name, - trait_type_id, - } => { - let item_ref = self.namespace().get_root_trait_item_for_type( - handler, - self.engines, - &name, - trait_type_id, - None, - )?; - if let ResolvedTraitImplItem::Typed(TyTraitItem::Type(type_ref)) = item_ref { - let type_decl = self.engines.de().get_type(type_ref.id()); - if let Some(ty) = &type_decl.ty { - ty.type_id - } else { - type_id - } - } else { - return Err(handler.emit_err(CompileError::Internal( - "Expecting associated type", - item_ref.span(self.engines), - ))); - } - } - TypeInfo::Ref { - referenced_type: mut ty, - to_mutable_value, - } => { - ty.type_id = self - .resolve( - handler, - ty.type_id, - span, - enforce_type_arguments, - None, - mod_path, - ) - .unwrap_or_else(|err| { - self.engines - .te() - .insert(self.engines, TypeInfo::ErrorRecovery(err), None) - }); - - self.engines.te().insert( - self.engines, - TypeInfo::Ref { - to_mutable_value, - referenced_type: ty.clone(), - }, - None, - ) - } - _ => type_id, - }; - - let mut type_id = type_id; - type_id.subst( - &self.type_subst(), - &SubstTypesContext::new(engines, !self.collecting_unifications()), - ); - - Ok(type_id) - } - /// Short-hand for calling [Root::resolve_type_with_self] on `root` with the `mod_path`. #[allow(clippy::too_many_arguments)] // TODO: remove lint bypass once private modules are no longer experimental pub(crate) fn resolve_type( @@ -837,33 +660,17 @@ impl<'a> TypeCheckContext<'a> { enforce_type_arguments: EnforceTypeArguments, type_info_prefix: Option<&ModulePath>, ) -> Result { - let mod_path = self.namespace().mod_path.clone(); - self.resolve( + resolve_type( handler, + self.engines(), + self.namespace(), + &self.namespace().mod_path, type_id, span, enforce_type_arguments, type_info_prefix, - &mod_path, - ) - } - - /// Short-hand for calling [Root::resolve_type_without_self] on `root` and with the `mod_path`. - pub(crate) fn resolve_type_without_self( - &mut self, - handler: &Handler, - type_id: TypeId, - span: &Span, - type_info_prefix: Option<&ModulePath>, - ) -> Result { - let mod_path = self.namespace().mod_path.clone(); - self.resolve( - handler, - type_id, - span, - EnforceTypeArguments::Yes, - type_info_prefix, - &mod_path, + self.self_type(), + &self.subst_ctx(), ) } @@ -873,271 +680,32 @@ impl<'a> TypeCheckContext<'a> { handler: &Handler, call_path: &CallPath, ) -> Result { - self.resolve_call_path_with_visibility_check_and_modpath( + resolve_call_path( handler, + self.engines(), + self.namespace(), &self.namespace().mod_path, call_path, + self.self_type(), ) } - /// Resolve a symbol that is potentially prefixed with some path, e.g. `foo::bar::symbol`. - /// - /// This will concatenate the `mod_path` with the `call_path`'s prefixes and - /// then calling `resolve_symbol` with the resulting path and call_path's suffix. - /// - /// The `mod_path` is significant here as we assume the resolution is done within the - /// context of the module pointed to by `mod_path` and will only check the call path prefixes - /// and the symbol's own visibility. - pub(crate) fn resolve_call_path_with_visibility_check_and_modpath( - &self, - handler: &Handler, - mod_path: &ModulePath, - call_path: &CallPath, - ) -> Result { - let engines = self.engines; - let (decl, mod_path) = self.namespace().root.resolve_call_path_and_mod_path( - handler, - self.engines, - mod_path, - call_path, - self.self_type, - )?; - let decl = decl.expect_typed(); - - // In case there is no mod path we don't need to check visibility - if mod_path.is_empty() { - return Ok(decl); - } - - // In case there are no prefixes we don't need to check visibility - if call_path.prefixes.is_empty() { - return Ok(decl); - } - - // check the visibility of the call path elements - // we don't check the first prefix because direct children are always accessible - for prefix in iter_prefixes(&call_path.prefixes).skip(1) { - let module = self - .namespace() - .lookup_submodule_from_absolute_path(handler, engines, prefix)?; - if module.visibility().is_private() { - let prefix_last = prefix[prefix.len() - 1].clone(); - handler.emit_err(CompileError::ImportPrivateModule { - span: prefix_last.span(), - name: prefix_last, - }); - } - } - - // check the visibility of the symbol itself - if !decl.visibility(self.engines.de()).is_public() { - handler.emit_err(CompileError::ImportPrivateSymbol { - name: call_path.suffix.clone(), - span: call_path.suffix.span(), - }); - } - - Ok(decl) - } - pub(crate) fn resolve_qualified_call_path_with_visibility_check( &mut self, handler: &Handler, qualified_call_path: &QualifiedCallPath, ) -> Result { - self.resolve_qualified_call_path_with_visibility_check_and_modpath( + resolve_qualified_call_path( handler, + self.engines(), + self.namespace(), &self.namespace().mod_path.clone(), qualified_call_path, + self.self_type(), + &self.subst_ctx(), ) } - pub(crate) fn resolve_qualified_call_path_with_visibility_check_and_modpath( - &mut self, - handler: &Handler, - mod_path: &ModulePath, - qualified_call_path: &QualifiedCallPath, - ) -> Result { - let type_engine = self.engines().te(); - if let Some(qualified_path_root) = qualified_call_path.clone().qualified_path_root { - let root_type_id = match &&*type_engine.get(qualified_path_root.ty.type_id) { - TypeInfo::Custom { - qualified_call_path, - type_arguments, - .. - } => { - let type_decl = self.resolve_call_path_with_visibility_check_and_modpath( - handler, - mod_path, - &qualified_call_path.clone().to_call_path(handler)?, - )?; - self.type_decl_opt_to_type_id( - handler, - Some(type_decl), - &qualified_call_path.call_path, - &qualified_path_root.ty.span(), - EnforceTypeArguments::No, - mod_path, - type_arguments.clone(), - )? - } - _ => qualified_path_root.ty.type_id, - }; - - let as_trait_opt = match &&*type_engine.get(qualified_path_root.as_trait) { - TypeInfo::Custom { - qualified_call_path: call_path, - .. - } => Some( - call_path - .clone() - .to_call_path(handler)? - .to_fullpath(self.engines(), self.namespace()), - ), - _ => None, - }; - - self.namespace() - .root - .resolve_call_path_and_root_type_id( - handler, - self.engines, - &self.namespace().root.module, - root_type_id, - as_trait_opt, - &qualified_call_path.call_path, - self.self_type(), - ) - .map(|decl| decl.expect_typed()) - } else { - self.resolve_call_path_with_visibility_check_and_modpath( - handler, - mod_path, - &qualified_call_path.call_path, - ) - } - } - - #[allow(clippy::too_many_arguments)] - fn type_decl_opt_to_type_id( - &mut self, - handler: &Handler, - type_decl_opt: Option, - call_path: &CallPath, - span: &Span, - enforce_type_arguments: EnforceTypeArguments, - mod_path: &ModulePath, - type_arguments: Option>, - ) -> Result { - let decl_engine = self.engines.de(); - let type_engine = self.engines.te(); - Ok(match type_decl_opt { - Some(ty::TyDecl::StructDecl(ty::StructDecl { - decl_id: original_id, - .. - })) => { - // get the copy from the declaration engine - let mut new_copy = (*decl_engine.get_struct(&original_id)).clone(); - - // monomorphize the copy, in place - self.monomorphize_with_modpath( - handler, - &mut new_copy, - &mut type_arguments.unwrap_or_default(), - enforce_type_arguments, - span, - mod_path, - )?; - - // insert the new copy in the decl engine - let new_decl_ref = decl_engine.insert( - new_copy, - decl_engine.get_parsed_decl_id(&original_id).as_ref(), - ); - - // create the type id from the copy - type_engine.insert( - self.engines, - TypeInfo::Struct(*new_decl_ref.id()), - new_decl_ref.span().source_id(), - ) - } - Some(ty::TyDecl::EnumDecl(ty::EnumDecl { - decl_id: original_id, - .. - })) => { - // get the copy from the declaration engine - let mut new_copy = (*decl_engine.get_enum(&original_id)).clone(); - - // monomorphize the copy, in place - self.monomorphize_with_modpath( - handler, - &mut new_copy, - &mut type_arguments.unwrap_or_default(), - enforce_type_arguments, - span, - mod_path, - )?; - - // insert the new copy in the decl engine - let new_decl_ref = decl_engine.insert( - new_copy, - decl_engine.get_parsed_decl_id(&original_id).as_ref(), - ); - - // create the type id from the copy - type_engine.insert( - self.engines, - TypeInfo::Enum(*new_decl_ref.id()), - new_decl_ref.span().source_id(), - ) - } - Some(ty::TyDecl::TypeAliasDecl(ty::TypeAliasDecl { - decl_id: original_id, - .. - })) => { - let new_copy = decl_engine.get_type_alias(&original_id); - - // TODO: monomorphize the copy, in place, when generic type aliases are - // supported - - new_copy.create_type_id(self.engines) - } - Some(ty::TyDecl::GenericTypeForFunctionScope(ty::GenericTypeForFunctionScope { - type_id, - .. - })) => type_id, - Some(ty::TyDecl::TraitTypeDecl(ty::TraitTypeDecl { decl_id })) => { - let decl_type = decl_engine.get_type(&decl_id); - - if let Some(ty) = &decl_type.ty { - ty.type_id - } else if let Some(implementing_type) = self.self_type() { - type_engine.insert( - self.engines, - TypeInfo::TraitType { - name: decl_type.name.clone(), - trait_type_id: implementing_type, - }, - decl_type.name.span().source_id(), - ) - } else { - return Err(handler.emit_err(CompileError::Internal( - "Self type not provided.", - span.clone(), - ))); - } - } - _ => { - let err = handler.emit_err(CompileError::UnknownTypeName { - name: call_path.to_string(), - span: call_path.span(), - }); - type_engine.insert(self.engines, TypeInfo::ErrorRecovery(err), None) - } - }) - } - /// Given a name and a type (plus a `self_type` to potentially /// resolve it), find items matching in the namespace. pub(crate) fn find_items_for_type( @@ -1170,18 +738,19 @@ impl<'a> TypeCheckContext<'a> { .get_items_for_type(self.engines, type_id); // resolve the type - let type_id = self - .resolve( - handler, - type_id, - &item_name.span(), - EnforceTypeArguments::No, - None, - item_prefix, - ) - .unwrap_or_else(|err| { - type_engine.insert(self.engines, TypeInfo::ErrorRecovery(err), None) - }); + let type_id = resolve_type( + handler, + self.engines(), + self.namespace(), + item_prefix, + type_id, + &item_name.span(), + EnforceTypeArguments::No, + None, + self.self_type(), + &self.subst_ctx(), + ) + .unwrap_or_else(|err| type_engine.insert(self.engines, TypeInfo::ErrorRecovery(err), None)); // grab the module where the type itself is declared let type_module = self.namespace().lookup_submodule_from_absolute_path( @@ -1330,11 +899,19 @@ impl<'a> TypeCheckContext<'a> { .iter() .zip(trait_decl.trait_type_arguments.clone()) { - let p1_type_id = self.resolve_type_without_self( - handler, p1.type_id, &p1.span, None, + let p1_type_id = self.resolve_type( + handler, + p1.type_id, + &p1.span, + EnforceTypeArguments::Yes, + None, )?; - let p2_type_id = self.resolve_type_without_self( - handler, p2.type_id, &p2.span, None, + let p2_type_id = self.resolve_type( + handler, + p2.type_id, + &p2.span, + EnforceTypeArguments::Yes, + None, )?; if !eq_check.check(p1_type_id, p2_type_id) { params_equal = false; @@ -1679,187 +1256,6 @@ impl<'a> TypeCheckContext<'a> { ) } - /// Given a `value` of type `T` that is able to be monomorphized and a set - /// of `type_arguments`, monomorphize `value` with the `type_arguments`. - /// - /// When this function is called, it is passed a `T` that is a copy of some - /// original declaration for `T` (let's denote the original with `[T]`). - /// Because monomorphization happens at application time (e.g. function - /// application), we want to be able to modify `value` such that type - /// checking the application of `value` affects only `T` and not `[T]`. - /// - /// So, at a high level, this function does two things. It 1) performs the - /// necessary work to refresh the relevant generic types in `T` so that they - /// are distinct from the generics of the same name in `[T]`. And it 2) - /// applies `type_arguments` (if any are provided) to the type parameters - /// of `value`, unifying the types. - /// - /// There are 4 cases that are handled in this function: - /// - /// 1. `value` does not have type parameters + `type_arguments` is empty: - /// 1a. return ok - /// 2. `value` has type parameters + `type_arguments` is empty: - /// 2a. if the [EnforceTypeArguments::Yes] variant is provided, then - /// error - /// 2b. refresh the generic types with a [TypeSubstMapping] - /// 3. `value` does have type parameters + `type_arguments` is nonempty: - /// 3a. error - /// 4. `value` has type parameters + `type_arguments` is nonempty: - /// 4a. check to see that the type parameters and `type_arguments` have - /// the same length - /// 4b. for each type argument in `type_arguments`, resolve the type - /// 4c. refresh the generic types with a [TypeSubstMapping] - #[allow(clippy::too_many_arguments)] - pub(crate) fn monomorphize_with_modpath( - &mut self, - handler: &Handler, - value: &mut T, - type_arguments: &mut [TypeArgument], - enforce_type_arguments: EnforceTypeArguments, - call_site_span: &Span, - mod_path: &ModulePath, - ) -> Result<(), ErrorEmitted> - where - T: MonomorphizeHelper + SubstTypes, - { - let type_mapping = self.prepare_type_subst_map_for_monomorphize( - handler, - value, - type_arguments, - enforce_type_arguments, - call_site_span, - mod_path, - )?; - value.subst(&type_mapping, &SubstTypesContext::new(self.engines, true)); - Ok(()) - } - - /// Given a `value` of type `T` that is able to be monomorphized and a set - /// of `type_arguments`, prepare a `TypeSubstMap` that can be used as an - /// input for monomorphization. - #[allow(clippy::too_many_arguments)] - pub(crate) fn prepare_type_subst_map_for_monomorphize( - &mut self, - handler: &Handler, - value: &T, - type_arguments: &mut [TypeArgument], - enforce_type_arguments: EnforceTypeArguments, - call_site_span: &Span, - mod_path: &ModulePath, - ) -> Result - where - T: MonomorphizeHelper + SubstTypes, - { - fn make_type_arity_mismatch_error( - name: Ident, - span: Span, - given: usize, - expected: usize, - ) -> CompileError { - match (expected, given) { - (0, 0) => unreachable!(), - (_, 0) => CompileError::NeedsTypeArguments { name, span }, - (0, _) => CompileError::DoesNotTakeTypeArguments { name, span }, - (_, _) => CompileError::IncorrectNumberOfTypeArguments { - name, - given, - expected, - span, - }, - } - } - - match (value.type_parameters().len(), type_arguments.len()) { - (0, 0) => Ok(TypeSubstMap::default()), - (num_type_params, 0) => { - if let EnforceTypeArguments::Yes = enforce_type_arguments { - return Err(handler.emit_err(make_type_arity_mismatch_error( - value.name().clone(), - call_site_span.clone(), - 0, - num_type_params, - ))); - } - let type_mapping = - TypeSubstMap::from_type_parameters(self.engines, value.type_parameters()); - Ok(type_mapping) - } - (0, num_type_args) => { - let type_arguments_span = type_arguments - .iter() - .map(|x| x.span.clone()) - .reduce(|s1: Span, s2: Span| Span::join(s1, &s2)) - .unwrap_or_else(|| value.name().span()); - Err(handler.emit_err(make_type_arity_mismatch_error( - value.name().clone(), - type_arguments_span.clone(), - num_type_args, - 0, - ))) - } - (_, num_type_args) => { - // a trait decl is passed the self type parameter and the corresponding argument - // but it would be confusing for the user if the error reporting mechanism - // reported the number of arguments including the implicit self, hence - // we adjust it below - let adjust_for_trait_decl = value.has_self_type_param() as usize; - let non_parent_type_params = value - .type_parameters() - .iter() - .filter(|x| !x.is_from_parent) - .count() - - adjust_for_trait_decl; - - let num_type_args = num_type_args - adjust_for_trait_decl; - if non_parent_type_params != num_type_args { - let type_arguments_span = type_arguments - .iter() - .map(|x| x.span.clone()) - .reduce(|s1: Span, s2: Span| Span::join(s1, &s2)) - .unwrap_or_else(|| value.name().span()); - - return Err(handler.emit_err(make_type_arity_mismatch_error( - value.name().clone(), - type_arguments_span, - num_type_args, - non_parent_type_params, - ))); - } - - for type_argument in type_arguments.iter_mut() { - type_argument.type_id = self - .resolve( - handler, - type_argument.type_id, - &type_argument.span, - enforce_type_arguments, - None, - mod_path, - ) - .unwrap_or_else(|err| { - self.engines.te().insert( - self.engines, - TypeInfo::ErrorRecovery(err), - None, - ) - }); - } - let type_mapping = TypeSubstMap::from_type_parameters_and_type_arguments( - value - .type_parameters() - .iter() - .map(|type_param| type_param.type_id) - .collect(), - type_arguments - .iter() - .map(|type_arg| type_arg.type_id) - .collect(), - ); - Ok(type_mapping) - } - } - } - pub(crate) fn insert_trait_implementation_for_type(&mut self, type_id: TypeId) { let engines = self.engines; let code_block_first_pass = self.code_block_first_pass(); @@ -1894,44 +1290,3 @@ impl<'a> TypeCheckContext<'a> { .is_ok() } } - -pub(crate) trait MonomorphizeHelper { - fn name(&self) -> &Ident; - fn type_parameters(&self) -> &[TypeParameter]; - fn has_self_type_param(&self) -> bool; -} - -/// This type is used to denote if, during monomorphization, the compiler -/// should enforce that type arguments be provided. An example of that -/// might be this: -/// -/// ```ignore -/// struct Point { -/// x: u64, -/// y: u64 -/// } -/// -/// fn add(p1: Point, p2: Point) -> Point { -/// Point { -/// x: p1.x + p2.x, -/// y: p1.y + p2.y -/// } -/// } -/// ``` -/// -/// `EnforceTypeArguments` would require that the type annotations -/// for `p1` and `p2` contain `<...>`. This is to avoid ambiguous definitions: -/// -/// ```ignore -/// fn add(p1: Point, p2: Point) -> Point { -/// Point { -/// x: p1.x + p2.x, -/// y: p1.y + p2.y -/// } -/// } -/// ``` -#[derive(Clone, Copy)] -pub(crate) enum EnforceTypeArguments { - Yes, - No, -} diff --git a/sway-core/src/semantic_analysis/type_resolve.rs b/sway-core/src/semantic_analysis/type_resolve.rs new file mode 100644 index 00000000000..d29bcfd4952 --- /dev/null +++ b/sway-core/src/semantic_analysis/type_resolve.rs @@ -0,0 +1,355 @@ +use sway_error::{ + error::CompileError, + handler::{ErrorEmitted, Handler}, +}; +use sway_types::{Span, Spanned}; +use sway_utils::iter_prefixes; + +use crate::{ + language::{ + ty::{self, TyTraitItem}, + CallPath, QualifiedCallPath, + }, + monomorphization::type_decl_opt_to_type_id, + namespace::{ModulePath, ResolvedTraitImplItem}, + type_system::SubstTypes, + EnforceTypeArguments, Engines, Namespace, SubstTypesContext, TypeId, TypeInfo, +}; + +/// Resolve the type of the given [TypeId], replacing any instances of +/// [TypeInfo::Custom] with either a monomorphized struct, monomorphized +/// enum, or a reference to a type parameter. +#[allow(clippy::too_many_arguments)] +pub fn resolve_type( + handler: &Handler, + engines: &Engines, + namespace: &Namespace, + mod_path: &ModulePath, + type_id: TypeId, + span: &Span, + enforce_type_arguments: EnforceTypeArguments, + type_info_prefix: Option<&ModulePath>, + self_type: Option, + subst_ctx: &SubstTypesContext, +) -> Result { + let type_engine = engines.te(); + let module_path = type_info_prefix.unwrap_or(mod_path); + let type_id = match (*type_engine.get(type_id)).clone() { + TypeInfo::Custom { + qualified_call_path, + type_arguments, + root_type_id, + } => { + let type_decl_opt = if let Some(root_type_id) = root_type_id { + namespace + .root() + .resolve_call_path_and_root_type_id( + handler, + engines, + namespace.module(engines), + root_type_id, + None, + &qualified_call_path.clone().to_call_path(handler)?, + self_type, + ) + .map(|decl| decl.expect_typed()) + .ok() + } else { + resolve_qualified_call_path( + handler, + engines, + namespace, + module_path, + &qualified_call_path, + self_type, + subst_ctx, + ) + .ok() + }; + type_decl_opt_to_type_id( + handler, + engines, + namespace, + type_decl_opt, + &qualified_call_path.call_path, + span, + enforce_type_arguments, + mod_path, + type_arguments.clone(), + self_type, + subst_ctx, + )? + } + TypeInfo::Array(mut elem_ty, n) => { + elem_ty.type_id = resolve_type( + handler, + engines, + namespace, + mod_path, + elem_ty.type_id, + span, + enforce_type_arguments, + None, + self_type, + subst_ctx, + ) + .unwrap_or_else(|err| { + engines + .te() + .insert(engines, TypeInfo::ErrorRecovery(err), None) + }); + + engines.te().insert( + engines, + TypeInfo::Array(elem_ty.clone(), n.clone()), + elem_ty.span.source_id(), + ) + } + TypeInfo::Slice(mut elem_ty) => { + elem_ty.type_id = resolve_type( + handler, + engines, + namespace, + mod_path, + elem_ty.type_id, + span, + enforce_type_arguments, + None, + self_type, + subst_ctx, + ) + .unwrap_or_else(|err| { + engines + .te() + .insert(engines, TypeInfo::ErrorRecovery(err), None) + }); + + engines.te().insert( + engines, + TypeInfo::Slice(elem_ty.clone()), + elem_ty.span.source_id(), + ) + } + TypeInfo::Tuple(mut type_arguments) => { + for type_argument in type_arguments.iter_mut() { + type_argument.type_id = resolve_type( + handler, + engines, + namespace, + mod_path, + type_argument.type_id, + span, + enforce_type_arguments, + None, + self_type, + subst_ctx, + ) + .unwrap_or_else(|err| { + engines + .te() + .insert(engines, TypeInfo::ErrorRecovery(err), None) + }); + } + + engines + .te() + .insert(engines, TypeInfo::Tuple(type_arguments), span.source_id()) + } + TypeInfo::TraitType { + name, + trait_type_id, + } => { + let item_ref = namespace.get_root_trait_item_for_type( + handler, + engines, + &name, + trait_type_id, + None, + )?; + if let ResolvedTraitImplItem::Typed(TyTraitItem::Type(type_ref)) = item_ref { + let type_decl = engines.de().get_type(type_ref.id()); + if let Some(ty) = &type_decl.ty { + ty.type_id + } else { + type_id + } + } else { + return Err(handler.emit_err(CompileError::Internal( + "Expecting associated type", + item_ref.span(engines), + ))); + } + } + TypeInfo::Ref { + referenced_type: mut ty, + to_mutable_value, + } => { + ty.type_id = resolve_type( + handler, + engines, + namespace, + mod_path, + ty.type_id, + span, + enforce_type_arguments, + None, + self_type, + subst_ctx, + ) + .unwrap_or_else(|err| { + engines + .te() + .insert(engines, TypeInfo::ErrorRecovery(err), None) + }); + + engines.te().insert( + engines, + TypeInfo::Ref { + to_mutable_value, + referenced_type: ty.clone(), + }, + None, + ) + } + _ => type_id, + }; + + let mut type_id = type_id; + type_id.subst(subst_ctx); + + Ok(type_id) +} + +pub fn resolve_qualified_call_path( + handler: &Handler, + engines: &Engines, + namespace: &Namespace, + mod_path: &ModulePath, + qualified_call_path: &QualifiedCallPath, + self_type: Option, + subst_ctx: &SubstTypesContext, +) -> Result { + let type_engine = engines.te(); + if let Some(qualified_path_root) = qualified_call_path.clone().qualified_path_root { + let root_type_id = match &&*type_engine.get(qualified_path_root.ty.type_id) { + TypeInfo::Custom { + qualified_call_path, + type_arguments, + .. + } => { + let type_decl = resolve_call_path( + handler, + engines, + namespace, + mod_path, + &qualified_call_path.clone().to_call_path(handler)?, + self_type, + )?; + type_decl_opt_to_type_id( + handler, + engines, + namespace, + Some(type_decl), + &qualified_call_path.call_path, + &qualified_path_root.ty.span(), + EnforceTypeArguments::No, + mod_path, + type_arguments.clone(), + self_type, + subst_ctx, + )? + } + _ => qualified_path_root.ty.type_id, + }; + + let as_trait_opt = match &&*type_engine.get(qualified_path_root.as_trait) { + TypeInfo::Custom { + qualified_call_path: call_path, + .. + } => Some( + call_path + .clone() + .to_call_path(handler)? + .to_fullpath(engines, namespace), + ), + _ => None, + }; + + namespace + .root + .resolve_call_path_and_root_type_id( + handler, + engines, + &namespace.root.module, + root_type_id, + as_trait_opt, + &qualified_call_path.call_path, + self_type, + ) + .map(|decl| decl.expect_typed()) + } else { + resolve_call_path( + handler, + engines, + namespace, + mod_path, + &qualified_call_path.call_path, + self_type, + ) + } +} + +/// Resolve a symbol that is potentially prefixed with some path, e.g. `foo::bar::symbol`. +/// +/// This will concatenate the `mod_path` with the `call_path`'s prefixes and +/// then calling `resolve_symbol` with the resulting path and call_path's suffix. +/// +/// The `mod_path` is significant here as we assume the resolution is done within the +/// context of the module pointed to by `mod_path` and will only check the call path prefixes +/// and the symbol's own visibility. +pub fn resolve_call_path( + handler: &Handler, + engines: &Engines, + namespace: &Namespace, + mod_path: &ModulePath, + call_path: &CallPath, + self_type: Option, +) -> Result { + let (decl, mod_path) = namespace + .root + .resolve_call_path_and_mod_path(handler, engines, mod_path, call_path, self_type)?; + let decl = decl.expect_typed(); + + // In case there is no mod path we don't need to check visibility + if mod_path.is_empty() { + return Ok(decl); + } + + // In case there are no prefixes we don't need to check visibility + if call_path.prefixes.is_empty() { + return Ok(decl); + } + + // check the visibility of the call path elements + // we don't check the first prefix because direct children are always accessible + for prefix in iter_prefixes(&call_path.prefixes).skip(1) { + let module = namespace.lookup_submodule_from_absolute_path(handler, engines, prefix)?; + if module.visibility().is_private() { + let prefix_last = prefix[prefix.len() - 1].clone(); + handler.emit_err(CompileError::ImportPrivateModule { + span: prefix_last.span(), + name: prefix_last, + }); + } + } + + // check the visibility of the symbol itself + if !decl.visibility(engines.de()).is_public() { + handler.emit_err(CompileError::ImportPrivateSymbol { + name: call_path.suffix.clone(), + span: call_path.suffix.span(), + }); + } + + Ok(decl) +} diff --git a/sway-core/src/type_system/ast_elements/binding.rs b/sway-core/src/type_system/ast_elements/binding.rs index d6022709fa6..07b543071be 100644 --- a/sway-core/src/type_system/ast_elements/binding.rs +++ b/sway-core/src/type_system/ast_elements/binding.rs @@ -13,10 +13,10 @@ use crate::{ }, semantic_analysis::{ symbol_resolve::ResolveSymbols, symbol_resolve_context::SymbolResolveContext, - type_check_context::EnforceTypeArguments, TypeCheckContext, + TypeCheckContext, }, type_system::priv_prelude::*, - Ident, + EnforceTypeArguments, Ident, }; /// A `TypeBinding` is the result of using turbofish to bind types to diff --git a/sway-core/src/type_system/ast_elements/trait_constraint.rs b/sway-core/src/type_system/ast_elements/trait_constraint.rs index e9fbff449fa..b725eabf3eb 100644 --- a/sway-core/src/type_system/ast_elements/trait_constraint.rs +++ b/sway-core/src/type_system/ast_elements/trait_constraint.rs @@ -15,11 +15,11 @@ use crate::{ language::{parsed::Supertrait, ty, CallPath}, semantic_analysis::{ declaration::{insert_supertraits_into_namespace, SupertraitOf}, - type_check_context::EnforceTypeArguments, TypeCheckContext, }, type_system::priv_prelude::*, types::{CollectTypesMetadata, CollectTypesMetadataContext, TypeMetadata}, + EnforceTypeArguments, }; #[derive(Debug, Clone)] @@ -98,8 +98,8 @@ impl Spanned for TraitConstraint { } impl SubstTypes for TraitConstraint { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { - self.type_arguments.subst(type_mapping, ctx) + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { + self.type_arguments.subst(ctx) } } diff --git a/sway-core/src/type_system/ast_elements/type_argument.rs b/sway-core/src/type_system/ast_elements/type_argument.rs index 03ab8ab1ec6..1476fe6627b 100644 --- a/sway-core/src/type_system/ast_elements/type_argument.rs +++ b/sway-core/src/type_system/ast_elements/type_argument.rs @@ -109,7 +109,7 @@ impl From<&TypeParameter> for TypeArgument { } impl SubstTypes for TypeArgument { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { - self.type_id.subst(type_mapping, ctx) + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { + self.type_id.subst(ctx) } } diff --git a/sway-core/src/type_system/ast_elements/type_parameter.rs b/sway-core/src/type_system/ast_elements/type_parameter.rs index 40cd55f1f50..e79a4bfce64 100644 --- a/sway-core/src/type_system/ast_elements/type_parameter.rs +++ b/sway-core/src/type_system/ast_elements/type_parameter.rs @@ -96,10 +96,10 @@ impl OrdWithEngines for TypeParameter { } impl SubstTypes for TypeParameter { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { has_changes! { - self.type_id.subst(type_mapping, ctx); - self.trait_constraints.subst(type_mapping, ctx); + self.type_id.subst(ctx); + self.trait_constraints.subst(ctx); } } } diff --git a/sway-core/src/type_system/id.rs b/sway-core/src/type_system/id.rs index 6bd1a07950d..2b72ef23fe3 100644 --- a/sway-core/src/type_system/id.rs +++ b/sway-core/src/type_system/id.rs @@ -9,10 +9,10 @@ use crate::{ decl_engine::DeclEngineGet, engine_threading::{DebugWithEngines, DisplayWithEngines, Engines, WithEngines}, language::CallPath, - semantic_analysis::type_check_context::EnforceTypeArguments, semantic_analysis::TypeCheckContext, type_system::priv_prelude::*, types::{CollectTypesMetadata, CollectTypesMetadataContext, TypeMetadata}, + EnforceTypeArguments, }; use std::{ @@ -91,9 +91,9 @@ impl CollectTypesMetadata for TypeId { } impl SubstTypes for TypeId { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { let type_engine = ctx.engines.te(); - if let Some(matching_id) = type_mapping.find_match(*self, ctx.engines) { + if let Some(matching_id) = ctx.type_subst_map.find_match(*self, ctx.engines) { if !matches!(&*type_engine.get(matching_id), TypeInfo::ErrorRecovery(_)) { *self = matching_id; HasChanges::Yes diff --git a/sway-core/src/type_system/mod.rs b/sway-core/src/type_system/mod.rs index 85407de3a4e..37446b5843c 100644 --- a/sway-core/src/type_system/mod.rs +++ b/sway-core/src/type_system/mod.rs @@ -2,6 +2,7 @@ pub(crate) mod ast_elements; mod engine; mod id; mod info; +pub(crate) mod monomorphization; mod priv_prelude; mod substitute; pub(crate) mod unify; @@ -9,6 +10,8 @@ pub(crate) mod unify; #[allow(unused)] use std::ops::Deref; +pub use substitute::subst_types::SubstTypesContext; + #[cfg(test)] use crate::language::CallPath; #[cfg(test)] @@ -21,6 +24,41 @@ use sway_types::BaseIdent; #[cfg(test)] use sway_types::{integer_bits::IntegerBits, Span}; +/// This type is used to denote if, during monomorphization, the compiler +/// should enforce that type arguments be provided. An example of that +/// might be this: +/// +/// ```ignore +/// struct Point { +/// x: u64, +/// y: u64 +/// } +/// +/// fn add(p1: Point, p2: Point) -> Point { +/// Point { +/// x: p1.x + p2.x, +/// y: p1.y + p2.y +/// } +/// } +/// ``` +/// +/// `EnforceTypeArguments` would require that the type annotations +/// for `p1` and `p2` contain `<...>`. This is to avoid ambiguous definitions: +/// +/// ```ignore +/// fn add(p1: Point, p2: Point) -> Point { +/// Point { +/// x: p1.x + p2.x, +/// y: p1.y + p2.y +/// } +/// } +/// ``` +#[derive(Clone, Copy)] +pub(crate) enum EnforceTypeArguments { + Yes, + No, +} + #[test] fn generic_enum_resolution() { use crate::{ diff --git a/sway-core/src/type_system/monomorphization.rs b/sway-core/src/type_system/monomorphization.rs new file mode 100644 index 00000000000..736e2bd3ad2 --- /dev/null +++ b/sway-core/src/type_system/monomorphization.rs @@ -0,0 +1,346 @@ +use sway_error::{ + error::CompileError, + handler::{ErrorEmitted, Handler}, +}; +use sway_types::{Ident, Span, Spanned}; + +use crate::{ + decl_engine::{engine::DeclEngineGetParsedDeclId, DeclEngineInsert}, + language::{ + ty::{self, TyDecl}, + CallPath, + }, + namespace::ModulePath, + semantic_analysis::type_resolve::resolve_type, + type_system::ast_elements::create_type_id::CreateTypeId, + EnforceTypeArguments, Engines, Namespace, SubstTypes, SubstTypesContext, TypeArgument, TypeId, + TypeInfo, TypeParameter, TypeSubstMap, +}; + +pub(crate) trait MonomorphizeHelper { + fn name(&self) -> &Ident; + fn type_parameters(&self) -> &[TypeParameter]; + fn has_self_type_param(&self) -> bool; +} + +/// Given a `value` of type `T` that is able to be monomorphized and a set +/// of `type_arguments`, prepare a `TypeSubstMap` that can be used as an +/// input for monomorphization. +#[allow(clippy::too_many_arguments)] +pub(crate) fn prepare_type_subst_map_for_monomorphize( + handler: &Handler, + engines: &Engines, + namespace: &Namespace, + value: &T, + type_arguments: &mut [TypeArgument], + enforce_type_arguments: EnforceTypeArguments, + call_site_span: &Span, + mod_path: &ModulePath, + self_type: Option, + subst_ctx: &SubstTypesContext, +) -> Result +where + T: MonomorphizeHelper + SubstTypes, +{ + fn make_type_arity_mismatch_error( + name: Ident, + span: Span, + given: usize, + expected: usize, + ) -> CompileError { + match (expected, given) { + (0, 0) => unreachable!(), + (_, 0) => CompileError::NeedsTypeArguments { name, span }, + (0, _) => CompileError::DoesNotTakeTypeArguments { name, span }, + (_, _) => CompileError::IncorrectNumberOfTypeArguments { + name, + given, + expected, + span, + }, + } + } + + match (value.type_parameters().len(), type_arguments.len()) { + (0, 0) => Ok(TypeSubstMap::default()), + (num_type_params, 0) => { + if let EnforceTypeArguments::Yes = enforce_type_arguments { + return Err(handler.emit_err(make_type_arity_mismatch_error( + value.name().clone(), + call_site_span.clone(), + 0, + num_type_params, + ))); + } + let type_mapping = TypeSubstMap::from_type_parameters(engines, value.type_parameters()); + Ok(type_mapping) + } + (0, num_type_args) => { + let type_arguments_span = type_arguments + .iter() + .map(|x| x.span.clone()) + .reduce(|s1: Span, s2: Span| Span::join(s1, &s2)) + .unwrap_or_else(|| value.name().span()); + Err(handler.emit_err(make_type_arity_mismatch_error( + value.name().clone(), + type_arguments_span.clone(), + num_type_args, + 0, + ))) + } + (_, num_type_args) => { + // a trait decl is passed the self type parameter and the corresponding argument + // but it would be confusing for the user if the error reporting mechanism + // reported the number of arguments including the implicit self, hence + // we adjust it below + let adjust_for_trait_decl = value.has_self_type_param() as usize; + let non_parent_type_params = value + .type_parameters() + .iter() + .filter(|x| !x.is_from_parent) + .count() + - adjust_for_trait_decl; + + let num_type_args = num_type_args - adjust_for_trait_decl; + if non_parent_type_params != num_type_args { + let type_arguments_span = type_arguments + .iter() + .map(|x| x.span.clone()) + .reduce(|s1: Span, s2: Span| Span::join(s1, &s2)) + .unwrap_or_else(|| value.name().span()); + + return Err(handler.emit_err(make_type_arity_mismatch_error( + value.name().clone(), + type_arguments_span, + num_type_args, + non_parent_type_params, + ))); + } + + for type_argument in type_arguments.iter_mut() { + type_argument.type_id = resolve_type( + handler, + engines, + namespace, + mod_path, + type_argument.type_id, + &type_argument.span, + enforce_type_arguments, + None, + self_type, + subst_ctx, + ) + .unwrap_or_else(|err| { + engines + .te() + .insert(engines, TypeInfo::ErrorRecovery(err), None) + }); + } + let type_mapping = TypeSubstMap::from_type_parameters_and_type_arguments( + value + .type_parameters() + .iter() + .map(|type_param| type_param.type_id) + .collect(), + type_arguments + .iter() + .map(|type_arg| type_arg.type_id) + .collect(), + ); + Ok(type_mapping) + } + } +} + +/// Given a `value` of type `T` that is able to be monomorphized and a set +/// of `type_arguments`, monomorphize `value` with the `type_arguments`. +/// +/// When this function is called, it is passed a `T` that is a copy of some +/// original declaration for `T` (let's denote the original with `[T]`). +/// Because monomorphization happens at application time (e.g. function +/// application), we want to be able to modify `value` such that type +/// checking the application of `value` affects only `T` and not `[T]`. +/// +/// So, at a high level, this function does two things. It 1) performs the +/// necessary work to refresh the relevant generic types in `T` so that they +/// are distinct from the generics of the same name in `[T]`. And it 2) +/// applies `type_arguments` (if any are provided) to the type parameters +/// of `value`, unifying the types. +/// +/// There are 4 cases that are handled in this function: +/// +/// 1. `value` does not have type parameters + `type_arguments` is empty: +/// 1a. return ok +/// 2. `value` has type parameters + `type_arguments` is empty: +/// 2a. if the [EnforceTypeArguments::Yes] variant is provided, then +/// error +/// 2b. refresh the generic types with a [TypeSubstMapping] +/// 3. `value` does have type parameters + `type_arguments` is nonempty: +/// 3a. error +/// 4. `value` has type parameters + `type_arguments` is nonempty: +/// 4a. check to see that the type parameters and `type_arguments` have +/// the same length +/// 4b. for each type argument in `type_arguments`, resolve the type +/// 4c. refresh the generic types with a [TypeSubstMapping] +#[allow(clippy::too_many_arguments)] +pub(crate) fn monomorphize_with_modpath( + handler: &Handler, + engines: &Engines, + namespace: &Namespace, + value: &mut T, + type_arguments: &mut [TypeArgument], + enforce_type_arguments: EnforceTypeArguments, + call_site_span: &Span, + mod_path: &ModulePath, + self_type: Option, + subst_ctx: &SubstTypesContext, +) -> Result<(), ErrorEmitted> +where + T: MonomorphizeHelper + SubstTypes, +{ + let type_mapping = prepare_type_subst_map_for_monomorphize( + handler, + engines, + namespace, + value, + type_arguments, + enforce_type_arguments, + call_site_span, + mod_path, + self_type, + subst_ctx, + )?; + value.subst(&SubstTypesContext::new(engines, &type_mapping, true)); + Ok(()) +} + +#[allow(clippy::too_many_arguments)] +pub(crate) fn type_decl_opt_to_type_id( + handler: &Handler, + engines: &Engines, + namespace: &Namespace, + type_decl_opt: Option, + call_path: &CallPath, + span: &Span, + enforce_type_arguments: EnforceTypeArguments, + mod_path: &ModulePath, + type_arguments: Option>, + self_type: Option, + subst_ctx: &SubstTypesContext, +) -> Result { + let decl_engine = engines.de(); + let type_engine = engines.te(); + Ok(match type_decl_opt { + Some(ty::TyDecl::StructDecl(ty::StructDecl { + decl_id: original_id, + .. + })) => { + // get the copy from the declaration engine + let mut new_copy = (*decl_engine.get_struct(&original_id)).clone(); + + // monomorphize the copy, in place + monomorphize_with_modpath( + handler, + engines, + namespace, + &mut new_copy, + &mut type_arguments.unwrap_or_default(), + enforce_type_arguments, + span, + mod_path, + self_type, + subst_ctx, + )?; + + // insert the new copy in the decl engine + let new_decl_ref = decl_engine.insert( + new_copy, + decl_engine.get_parsed_decl_id(&original_id).as_ref(), + ); + + // create the type id from the copy + type_engine.insert( + engines, + TypeInfo::Struct(*new_decl_ref.id()), + new_decl_ref.span().source_id(), + ) + } + Some(ty::TyDecl::EnumDecl(ty::EnumDecl { + decl_id: original_id, + .. + })) => { + // get the copy from the declaration engine + let mut new_copy = (*decl_engine.get_enum(&original_id)).clone(); + + // monomorphize the copy, in place + monomorphize_with_modpath( + handler, + engines, + namespace, + &mut new_copy, + &mut type_arguments.unwrap_or_default(), + enforce_type_arguments, + span, + mod_path, + self_type, + subst_ctx, + )?; + + // insert the new copy in the decl engine + let new_decl_ref = decl_engine.insert( + new_copy, + decl_engine.get_parsed_decl_id(&original_id).as_ref(), + ); + + // create the type id from the copy + type_engine.insert( + engines, + TypeInfo::Enum(*new_decl_ref.id()), + new_decl_ref.span().source_id(), + ) + } + Some(ty::TyDecl::TypeAliasDecl(ty::TypeAliasDecl { + decl_id: original_id, + .. + })) => { + let new_copy = decl_engine.get_type_alias(&original_id); + + // TODO: monomorphize the copy, in place, when generic type aliases are + // supported + + new_copy.create_type_id(engines) + } + Some(ty::TyDecl::GenericTypeForFunctionScope(ty::GenericTypeForFunctionScope { + type_id, + .. + })) => type_id, + Some(ty::TyDecl::TraitTypeDecl(ty::TraitTypeDecl { decl_id })) => { + let decl_type = decl_engine.get_type(&decl_id); + + if let Some(ty) = &decl_type.ty { + ty.type_id + } else if let Some(implementing_type) = self_type { + type_engine.insert( + engines, + TypeInfo::TraitType { + name: decl_type.name.clone(), + trait_type_id: implementing_type, + }, + decl_type.name.span().source_id(), + ) + } else { + return Err(handler.emit_err(CompileError::Internal( + "Self type not provided.", + span.clone(), + ))); + } + } + _ => { + let err = handler.emit_err(CompileError::UnknownTypeName { + name: call_path.to_string(), + span: call_path.span(), + }); + type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None) + } + }) +} diff --git a/sway-core/src/type_system/substitute/subst_list.rs b/sway-core/src/type_system/substitute/subst_list.rs deleted file mode 100644 index 4c5dad10b5f..00000000000 --- a/sway-core/src/type_system/substitute/subst_list.rs +++ /dev/null @@ -1,92 +0,0 @@ -use std::{ - hash::Hasher, - slice::{Iter, IterMut}, - vec::IntoIter, -}; - -use crate::{ - engine_threading::{ - Engines, EqWithEngines, HashWithEngines, OrdWithEngines, OrdWithEnginesContext, - PartialEqWithEngines, PartialEqWithEnginesContext, - }, - type_system::priv_prelude::*, -}; - -/// A list of types that serve as the list of type params for type substitution. -/// Any types of the [TypeParam][TypeInfo::TypeParam] variant will point to an -/// index in this list. -#[derive(Debug, Clone, Default)] -pub struct SubstList { - list: Vec, -} - -impl SubstList { - pub(crate) fn new() -> SubstList { - SubstList { list: vec![] } - } - - #[allow(dead_code)] - pub(crate) fn is_empty(&self) -> bool { - self.list.is_empty() - } - - #[allow(dead_code)] - pub(crate) fn len(&self) -> usize { - self.list.len() - } - - #[allow(dead_code)] - pub(crate) fn push(&mut self, type_param: TypeParameter) { - self.list.push(type_param); - } - - #[allow(dead_code)] - pub(crate) fn iter(&self) -> Iter<'_, TypeParameter> { - self.list.iter() - } - - #[allow(dead_code)] - pub(crate) fn into_iter(self) -> IntoIter { - self.list.into_iter() - } - - #[allow(dead_code)] - pub(crate) fn iter_mut(&mut self) -> IterMut<'_, TypeParameter> { - self.list.iter_mut() - } -} - -impl std::iter::FromIterator for SubstList { - fn from_iter>(iter: T) -> Self { - SubstList { - list: iter.into_iter().collect::>(), - } - } -} - -impl EqWithEngines for SubstList {} -impl PartialEqWithEngines for SubstList { - fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool { - self.list.eq(&other.list, ctx) - } -} - -impl HashWithEngines for SubstList { - fn hash(&self, state: &mut H, engines: &Engines) { - self.list.hash(state, engines); - } -} - -impl OrdWithEngines for SubstList { - fn cmp(&self, other: &Self, ctx: &OrdWithEnginesContext) -> std::cmp::Ordering { - let SubstList { list: ll } = self; - let SubstList { list: rl } = other; - ll.cmp(rl, ctx) - } -} - -impl SubstTypes for SubstList { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { - self.list.subst(type_mapping, ctx) - } -} diff --git a/sway-core/src/type_system/substitute/subst_types.rs b/sway-core/src/type_system/substitute/subst_types.rs index b6fcf5322d2..f5107ebd59a 100644 --- a/sway-core/src/type_system/substitute/subst_types.rs +++ b/sway-core/src/type_system/substitute/subst_types.rs @@ -24,57 +24,60 @@ impl std::ops::BitOr for HasChanges { } } -pub struct SubstTypesContext<'a> { +pub struct SubstTypesContext<'a, 'b> { pub engines: &'a Engines, + pub type_subst_map: &'b TypeSubstMap, pub subst_function_body: bool, } -impl<'a> SubstTypesContext<'a> { - pub fn new(engines: &Engines, subst_function_body: bool) -> SubstTypesContext { +impl<'a, 'b> SubstTypesContext<'a, 'b> { + pub fn new( + engines: &'a Engines, + type_subst_map: &'b TypeSubstMap, + subst_function_body: bool, + ) -> SubstTypesContext<'a, 'b> { SubstTypesContext { engines, + type_subst_map, subst_function_body, } } } pub trait SubstTypes { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges; + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges; - fn subst(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { - if type_mapping.is_empty() { + fn subst(&mut self, ctx: &SubstTypesContext) -> HasChanges { + if ctx.type_subst_map.is_empty() { HasChanges::No } else { - self.subst_inner(type_mapping, ctx) + self.subst_inner(ctx) } } } impl SubstTypes for (A, B) { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { - self.1.subst(type_mapping, ctx) + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { + self.1.subst(ctx) } } impl SubstTypes for Box { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { - self.as_mut().subst(type_mapping, ctx) + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { + self.as_mut().subst(ctx) } } impl SubstTypes for Option { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { - self.as_mut() - .map(|x| x.subst(type_mapping, ctx)) - .unwrap_or_default() + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { + self.as_mut().map(|x| x.subst(ctx)).unwrap_or_default() } } impl SubstTypes for Vec { - fn subst_inner(&mut self, type_mapping: &TypeSubstMap, ctx: &SubstTypesContext) -> HasChanges { - self.iter_mut().fold(HasChanges::No, |has_change, x| { - x.subst(type_mapping, ctx) | has_change - }) + fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges { + self.iter_mut() + .fold(HasChanges::No, |has_change, x| x.subst(ctx) | has_change) } } From 79170dbecb06d325a017456bbb75ac5ac20a2e5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaya=20G=C3=B6kalp?= Date: Mon, 21 Oct 2024 16:27:08 -0700 Subject: [PATCH 070/115] ci: move to buildjet (#6656) ## Description Moves CI runners to buildjet from github. ## Benchmarks | | before | after | |---------|--------|-------| | total | 6823 | 4815 | | slowest | 1004 | 717 | Overall, %30 faster CI times, ~5 minutes removed for each PR in slowest run (e2e testing). --- .github/workflows/ci.yml | 108 ++++++++++++++++++++++++++++----------- 1 file changed, 77 insertions(+), 31 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c0a6c041059..58be69c8e88 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ env: jobs: get-fuel-core-version: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 outputs: fuel_core_version: ${{steps.get_fuel_core_ver.outputs.version}} steps: @@ -40,7 +40,7 @@ jobs: echo "version=$version" >> "$GITHUB_OUTPUT" build-sway-lib-core: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 steps: - uses: actions/checkout@v3 - name: Install toolchain @@ -48,13 +48,15 @@ jobs: with: toolchain: ${{ env.RUST_VERSION }} - uses: Swatinem/rust-cache@v2 + with: + cache-provider: "buildjet" - name: Install Forc run: cargo install --locked --debug --path ./forc - name: Build sway-lib-core run: forc build --path sway-lib-core build-sway-lib-std: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 steps: - uses: actions/checkout@v3 - name: Install toolchain @@ -62,13 +64,15 @@ jobs: with: toolchain: ${{ env.RUST_VERSION }} - uses: Swatinem/rust-cache@v2 + with: + cache-provider: "buildjet" - name: Install Forc run: cargo install --locked --debug --path ./forc - name: Build sway-lib-std run: forc build --path sway-lib-std build-sway-examples: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 steps: - uses: actions/checkout@v3 - name: Install toolchain @@ -76,11 +80,13 @@ jobs: with: toolchain: ${{ env.RUST_VERSION }} - uses: Swatinem/rust-cache@v2 + with: + cache-provider: "buildjet" - name: Build Sway examples workspace run: cargo run --locked -p forc -- build --locked --path ./examples/Forc.toml build-reference-examples: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 steps: - uses: actions/checkout@v3 - name: Install toolchain @@ -88,11 +94,13 @@ jobs: with: toolchain: ${{ env.RUST_VERSION }} - uses: Swatinem/rust-cache@v2 + with: + cache-provider: "buildjet" - name: Build Sway examples workspace run: cargo run --locked -p forc -- build --locked --path ./docs/reference/src/code/Forc.toml forc-fmt-check-sway-lib-core: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 steps: - uses: actions/checkout@v3 - name: Install toolchain @@ -100,11 +108,13 @@ jobs: with: toolchain: ${{ env.RUST_VERSION }} - uses: Swatinem/rust-cache@v2 + with: + cache-provider: "buildjet" - name: Check Sway sway-lib-core formatting run: cargo run --locked -p forc-fmt -- --check --path ./sway-lib-core forc-fmt-check-sway-lib-std: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 steps: - uses: actions/checkout@v3 - name: Install toolchain @@ -112,11 +122,13 @@ jobs: with: toolchain: ${{ env.RUST_VERSION }} - uses: Swatinem/rust-cache@v2 + with: + cache-provider: "buildjet" - name: Check Sway sway-lib-std formatting run: cargo run --locked -p forc-fmt -- --check --path ./sway-lib-std forc-fmt-check-sway-examples: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 steps: - uses: actions/checkout@v3 - name: Install toolchain @@ -124,11 +136,13 @@ jobs: with: toolchain: ${{ env.RUST_VERSION }} - uses: Swatinem/rust-cache@v2 + with: + cache-provider: "buildjet" - name: Check Sway examples formatting run: cargo run --locked -p forc-fmt -- --check --path ./examples forc-fmt-check-panic: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 steps: - uses: actions/checkout@v3 - name: Install toolchain @@ -136,13 +150,15 @@ jobs: with: toolchain: ${{ env.RUST_VERSION }} - uses: Swatinem/rust-cache@v2 + with: + cache-provider: "buildjet" - name: Install forc-fmt run: cargo install --locked --debug --path ./forc-plugins/forc-fmt - name: Run the formatter against all sway projects and fail if any of them panic run: scripts/formatter/forc-fmt-check-panic.sh check-sdk-harness-test-suite-compatibility: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 steps: - name: Checkout code uses: actions/checkout@v2 @@ -219,7 +235,7 @@ jobs: fi build-forc-doc-sway-lib-std: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 steps: - uses: actions/checkout@v3 - name: Install toolchain @@ -227,6 +243,8 @@ jobs: with: toolchain: ${{ env.RUST_VERSION }} - uses: Swatinem/rust-cache@v2 + with: + cache-provider: "buildjet" - name: Install Forc run: cargo install --locked --debug --path ./forc - name: Install Forc plugins @@ -236,7 +254,7 @@ jobs: run: forc doc --manifest-path ./sway-lib-std build-forc-test-project: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 steps: - uses: actions/checkout@v3 - name: Install toolchain @@ -245,6 +263,8 @@ jobs: toolchain: ${{ env.RUST_VERSION }} targets: wasm32-unknown-unknown - uses: Swatinem/rust-cache@v2 + with: + cache-provider: "buildjet" - name: Install Forc run: cargo install --locked --debug --path ./forc - name: Initialize test project @@ -279,13 +299,15 @@ jobs: with: toolchain: ${{ env.RUST_VERSION }} - uses: Swatinem/rust-cache@v2 + with: + cache-provider: "buildjet" - name: "Build Workspace" run: cargo build --locked --workspace --all-features --all-targets env: RUSTFLAGS: "-D warnings" cargo-clippy: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 steps: - uses: actions/checkout@v3 - name: Install toolchain @@ -294,11 +316,13 @@ jobs: toolchain: ${{ env.RUST_VERSION }} components: clippy - uses: Swatinem/rust-cache@v2 + with: + cache-provider: "buildjet" - name: Check Clippy Linter run: cargo clippy --all-features --all-targets -- -D warnings cargo-toml-fmt-check: - runs-on: ubuntu-latest + runs-on: ubuntu-latest # Switching this runner to buildjet causes failure. steps: - uses: actions/checkout@v3 - name: Install toolchain @@ -314,7 +338,7 @@ jobs: run: git ls-files | grep Cargo.toml$ | grep -v 'templates/' | xargs --verbose -n 1 cargo-toml-lint cargo-fmt-check: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 steps: - uses: actions/checkout@v3 - name: Install toolchain @@ -326,7 +350,7 @@ jobs: run: cargo fmt --all -- --check cargo-run-e2e-test: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 needs: get-fuel-core-version steps: - uses: actions/checkout@v3 @@ -336,6 +360,8 @@ jobs: toolchain: ${{ env.RUST_VERSION }} targets: "x86_64-unknown-linux-gnu, wasm32-unknown-unknown" - uses: Swatinem/rust-cache@v2 + with: + cache-provider: "buildjet" - name: Install fuel-core for tests run: | curl -sSLf https://github.com/FuelLabs/fuel-core/releases/download/v${{ needs.get-fuel-core-version.outputs.fuel_core_version }}/fuel-core-${{ needs.get-fuel-core-version.outputs.fuel_core_version }}-x86_64-unknown-linux-gnu.tar.gz -L -o fuel-core.tar.gz @@ -349,7 +375,7 @@ jobs: cargo run --locked --release --bin test -- --locked cargo-run-e2e-test-release: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 needs: get-fuel-core-version steps: - uses: actions/checkout@v3 @@ -359,6 +385,8 @@ jobs: toolchain: ${{ env.RUST_VERSION }} targets: "x86_64-unknown-linux-gnu, wasm32-unknown-unknown" - uses: Swatinem/rust-cache@v2 + with: + cache-provider: "buildjet" - name: Install fuel-core for tests run: | curl -sSLf https://github.com/FuelLabs/fuel-core/releases/download/v${{ needs.get-fuel-core-version.outputs.fuel_core_version }}/fuel-core-${{ needs.get-fuel-core-version.outputs.fuel_core_version }}-x86_64-unknown-linux-gnu.tar.gz -L -o fuel-core.tar.gz @@ -372,7 +400,7 @@ jobs: cargo run --locked --release --bin test -- --locked --release cargo-run-e2e-test-evm: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 steps: - uses: actions/checkout@v3 - name: Install toolchain @@ -381,6 +409,8 @@ jobs: toolchain: ${{ env.RUST_VERSION }} targets: "x86_64-unknown-linux-gnu, wasm32-unknown-unknown" - uses: Swatinem/rust-cache@v2 + with: + cache-provider: "buildjet" - name: Cargo Run E2E Tests (EVM) run: cargo run --locked --release --bin test -- --target evm --locked --no-encoding-v1 @@ -406,7 +436,7 @@ jobs: run: cargo test --locked --release --manifest-path ./test/src/sdk-harness/Cargo.toml -- --nocapture forc-run-benchmarks: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 permissions: contents: write steps: @@ -416,6 +446,8 @@ jobs: with: toolchain: ${{ env.RUST_VERSION }} - uses: Swatinem/rust-cache@v2 + with: + cache-provider: "buildjet" - name: Install Forc run: cargo install --locked --debug --path ./forc - name: Run benchmarks @@ -443,7 +475,7 @@ jobs: default_author: github_actions forc-unit-tests: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 steps: - uses: actions/checkout@v3 - name: Install toolchain @@ -451,6 +483,8 @@ jobs: with: toolchain: ${{ env.RUST_VERSION }} - uses: Swatinem/rust-cache@v2 + with: + cache-provider: "buildjet" - name: Install Forc run: cargo install --locked --debug --path ./forc - name: Run Core Unit Tests @@ -461,7 +495,7 @@ jobs: run: forc build --path test/src/in_language_tests && forc test --path test/src/in_language_tests forc-pkg-fuels-deps-check: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 steps: - uses: actions/checkout@v3 - name: Install toolchain @@ -469,6 +503,8 @@ jobs: with: toolchain: ${{ env.RUST_VERSION }} - uses: Swatinem/rust-cache@v2 + with: + cache-provider: "buildjet" # We require this check to avoid cyclic dependencies between 'fuels' and 'forc-pkg'. # Detailed explanation is found in the echo below. @@ -492,7 +528,7 @@ jobs: ;; esac cargo-test-forc-debug: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 needs: get-fuel-core-version steps: - uses: actions/checkout@v3 @@ -502,6 +538,8 @@ jobs: toolchain: ${{ env.RUST_VERSION }} targets: "x86_64-unknown-linux-gnu, wasm32-unknown-unknown" - uses: Swatinem/rust-cache@v2 + with: + cache-provider: "buildjet" - name: Install fuel-core for tests run: | curl -sSLf https://github.com/FuelLabs/fuel-core/releases/download/v${{ needs.get-fuel-core-version.outputs.fuel_core_version }}/fuel-core-${{ needs.get-fuel-core-version.outputs.fuel_core_version }}-x86_64-unknown-linux-gnu.tar.gz -L -o fuel-core.tar.gz @@ -511,7 +549,7 @@ jobs: - name: Run tests run: cargo test --locked --release -p forc-debug cargo-test-forc-client: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 needs: get-fuel-core-version steps: - uses: actions/checkout@v3 @@ -521,6 +559,8 @@ jobs: toolchain: ${{ env.RUST_VERSION }} targets: "x86_64-unknown-linux-gnu, wasm32-unknown-unknown" - uses: Swatinem/rust-cache@v2 + with: + cache-provider: "buildjet" - name: Install fuel-core for tests run: | curl -sSLf https://github.com/FuelLabs/fuel-core/releases/download/v${{ needs.get-fuel-core-version.outputs.fuel_core_version }}/fuel-core-${{ needs.get-fuel-core-version.outputs.fuel_core_version }}-x86_64-unknown-linux-gnu.tar.gz -L -o fuel-core.tar.gz @@ -530,7 +570,7 @@ jobs: - name: Run tests run: cargo test --locked --release -p forc-client -- --test-threads 1 cargo-test-sway-lsp: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 steps: - uses: actions/checkout@v3 - name: Setup Rust and cargo-nextest @@ -544,7 +584,7 @@ jobs: RUST_BACKTRACE: full run: cargo nextest run --locked --release -p sway-lsp --no-capture --profile ci --config-file sway-lsp/tests/nextest.toml cargo-test-forc: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 steps: - uses: actions/checkout@v3 - name: Install toolchain @@ -552,12 +592,14 @@ jobs: with: toolchain: ${{ env.RUST_VERSION }} - uses: Swatinem/rust-cache@v2 + with: + cache-provider: "buildjet" - name: Run forc tests separately env: RUST_BACKTRACE: full run: cargo test --locked --release -p forc -- --nocapture cargo-test-workspace: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 steps: - uses: actions/checkout@v3 - name: Install toolchain @@ -565,10 +607,12 @@ jobs: with: toolchain: ${{ env.RUST_VERSION }} - uses: Swatinem/rust-cache@v2 + with: + cache-provider: "buildjet" - name: Run tests run: cargo test --locked --release --workspace --exclude forc-debug --exclude sway-lsp --exclude forc-client --exclude forc cargo-unused-deps-check: - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 steps: - uses: actions/checkout@v3 - name: Install toolchain @@ -577,6 +621,8 @@ jobs: # `cargo-udeps` requires nightly to run toolchain: ${{ env.NIGHTLY_RUST_VERSION }} - uses: Swatinem/rust-cache@v2 + with: + cache-provider: "buildjet" - name: Install cargo-udeps run: cargo install --locked cargo-udeps - name: Check Unused Deps @@ -599,7 +645,7 @@ jobs: cargo-test-sway-lsp, cargo-unused-deps-check, ] - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 steps: - name: Notify Slack On Failure uses: ravsamhq/notify-slack-action@v2 @@ -618,7 +664,7 @@ jobs: # This is a separate job because we want this to fail fast if something is invalid here. pre-publish-check: if: github.event_name == 'release' && github.event.action == 'published' - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 steps: - name: Checkout repository uses: actions/checkout@v3 @@ -714,7 +760,7 @@ jobs: cargo-unused-deps-check, ] if: github.ref == 'refs/heads/master' - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 permissions: contents: read packages: write @@ -776,7 +822,7 @@ jobs: build-publish-release-image: # Build & Publish Docker Image Per Sway Release needs: publish - runs-on: ubuntu-latest + runs-on: buildjet-4vcpu-ubuntu-2204 permissions: contents: read packages: write From 492db76fe9651e68b0beec569bd6fa35f54274de Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite Date: Tue, 22 Oct 2024 19:02:58 +0100 Subject: [PATCH 071/115] Function dedup conf decode (#6623) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description This PR improves `fn_dedup` to also deduplicate config decode functions. Given how early this optimization was running, some optimizations were being lost, because some functions only get identical at the final IR. I believe we chose to run this early to decrease the pressure in other passes, but to allow this pass to really coalesce decodes I think makes sense to run it again at the end. I am also deleting from the IR functions that were being replaced. This allowed the new test to decrease around 100 bytes. Our old configurable test went from 7600 to 7250 bytes. ![image](https://github.com/user-attachments/assets/b08d22f9-289b-44a7-b939-353e0e7f6abb) ## 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. - [ ] 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). - [ ] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: Joshua Batty Co-authored-by: IGI-111 Co-authored-by: Kaya Gökalp --- Cargo.lock | 1098 +++++++++-------- forc-plugins/forc-client/tests/deploy.rs | 8 +- .../asm_generation/fuel/fuel_asm_builder.rs | 2 +- sway-core/src/ir_generation/compile.rs | 4 +- sway-ir/src/module.rs | 7 +- sway-ir/src/optimize/dce.rs | 2 +- sway-ir/src/optimize/fn_dedup.rs | 33 + sway-ir/src/parser.rs | 5 +- sway-ir/src/pass_manager.rs | 1 + sway-ir/src/printer.rs | 2 +- test/Cargo.toml | 2 + .../array_wrong_elements_types/stdout.snap | 7 +- .../type_check_analyze_errors/stdout.snap | 7 +- .../json_abi_oracle_new_encoding.json | 32 +- .../configurable_dedup_decode/Forc.lock | 13 + .../configurable_dedup_decode/Forc.toml | 8 + .../json_abi_oracle.json | 284 +++++ .../json_abi_oracle_new_encoding.json | 228 ++++ .../configurable_dedup_decode/snapshot.toml | 1 + .../configurable_dedup_decode/src/main.sw | 16 + .../configurable_dedup_decode/stdout.snap | 361 ++++++ .../call_basic_storage/src/main.sw | 2 +- .../storage_access_caller/src/main.sw | 2 +- test/tests/tests.rs | 93 +- 24 files changed, 1653 insertions(+), 565 deletions(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/json_abi_oracle.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/json_abi_oracle_new_encoding.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/snapshot.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/stdout.snap diff --git a/Cargo.lock b/Cargo.lock index d7bc78caa7e..a858d89ffa4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,18 +14,18 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ - "gimli 0.29.0", + "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "aes" @@ -85,54 +85,46 @@ checksum = "0069cf0642457f87a01a014f6dc29d5d893cd4fd8fddf0c3cdfad1bb3ebafc41" dependencies = [ "alloy-primitives", "alloy-rlp", + "serde", ] [[package]] name = "alloy-eip7702" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d319bb544ca6caeab58c39cea8921c55d924d4f68f2c60f24f914673f9a74a" +checksum = "ea59dc42102bc9a1905dc57901edc6dd48b9f38115df86c7d252acba70d71d04" dependencies = [ "alloy-primitives", "alloy-rlp", "k256", -] - -[[package]] -name = "alloy-eips" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f923dd5fca5f67a43d81ed3ebad0880bd41f6dd0ada930030353ac356c54cd0f" -dependencies = [ - "alloy-eip2930", - "alloy-eip7702", - "alloy-primitives", - "alloy-rlp", - "c-kzg", - "derive_more 1.0.0", - "once_cell", "serde", ] [[package]] name = "alloy-primitives" -version = "0.8.3" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "411aff151f2a73124ee473708e82ed51b2535f68928b6a1caa8bc1246ae6f7cd" +checksum = "38f35429a652765189c1c5092870d8360ee7b7769b09b06d89ebaefd34676446" dependencies = [ "alloy-rlp", "bytes", "cfg-if 1.0.0", "const-hex", "derive_more 1.0.0", + "foldhash", + "hashbrown 0.15.0", "hex-literal", + "indexmap 2.6.0", "itoa", "k256", "keccak-asm", + "paste", "proptest", "rand", "ruint", + "rustc-hash 2.0.0", "serde", + "sha3", "tiny-keccak", ] @@ -155,7 +147,7 @@ checksum = "4d0f2d905ebd295e7effec65e5f6868d153936130ae718352771de3e7d03c75c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -249,9 +241,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "arc-swap" @@ -293,7 +285,7 @@ dependencies = [ "num-bigint", "num-traits", "paste", - "rustc_version 0.4.0", + "rustc_version 0.4.1", "zeroize", ] @@ -385,15 +377,15 @@ dependencies = [ [[package]] name = "arrayref" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "ascii" @@ -425,13 +417,13 @@ checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" [[package]] name = "async-trait" -version = "0.1.81" +version = "0.1.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -478,20 +470,20 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "aws-config" -version = "1.5.6" +version = "1.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "848d7b9b605720989929279fa644ce8f244d0ce3146fcca5b70e4eb7b3c020fc" +checksum = "7198e6f03240fdceba36656d8be440297b6b82270325908c7381f37d826a74f6" dependencies = [ "aws-credential-types", "aws-runtime", @@ -551,14 +543,14 @@ dependencies = [ "percent-encoding", "pin-project-lite", "tracing", - "uuid 1.10.0", + "uuid 1.11.0", ] [[package]] name = "aws-sdk-kms" -version = "1.44.0" +version = "1.47.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6550445e0913c9383375f4a5a2f550817567a19a178107fce1e1afd767f802a" +checksum = "564a597a3c71a957d60a2e4c62c93d78ee5a0d636531e15b760acad983a5c18e" dependencies = [ "aws-credential-types", "aws-runtime", @@ -578,9 +570,9 @@ dependencies = [ [[package]] name = "aws-sdk-sso" -version = "1.43.0" +version = "1.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a9d27ed1c12b1140c47daf1bc541606c43fdafd918c4797d520db0043ceef2" +checksum = "0dc2faec3205d496c7e57eff685dd944203df7ce16a4116d0281c44021788a7b" dependencies = [ "aws-credential-types", "aws-runtime", @@ -600,9 +592,9 @@ dependencies = [ [[package]] name = "aws-sdk-ssooidc" -version = "1.44.0" +version = "1.47.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44514a6ca967686cde1e2a1b81df6ef1883d0e3e570da8d8bc5c491dcb6fc29b" +checksum = "c93c241f52bc5e0476e259c953234dab7e2a35ee207ee202e86c0095ec4951dc" dependencies = [ "aws-credential-types", "aws-runtime", @@ -622,9 +614,9 @@ dependencies = [ [[package]] name = "aws-sdk-sts" -version = "1.43.0" +version = "1.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7a4d279762a35b9df97209f6808b95d4fe78547fe2316b4d200a0283960c5a" +checksum = "b259429be94a3459fa1b00c5684faee118d74f9577cc50aebadc36e507c63b5f" dependencies = [ "aws-credential-types", "aws-runtime", @@ -718,9 +710,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1ce695746394772e7000b39fe073095db6d45a862d0767dd5ad0ac0d7f8eb87" +checksum = "a065c0fe6fdbdf9f11817eb68582b2ab4aff9e9c39e986ae48f7ec576c6322db" dependencies = [ "aws-smithy-async", "aws-smithy-http", @@ -733,7 +725,7 @@ dependencies = [ "http-body 0.4.6", "http-body 1.0.1", "httparse", - "hyper 0.14.30", + "hyper 0.14.31", "hyper-rustls 0.24.2", "once_cell", "pin-project-lite", @@ -762,9 +754,9 @@ dependencies = [ [[package]] name = "aws-smithy-types" -version = "1.2.6" +version = "1.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03701449087215b5369c7ea17fef0dd5d24cb93439ec5af0c7615f58c3f22605" +checksum = "147100a7bea70fa20ef224a6bad700358305f5dc0f84649c53769761395b355b" dependencies = [ "base64-simd", "bytes", @@ -805,24 +797,24 @@ dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", "aws-smithy-types", - "rustc_version 0.4.0", + "rustc_version 0.4.1", "tracing", ] [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if 1.0.0", "libc", "miniz_oxide", "object", "rustc-demangle", "serde", + "windows-targets 0.52.6", ] [[package]] @@ -909,9 +901,9 @@ checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" [[package]] name = "bitflags" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" @@ -990,10 +982,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" dependencies = [ "once_cell", - "proc-macro-crate 3.1.0", + "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", "syn_derive", ] @@ -1014,7 +1006,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" dependencies = [ "memchr", - "regex-automata 0.4.7", + "regex-automata 0.4.8", "serde", ] @@ -1077,9 +1069,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "bytes-utils" @@ -1124,9 +1116,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.1.12" +version = "1.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68064e60dbf1f17005c2fde4d07c16d8baa506fd7ffed8ccab702d93617975c7" +checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945" dependencies = [ "jobserver", "libc", @@ -1223,7 +1215,7 @@ checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ "ansi_term", "atty", - "bitflags 1.2.1", + "bitflags 1.3.2", "strsim 0.8.0", "textwrap 0.11.0", "unicode-width", @@ -1232,9 +1224,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.16" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", "clap_derive", @@ -1242,9 +1234,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.15" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstream", "anstyle", @@ -1255,11 +1247,11 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.16" +version = "4.5.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c677cd0126f3026d8b093fa29eae5d812fde5c05bc66dbb29d0374eea95113a" +checksum = "9646e2e245bf62f45d39a0f3f36f1171ad1ea0d6967fd114bca72cb02a8fcdfb" dependencies = [ - "clap 4.5.16", + "clap 4.5.20", ] [[package]] @@ -1268,20 +1260,20 @@ version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d494102c8ff3951810c72baf96910b980fb065ca5d3101243e6a8dc19747c86b" dependencies = [ - "clap 4.5.16", + "clap 4.5.20", "clap_complete", ] [[package]] name = "clap_derive" -version = "4.5.13" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -1307,9 +1299,9 @@ checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" [[package]] name = "codspeed" -version = "2.6.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a104ac948e0188b921eb3fcbdd55dcf62e542df4c7ab7e660623f6288302089" +checksum = "450a0e9df9df1c154156f4344f99d8f6f6e69d0fc4de96ef6e2e68b2ec3bce97" dependencies = [ "colored", "libc", @@ -1318,9 +1310,9 @@ dependencies = [ [[package]] name = "codspeed-criterion-compat" -version = "2.6.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "722c36bdc62d9436d027256ce2627af81ac7a596dfc7d13d849d0d212448d7fe" +checksum = "8eb1a6cb9c20e177fde58cdef97c1c7c9264eb1424fe45c4fccedc2fb078a569" dependencies = [ "codspeed", "colored", @@ -1438,9 +1430,9 @@ checksum = "410de1ffe61368aa040f599747584e9e3d19235cf4045be6159edb167ef45ddb" [[package]] name = "completest-pty" -version = "0.5.3" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3635aa91b48c47ea30fe12fe7c04efbbf17dade642d4dbaa1e9cfbf3593eed4a" +checksum = "fbd2f22a999db122bd2861c504aa363bbacaa32ebea29edf6924ee6cfe044313" dependencies = [ "completest", "ptyprocess", @@ -1454,7 +1446,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c93ab3577cca16b4a1d80a88c2e0cd8b6e969e51696f0bbb0d1dcb0157109832" dependencies = [ "caseless", - "clap 4.5.16", + "clap 4.5.20", "derive_builder", "entities", "memchr", @@ -1483,9 +1475,9 @@ dependencies = [ [[package]] name = "const-hex" -version = "1.12.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8a24a26d37e1ffd45343323dc9fe6654ceea44c12f2fcb3d7ac29e610bc6" +checksum = "0121754e84117e65f9d90648ee6aa4882a6e63110307ab73967a4c5e7e69e586" dependencies = [ "cfg-if 1.0.0", "cpufeatures", @@ -1576,9 +1568,9 @@ checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636" [[package]] name = "cpufeatures" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] @@ -1601,7 +1593,7 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.5.16", + "clap 4.5.20", "criterion-plot", "is-terminal", "itertools 0.10.5", @@ -1630,9 +1622,9 @@ dependencies = [ [[package]] name = "critical-section" -version = "1.1.2" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" [[package]] name = "crossbeam-channel" @@ -1747,7 +1739,7 @@ dependencies = [ "curve25519-dalek-derive", "digest 0.10.7", "fiat-crypto", - "rustc_version 0.4.0", + "rustc_version 0.4.1", "subtle", ] @@ -1759,7 +1751,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -1858,7 +1850,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -1880,7 +1872,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core 0.20.10", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -1980,33 +1972,33 @@ dependencies = [ [[package]] name = "derive_builder" -version = "0.20.1" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd33f37ee6a119146a1781d3356a7c26028f83d779b2e04ecd45fdc75c76877b" +checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" dependencies = [ "derive_builder_macro", ] [[package]] name = "derive_builder_core" -version = "0.20.1" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7431fa049613920234f22c47fdc33e6cf3ee83067091ea4277a3f8c4587aae38" +checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] name = "derive_builder_macro" -version = "0.20.1" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4abae7035bf79b9877b779505d8cf3749285b80c43941eda66604841889451dc" +checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -2018,8 +2010,8 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "rustc_version 0.4.0", - "syn 2.0.74", + "rustc_version 0.4.1", + "syn 2.0.79", ] [[package]] @@ -2039,7 +2031,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", "unicode-xid", ] @@ -2198,6 +2190,18 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" +[[package]] +name = "duct" +version = "0.13.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4ab5718d1224b63252cd0c6f74f6480f9ffeb117438a2e0f5cf6d9a4798929c" +dependencies = [ + "libc", + "once_cell", + "os_pipe", + "shared_child", +] + [[package]] name = "dyn-clone" version = "1.0.17" @@ -2282,6 +2286,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + [[package]] name = "encode_unicode" version = "0.3.6" @@ -2332,7 +2342,7 @@ checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -2345,7 +2355,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -2356,7 +2366,7 @@ checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -2494,7 +2504,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43ddc25e1ad2cc0106d5e2d967397b4fb2068a66677ee9b0eea4600e5cfe8fb4" dependencies = [ "futures", - "hyper 0.14.30", + "hyper 0.14.31", "hyper-rustls 0.24.2", "hyper-timeout", "log", @@ -2521,7 +2531,7 @@ checksum = "dd65f1b59dd22d680c7a626cc4a000c1e03d241c51c3e034d2bc9f1e90734f9b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -2548,9 +2558,9 @@ checksum = "a2a2b11eda1d40935b26cf18f6833c526845ae8c41e58d09af6adeb6f0269183" [[package]] name = "fastrand" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fastrlp" @@ -2613,9 +2623,9 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.24" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf401df4a4e3872c4fe8151134cf483738e74b67fc934d6532c882b3d24a4550" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" dependencies = [ "cfg-if 1.0.0", "libc", @@ -2643,9 +2653,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.31" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f211bbe8e69bbd0cfdea405084f128ae8b4aaa6b0b522fc8f2b009084797920" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" dependencies = [ "crc32fast", "miniz_oxide", @@ -2657,6 +2667,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" + [[package]] name = "forc" version = "0.66.2" @@ -2664,7 +2680,7 @@ dependencies = [ "annotate-snippets", "ansi_term", "anyhow", - "clap 4.5.16", + "clap 4.5.20", "clap_complete", "clap_complete_fig", "completest-pty", @@ -2686,7 +2702,7 @@ dependencies = [ "term-table", "tokio", "toml 0.8.19", - "toml_edit 0.22.20", + "toml_edit", "tracing", "url", "uwuify", @@ -2703,7 +2719,7 @@ dependencies = [ "aws-config", "aws-sdk-kms", "chrono", - "clap 4.5.16", + "clap 4.5.20", "devault", "dialoguer", "forc", @@ -2737,7 +2753,7 @@ dependencies = [ "sway-utils", "tempfile", "tokio", - "toml_edit 0.22.20", + "toml_edit", "tracing", ] @@ -2748,7 +2764,7 @@ dependencies = [ "anyhow", "async-trait", "atty", - "clap 4.5.16", + "clap 4.5.20", "forc-tracing 0.66.2", "forc-util", "fuel-core-types", @@ -2762,7 +2778,7 @@ dependencies = [ "serde_json", "serde_yaml", "sha3", - "termion 4.0.2", + "termion 4.0.3", "tokio", "tracing", ] @@ -2772,7 +2788,7 @@ name = "forc-debug" version = "0.66.2" dependencies = [ "anyhow", - "clap 4.5.16", + "clap 4.5.20", "dap", "escargot", "forc-pkg", @@ -2798,7 +2814,7 @@ name = "forc-doc" version = "0.66.2" dependencies = [ "anyhow", - "clap 4.5.16", + "clap 4.5.20", "comrak", "dir_indexer", "expect-test", @@ -2823,7 +2839,7 @@ name = "forc-fmt" version = "0.66.2" dependencies = [ "anyhow", - "clap 4.5.16", + "clap 4.5.20", "forc-pkg", "forc-tracing 0.66.2", "forc-util", @@ -2840,7 +2856,7 @@ name = "forc-lsp" version = "0.66.2" dependencies = [ "anyhow", - "clap 4.5.16", + "clap 4.5.20", "sway-lsp", "tikv-jemallocator", "tokio", @@ -2864,7 +2880,7 @@ dependencies = [ "ipfs-api-backend-hyper", "petgraph", "regex", - "reqwest 0.12.5", + "reqwest 0.12.8", "semver 1.0.23", "serde", "serde_ignored", @@ -2925,7 +2941,7 @@ name = "forc-tx" version = "0.66.2" dependencies = [ "anyhow", - "clap 4.5.16", + "clap 4.5.20", "devault", "forc-util", "fuel-tx", @@ -2942,7 +2958,7 @@ dependencies = [ "annotate-snippets", "ansi_term", "anyhow", - "clap 4.5.16", + "clap 4.5.20", "dirs 5.0.1", "fd-lock", "forc-tracing 0.66.2", @@ -2969,7 +2985,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e6ad4498ecab72fa7c5e134ade0137279d1b8f4a6df50963bb3803fdeb69dac" dependencies = [ "anyhow", - "clap 4.5.16", + "clap 4.5.20", "eth-keystore", "forc-tracing 0.47.0", "fuel-crypto", @@ -3040,7 +3056,7 @@ dependencies = [ "regex", "serde", "serde_json", - "syn 2.0.74", + "syn 2.0.79", "thiserror", ] @@ -3221,7 +3237,7 @@ checksum = "ab0bc46a3552964bae5169e79b383761a54bd115ea66951a1a7a229edcefa55a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", "synstructure 0.13.1", ] @@ -3416,7 +3432,7 @@ dependencies = [ "quote", "regex", "serde_json", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -3458,7 +3474,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -3512,9 +3528,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -3527,9 +3543,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -3537,15 +3553,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -3554,38 +3570,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -3633,18 +3649,12 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" - -[[package]] -name = "gimli" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" dependencies = [ "fallible-iterator", - "indexmap 2.5.0", + "indexmap 2.6.0", "stable_deref_trait", ] @@ -3686,9 +3696,9 @@ dependencies = [ [[package]] name = "gix-path" -version = "0.10.9" +version = "0.10.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d23d5bbda31344d8abc8de7c075b3cf26e5873feba7c4a15d916bce67382bd9" +checksum = "ebfc4febd088abdcbc9f1246896e57e37b7a34f6909840045a1767c6dafac7af" dependencies = [ "bstr", "gix-trace", @@ -3699,15 +3709,15 @@ dependencies = [ [[package]] name = "gix-trace" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f924267408915fddcd558e3f37295cc7d6a3e50f8bd8b606cee0808c3915157e" +checksum = "6cae0e8661c3ff92688ce1c8b8058b3efb312aba9492bbe93661a21705ab431b" [[package]] name = "gix-url" -version = "0.27.4" +version = "0.27.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2eb9b35bba92ea8f0b5ab406fad3cf6b87f7929aa677ff10aa042c6da621156" +checksum = "fd280c5e84fb22e128ed2a053a0daeacb6379469be6a85e3d518a0636e160c89" dependencies = [ "bstr", "gix-features", @@ -3733,8 +3743,8 @@ dependencies = [ "aho-corasick", "bstr", "log", - "regex-automata 0.4.7", - "regex-syntax 0.8.4", + "regex-automata 0.4.8", + "regex-syntax 0.8.5", ] [[package]] @@ -3781,7 +3791,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.5.0", + "indexmap 2.6.0", "slab", "tokio", "tokio-util", @@ -3790,9 +3800,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" dependencies = [ "atomic-waker", "bytes", @@ -3800,7 +3810,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.1.0", - "indexmap 2.5.0", + "indexmap 2.6.0", "slab", "tokio", "tokio-util", @@ -3869,6 +3879,15 @@ dependencies = [ "serde", ] +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +dependencies = [ + "foldhash", +] + [[package]] name = "heapless" version = "0.7.17" @@ -3877,7 +3896,7 @@ checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" dependencies = [ "atomic-polyfill", "hash32", - "rustc_version 0.4.0", + "rustc_version 0.4.1", "serde", "spin", "stable_deref_trait", @@ -4052,9 +4071,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.9.4" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" [[package]] name = "httpdate" @@ -4070,9 +4089,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.30" +version = "0.14.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" dependencies = [ "bytes", "futures-channel", @@ -4094,14 +4113,14 @@ dependencies = [ [[package]] name = "hyper" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.5", + "h2 0.4.6", "http 1.1.0", "http-body 1.0.1", "httparse", @@ -4122,7 +4141,7 @@ dependencies = [ "common-multipart-rfc7578", "futures-core", "http 0.2.12", - "hyper 0.14.30", + "hyper 0.14.31", ] [[package]] @@ -4133,7 +4152,7 @@ checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", "http 0.2.12", - "hyper 0.14.30", + "hyper 0.14.31", "log", "rustls 0.21.12", "rustls-native-certs", @@ -4144,15 +4163,15 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.2" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", "http 1.1.0", - "hyper 1.4.1", + "hyper 1.5.0", "hyper-util", - "rustls 0.23.12", + "rustls 0.23.15", "rustls-pki-types", "tokio", "tokio-rustls 0.26.0", @@ -4165,7 +4184,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ - "hyper 0.14.30", + "hyper 0.14.31", "pin-project-lite", "tokio", "tokio-io-timeout", @@ -4179,7 +4198,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper 1.4.1", + "hyper 1.5.0", "hyper-util", "native-tls", "tokio", @@ -4189,29 +4208,28 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.7" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" +checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" dependencies = [ "bytes", "futures-channel", "futures-util", "http 1.1.0", "http-body 1.0.1", - "hyper 1.4.1", + "hyper 1.5.0", "pin-project-lite", "socket2", "tokio", - "tower 0.4.13", "tower-service", "tracing", ] [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -4306,7 +4324,7 @@ dependencies = [ "autocfg", "impl-tools-lib", "proc-macro-error", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -4318,7 +4336,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -4370,12 +4388,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.0", "rayon", "serde", ] @@ -4392,7 +4410,7 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" dependencies = [ - "bitflags 1.2.1", + "bitflags 1.3.2", "inotify-sys", "libc", ] @@ -4449,7 +4467,7 @@ dependencies = [ "bytes", "futures", "http 0.2.12", - "hyper 0.14.30", + "hyper 0.14.31", "hyper-multipart-rfc7578", "ipfs-api-prelude", "thiserror", @@ -4483,9 +4501,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.9.0" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" [[package]] name = "is-terminal" @@ -4557,9 +4575,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.70" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" dependencies = [ "wasm-bindgen", ] @@ -4613,7 +4631,7 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" dependencies = [ - "bitflags 1.2.1", + "bitflags 1.3.2", "libc", ] @@ -4628,9 +4646,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.156" +version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5f43f184355eefb8d17fc948dbecf6c13be3c141f20d834ae842193a448c72a" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] name = "libdbus-sys" @@ -4699,7 +4717,7 @@ checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ "bitflags 2.6.0", "libc", - "redox_syscall 0.5.3", + "redox_syscall 0.5.7", ] [[package]] @@ -4770,7 +4788,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc0bda45ed5b3a2904262c1bb91e526127aa70e7ef3758aba2ef93cf896b9b58" dependencies = [ - "clap 4.5.16", + "clap 4.5.20", "escape8259", "termcolor", "threadpool", @@ -4778,9 +4796,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.19" +version = "1.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc53a7799a7496ebc9fd29f31f7df80e83c9bda5299768af5f9e59eeea74647" +checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472" dependencies = [ "cc", "libc", @@ -4845,7 +4863,7 @@ version = "0.94.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c66bfd44a06ae10647fe3f8214762e9369fd4248df1350924b4ef9e770a85ea1" dependencies = [ - "bitflags 1.2.1", + "bitflags 1.3.2", "serde", "serde_json", "serde_repr", @@ -4869,7 +4887,7 @@ checksum = "b45a38e19bd200220ef07c892b0157ad3d2365e5b5a267ca01ad12182491eea5" dependencies = [ "anyhow", "chrono", - "clap 4.5.16", + "clap 4.5.20", "clap_complete", "env_logger", "handlebars", @@ -4892,7 +4910,7 @@ name = "mdbook-forc-documenter" version = "0.0.0" dependencies = [ "anyhow", - "clap 4.5.16", + "clap 4.5.20", "mdbook", "semver 1.0.23", "serde", @@ -4941,17 +4959,20 @@ dependencies = [ [[package]] name = "minifier" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95bbbf96b9ac3482c2a25450b67a15ed851319bc5fabf3b40742ea9066e84282" +checksum = "9aa3f302fe0f8de065d4a2d1ed64f60204623cac58b80cd3c2a83a25d5a7d437" +dependencies = [ + "clap 4.5.20", +] [[package]] name = "miniz_oxide" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", ] [[package]] @@ -5075,7 +5096,7 @@ version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" dependencies = [ - "bitflags 1.2.1", + "bitflags 1.3.2", "cc", "cfg-if 0.1.10", "libc", @@ -5089,7 +5110,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" dependencies = [ "autocfg", - "bitflags 1.2.1", + "bitflags 1.3.2", "cfg-if 1.0.0", "libc", "memoffset 0.6.5", @@ -5102,7 +5123,7 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" dependencies = [ - "bitflags 1.2.1", + "bitflags 1.3.2", "cfg-if 1.0.0", "libc", "memoffset 0.7.1", @@ -5120,6 +5141,12 @@ dependencies = [ "libc", ] +[[package]] +name = "normalize-path" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5438dd2b2ff4c6df6e1ce22d825ed2fa93ee2922235cc45186991717f0a892d" + [[package]] name = "normpath" version = "1.3.0" @@ -5284,10 +5311,10 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -5296,35 +5323,41 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" +[[package]] +name = "numtoa" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aa2c4e539b869820a2b82e1aef6ff40aa85e65decdd5185e83fb4b1249cd00f" + [[package]] name = "object" -version = "0.36.3" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "crc32fast", "flate2", - "hashbrown 0.14.5", - "indexmap 2.5.0", + "hashbrown 0.15.0", + "indexmap 2.6.0", "memchr", "ruzstd", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "onig" -version = "6.3.1" +version = "6.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ddfe2c93bb389eea6e6d713306880c7f6dcc99a75b659ce145d962c861b225" +checksum = "8c4b31c8722ad9171c6d77d3557db078cab2bd50afcc9d09c8b315c59df8ca4f" dependencies = [ - "bitflags 1.2.1", - "lazy_static", + "bitflags 1.3.2", "libc", + "once_cell", "onig_sys", ] @@ -5364,9 +5397,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.66" +version = "0.10.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" dependencies = [ "bitflags 2.6.0", "cfg-if 1.0.0", @@ -5385,7 +5418,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -5396,18 +5429,18 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "300.3.1+3.3.1" +version = "300.3.2+3.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7259953d42a81bf137fbbd73bd30a8e1914d6dce43c2b90ed575783a22608b91" +checksum = "a211a18d945ef7e648cc6e0058f4c548ee46aab922ea203e0d30e966ea23647b" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.103" +version = "0.9.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" dependencies = [ "cc", "libc", @@ -5422,6 +5455,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "os_pipe" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ffd2b0a5634335b135d5728d84c5e0fd726954b87111f7506a61c502280d982" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "outref" version = "0.5.1" @@ -5487,7 +5530,7 @@ version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate 3.2.0", "proc-macro2", "quote", "syn 1.0.109", @@ -5536,7 +5579,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.5.3", + "redox_syscall 0.5.7", "smallvec", "windows-targets 0.52.6", ] @@ -5601,9 +5644,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.11" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" +checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" dependencies = [ "memchr", "thiserror", @@ -5612,9 +5655,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.11" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a548d2beca6773b1c244554d36fcf8548a8a58e74156968211567250e48e49a" +checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd" dependencies = [ "pest", "pest_generator", @@ -5622,22 +5665,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.11" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c93a82e8d145725dcbaf44e5ea887c8a869efdcc28706df2d08c69e17077183" +checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] name = "pest_meta" -version = "2.7.11" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a941429fea7e08bedec25e4f6785b6ffaacc6b755da98df5ef3e7dcf4a124c4f" +checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d" dependencies = [ "once_cell", "pest", @@ -5651,7 +5694,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.5.0", + "indexmap 2.6.0", "serde", "serde_derive", ] @@ -5686,7 +5729,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -5700,22 +5743,22 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.5" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +checksum = "baf123a161dde1e524adf36f90bc5d8d3462824a9c43553ad07a8183161189ec" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.5" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -5742,9 +5785,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "plist" @@ -5753,7 +5796,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016" dependencies = [ "base64 0.22.1", - "indexmap 2.5.0", + "indexmap 2.6.0", "quick-xml", "serde", "time", @@ -5761,9 +5804,9 @@ dependencies = [ [[package]] name = "plotters" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" dependencies = [ "num-traits", "plotters-backend", @@ -5774,15 +5817,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" [[package]] name = "plotters-svg" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" dependencies = [ "plotters-backend", ] @@ -5798,12 +5841,13 @@ dependencies = [ [[package]] name = "postcard" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55c51ee6c0db07e68448e336cf8ea4131a620edefebf9893e759b2d793420f8" +checksum = "5f7f0a8d620d71c457dd1d47df76bb18960378da56af4527aaa10f515eee732e" dependencies = [ "cobs", - "embedded-io", + "embedded-io 0.4.0", + "embedded-io 0.6.1", "heapless", "serde", ] @@ -5904,11 +5948,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ - "toml_edit 0.21.1", + "toml_edit", ] [[package]] @@ -5937,9 +5981,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" dependencies = [ "unicode-ident", ] @@ -5964,7 +6008,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -5981,7 +6025,7 @@ dependencies = [ "rand", "rand_chacha", "rand_xorshift", - "regex-syntax 0.8.4", + "regex-syntax 0.8.5", "rusty-fork", "tempfile", "unarray", @@ -6076,9 +6120,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -6184,7 +6228,7 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags 1.2.1", + "bitflags 1.3.2", ] [[package]] @@ -6193,14 +6237,14 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ - "bitflags 1.2.1", + "bitflags 1.3.2", ] [[package]] name = "redox_syscall" -version = "0.5.3" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags 2.6.0", ] @@ -6213,9 +6257,9 @@ checksum = "20145670ba436b55d91fc92d25e71160fbfbdd57831631c8d7d36377a476f1cb" [[package]] name = "redox_users" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox 0.1.3", @@ -6224,14 +6268,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.6" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.7", - "regex-syntax 0.8.4", + "regex-automata 0.4.8", + "regex-syntax 0.8.5", ] [[package]] @@ -6245,13 +6289,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.4", + "regex-syntax 0.8.5", ] [[package]] @@ -6268,9 +6312,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rend" @@ -6297,7 +6341,7 @@ dependencies = [ "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.30", + "hyper 0.14.31", "hyper-rustls 0.24.2", "ipnet", "js-sys", @@ -6312,7 +6356,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "sync_wrapper 0.1.2", - "system-configuration", + "system-configuration 0.5.1", "tokio", "tokio-rustls 0.24.1", "tower-service", @@ -6321,26 +6365,26 @@ dependencies = [ "wasm-bindgen-futures", "web-sys", "webpki-roots", - "winreg 0.50.0", + "winreg", ] [[package]] name = "reqwest" -version = "0.12.5" +version = "0.12.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" +checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b" dependencies = [ "base64 0.22.1", "bytes", "encoding_rs", "futures-core", "futures-util", - "h2 0.4.5", + "h2 0.4.6", "http 1.1.0", "http-body 1.0.1", "http-body-util", - "hyper 1.4.1", - "hyper-rustls 0.27.2", + "hyper 1.5.0", + "hyper-rustls 0.27.3", "hyper-tls", "hyper-util", "ipnet", @@ -6351,12 +6395,12 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls-pemfile 2.1.3", + "rustls-pemfile 2.2.0", "serde", "serde_json", "serde_urlencoded", "sync_wrapper 1.0.1", - "system-configuration", + "system-configuration 0.6.1", "tokio", "tokio-native-tls", "tower-service", @@ -6364,14 +6408,14 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "winreg 0.52.0", + "windows-registry", ] [[package]] name = "revm" -version = "14.0.2" +version = "14.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9f3f55d0414c3d73902d876ba3d55a654f05fe937089fbf5f34b1ced26d78d5" +checksum = "641702b12847f9ed418d552f4fcabe536d867a2c980e96b6e7e25d7b992f929f" dependencies = [ "auto_impl", "cfg-if 1.0.0", @@ -6384,9 +6428,9 @@ dependencies = [ [[package]] name = "revm-interpreter" -version = "10.0.2" +version = "10.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713dbb271acd13afb06dcd460c1dc43da211e7ac9bc73cdf13528f615f55f96b" +checksum = "2e5e14002afae20b5bf1566f22316122f42f57517000e559c55b25bf7a49cba2" dependencies = [ "revm-primitives", "serde", @@ -6394,9 +6438,9 @@ dependencies = [ [[package]] name = "revm-precompile" -version = "11.0.2" +version = "11.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73010c271d53fa7904e9845338e95f3955eb1200a0355e0abfdb89c41aaa9cd" +checksum = "3198c06247e8d4ad0d1312591edf049b0de4ddffa9fecb625c318fd67db8639b" dependencies = [ "aurora-engine-modexp", "blst", @@ -6413,11 +6457,12 @@ dependencies = [ [[package]] name = "revm-primitives" -version = "9.0.2" +version = "10.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7a6bff9dbde3370a5ac9555104117f7e6039b3cc76e8d5d9d01899088beca2a" +checksum = "6f1525851a03aff9a9d6a1d018b414d76252d6802ab54695b27093ecd7e7a101" dependencies = [ - "alloy-eips", + "alloy-eip2930", + "alloy-eip7702", "alloy-primitives", "auto_impl", "bitflags 2.6.0", @@ -6426,7 +6471,6 @@ dependencies = [ "cfg-if 1.0.0", "dyn-clone", "enumn", - "hashbrown 0.14.5", "hex", "serde", ] @@ -6492,9 +6536,9 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.7.44" +version = "0.7.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" +checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" dependencies = [ "bitvec", "bytecheck", @@ -6505,14 +6549,14 @@ dependencies = [ "rkyv_derive", "seahash", "tinyvec", - "uuid 1.10.0", + "uuid 1.11.0", ] [[package]] name = "rkyv_derive" -version = "0.7.44" +version = "0.7.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" +checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" dependencies = [ "proc-macro2", "quote", @@ -6536,7 +6580,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88073939a61e5b7680558e6be56b419e208420c2adb92be54921fa6b72283f1a" dependencies = [ "base64 0.13.1", - "bitflags 1.2.1", + "bitflags 1.3.2", "serde", ] @@ -6558,7 +6602,7 @@ checksum = "0a542b0253fa46e632d27a1dc5cf7b930de4df8659dc6e720b647fc72147ae3d" dependencies = [ "countme", "hashbrown 0.14.5", - "rustc-hash", + "rustc-hash 1.1.0", "text-size", ] @@ -6615,9 +6659,9 @@ checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" [[package]] name = "rust_decimal" -version = "1.35.0" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a" +checksum = "b082d80e3e3cc52b2ed634388d436fe1f4de6af5786cc2de9ba9737527bdf555" dependencies = [ "arrayvec", "borsh", @@ -6641,6 +6685,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc-hash" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" + [[package]] name = "rustc-hex" version = "2.1.0" @@ -6658,18 +6708,18 @@ dependencies = [ [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver 1.0.23", ] [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ "bitflags 2.6.0", "errno", @@ -6692,13 +6742,13 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.12" +version = "0.23.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" +checksum = "5fbb44d7acc4e873d613422379f69f237a1b141928c02f6bc6ccfddddc2d7993" dependencies = [ "once_cell", "rustls-pki-types", - "rustls-webpki 0.102.6", + "rustls-webpki 0.102.8", "subtle", "zeroize", ] @@ -6726,19 +6776,18 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "2.1.3" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" dependencies = [ - "base64 0.22.1", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" [[package]] name = "rustls-webpki" @@ -6752,9 +6801,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.102.6" +version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ "ring", "rustls-pki-types", @@ -6763,9 +6812,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] name = "rusty-fork" @@ -6836,20 +6885,20 @@ dependencies = [ [[package]] name = "scc" -version = "2.1.15" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c478f373151538826ed50feaceeef7095ad435065a48153af789005fd5e44c0d" +checksum = "f2c1f7fc6deb21665a9060dfc7d271be784669295a31babdcd4dd2c79ae8cbfb" dependencies = [ "sdd", ] [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -6908,9 +6957,9 @@ dependencies = [ [[package]] name = "sdd" -version = "3.0.2" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0495e4577c672de8254beb68d01a9b62d0e8a13c099edecdbedccce3223cd29f" +checksum = "49c1eeaf4b6a87c7479688c6d52b9f1153cedd3c489300564f932b065c6eab95" [[package]] name = "seahash" @@ -6975,9 +7024,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.11.1" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" +checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" dependencies = [ "core-foundation-sys", "libc", @@ -7012,22 +7061,22 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.208" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.208" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -7041,11 +7090,11 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.125" +version = "1.0.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" +checksum = "6dbcf9b78a125ee667ae19388837dd12294b858d101fdd393cb9d5501ef09eb2" dependencies = [ - "indexmap 2.5.0", + "indexmap 2.6.0", "itoa", "memchr", "ryu", @@ -7060,14 +7109,14 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] name = "serde_spanned" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] @@ -7086,15 +7135,15 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.9.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857" +checksum = "8e28bdad6db2b8340e449f7108f020b3b092e8583a9e3fb82713e1d4e71fe817" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.5.0", + "indexmap 2.6.0", "serde", "serde_derive", "serde_json", @@ -7104,14 +7153,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.9.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350" +checksum = "9d846214a9854ef724f3da161b426242d8de7c1fc7de2f89bb1efcb154dca79d" dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -7120,7 +7169,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.5.0", + "indexmap 2.6.0", "itoa", "ryu", "serde", @@ -7149,7 +7198,7 @@ checksum = "82fe9db325bcef1fbcde82e078a5cc4efdf787e96b3b9cf45b50b529f2083d67" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -7205,6 +7254,16 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shared_child" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09fa9338aed9a1df411814a5b2252f7cd206c55ae9bf2fa763f8de84603aa60c" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "shell-words" version = "1.1.0" @@ -7253,9 +7312,9 @@ dependencies = [ [[package]] name = "simdutf8" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "similar" @@ -7478,7 +7537,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -7491,7 +7550,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -7529,7 +7588,7 @@ dependencies = [ name = "sway-core" version = "0.66.2" dependencies = [ - "clap 4.5.16", + "clap 4.5.20", "derivative", "dirs 5.0.1", "either", @@ -7538,12 +7597,12 @@ dependencies = [ "fuel-etk-asm", "fuel-etk-ops", "fuel-vm", - "gimli 0.31.0", + "gimli", "graph-cycles", "hashbrown 0.14.5", "hex", "im", - "indexmap 2.5.0", + "indexmap 2.6.0", "itertools 0.13.0", "lazy_static", "object", @@ -7551,7 +7610,7 @@ dependencies = [ "pest", "pest_derive", "petgraph", - "rustc-hash", + "rustc-hash 1.1.0", "serde", "serde_json", "sha2 0.10.8", @@ -7590,12 +7649,12 @@ dependencies = [ "anyhow", "downcast-rs", "filecheck", - "indexmap 2.5.0", + "indexmap 2.6.0", "itertools 0.13.0", "once_cell", "peg", "prettydiff 0.7.0", - "rustc-hash", + "rustc-hash 1.1.0", "slotmap", "sway-ir-macros", "sway-types", @@ -7609,7 +7668,7 @@ dependencies = [ "itertools 0.13.0", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -7628,7 +7687,7 @@ dependencies = [ "forc-tracing 0.66.2", "forc-util", "futures", - "indexmap 2.5.0", + "indexmap 2.6.0", "lsp-types", "notify", "notify-debouncer-mini", @@ -7650,12 +7709,12 @@ dependencies = [ "sway-types", "sway-utils", "swayfmt", - "syn 2.0.74", + "syn 2.0.79", "tempfile", "thiserror", "tikv-jemallocator", "tokio", - "toml_edit 0.22.20", + "toml_edit", "tower 0.4.13", "tower-lsp", "tracing", @@ -7703,12 +7762,12 @@ dependencies = [ "fuel-asm", "fuel-crypto", "fuel-tx", - "indexmap 2.5.0", + "indexmap 2.6.0", "lazy_static", "num-bigint", "num-traits", "parking_lot 0.12.3", - "rustc-hash", + "rustc-hash 1.1.0", "serde", "sway-utils", "thiserror", @@ -7759,9 +7818,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.74" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -7777,7 +7836,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -7791,6 +7850,9 @@ name = "sync_wrapper" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +dependencies = [ + "futures-core", +] [[package]] name = "synstructure" @@ -7812,7 +7874,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -7822,14 +7884,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "874dcfa363995604333cf947ae9f751ca3af4522c60886774c4963943b4746b1" dependencies = [ "bincode", - "bitflags 1.2.1", + "bitflags 1.3.2", "fancy-regex", "flate2", "fnv", "once_cell", "onig", "plist", - "regex-syntax 0.8.4", + "regex-syntax 0.8.5", "serde", "serde_derive", "serde_json", @@ -7859,9 +7921,20 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ - "bitflags 1.2.1", + "bitflags 1.3.2", "core-foundation", - "system-configuration-sys", + "system-configuration-sys 0.5.0", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "system-configuration-sys 0.6.0", ] [[package]] @@ -7874,6 +7947,16 @@ dependencies = [ "libc", ] +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tai64" version = "4.0.0" @@ -7912,9 +7995,9 @@ dependencies = [ [[package]] name = "tar" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909" +checksum = "4ff6c40d3aedb5e06b57c6f669ad17ab063dd1e63d977c6a88e7f4dfa4f04020" dependencies = [ "filetime", "libc", @@ -7923,9 +8006,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.12.0" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" dependencies = [ "cfg-if 1.0.0", "fastrand", @@ -7967,12 +8050,12 @@ dependencies = [ [[package]] name = "terminal_size" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +checksum = "4f599bd7ca042cfdf8f4512b277c02ba102247820f9d9d4a9f521f496751a6ef" dependencies = [ "rustix", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -7983,19 +8066,19 @@ checksum = "c4648c7def6f2043b2568617b9f9b75eae88ca185dbc1f1fda30e95a85d49d7d" dependencies = [ "libc", "libredox 0.0.2", - "numtoa", + "numtoa 0.1.0", "redox_termios", ] [[package]] name = "termion" -version = "4.0.2" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ccce68e518d1173e80876edd54760b60b792750d0cab6444a79101c6ea03848" +checksum = "7eaa98560e51a2cf4f0bb884d8b2098a9ea11ecf3b7078e9c68242c74cc923a7" dependencies = [ "libc", - "libredox 0.0.2", - "numtoa", + "libredox 0.1.3", + "numtoa 0.2.4", "redox_termios", ] @@ -8005,8 +8088,9 @@ version = "0.0.0" dependencies = [ "anyhow", "bytes", - "clap 4.5.16", + "clap 4.5.20", "colored", + "duct", "filecheck", "forc", "forc-client", @@ -8020,6 +8104,7 @@ dependencies = [ "hex", "insta", "libtest-mimic", + "normalize-path", "prettydiff 0.7.0", "rand", "regex", @@ -8073,22 +8158,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -8172,7 +8257,7 @@ dependencies = [ "once_cell", "pbkdf2 0.11.0", "rand", - "rustc-hash", + "rustc-hash 1.1.0", "sha2 0.10.8", "thiserror", "unicode-normalization", @@ -8216,9 +8301,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.39.2" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", "bytes", @@ -8250,7 +8335,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -8279,16 +8364,16 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.12", + "rustls 0.23.15", "rustls-pki-types", "tokio", ] [[package]] name = "tokio-stream" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" dependencies = [ "futures-core", "pin-project-lite", @@ -8297,9 +8382,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes", "futures-core", @@ -8326,7 +8411,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.20", + "toml_edit", ] [[package]] @@ -8340,26 +8425,15 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.21.1" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap 2.5.0", - "toml_datetime", - "winnow 0.5.40", -] - -[[package]] -name = "toml_edit" -version = "0.22.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" -dependencies = [ - "indexmap 2.5.0", + "indexmap 2.6.0", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.18", + "winnow", ] [[package]] @@ -8378,7 +8452,6 @@ dependencies = [ "futures-util", "pin-project", "pin-project-lite", - "tokio", "tower-layer", "tower-service", ] @@ -8434,7 +8507,7 @@ checksum = "84fd902d4e0b9a4b27f2f440108dc034e1758628a9b702f8ec61ad66355422fa" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -8462,7 +8535,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -8535,7 +8608,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04659ddb06c87d233c566112c1c9c5b9e98256d9af50ec3bc9c8327f873a7568" dependencies = [ "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -8579,9 +8652,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "ucd-trie" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" [[package]] name = "uint" @@ -8612,15 +8685,15 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.15" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-linebreak" @@ -8630,30 +8703,30 @@ checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-xid" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "unicode_categories" @@ -8736,9 +8809,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" [[package]] name = "uwuify" @@ -8880,9 +8953,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" dependencies = [ "cfg-if 1.0.0", "once_cell", @@ -8891,24 +8964,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.43" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" +checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -8918,9 +8991,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -8928,28 +9001,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] name = "web-sys" -version = "0.3.70" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" dependencies = [ "js-sys", "wasm-bindgen", @@ -8963,9 +9036,9 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "which" -version = "6.0.2" +version = "6.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d9c5ed668ee1f17edb3b627225343d210006a90bb1e3745ce1f30b1fb115075" +checksum = "b4ee928febd44d98f2f459a4a79bd4d928591333a494a10a868418ac1b39cf1f" dependencies = [ "either", "home", @@ -8975,11 +9048,11 @@ dependencies = [ [[package]] name = "whoami" -version = "1.5.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" +checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d" dependencies = [ - "redox_syscall 0.4.1", + "redox_syscall 0.5.7", "wasite", "web-sys", ] @@ -9024,6 +9097,36 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -9174,18 +9277,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - -[[package]] -name = "winnow" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] @@ -9200,16 +9294,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "winreg" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" -dependencies = [ - "cfg-if 1.0.0", - "windows-sys 0.48.0", -] - [[package]] name = "winsafe" version = "0.0.19" @@ -9287,7 +9371,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -9307,5 +9391,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] diff --git a/forc-plugins/forc-client/tests/deploy.rs b/forc-plugins/forc-client/tests/deploy.rs index e1f416062ff..dae3c123f51 100644 --- a/forc-plugins/forc-client/tests/deploy.rs +++ b/forc-plugins/forc-client/tests/deploy.rs @@ -373,7 +373,7 @@ async fn test_simple_deploy() { node.kill().unwrap(); let expected = vec![DeployedPackage::Contract(DeployedContract { id: ContractId::from_str( - "4ea5fa100cd7c8972bc8925ed6f8ccfb6bf1e16f79c3642c3a503c73b7d18de2", + "e50f0b4b396504398c0aff45951b1e44e108399c856cb92257dfa58fe96d53eb", ) .unwrap(), proxy: None, @@ -416,7 +416,7 @@ async fn test_deploy_submit_only() { node.kill().unwrap(); let expected = vec![DeployedPackage::Contract(DeployedContract { id: ContractId::from_str( - "4ea5fa100cd7c8972bc8925ed6f8ccfb6bf1e16f79c3642c3a503c73b7d18de2", + "e50f0b4b396504398c0aff45951b1e44e108399c856cb92257dfa58fe96d53eb", ) .unwrap(), proxy: None, @@ -462,12 +462,12 @@ async fn test_deploy_fresh_proxy() { node.kill().unwrap(); let impl_contract = DeployedPackage::Contract(DeployedContract { id: ContractId::from_str( - "4ea5fa100cd7c8972bc8925ed6f8ccfb6bf1e16f79c3642c3a503c73b7d18de2", + "e50f0b4b396504398c0aff45951b1e44e108399c856cb92257dfa58fe96d53eb", ) .unwrap(), proxy: Some( ContractId::from_str( - "deb633128bceadcd4eb4fe546089f6653727348b60228638a7f9d55d0b6da1ae", + "1c50e2d4d602fdd88b47fb7b84b7f87bbdefcf9b7e5985bb7ceeee9266a8e977", ) .unwrap(), ), diff --git a/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs b/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs index a97ff923635..b08361476c2 100644 --- a/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs +++ b/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs @@ -114,7 +114,7 @@ impl<'ir, 'eng> AsmBuilder for FuelAsmBuilder<'ir, 'eng> { self.globals_section.insert(name, size_in_bytes); let global = self.globals_section.get_by_name(name).unwrap(); - let (decode_fn_label, _) = self.func_label_map.get(decode_fn).unwrap(); + let (decode_fn_label, _) = self.func_label_map.get(&decode_fn.get()).unwrap(); let dataid = self.data_section.insert_data_value(Entry::new_byte_array( encoded_bytes.clone(), Some(name.clone()), diff --git a/sway-core/src/ir_generation/compile.rs b/sway-core/src/ir_generation/compile.rs index a0c2b10ca8e..e7c07932fa2 100644 --- a/sway-core/src/ir_generation/compile.rs +++ b/sway-core/src/ir_generation/compile.rs @@ -20,7 +20,7 @@ use sway_error::{error::CompileError, handler::Handler}; use sway_ir::{metadata::combine as md_combine, *}; use sway_types::{Ident, Spanned}; -use std::{collections::HashMap, sync::Arc}; +use std::{cell::Cell, collections::HashMap, sync::Arc}; #[allow(clippy::too_many_arguments)] pub(super) fn compile_script( @@ -359,7 +359,7 @@ pub(crate) fn compile_configurables( ty, ptr_ty, encoded_bytes, - decode_fn, + decode_fn: Cell::new(decode_fn), opt_metadata, }, ); diff --git a/sway-ir/src/module.rs b/sway-ir/src/module.rs index fbeb6ab1c3b..8e37e6bf1b5 100644 --- a/sway-ir/src/module.rs +++ b/sway-ir/src/module.rs @@ -2,7 +2,10 @@ //! //! A module also has a 'kind' corresponding to the different Sway module types. -use std::collections::{BTreeMap, HashMap}; +use std::{ + cell::Cell, + collections::{BTreeMap, HashMap}, +}; use crate::{ context::Context, @@ -38,7 +41,7 @@ pub enum ConfigContent { ty: Type, ptr_ty: Type, encoded_bytes: Vec, - decode_fn: Function, + decode_fn: Cell, opt_metadata: Option, }, } diff --git a/sway-ir/src/optimize/dce.rs b/sway-ir/src/optimize/dce.rs index 389e67aba1f..7883a8b74bc 100644 --- a/sway-ir/src/optimize/dce.rs +++ b/sway-ir/src/optimize/dce.rs @@ -360,7 +360,7 @@ pub fn fn_dce(context: &mut Context, _: &AnalysisResults, module: Module) -> Res // config decode fns for config in context.modules[module.0].configs.iter() { if let crate::ConfigContent::V1 { decode_fn, .. } = config.1 { - grow_called_function_set(context, *decode_fn, &mut called_fns); + grow_called_function_set(context, decode_fn.get(), &mut called_fns); } } diff --git a/sway-ir/src/optimize/fn_dedup.rs b/sway-ir/src/optimize/fn_dedup.rs index 257db379a72..c53aef4cb43 100644 --- a/sway-ir/src/optimize/fn_dedup.rs +++ b/sway-ir/src/optimize/fn_dedup.rs @@ -286,6 +286,9 @@ pub fn dedup_fns( hash_set_map: FxHashMap::default(), function_hash_map: FxHashMap::default(), }; + + let mut dups_to_delete = vec![]; + let cg = build_call_graph(context, &context.modules.get(module.0).unwrap().functions); let callee_first = callee_first_order(&cg); for function in callee_first { @@ -324,6 +327,7 @@ pub fn dedup_fns( else { continue; }; + dups_to_delete.push(*callee); replacements.push((inst, args.clone(), callee_rep)); } if !replacements.is_empty() { @@ -340,6 +344,35 @@ pub fn dedup_fns( } } + // Replace config decode fns + for config in module.iter_configs(context) { + if let crate::ConfigContent::V1 { decode_fn, .. } = config { + let f = decode_fn.get(); + + let Some(callee_hash) = eq_class.function_hash_map.get(&f) else { + continue; + }; + + // If the representative (first element in the set) is different, we need to replace. + let Some(callee_rep) = eq_class + .hash_set_map + .get(callee_hash) + .and_then(|f| f.iter().next()) + .filter(|rep| *rep != &f) + else { + continue; + }; + + dups_to_delete.push(decode_fn.get()); + decode_fn.replace(*callee_rep); + } + } + + // Remove replaced functions + for function in dups_to_delete { + module.remove_function(context, &function); + } + Ok(modified) } diff --git a/sway-ir/src/parser.rs b/sway-ir/src/parser.rs index caa439c3fb7..bb77348cf81 100644 --- a/sway-ir/src/parser.rs +++ b/sway-ir/src/parser.rs @@ -953,6 +953,7 @@ mod ir_builder { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - use std::{ + cell::Cell, collections::{BTreeMap, HashMap}, iter::FromIterator, }; @@ -1465,7 +1466,7 @@ mod ir_builder { .configs .get_mut(&configurable_name) { - *decode_fn = f; + decode_fn.replace(f); } } @@ -1521,7 +1522,7 @@ mod ir_builder { ptr_ty: Type::new_ptr(context, ty), encoded_bytes: config.encoded_bytes, // this will point to the correct function after all functions are compiled - decode_fn: Function(KeyData::default().into()), + decode_fn: Cell::new(Function(KeyData::default().into())), opt_metadata, }; diff --git a/sway-ir/src/pass_manager.rs b/sway-ir/src/pass_manager.rs index 9edb21626c3..b1c069a39dd 100644 --- a/sway-ir/src/pass_manager.rs +++ b/sway-ir/src/pass_manager.rs @@ -427,6 +427,7 @@ pub fn create_o1_pass_group() -> PassGroup { o1.append_pass(SIMPLIFY_CFG_NAME); o1.append_pass(FN_DCE_NAME); o1.append_pass(DCE_NAME); + o1.append_pass(FN_DEDUP_RELEASE_PROFILE_NAME); o1 } diff --git a/sway-ir/src/printer.rs b/sway-ir/src/printer.rs index 2478b3ef4f9..b589c329c3b 100644 --- a/sway-ir/src/printer.rs +++ b/sway-ir/src/printer.rs @@ -274,7 +274,7 @@ fn config_to_doc( "{} = config {}, {}, 0x{}", name, ty, - decode_fn.get_name(context), + decode_fn.get().get_name(context), bytes, )) .append(md_namer.md_idx_to_doc(context, opt_metadata)), diff --git a/test/Cargo.toml b/test/Cargo.toml index d2400d6c1c7..3854b55f458 100644 --- a/test/Cargo.toml +++ b/test/Cargo.toml @@ -10,6 +10,7 @@ anyhow.workspace = true bytes.workspace = true clap = { workspace = true, features = ["derive", "env"] } colored.workspace = true +duct = "0.13.7" filecheck.workspace = true forc = { workspace = true, features = ["test"] } forc-client.workspace = true @@ -23,6 +24,7 @@ glob.workspace = true hex.workspace = true insta.workspace = true libtest-mimic.workspace = true +normalize-path = "0.2.1" prettydiff.workspace = true rand.workspace = true regex.workspace = true diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/stdout.snap index 3a28c876aaf..f1694aba064 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/stdout.snap @@ -1,14 +1,13 @@ --- source: test/tests/tests.rs --- +> forc build --path test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types exit status: 1 -stdout: - Building src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types +output: + Building test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types Compiling library core (sway-lib-core) Compiling library std (sway-lib-std) Compiling script array_wrong_elements_types (test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types) - -stderr: error --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:41:27 | diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/stdout.snap index 858d27be7e6..cc63d82067b 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/stdout.snap @@ -1,14 +1,13 @@ --- source: test/tests/tests.rs --- +> forc build --path test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors exit status: 1 -stdout: - Building src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors +output: + Building test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors Compiling library core (sway-lib-core) Compiling library std (sway-lib-std) Compiling script type_check_analyze_errors (test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors) - -stderr: error --> test/src/e2e_vm_tests/test_programs/should_fail/type_check_analyze_errors/src/main.sw:5:14 | diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle_new_encoding.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle_new_encoding.json index b5e886d1a19..2daeaffdc6a 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle_new_encoding.json +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle_new_encoding.json @@ -62,82 +62,82 @@ { "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", "name": "BOOL", - "offset": 7216 + "offset": 6896 }, { "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", "name": "U8", - "offset": 7408 + "offset": 7088 }, { "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", "name": "ANOTHER_U8", - "offset": 7144 + "offset": 6824 }, { "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", "name": "U16", - "offset": 7352 + "offset": 7032 }, { "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", "name": "U32", - "offset": 7392 + "offset": 7072 }, { "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", "name": "U64", - "offset": 7400 + "offset": 7080 }, { "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", "name": "U256", - "offset": 7360 + "offset": 7040 }, { "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", "name": "B256", - "offset": 7184 + "offset": 6864 }, { "concreteTypeId": "81fc10c4681a3271cf2d66b2ec6fbc8ed007a442652930844fcf11818c295bff", "name": "CONFIGURABLE_STRUCT", - "offset": 7304 + "offset": 6984 }, { "concreteTypeId": "a2922861f03be8a650595dd76455b95383a61b46dd418f02607fa2e00dc39d5c", "name": "CONFIGURABLE_ENUM_A", - "offset": 7224 + "offset": 6904 }, { "concreteTypeId": "a2922861f03be8a650595dd76455b95383a61b46dd418f02607fa2e00dc39d5c", "name": "CONFIGURABLE_ENUM_B", - "offset": 7264 + "offset": 6944 }, { "concreteTypeId": "4926d35d1a5157936b0a29bc126b8aace6d911209a5c130e9b716b0c73643ea6", "name": "ARRAY_BOOL", - "offset": 7152 + "offset": 6832 }, { "concreteTypeId": "776fb5a3824169d6736138565fdc20aad684d9111266a5ff6d5c675280b7e199", "name": "ARRAY_U64", - "offset": 7160 + "offset": 6840 }, { "concreteTypeId": "c998ca9a5f221fe7b5c66ae70c8a9562b86d964408b00d17f883c906bc1fe4be", "name": "TUPLE_BOOL_U64", - "offset": 7336 + "offset": 7016 }, { "concreteTypeId": "94f0fa95c830be5e4f711963e83259fe7e8bc723278ab6ec34449e791a99b53a", "name": "STR_4", - "offset": 7328 + "offset": 7008 }, { "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", "name": "NOT_USED", - "offset": 7320 + "offset": 7000 } ], "encodingVersion": "1", diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/Forc.lock new file mode 100644 index 00000000000..464a5ea4506 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/Forc.lock @@ -0,0 +1,13 @@ +[[package]] +name = "configurable_dedup_decode" +source = "member" +dependencies = ["std"] + +[[package]] +name = "core" +source = "path+from-root-5BADD42D3D8D8FF8" + +[[package]] +name = "std" +source = "path+from-root-5BADD42D3D8D8FF8" +dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/Forc.toml new file mode 100644 index 00000000000..09b0b0c1893 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "configurable_dedup_decode" + +[dependencies] +std = { path = "../../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/json_abi_oracle.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/json_abi_oracle.json new file mode 100644 index 00000000000..096b1d487c9 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/json_abi_oracle.json @@ -0,0 +1,284 @@ +{ + "configurables": [ + { + "configurableType": { + "name": "", + "type": 5, + "typeArguments": null + }, + "name": "BOOL", + "offset": 3392 + }, + { + "configurableType": { + "name": "", + "type": 13, + "typeArguments": null + }, + "name": "U8", + "offset": 3528 + }, + { + "configurableType": { + "name": "", + "type": 13, + "typeArguments": null + }, + "name": "ANOTHER_U8", + "offset": 3320 + }, + { + "configurableType": { + "name": "", + "type": 9, + "typeArguments": null + }, + "name": "U16", + "offset": 3472 + }, + { + "configurableType": { + "name": "", + "type": 11, + "typeArguments": null + }, + "name": "U32", + "offset": 3512 + }, + { + "configurableType": { + "name": "", + "type": 11, + "typeArguments": null + }, + "name": "U64", + "offset": 3520 + }, + { + "configurableType": { + "name": "", + "type": 10, + "typeArguments": null + }, + "name": "U256", + "offset": 3480 + }, + { + "configurableType": { + "name": "", + "type": 4, + "typeArguments": null + }, + "name": "B256", + "offset": 3360 + }, + { + "configurableType": { + "name": "", + "type": 8, + "typeArguments": [] + }, + "name": "CONFIGURABLE_STRUCT", + "offset": 3432 + }, + { + "configurableType": { + "name": "", + "type": 6, + "typeArguments": [] + }, + "name": "CONFIGURABLE_ENUM_A", + "offset": 3400 + }, + { + "configurableType": { + "name": "", + "type": 6, + "typeArguments": [] + }, + "name": "CONFIGURABLE_ENUM_B", + "offset": 3416 + }, + { + "configurableType": { + "name": "", + "type": 2, + "typeArguments": null + }, + "name": "ARRAY_BOOL", + "offset": 3328 + }, + { + "configurableType": { + "name": "", + "type": 3, + "typeArguments": null + }, + "name": "ARRAY_U64", + "offset": 3336 + }, + { + "configurableType": { + "name": "", + "type": 1, + "typeArguments": null + }, + "name": "TUPLE_BOOL_U64", + "offset": 3456 + }, + { + "configurableType": { + "name": "", + "type": 7, + "typeArguments": null + }, + "name": "STR_4", + "offset": 3448 + } + ], + "functions": [ + { + "attributes": null, + "inputs": [], + "name": "main", + "output": { + "name": "", + "type": 0, + "typeArguments": null + } + } + ], + "loggedTypes": [], + "messagesTypes": [], + "types": [ + { + "components": [], + "type": "()", + "typeId": 0, + "typeParameters": null + }, + { + "components": [ + { + "name": "__tuple_element", + "type": 5, + "typeArguments": null + }, + { + "name": "__tuple_element", + "type": 12, + "typeArguments": null + } + ], + "type": "(_, _)", + "typeId": 1, + "typeParameters": null + }, + { + "components": [ + { + "name": "__array_element", + "type": 5, + "typeArguments": null + } + ], + "type": "[_; 3]", + "typeId": 2, + "typeParameters": null + }, + { + "components": [ + { + "name": "__array_element", + "type": 12, + "typeArguments": null + } + ], + "type": "[_; 3]", + "typeId": 3, + "typeParameters": null + }, + { + "components": null, + "type": "b256", + "typeId": 4, + "typeParameters": null + }, + { + "components": null, + "type": "bool", + "typeId": 5, + "typeParameters": null + }, + { + "components": [ + { + "name": "A", + "type": 5, + "typeArguments": null + }, + { + "name": "B", + "type": 12, + "typeArguments": null + } + ], + "type": "enum ConfigurableEnum", + "typeId": 6, + "typeParameters": null + }, + { + "components": null, + "type": "str[4]", + "typeId": 7, + "typeParameters": null + }, + { + "components": [ + { + "name": "a", + "type": 5, + "typeArguments": null + }, + { + "name": "b", + "type": 12, + "typeArguments": null + } + ], + "type": "struct ConfigurableStruct", + "typeId": 8, + "typeParameters": null + }, + { + "components": null, + "type": "u16", + "typeId": 9, + "typeParameters": null + }, + { + "components": null, + "type": "u256", + "typeId": 10, + "typeParameters": null + }, + { + "components": null, + "type": "u32", + "typeId": 11, + "typeParameters": null + }, + { + "components": null, + "type": "u64", + "typeId": 12, + "typeParameters": null + }, + { + "components": null, + "type": "u8", + "typeId": 13, + "typeParameters": null + } + ] +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/json_abi_oracle_new_encoding.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/json_abi_oracle_new_encoding.json new file mode 100644 index 00000000000..b5e886d1a19 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/json_abi_oracle_new_encoding.json @@ -0,0 +1,228 @@ +{ + "concreteTypes": [ + { + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "type": "()" + }, + { + "concreteTypeId": "c998ca9a5f221fe7b5c66ae70c8a9562b86d964408b00d17f883c906bc1fe4be", + "metadataTypeId": 0, + "type": "(bool, u64)" + }, + { + "concreteTypeId": "4926d35d1a5157936b0a29bc126b8aace6d911209a5c130e9b716b0c73643ea6", + "metadataTypeId": 1, + "type": "[bool; 3]" + }, + { + "concreteTypeId": "776fb5a3824169d6736138565fdc20aad684d9111266a5ff6d5c675280b7e199", + "metadataTypeId": 2, + "type": "[u64; 3]" + }, + { + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "type": "b256" + }, + { + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "type": "bool" + }, + { + "concreteTypeId": "a2922861f03be8a650595dd76455b95383a61b46dd418f02607fa2e00dc39d5c", + "metadataTypeId": 3, + "type": "enum ConfigurableEnum" + }, + { + "concreteTypeId": "94f0fa95c830be5e4f711963e83259fe7e8bc723278ab6ec34449e791a99b53a", + "type": "str[4]" + }, + { + "concreteTypeId": "81fc10c4681a3271cf2d66b2ec6fbc8ed007a442652930844fcf11818c295bff", + "metadataTypeId": 4, + "type": "struct ConfigurableStruct" + }, + { + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", + "type": "u16" + }, + { + "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", + "type": "u256" + }, + { + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", + "type": "u32" + }, + { + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "type": "u8" + } + ], + "configurables": [ + { + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "name": "BOOL", + "offset": 7216 + }, + { + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "name": "U8", + "offset": 7408 + }, + { + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "name": "ANOTHER_U8", + "offset": 7144 + }, + { + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", + "name": "U16", + "offset": 7352 + }, + { + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", + "name": "U32", + "offset": 7392 + }, + { + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", + "name": "U64", + "offset": 7400 + }, + { + "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", + "name": "U256", + "offset": 7360 + }, + { + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "name": "B256", + "offset": 7184 + }, + { + "concreteTypeId": "81fc10c4681a3271cf2d66b2ec6fbc8ed007a442652930844fcf11818c295bff", + "name": "CONFIGURABLE_STRUCT", + "offset": 7304 + }, + { + "concreteTypeId": "a2922861f03be8a650595dd76455b95383a61b46dd418f02607fa2e00dc39d5c", + "name": "CONFIGURABLE_ENUM_A", + "offset": 7224 + }, + { + "concreteTypeId": "a2922861f03be8a650595dd76455b95383a61b46dd418f02607fa2e00dc39d5c", + "name": "CONFIGURABLE_ENUM_B", + "offset": 7264 + }, + { + "concreteTypeId": "4926d35d1a5157936b0a29bc126b8aace6d911209a5c130e9b716b0c73643ea6", + "name": "ARRAY_BOOL", + "offset": 7152 + }, + { + "concreteTypeId": "776fb5a3824169d6736138565fdc20aad684d9111266a5ff6d5c675280b7e199", + "name": "ARRAY_U64", + "offset": 7160 + }, + { + "concreteTypeId": "c998ca9a5f221fe7b5c66ae70c8a9562b86d964408b00d17f883c906bc1fe4be", + "name": "TUPLE_BOOL_U64", + "offset": 7336 + }, + { + "concreteTypeId": "94f0fa95c830be5e4f711963e83259fe7e8bc723278ab6ec34449e791a99b53a", + "name": "STR_4", + "offset": 7328 + }, + { + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "name": "NOT_USED", + "offset": 7320 + } + ], + "encodingVersion": "1", + "functions": [ + { + "attributes": null, + "inputs": [], + "name": "main", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ], + "loggedTypes": [], + "messagesTypes": [], + "metadataTypes": [ + { + "components": [ + { + "name": "__tuple_element", + "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "name": "__tuple_element", + "typeId": 5 + } + ], + "metadataTypeId": 0, + "type": "(_, _)" + }, + { + "components": [ + { + "name": "__array_element", + "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + ], + "metadataTypeId": 1, + "type": "[_; 3]" + }, + { + "components": [ + { + "name": "__array_element", + "typeId": 5 + } + ], + "metadataTypeId": 2, + "type": "[_; 3]" + }, + { + "components": [ + { + "name": "A", + "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "name": "B", + "typeId": 5 + }, + { + "name": "C", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ], + "metadataTypeId": 3, + "type": "enum ConfigurableEnum" + }, + { + "components": [ + { + "name": "a", + "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "name": "b", + "typeId": 5 + } + ], + "metadataTypeId": 4, + "type": "struct ConfigurableStruct" + }, + { + "metadataTypeId": 5, + "type": "u64" + } + ], + "programType": "script", + "specVersion": "1" +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/snapshot.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/snapshot.toml new file mode 100644 index 00000000000..784ff71e177 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/snapshot.toml @@ -0,0 +1 @@ +cmds = ["forc build --path {root} --release --ir final"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/src/main.sw new file mode 100644 index 00000000000..74507d6d6ad --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/src/main.sw @@ -0,0 +1,16 @@ +script; + +struct Wrapped { + v: u64, +} + +// These types decode fns should coalesce into +// only one in the final IR +configurable { + WRAPPED: Wrapped = Wrapped { v: 1 }, + TUPLE: (u64,) = (2,), +} + +fn main() -> u64 { + WRAPPED.v + TUPLE.0 +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/stdout.snap new file mode 100644 index 00000000000..283bf9e035f --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/stdout.snap @@ -0,0 +1,361 @@ +--- +source: test/tests/tests.rs +--- +> forc build --path test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode --release --ir final +exit status: 0 +output: + Building test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode + Compiling library core (sway-lib-core) + Compiling library std (sway-lib-std) +// IR: Final +library { +} + + Compiling script configurable_dedup_decode (test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode) +// IR: Final +script { + TUPLE = config { u64 }, abi_decode_in_place_0, 0x0000000000000002, !1 + WRAPPED = config { u64 }, abi_decode_in_place_0, 0x0000000000000001, !2 + + pub fn abi_decode_in_place_0(ptr !4: u64, len !5: u64, target !6: u64) -> (), !10 { + local { u64 } __ret_val + local mut { u64 } buffer + local { u64 } temp + + entry(ptr: u64, len: u64, target: u64): + v0 = get_local ptr { u64 }, __ret_val + v1 = call from_parts_1(ptr, len, v0) + v2 = const u64 0 + v3 = get_elem_ptr v1, ptr u64, v2 + v4 = load v3 + v5 = get_local ptr { u64 }, buffer, !11 + v6 = const u64 0 + v7 = get_elem_ptr v5, ptr u64, v6 + store v4 to v7 + v8 = get_local ptr { u64 }, buffer, !12 + v9 = call abi_decode_3(v8), !17 + v10 = get_local ptr { u64 }, temp, !18 + v11 = const u64 0 + v12 = get_elem_ptr v10, ptr u64, v11 + store v9 to v12 + v13 = get_local ptr { u64 }, temp, !19 + v14 = ptr_to_int v13 to u64, !20 + v15 = const u64 8 + v16 = asm(target: target, temp: v14, size: v15) -> (), !21 { + mcp target temp size, !22 + } + v17 = const unit () + ret () v17 + } + + pub fn from_parts_1(ptr !23: u64, _len !24: u64, __ret_value: ptr { u64 }) -> ptr { u64 }, !27 { + entry(ptr: u64, _len: u64, __ret_value: ptr { u64 }): + v0 = const u64 0 + v1 = get_elem_ptr __ret_value, ptr u64, v0 + store ptr to v1 + ret ptr { u64 } __ret_value + } + + pub fn abi_decode_3(buffer !28: ptr { u64 }) -> u64, !31 { + entry(buffer: ptr { u64 }): + v0 = const u64 0 + v1 = get_elem_ptr buffer, ptr u64, v0, !35 + v2 = load v1, !36 + v3 = asm(ptr: v2, val) -> u64 val, !38 { + lw val ptr i0, !39 + } + v4 = load v1, !36 + v5 = const u64 8, !36 + v6 = add v4, v5, !36 + store v6 to v1, !41 + ret u64 v3 + } + + pub entry fn __entry() -> ptr slice, !45 { + local mut { u64, u64, u64 } __aggr_memcpy_0 + local mut { u64, u64, u64 } __aggr_memcpy_00 + local mut { u64, u64, u64 } __aggr_memcpy_01 + local mut { u64, u64, u64 } __aggr_memcpy_02 + local mut slice __aggr_memcpy_03 + local { u64, u64, u64 } __anon_0 + local { u64, u64, u64 } __anon_00 + local { u64, u64, u64 } __anon_01 + local { { u64, u64, u64 } } __anon_1 + local { u64, u64, u64 } __anon_10 + local { u64, u64 } __anon_11 + local { { u64, u64, u64 } } __anon_2 + local { u64, u64, u64 } __asm_arg + local { u64, u64, u64 } __asm_arg0 + local slice __ret_value + local { { u64, u64, u64 } } buffer + + entry(): + v0 = get_local ptr slice, __ret_value + v1 = call main_8(), !48 + v2 = const u64 1024 + v3 = asm(cap: v2) -> u64 hp, !53 { + aloc cap + } + v4 = int_to_ptr v3 to ptr u8, !54 + v5 = ptr_to_int v4 to u64, !55 + v6 = get_local ptr { u64, u64, u64 }, __anon_0, !56 + v7 = const u64 0 + v8 = get_elem_ptr v6, ptr u64, v7, !57 + store v5 to v8, !58 + v9 = const u64 1 + v10 = get_elem_ptr v6, ptr u64, v9, !59 + store v2 to v10, !60 + v11 = const u64 2 + v12 = get_elem_ptr v6, ptr u64, v11, !61 + v13 = const u64 0 + store v13 to v12, !62 + v14 = asm(buffer: v6) -> ptr { u64, u64, u64 } buffer { + } + v15 = get_local ptr { u64, u64, u64 }, __aggr_memcpy_0 + mem_copy_val v15, v14 + v16 = get_local ptr { { u64, u64, u64 } }, __anon_1, !64 + v17 = const u64 0 + v18 = get_elem_ptr v16, ptr { u64, u64, u64 }, v17, !65 + mem_copy_val v18, v15 + v19 = ptr_to_int v16 to u64, !68 + v20 = int_to_ptr v19 to ptr { { u64, u64, u64 } }, !69 + v21 = const u64 0 + v22 = get_elem_ptr v20, ptr { u64, u64, u64 }, v21, !71 + v23 = get_local ptr { u64, u64, u64 }, __asm_arg + mem_copy_val v23, v22 + v24 = asm(buffer: v23) -> ptr { u64, u64, u64 } buffer { + } + v25 = get_local ptr { u64, u64, u64 }, __aggr_memcpy_00 + mem_copy_val v25, v24 + v26 = get_local ptr { u64, u64, u64 }, __anon_00, !72 + mem_copy_val v26, v25 + v27 = const u64 0 + v28 = get_elem_ptr v26, ptr u64, v27, !73 + v29 = load v28, !74 + v30 = int_to_ptr v29 to ptr u8, !75 + v31 = const u64 1 + v32 = get_elem_ptr v26, ptr u64, v31, !76 + v33 = load v32, !77 + v34 = const u64 2 + v35 = get_elem_ptr v26, ptr u64, v34, !78 + v36 = load v35, !79 + v37 = const u64 8 + v38 = add v36, v37, !80 + v39 = cmp gt v38 v33, !81 + cbr v39, encode_10_abi_encode_11_block1(), encode_10_abi_encode_11_block0(v30, v33), !82 + + encode_10_abi_encode_11_block0(v40: ptr u8, v41: u64): + v42 = ptr_to_int v40 to u64, !83 + v43 = add v42, v36, !84 + v44 = int_to_ptr v43 to ptr u64, !85 + store v1 to v44, !86 + v45 = get_local ptr { u64, u64, u64 }, __anon_10, !87 + v46 = const u64 0 + v47 = get_elem_ptr v45, ptr u64, v46, !88 + store v42 to v47, !89 + v48 = const u64 1 + v49 = get_elem_ptr v45, ptr u64, v48, !90 + store v41 to v49, !91 + v50 = const u64 2 + v51 = get_elem_ptr v45, ptr u64, v50, !92 + store v38 to v51, !93 + v52 = asm(buffer: v45) -> ptr { u64, u64, u64 } buffer { + } + v53 = get_local ptr { u64, u64, u64 }, __aggr_memcpy_01 + mem_copy_val v53, v52 + v54 = get_local ptr { { u64, u64, u64 } }, __anon_2, !95 + v55 = const u64 0 + v56 = get_elem_ptr v54, ptr { u64, u64, u64 }, v55, !96 + mem_copy_val v56, v53 + v57 = get_local ptr { { u64, u64, u64 } }, buffer, !98 + mem_copy_val v57, v54 + v58 = get_local ptr { { u64, u64, u64 } }, buffer, !100 + v59 = ptr_to_int v58 to u64, !103 + v60 = int_to_ptr v59 to ptr { { u64, u64, u64 } }, !104 + v61 = const u64 0 + v62 = get_elem_ptr v60, ptr { u64, u64, u64 }, v61, !105 + v63 = get_local ptr { u64, u64, u64 }, __asm_arg0 + mem_copy_val v63, v62 + v64 = asm(buffer: v63) -> ptr { u64, u64, u64 } buffer { + } + v65 = get_local ptr { u64, u64, u64 }, __aggr_memcpy_02 + mem_copy_val v65, v64 + v66 = get_local ptr { u64, u64, u64 }, __anon_01, !106 + mem_copy_val v66, v65 + v67 = const u64 0 + v68 = get_elem_ptr v66, ptr u64, v67, !107 + v69 = load v68, !108 + v70 = int_to_ptr v69 to ptr u8, !109 + v71 = const u64 2 + v72 = get_elem_ptr v66, ptr u64, v71, !110 + v73 = ptr_to_int v70 to u64, !111 + v74 = get_local ptr { u64, u64 }, __anon_11, !112 + v75 = const u64 0 + v76 = get_elem_ptr v74, ptr u64, v75, !113 + store v73 to v76, !114 + v77 = const u64 1 + v78 = get_elem_ptr v74, ptr u64, v77, !115 + mem_copy_val v78, v72 + v79 = asm(s: v74) -> ptr slice s { + } + v80 = get_local ptr slice, __aggr_memcpy_03 + mem_copy_val v80, v79 + mem_copy_val v0, v80 + ret ptr slice v0 + + encode_10_abi_encode_11_block1(): + v81 = const u64 2 + v82 = mul v33, v81, !116 + v83 = asm(new_cap: v82, old_ptr: v30, len: v36) -> ptr u8 hp, !117 { + aloc new_cap + mcp hp old_ptr len + } + br encode_10_abi_encode_11_block0(v83, v82), !118 + } + + entry_orig fn main_8() -> u64, !121 { + entry(): + v0 = get_config ptr { u64 }, WRAPPED, !122 + v1 = const u64 0 + v2 = get_elem_ptr v0, ptr u64, v1, !123 + v3 = load v2 + v4 = get_config ptr { u64 }, TUPLE, !124 + v5 = const u64 0 + v6 = get_elem_ptr v4, ptr u64, v5, !125 + v7 = load v6 + v8 = add v3, v7, !128 + ret u64 v8 + } +} + +!0 = "test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/src/main.sw" +!1 = span !0 177 182 +!2 = span !0 136 143 +!3 = "sway-lib-core/src/codec.sw" +!4 = span !3 64814 64817 +!5 = span !3 64828 64831 +!6 = span !3 64838 64844 +!7 = span !3 64784 65117 +!8 = fn_name_span !3 64791 64810 +!9 = inline "never" +!10 = (!7 !8 !9) +!11 = span !3 64885 64937 +!12 = span !3 64967 64973 +!13 = span !3 64953 64974 +!14 = fn_call_path_span !3 64953 64966 +!15 = span !3 102115 102136 +!16 = fn_call_path_span !3 102115 102128 +!17 = (!13 !14 !15 !16) +!18 = span !3 64942 64975 +!19 = span !3 65033 65037 +!20 = span !3 65023 65038 +!21 = span !3 64980 65115 +!22 = span !3 65088 65108 +!23 = span !3 652 655 +!24 = span !3 666 670 +!25 = span !3 634 729 +!26 = fn_name_span !3 641 651 +!27 = (!25 !26) +!28 = span !3 65527 65533 +!29 = span !3 65505 65600 +!30 = fn_name_span !3 65508 65518 +!31 = (!29 !30) +!32 = span !3 65566 65594 +!33 = fn_call_path_span !3 65573 65585 +!34 = span !3 593 605 +!35 = (!32 !33 !34) +!36 = (!32 !33) +!37 = span !3 2734 2815 +!38 = (!32 !33 !37) +!39 = span !3 2772 2785 +!40 = span !3 2825 2864 +!41 = (!32 !33 !40) +!42 = "" +!43 = span !42 0 125 +!44 = fn_name_span !42 7 14 +!45 = (!43 !44) +!46 = span !42 66 72 +!47 = fn_call_path_span !42 66 70 +!48 = (!46 !47) +!49 = span !42 90 111 +!50 = fn_call_path_span !42 90 96 +!51 = span !3 64530 64543 +!52 = fn_call_path_span !3 64530 64541 +!53 = (!49 !50 !51 !52) +!54 = (!49 !50 !51 !52) +!55 = (!49 !50 !51 !52) +!56 = (!49 !50 !51 !52) +!57 = (!49 !50 !51 !52) +!58 = (!49 !50 !51 !52) +!59 = (!49 !50 !51 !52) +!60 = (!49 !50 !51 !52) +!61 = (!49 !50 !51 !52) +!62 = (!49 !50 !51 !52) +!63 = span !3 159 222 +!64 = (!49 !50 !51 !52 !63) +!65 = (!49 !50 !51 !52) +!66 = span !3 64514 64544 +!67 = fn_call_path_span !3 64519 64529 +!68 = (!49 !50 !66 !67) +!69 = (!49 !50 !66 !67) +!70 = span !3 55 82 +!71 = (!49 !50 !66 !67 !70) +!72 = (!49 !50 !66 !67) +!73 = (!49 !50 !66 !67) +!74 = (!49 !50 !66 !67) +!75 = (!49 !50 !66 !67) +!76 = (!49 !50 !66 !67) +!77 = (!49 !50 !66 !67) +!78 = (!49 !50 !66 !67) +!79 = (!49 !50 !66 !67) +!80 = (!49 !50 !66 !67) +!81 = (!49 !50 !66 !67) +!82 = (!49 !50 !66 !67) +!83 = (!49 !50 !66 !67) +!84 = (!49 !50 !66 !67) +!85 = (!49 !50 !66 !67) +!86 = (!49 !50 !66 !67) +!87 = (!49 !50 !66 !67) +!88 = (!49 !50 !66 !67) +!89 = (!49 !50 !66 !67) +!90 = (!49 !50 !66 !67) +!91 = (!49 !50 !66 !67) +!92 = (!49 !50 !66 !67) +!93 = (!49 !50 !66 !67) +!94 = span !3 4684 4767 +!95 = (!49 !50 !66 !67 !94) +!96 = (!49 !50 !66 !67) +!97 = span !3 64501 64545 +!98 = (!49 !50 !97) +!99 = span !3 64550 64556 +!100 = (!49 !50 !99) +!101 = span !3 64550 64571 +!102 = fn_call_path_span !3 64557 64569 +!103 = (!49 !50 !101 !102) +!104 = (!49 !50 !101 !102) +!105 = (!49 !50 !101 !102 !70) +!106 = (!49 !50 !101 !102) +!107 = (!49 !50 !101 !102) +!108 = (!49 !50 !101 !102) +!109 = (!49 !50 !101 !102) +!110 = (!49 !50 !101 !102) +!111 = (!49 !50 !101 !102) +!112 = (!49 !50 !101 !102) +!113 = (!49 !50 !101 !102) +!114 = (!49 !50 !101 !102) +!115 = (!49 !50 !101 !102) +!116 = (!49 !50 !66 !67) +!117 = (!49 !50 !66 !67) +!118 = (!49 !50 !66 !67) +!119 = span !0 202 246 +!120 = fn_name_span !0 205 209 +!121 = (!119 !120) +!122 = span !0 225 232 +!123 = span !0 30 36 +!124 = span !0 237 242 +!125 = span !0 243 244 +!126 = span !0 225 244 +!127 = fn_call_path_span !0 235 236 +!128 = (!126 !127) + + Finished release [optimized + fuel] target(s) [736 B] in ??? 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 b1166cfb9fb..1f66a607f42 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 = 0xd8e3576d2f7b2ed2d5f8935aef4837e6ff32b1c092d8ae369ad0fdd955a52169; // AUTO-CONTRACT-ID ../../test_contracts/basic_storage --release +const CONTRACT_ID = 0xfa786fd319eeb24fe328ceb0e033779ba444962f5534ec4ec24dc6686d3fdc1d; // 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/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 13dd55fec91..d8f0d656e18 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 = 0x83ec366b3623ee28ec09d3d92dcc2e113cc7427adb194fb42608103b0188fb83; // AUTO-CONTRACT-ID ../../test_contracts/storage_access_contract --release +const CONTRACT_ID = 0xdc525dd2ea57aa691d4d61acd725ebbefd974eaeb397598ca90c38807dc749bb; // AUTO-CONTRACT-ID ../../test_contracts/storage_access_contract --release fn main() -> bool { let caller = abi(StorageAccess, CONTRACT_ID); diff --git a/test/tests/tests.rs b/test/tests/tests.rs index d4121961e6e..626864f2e74 100644 --- a/test/tests/tests.rs +++ b/test/tests/tests.rs @@ -1,5 +1,7 @@ use libtest_mimic::{Arguments, Trial}; -use std::{path::PathBuf, sync::Once}; +use normalize_path::NormalizePath; +use regex::Regex; +use std::{path::PathBuf, str::FromStr, sync::Once}; static FORC_COMPILATION: Once = Once::new(); @@ -13,35 +15,82 @@ fn compile_forc() { } pub fn main() { + let repo_root: PathBuf = + PathBuf::from_str(&std::env::var("CARGO_MANIFEST_DIR").unwrap()).unwrap(); + let repo_root = repo_root.parent().unwrap().to_path_buf(); + let mut args = Arguments::from_args(); args.nocapture = true; let tests = discover_test() .into_iter() .map(|dir| { - let manifest_dir = "src/e2e_vm_tests/test_programs/"; - let name = dir.to_str().unwrap().to_string().replace(manifest_dir, ""); + let test_programs_dir = "src/e2e_vm_tests/test_programs/"; + let name = dir + .to_str() + .unwrap() + .to_string() + .replace(test_programs_dir, ""); + + let repo_root = repo_root.clone(); Trial::test(name, move || { FORC_COMPILATION.call_once(|| { compile_forc(); }); - let root = dir.to_str().unwrap(); - - let args = vec!["build", "--path", root]; - let o = std::process::Command::new("../target/release/forc") - .args(args) - .output() - .unwrap(); - - let snapshot = clean_output(&format!( - "exit status: {}\nstdout:\n{}\nstderr:\n{}", - o.status.code().unwrap(), - String::from_utf8(o.stdout).unwrap(), - String::from_utf8(o.stderr).unwrap() - )); + let snapshot_toml = + std::fs::read_to_string(format!("{}/snapshot.toml", dir.display()))?; + let snapshot_toml = toml::from_str::(&snapshot_toml)?; + let cmds = if let Some(cmds) = snapshot_toml.get("cmds") { + cmds.as_array() + .unwrap() + .iter() + .map(|v| v.as_str().unwrap()) + .collect::>() + } else { + vec!["forc build --path {root}"] + }; + + let root = format!("test/{}", dir.display()); + + use std::fmt::Write; + let mut snapshot = String::new(); + + for cmd in cmds { + let cmd = cmd.replace("{root}", &root); + + let _ = writeln!(&mut snapshot, "> {}", cmd); + + let cmd = if let Some(cmd) = cmd.strip_prefix("forc ") { + format!("target/release/forc {cmd} 1>&2") + } else { + panic!("Not supported. Possible commands: forc") + }; + + let o = duct::cmd!("bash", "-c", cmd.clone()) + .dir(repo_root.clone()) + .stderr_to_stdout() + .stdout_capture() + .unchecked() + .start() + .unwrap(); + let o = o.wait().unwrap(); + + let _ = writeln!( + &mut snapshot, + "{}", + clean_output(&format!( + "exit status: {}\noutput:\n{}", + o.status.code().unwrap(), + std::str::from_utf8(&o.stdout).unwrap(), + )) + ); + } fn stdout(root: &str, snapshot: &str) { + let root = PathBuf::from_str(root).unwrap(); + let root = root.normalize(); + let mut insta = insta::Settings::new(); insta.set_snapshot_path(root); insta.set_prepend_module_to_snapshot(false); @@ -50,7 +99,7 @@ pub fn main() { insta::assert_snapshot!("stdout", snapshot); drop(scope); } - stdout(&format!("../{root}"), &snapshot); + stdout(&format!("{}/{root}", repo_root.display()), &snapshot); Ok(()) }) @@ -115,5 +164,11 @@ fn clean_output(output: &str) -> String { let manifest_dir = env!("CARGO_MANIFEST_DIR"); let manifest_dir: PathBuf = PathBuf::from(manifest_dir); let parent = manifest_dir.parent().unwrap(); - raw.replace(&format!("{}/", parent.display()), "") + let result = raw.replace(&format!("{}/", parent.display()), ""); + + // Remove compilation time + let r = Regex::new("(Finished release \\[.*?\\] target\\(s\\) \\[.*?\\] in )(.*?s)").unwrap(); + let result = r.replace(&result, "$1???"); + + result.to_string() } From bf9695f1e1f29225dc07fb079d42e835f3548012 Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite Date: Wed, 23 Oct 2024 00:32:57 +0100 Subject: [PATCH 072/115] improve error messages for array items (#6663) ## Description This PR fixes an issue with array items that are typed as `TypeInfo::Error`. These errors were being swallowed and the compiler was failing later with an ICE. Now we correctly show the more user-friendly error. ``` --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:51:26 | 49 | 50 | // Literal too big 51 | let mut a = [8u8, 8, 18446744073709551615]; | ^^^^^^^^^^^^^^^^^^^^ Literal value is too large for type u8. 52 | } ``` ## 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. - [ ] 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). - [ ] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: Joshua Batty --- .../ast_node/expression/typed_expression.rs | 16 +++++++++++----- .../array_wrong_elements_types/src/main.sw | 3 +++ .../array_wrong_elements_types/stdout.snap | 13 ++++++++++++- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs index dd4a14f0b74..a26ebcf590d 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs @@ -1946,7 +1946,7 @@ impl ty::TyExpression { } fn type_check_array( - _handler: &Handler, + handler: &Handler, mut ctx: TypeCheckContext, contents: &[Expression], span: Span, @@ -2002,9 +2002,15 @@ impl ty::TyExpression { .with_type_annotation(type_engine.insert(engines, initial_type.clone(), None)); // type_check_analyze unification will give the final error - let handler = Handler::default(); - Self::type_check(&handler, ctx, expr) - .unwrap_or_else(|err| ty::TyExpression::error(err, span, engines)) + let type_check_handler = Handler::default(); + let result = Self::type_check(&type_check_handler, ctx, expr) + .unwrap_or_else(|err| ty::TyExpression::error(err, span, engines)); + + if let TypeInfo::ErrorRecovery(_) = &*engines.te().get(result.return_type) { + handler.append(type_check_handler); + } + + result }) .collect(); @@ -2982,7 +2988,7 @@ mod tests { let _comp_res = do_type_check_for_boolx2(&handler, &expr); let (errors, _warnings) = handler.consume(); - assert!(errors.len() == 1); + assert_eq!(errors.len(), 1); assert!(matches!(&errors[0], CompileError::TypeError(TypeError::MismatchedType { expected, diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw index ca7e2611018..8ed5c3be0af 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw @@ -46,4 +46,7 @@ fn main() { // Should not warn or error let _ : [u8 ; 0] = []; + + // Literal too big + let mut a = [8u8, 8, 18446744073709551615]; } diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/stdout.snap index f1694aba064..bb7fa87aa02 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/stdout.snap @@ -38,6 +38,17 @@ help: Variable declaration's type annotation does not match up with the assigned | ____ +error + --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:51:26 + | +49 | +50 | // Literal too big +51 | let mut a = [8u8, 8, 18446744073709551615]; + | ^^^^^^^^^^^^^^^^^^^^ Literal value is too large for type u8. +52 | } + | +____ + error --> test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw:9:22 | @@ -293,5 +304,5 @@ found: u8. | ____ - Aborting due to 19 errors. + Aborting due to 20 errors. error: Failed to compile array_wrong_elements_types From 40e2b30ecc1b04c87d6c92b28cbdd2cfd4d77aaf Mon Sep 17 00:00:00 2001 From: James <107906898+EdwardJES@users.noreply.github.com> Date: Wed, 23 Oct 2024 18:25:46 +1000 Subject: [PATCH 073/115] feat: add `TotalOrd` library to `core::ops` for `uint` types (#6635) ## Description This PR addresses https://github.com/FuelLabs/sway/issues/6597. A `cmp` trait has been added that exposes: - `min(self, Self) -> Self` - `max(self, Self) -> Self` ## 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. --------- Co-authored-by: K1-R1 <77465250+K1-R1@users.noreply.github.com> --- .../src/tests/expects/impl_trait/mod.rs | 3 +- sway-lib-core/src/ops.sw | 116 +++++++++++++++ sway-lib-std/src/u128.sw | 10 ++ .../should_pass/language/totalord/.gitignore | 2 + .../should_pass/language/totalord/Forc.lock | 13 ++ .../should_pass/language/totalord/Forc.toml | 8 + .../language/totalord/json_abi_oracle.json | 64 ++++++++ .../json_abi_oracle_new_encoding.json | 64 ++++++++ .../should_pass/language/totalord/src/main.sw | 138 ++++++++++++++++++ .../should_pass/language/totalord/test.toml | 4 + 10 files changed, 421 insertions(+), 1 deletion(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/.gitignore create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/json_abi_oracle.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/json_abi_oracle_new_encoding.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/test.toml diff --git a/forc-plugins/forc-doc/src/tests/expects/impl_trait/mod.rs b/forc-plugins/forc-doc/src/tests/expects/impl_trait/mod.rs index 4699c55a6a9..8f96a41e856 100644 --- a/forc-plugins/forc-doc/src/tests/expects/impl_trait/mod.rs +++ b/forc-plugins/forc-doc/src/tests/expects/impl_trait/mod.rs @@ -44,7 +44,7 @@ fn test_impl_traits_default() { assert_search_js( &doc_path, &expect![[r#" - var SEARCH_INDEX={"core":[{"html_filename":"trait.AsRawSlice.html","module_info":["core","raw_slice"],"name":"AsRawSlice","preview":"Trait to return a type as a raw_slice.\n","type_name":"trait"},{"html_filename":"fn.from_str_array.html","module_info":["core","str"],"name":"from_str_array","preview":"","type_name":"function"},{"html_filename":"trait.Add.html","module_info":["core","ops"],"name":"Add","preview":"Trait for the addition of two values.\n","type_name":"trait"},{"html_filename":"trait.Subtract.html","module_info":["core","ops"],"name":"Subtract","preview":"Trait for the subtraction of two values.\n","type_name":"trait"},{"html_filename":"trait.Multiply.html","module_info":["core","ops"],"name":"Multiply","preview":"Trait for the multiplication of two values.\n","type_name":"trait"},{"html_filename":"trait.Divide.html","module_info":["core","ops"],"name":"Divide","preview":"Trait for the division of two values.\n","type_name":"trait"},{"html_filename":"trait.Mod.html","module_info":["core","ops"],"name":"Mod","preview":"Trait for the modulo of two values.\n","type_name":"trait"},{"html_filename":"trait.Not.html","module_info":["core","ops"],"name":"Not","preview":"Trait to invert a type.\n","type_name":"trait"},{"html_filename":"trait.Eq.html","module_info":["core","ops"],"name":"Eq","preview":"Trait to evaluate if two types are equal.\n","type_name":"trait"},{"html_filename":"trait.Ord.html","module_info":["core","ops"],"name":"Ord","preview":"Trait to evaluate if one value is greater or less than another of the same type.\n","type_name":"trait"},{"html_filename":"trait.BitwiseAnd.html","module_info":["core","ops"],"name":"BitwiseAnd","preview":"Trait to bitwise AND two values of the same type.\n","type_name":"trait"},{"html_filename":"trait.BitwiseOr.html","module_info":["core","ops"],"name":"BitwiseOr","preview":"Trait to bitwise OR two values of the same type.\n","type_name":"trait"},{"html_filename":"trait.BitwiseXor.html","module_info":["core","ops"],"name":"BitwiseXor","preview":"Trait to bitwise XOR two values of the same type.\n","type_name":"trait"},{"html_filename":"trait.Shift.html","module_info":["core","ops"],"name":"Shift","preview":"Trait to bit shift a value.\n","type_name":"trait"},{"html_filename":"fn.ok_str_eq.html","module_info":["core","ops"],"name":"ok_str_eq","preview":"","type_name":"function"},{"html_filename":"struct.StorageKey.html","module_info":["core","storage"],"name":"StorageKey","preview":"Describes a location in storage.\n","type_name":"struct"},{"html_filename":"struct.Buffer.html","module_info":["core","codec"],"name":"Buffer","preview":"","type_name":"struct"},{"html_filename":"struct.BufferReader.html","module_info":["core","codec"],"name":"BufferReader","preview":"","type_name":"struct"},{"html_filename":"trait.AbiDecode.html","module_info":["core","codec"],"name":"AbiDecode","preview":"","type_name":"trait"},{"html_filename":"trait.AbiEncode.html","module_info":["core","codec"],"name":"AbiEncode","preview":"","type_name":"trait"},{"html_filename":"fn.encode.html","module_info":["core","codec"],"name":"encode","preview":"","type_name":"function"},{"html_filename":"fn.abi_decode.html","module_info":["core","codec"],"name":"abi_decode","preview":"","type_name":"function"},{"html_filename":"fn.abi_decode_in_place.html","module_info":["core","codec"],"name":"abi_decode_in_place","preview":"","type_name":"function"},{"html_filename":"fn.contract_call.html","module_info":["core","codec"],"name":"contract_call","preview":"","type_name":"function"},{"html_filename":"fn.decode_script_data.html","module_info":["core","codec"],"name":"decode_script_data","preview":"","type_name":"function"},{"html_filename":"fn.decode_predicate_data.html","module_info":["core","codec"],"name":"decode_predicate_data","preview":"","type_name":"function"},{"html_filename":"fn.decode_predicate_data_by_index.html","module_info":["core","codec"],"name":"decode_predicate_data_by_index","preview":"","type_name":"function"},{"html_filename":"fn.decode_first_param.html","module_info":["core","codec"],"name":"decode_first_param","preview":"","type_name":"function"},{"html_filename":"fn.decode_second_param.html","module_info":["core","codec"],"name":"decode_second_param","preview":"","type_name":"function"},{"html_filename":"primitive.u256.html","module_info":["core"],"name":"u256","preview":"256-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.u64.html","module_info":["core"],"name":"u64","preview":"64-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.u32.html","module_info":["core"],"name":"u32","preview":"32-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.u16.html","module_info":["core"],"name":"u16","preview":"16-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.u8.html","module_info":["core"],"name":"u8","preview":"8-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.b256.html","module_info":["core"],"name":"b256","preview":"256 bits (32 bytes), i.e. a hash","type_name":"primitive"},{"html_filename":"primitive.str.html","module_info":["core"],"name":"str","preview":"string slice","type_name":"primitive"},{"html_filename":"primitive.bool.html","module_info":["core"],"name":"bool","preview":"Boolean true or false","type_name":"primitive"},{"html_filename":"primitive.str[0].html","module_info":["core"],"name":"str[0]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[1].html","module_info":["core"],"name":"str[1]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[2].html","module_info":["core"],"name":"str[2]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[3].html","module_info":["core"],"name":"str[3]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[4].html","module_info":["core"],"name":"str[4]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[5].html","module_info":["core"],"name":"str[5]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[6].html","module_info":["core"],"name":"str[6]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[7].html","module_info":["core"],"name":"str[7]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[8].html","module_info":["core"],"name":"str[8]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[9].html","module_info":["core"],"name":"str[9]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[10].html","module_info":["core"],"name":"str[10]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[11].html","module_info":["core"],"name":"str[11]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[12].html","module_info":["core"],"name":"str[12]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[13].html","module_info":["core"],"name":"str[13]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[14].html","module_info":["core"],"name":"str[14]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[15].html","module_info":["core"],"name":"str[15]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[16].html","module_info":["core"],"name":"str[16]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[17].html","module_info":["core"],"name":"str[17]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[18].html","module_info":["core"],"name":"str[18]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[19].html","module_info":["core"],"name":"str[19]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[20].html","module_info":["core"],"name":"str[20]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[21].html","module_info":["core"],"name":"str[21]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[22].html","module_info":["core"],"name":"str[22]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[23].html","module_info":["core"],"name":"str[23]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[24].html","module_info":["core"],"name":"str[24]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[25].html","module_info":["core"],"name":"str[25]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[26].html","module_info":["core"],"name":"str[26]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[27].html","module_info":["core"],"name":"str[27]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[28].html","module_info":["core"],"name":"str[28]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[29].html","module_info":["core"],"name":"str[29]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[30].html","module_info":["core"],"name":"str[30]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[31].html","module_info":["core"],"name":"str[31]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[32].html","module_info":["core"],"name":"str[32]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[33].html","module_info":["core"],"name":"str[33]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[34].html","module_info":["core"],"name":"str[34]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[35].html","module_info":["core"],"name":"str[35]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[36].html","module_info":["core"],"name":"str[36]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[37].html","module_info":["core"],"name":"str[37]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[38].html","module_info":["core"],"name":"str[38]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[39].html","module_info":["core"],"name":"str[39]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[40].html","module_info":["core"],"name":"str[40]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[41].html","module_info":["core"],"name":"str[41]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[42].html","module_info":["core"],"name":"str[42]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[43].html","module_info":["core"],"name":"str[43]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[44].html","module_info":["core"],"name":"str[44]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[45].html","module_info":["core"],"name":"str[45]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[46].html","module_info":["core"],"name":"str[46]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[47].html","module_info":["core"],"name":"str[47]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[48].html","module_info":["core"],"name":"str[48]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[49].html","module_info":["core"],"name":"str[49]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[50].html","module_info":["core"],"name":"str[50]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[51].html","module_info":["core"],"name":"str[51]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[52].html","module_info":["core"],"name":"str[52]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[53].html","module_info":["core"],"name":"str[53]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[54].html","module_info":["core"],"name":"str[54]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[55].html","module_info":["core"],"name":"str[55]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[56].html","module_info":["core"],"name":"str[56]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[57].html","module_info":["core"],"name":"str[57]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[58].html","module_info":["core"],"name":"str[58]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[59].html","module_info":["core"],"name":"str[59]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[60].html","module_info":["core"],"name":"str[60]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[61].html","module_info":["core"],"name":"str[61]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[62].html","module_info":["core"],"name":"str[62]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[63].html","module_info":["core"],"name":"str[63]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[64].html","module_info":["core"],"name":"str[64]","preview":"fixed-length string","type_name":"primitive"}],"impl_traits":[{"html_filename":"trait.Foo.html","module_info":["impl_traits","foo"],"name":"Foo","preview":"","type_name":"trait"},{"html_filename":"trait.Baz.html","module_info":["impl_traits","foo"],"name":"Baz","preview":"","type_name":"trait"},{"html_filename":"struct.Bar.html","module_info":["impl_traits","bar"],"name":"Bar","preview":"","type_name":"struct"}]}; + var SEARCH_INDEX={"core":[{"html_filename":"trait.AsRawSlice.html","module_info":["core","raw_slice"],"name":"AsRawSlice","preview":"Trait to return a type as a raw_slice.\n","type_name":"trait"},{"html_filename":"fn.from_str_array.html","module_info":["core","str"],"name":"from_str_array","preview":"","type_name":"function"},{"html_filename":"trait.Add.html","module_info":["core","ops"],"name":"Add","preview":"Trait for the addition of two values.\n","type_name":"trait"},{"html_filename":"trait.Subtract.html","module_info":["core","ops"],"name":"Subtract","preview":"Trait for the subtraction of two values.\n","type_name":"trait"},{"html_filename":"trait.Multiply.html","module_info":["core","ops"],"name":"Multiply","preview":"Trait for the multiplication of two values.\n","type_name":"trait"},{"html_filename":"trait.Divide.html","module_info":["core","ops"],"name":"Divide","preview":"Trait for the division of two values.\n","type_name":"trait"},{"html_filename":"trait.Mod.html","module_info":["core","ops"],"name":"Mod","preview":"Trait for the modulo of two values.\n","type_name":"trait"},{"html_filename":"trait.Not.html","module_info":["core","ops"],"name":"Not","preview":"Trait to invert a type.\n","type_name":"trait"},{"html_filename":"trait.Eq.html","module_info":["core","ops"],"name":"Eq","preview":"Trait to evaluate if two types are equal.\n","type_name":"trait"},{"html_filename":"trait.Ord.html","module_info":["core","ops"],"name":"Ord","preview":"Trait to evaluate if one value is greater or less than another of the same type.\n","type_name":"trait"},{"html_filename":"trait.BitwiseAnd.html","module_info":["core","ops"],"name":"BitwiseAnd","preview":"Trait to bitwise AND two values of the same type.\n","type_name":"trait"},{"html_filename":"trait.BitwiseOr.html","module_info":["core","ops"],"name":"BitwiseOr","preview":"Trait to bitwise OR two values of the same type.\n","type_name":"trait"},{"html_filename":"trait.BitwiseXor.html","module_info":["core","ops"],"name":"BitwiseXor","preview":"Trait to bitwise XOR two values of the same type.\n","type_name":"trait"},{"html_filename":"trait.Shift.html","module_info":["core","ops"],"name":"Shift","preview":"Trait to bit shift a value.\n","type_name":"trait"},{"html_filename":"trait.TotalOrd.html","module_info":["core","ops"],"name":"TotalOrd","preview":"Trait to compare values of the same type.\n","type_name":"trait"},{"html_filename":"fn.ok_str_eq.html","module_info":["core","ops"],"name":"ok_str_eq","preview":"","type_name":"function"},{"html_filename":"struct.StorageKey.html","module_info":["core","storage"],"name":"StorageKey","preview":"Describes a location in storage.\n","type_name":"struct"},{"html_filename":"struct.Buffer.html","module_info":["core","codec"],"name":"Buffer","preview":"","type_name":"struct"},{"html_filename":"struct.BufferReader.html","module_info":["core","codec"],"name":"BufferReader","preview":"","type_name":"struct"},{"html_filename":"trait.AbiDecode.html","module_info":["core","codec"],"name":"AbiDecode","preview":"","type_name":"trait"},{"html_filename":"trait.AbiEncode.html","module_info":["core","codec"],"name":"AbiEncode","preview":"","type_name":"trait"},{"html_filename":"fn.encode.html","module_info":["core","codec"],"name":"encode","preview":"","type_name":"function"},{"html_filename":"fn.abi_decode.html","module_info":["core","codec"],"name":"abi_decode","preview":"","type_name":"function"},{"html_filename":"fn.abi_decode_in_place.html","module_info":["core","codec"],"name":"abi_decode_in_place","preview":"","type_name":"function"},{"html_filename":"fn.contract_call.html","module_info":["core","codec"],"name":"contract_call","preview":"","type_name":"function"},{"html_filename":"fn.decode_script_data.html","module_info":["core","codec"],"name":"decode_script_data","preview":"","type_name":"function"},{"html_filename":"fn.decode_predicate_data.html","module_info":["core","codec"],"name":"decode_predicate_data","preview":"","type_name":"function"},{"html_filename":"fn.decode_predicate_data_by_index.html","module_info":["core","codec"],"name":"decode_predicate_data_by_index","preview":"","type_name":"function"},{"html_filename":"fn.decode_first_param.html","module_info":["core","codec"],"name":"decode_first_param","preview":"","type_name":"function"},{"html_filename":"fn.decode_second_param.html","module_info":["core","codec"],"name":"decode_second_param","preview":"","type_name":"function"},{"html_filename":"primitive.u256.html","module_info":["core"],"name":"u256","preview":"256-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.u64.html","module_info":["core"],"name":"u64","preview":"64-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.u32.html","module_info":["core"],"name":"u32","preview":"32-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.u16.html","module_info":["core"],"name":"u16","preview":"16-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.u8.html","module_info":["core"],"name":"u8","preview":"8-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.b256.html","module_info":["core"],"name":"b256","preview":"256 bits (32 bytes), i.e. a hash","type_name":"primitive"},{"html_filename":"primitive.str.html","module_info":["core"],"name":"str","preview":"string slice","type_name":"primitive"},{"html_filename":"primitive.bool.html","module_info":["core"],"name":"bool","preview":"Boolean true or false","type_name":"primitive"},{"html_filename":"primitive.str[0].html","module_info":["core"],"name":"str[0]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[1].html","module_info":["core"],"name":"str[1]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[2].html","module_info":["core"],"name":"str[2]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[3].html","module_info":["core"],"name":"str[3]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[4].html","module_info":["core"],"name":"str[4]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[5].html","module_info":["core"],"name":"str[5]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[6].html","module_info":["core"],"name":"str[6]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[7].html","module_info":["core"],"name":"str[7]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[8].html","module_info":["core"],"name":"str[8]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[9].html","module_info":["core"],"name":"str[9]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[10].html","module_info":["core"],"name":"str[10]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[11].html","module_info":["core"],"name":"str[11]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[12].html","module_info":["core"],"name":"str[12]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[13].html","module_info":["core"],"name":"str[13]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[14].html","module_info":["core"],"name":"str[14]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[15].html","module_info":["core"],"name":"str[15]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[16].html","module_info":["core"],"name":"str[16]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[17].html","module_info":["core"],"name":"str[17]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[18].html","module_info":["core"],"name":"str[18]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[19].html","module_info":["core"],"name":"str[19]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[20].html","module_info":["core"],"name":"str[20]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[21].html","module_info":["core"],"name":"str[21]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[22].html","module_info":["core"],"name":"str[22]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[23].html","module_info":["core"],"name":"str[23]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[24].html","module_info":["core"],"name":"str[24]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[25].html","module_info":["core"],"name":"str[25]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[26].html","module_info":["core"],"name":"str[26]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[27].html","module_info":["core"],"name":"str[27]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[28].html","module_info":["core"],"name":"str[28]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[29].html","module_info":["core"],"name":"str[29]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[30].html","module_info":["core"],"name":"str[30]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[31].html","module_info":["core"],"name":"str[31]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[32].html","module_info":["core"],"name":"str[32]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[33].html","module_info":["core"],"name":"str[33]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[34].html","module_info":["core"],"name":"str[34]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[35].html","module_info":["core"],"name":"str[35]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[36].html","module_info":["core"],"name":"str[36]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[37].html","module_info":["core"],"name":"str[37]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[38].html","module_info":["core"],"name":"str[38]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[39].html","module_info":["core"],"name":"str[39]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[40].html","module_info":["core"],"name":"str[40]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[41].html","module_info":["core"],"name":"str[41]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[42].html","module_info":["core"],"name":"str[42]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[43].html","module_info":["core"],"name":"str[43]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[44].html","module_info":["core"],"name":"str[44]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[45].html","module_info":["core"],"name":"str[45]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[46].html","module_info":["core"],"name":"str[46]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[47].html","module_info":["core"],"name":"str[47]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[48].html","module_info":["core"],"name":"str[48]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[49].html","module_info":["core"],"name":"str[49]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[50].html","module_info":["core"],"name":"str[50]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[51].html","module_info":["core"],"name":"str[51]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[52].html","module_info":["core"],"name":"str[52]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[53].html","module_info":["core"],"name":"str[53]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[54].html","module_info":["core"],"name":"str[54]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[55].html","module_info":["core"],"name":"str[55]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[56].html","module_info":["core"],"name":"str[56]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[57].html","module_info":["core"],"name":"str[57]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[58].html","module_info":["core"],"name":"str[58]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[59].html","module_info":["core"],"name":"str[59]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[60].html","module_info":["core"],"name":"str[60]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[61].html","module_info":["core"],"name":"str[61]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[62].html","module_info":["core"],"name":"str[62]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[63].html","module_info":["core"],"name":"str[63]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[64].html","module_info":["core"],"name":"str[64]","preview":"fixed-length string","type_name":"primitive"}],"impl_traits":[{"html_filename":"trait.Foo.html","module_info":["impl_traits","foo"],"name":"Foo","preview":"","type_name":"trait"},{"html_filename":"trait.Baz.html","module_info":["impl_traits","foo"],"name":"Baz","preview":"","type_name":"trait"},{"html_filename":"struct.Bar.html","module_info":["impl_traits","bar"],"name":"Bar","preview":"","type_name":"struct"}]}; "object"==typeof exports&&"undefined"!=typeof module&&(module.exports=SEARCH_INDEX);"#]], ); assert_file_tree( @@ -154,6 +154,7 @@ fn test_impl_traits_default() { "core/ops/trait.Ord.html", "core/ops/trait.Shift.html", "core/ops/trait.Subtract.html", + "core/ops/trait.TotalOrd.html", "core/raw_slice/index.html", "core/raw_slice/trait.AsRawSlice.html", "core/storage/index.html", diff --git a/sway-lib-core/src/ops.sw b/sway-lib-core/src/ops.sw index 3e820b71025..371bbff5382 100644 --- a/sway-lib-core/src/ops.sw +++ b/sway-lib-core/src/ops.sw @@ -1215,6 +1215,122 @@ impl Shift for u16 { } } +/// Trait to compare values of the same type. +pub trait TotalOrd { + /// Finds the minimum value of two values of the same type. + /// + /// # Arguments + /// + /// * `other`: [Self] - The value of the same type. + /// + /// # Returns + /// + /// * Self - the minimum of the two values, or the same value if they are equal. + /// + /// # Examples + /// + /// ```sway + /// struct MyStruct { + /// val: u64, + /// } + /// + /// impl TotalOrd for MyStruct { + /// fn min(self, other: Self) -> Self { + /// if self.val < other.val { self } else { other } + /// } + /// } + /// + /// fn foo() { + /// let struct1 = MyStruct { val: 10 }; + /// let struct2 = MyStruct { val: 20 }; + /// let min = struct1.min(struct2); + /// assert(min.val == struct1.val); + /// } + /// ``` + fn min(self, other: Self) -> Self; + /// Finds the maximum value of two values of the same type. + /// + /// # Arguments + /// + /// * `other`: [Self] - The value of the same type. + /// + /// # Returns + /// + /// * Self - the maximum of the two values, or the same value if they are equal. + /// + /// # Examples + /// + /// ```sway + /// struct MyStruct { + /// val: u64, + /// } + /// + /// impl TotalOrd for MyStruct { + /// fn max(self, other: Self) -> Self { + /// if self.val > other.val { self } else { other } + /// } + /// } + /// + /// fn foo() { + /// let struct1 = MyStruct { val: 10 }; + /// let struct2 = MyStruct { val: 20 }; + /// let max = struct1.max(struct2); + /// assert(max.val == struct2.val); + /// } + /// ``` + fn max(self, other: Self) -> Self; +} + +impl TotalOrd for u8 { + fn min(self, other: Self) -> Self { + if self < other { self } else { other } + } + + fn max(self, other: Self) -> Self { + if self > other { self } else { other } + } +} + +impl TotalOrd for u16 { + fn min(self, other: Self) -> Self { + if self < other { self } else { other } + } + + fn max(self, other: Self) -> Self { + if self > other { self } else { other } + } +} + +impl TotalOrd for u32 { + fn min(self, other: Self) -> Self { + if self < other { self } else { other } + } + + fn max(self, other: Self) -> Self { + if self > other { self } else { other } + } +} + +impl TotalOrd for u64 { + fn min(self, other: Self) -> Self { + if self < other { self } else { other } + } + + fn max(self, other: Self) -> Self { + if self > other { self } else { other } + } +} + +impl TotalOrd for u256 { + fn min(self, other: Self) -> Self { + if self < other { self } else { other } + } + + fn max(self, other: Self) -> Self { + if self > other { self } else { other } + } +} + impl Shift for u8 { fn lsh(self, other: u64) -> Self { __and(__lsh(self, other), Self::max()) diff --git a/sway-lib-std/src/u128.sw b/sway-lib-std/src/u128.sw index c13248c5f80..8eb22317b64 100644 --- a/sway-lib-std/src/u128.sw +++ b/sway-lib-std/src/u128.sw @@ -864,3 +864,13 @@ impl Logarithm for U128 { result } } + +impl core::ops::TotalOrd for U128 { + fn min(self, other: Self) -> Self { + if self < other { self } else { other } + } + + fn max(self, other: Self) -> Self { + if self > other { self } else { other } + } +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/.gitignore b/test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/.gitignore new file mode 100644 index 00000000000..77d3844f58c --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/.gitignore @@ -0,0 +1,2 @@ +out +target diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/Forc.lock new file mode 100644 index 00000000000..27664e3bf63 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/Forc.lock @@ -0,0 +1,13 @@ +[[package]] +name = "core" +source = "path+from-root-AA6BA29B6C5ED809" + +[[package]] +name = "std" +source = "path+from-root-AA6BA29B6C5ED809" +dependencies = ["core"] + +[[package]] +name = "totalord" +source = "member" +dependencies = ["std"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/Forc.toml new file mode 100644 index 00000000000..fbde59dd326 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "totalord" + +[dependencies] +std = { path = "../../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/json_abi_oracle.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/json_abi_oracle.json new file mode 100644 index 00000000000..5d9532112a9 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/json_abi_oracle.json @@ -0,0 +1,64 @@ +{ + "concreteTypes": [ + { + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "type": "bool" + }, + { + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", + "type": "u16" + }, + { + "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", + "type": "u256" + }, + { + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", + "type": "u32" + }, + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "type": "u64" + }, + { + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "type": "u8" + } + ], + "configurables": [], + "encodingVersion": "1", + "functions": [ + { + "attributes": null, + "inputs": [], + "name": "main", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + ], + "loggedTypes": [ + { + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "logId": "14454674236531057292" + }, + { + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", + "logId": "2992671284987479467" + }, + { + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", + "logId": "15520703124961489725" + }, + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "logId": "1515152261580153489" + }, + { + "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", + "logId": "1970142151624111756" + } + ], + "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/totalord/json_abi_oracle_new_encoding.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/json_abi_oracle_new_encoding.json new file mode 100644 index 00000000000..5d9532112a9 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/json_abi_oracle_new_encoding.json @@ -0,0 +1,64 @@ +{ + "concreteTypes": [ + { + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "type": "bool" + }, + { + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", + "type": "u16" + }, + { + "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", + "type": "u256" + }, + { + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", + "type": "u32" + }, + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "type": "u64" + }, + { + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "type": "u8" + } + ], + "configurables": [], + "encodingVersion": "1", + "functions": [ + { + "attributes": null, + "inputs": [], + "name": "main", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + ], + "loggedTypes": [ + { + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "logId": "14454674236531057292" + }, + { + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", + "logId": "2992671284987479467" + }, + { + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", + "logId": "15520703124961489725" + }, + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "logId": "1515152261580153489" + }, + { + "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", + "logId": "1970142151624111756" + } + ], + "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/totalord/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/src/main.sw new file mode 100644 index 00000000000..81e8e852ad6 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/src/main.sw @@ -0,0 +1,138 @@ +script; + +use std::u128::*; + +fn test_totalord_u8() { + let a = 10u8; + let b = 20u8; + + let max = a.max(b); + assert_eq(max, 20u8); + + let min = a.min(b); + assert_eq(min, 10u8); + + let c = 30u8; + let d = 30u8; + + let max = c.max(d); + assert_eq(max, 30u8); + + let min = c.min(d); + assert_eq(min, 30u8); +} + +fn test_totalord_u16() { + let a = 10u16; + let b = 20u16; + + let max = a.max(b); + assert_eq(max, 20); + + let min = a.min(b); + assert_eq(min, 10); + + let c = 30u16; + let d = 30u16; + + let max = c.max(d); + assert_eq(max, 30); + + let min = c.min(d); + assert_eq(min, 30); +} + +fn test_totalord_u32() { + let a = 10u32; + let b = 20u32; + + let max = a.max(b); + assert_eq(max, 20u32); + + let min = a.min(b); + assert_eq(min, 10u32); + + let c = 30u32; + let d = 30u32; + + let max = c.max(d); + assert_eq(max, 30u32); + + let min = c.min(d); + assert_eq(min, 30u32); +} + +fn test_totalord_u64() { + let a = 10; + let b = 20; + + let max = a.max(b); + assert_eq(max, 20); + + let min = a.min(b); + assert_eq(min, 10); + + let c = 30; + let d = 30; + + let max = c.max(d); + assert_eq(max, 30); + + let min = c.min(d); + assert_eq(min, 30); +} + +fn test_totalord_u128() { + let a = U128::from((0, 0)); + let b = U128::from((0, 1)); + + let max = a.max(b); + assert(max.upper() == 0); + assert(max.lower() == 1); + + let min = a.min(b); + assert(min.upper() == 0); + assert(min.lower() == 0); + + let c = U128::from((2, 2)); + let d = U128::from((2, 2)); + + let max = c.max(d); + assert(max.upper() == 2); + assert(max.lower() == 2); + + let min = c.min(d); + assert(min.upper() == 2); + assert(min.lower() == 2); +} + +fn test_totalord_u256() { + let a = 0x01u256; + let b = 0x02u256; + + let max = a.max(b); + assert_eq(max, 0x02u256); + + let min = a.min(b); + assert_eq(min, 0x01u256); + + let c = 0x03u256; + let d = 0x03u256; + + let max = c.max(d); + assert_eq(max, 0x03u256); + + let min = c.min(d); + assert_eq(min, 0x03u256); +} + +fn main() -> bool { + test_totalord_u8(); + test_totalord_u16(); + test_totalord_u32(); + test_totalord_u64(); + test_totalord_u128(); + test_totalord_u256(); + + true +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/test.toml new file mode 100644 index 00000000000..53fb5ce9a94 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/totalord/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 = true From ba8951e0bdfd51c2d8df6784c69131cd4ae784f8 Mon Sep 17 00:00:00 2001 From: Marcos Henrich Date: Wed, 23 Oct 2024 11:58:47 +0100 Subject: [PATCH 074/115] Fixes ContractCaller type propagation. (#6662) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description ContractCaller comparison was too restrictive, we now just check if the span matches. This fixes unification of codeblock first pass variables with second pass variables. Fixes [#6614](https://github.com/FuelLabs/sway/issues/6614) ## 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: João Matos --- .../ast_node/expression/typed_expression.rs | 6 +----- sway-core/src/type_system/info.rs | 6 +++++- .../language/abi_cast_nested_method/Forc.lock | 13 ++++++++++++ .../language/abi_cast_nested_method/Forc.toml | 9 ++++++++ .../abi_cast_nested_method/src/main.sw | 21 +++++++++++++++++++ .../language/abi_cast_nested_method/test.toml | 2 ++ 6 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/abi_cast_nested_method/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/abi_cast_nested_method/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/abi_cast_nested_method/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/abi_cast_nested_method/test.toml diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs index a26ebcf590d..fc089206cfa 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs @@ -1780,14 +1780,10 @@ impl ty::TyExpression { // type check the address and make sure it is let err_span = address.span().clone(); let address_expr = { - // We want to type check the address expression as we do in the second pass, otherwise we get - // mismatched types while comparing TypeInfo::ContractCaller which is the return type of - // TyExpressionVariant::AbiCast. let ctx = ctx .by_ref() .with_help_text("An address that is being ABI cast must be of type b256") - .with_type_annotation(type_engine.insert(engines, TypeInfo::B256, None)) - .with_code_block_first_pass(false); + .with_type_annotation(type_engine.insert(engines, TypeInfo::B256, None)); ty::TyExpression::type_check(handler, ctx, address) .unwrap_or_else(|err| ty::TyExpression::error(err, err_span, engines)) }; diff --git a/sway-core/src/type_system/info.rs b/sway-core/src/type_system/info.rs index eeb22e6a734..d3825e51b51 100644 --- a/sway-core/src/type_system/info.rs +++ b/sway-core/src/type_system/info.rs @@ -379,7 +379,11 @@ impl PartialEqWithEngines for TypeInfo { abi_name: r_abi_name, address: r_address, }, - ) => l_abi_name == r_abi_name && l_address.as_deref().eq(&r_address.as_deref(), ctx), + ) => { + let l_address_span = l_address.as_ref().map(|x| x.span.clone()); + let r_address_span = r_address.as_ref().map(|x| x.span.clone()); + l_abi_name == r_abi_name && l_address_span == r_address_span + } (Self::Array(l0, l1), Self::Array(r0, r1)) => { ((l0.type_id == r0.type_id) || type_engine diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/abi_cast_nested_method/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/abi_cast_nested_method/Forc.lock new file mode 100644 index 00000000000..5b18add0faf --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/abi_cast_nested_method/Forc.lock @@ -0,0 +1,13 @@ +[[package]] +name = "abi_cast_nested_method" +source = "member" +dependencies = ["std"] + +[[package]] +name = "core" +source = "path+from-root-0D81C4DB888BC505" + +[[package]] +name = "std" +source = "path+from-root-0D81C4DB888BC505" +dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/abi_cast_nested_method/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/abi_cast_nested_method/Forc.toml new file mode 100644 index 00000000000..41edb934da4 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/abi_cast_nested_method/Forc.toml @@ -0,0 +1,9 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "abi_cast_nested_method" +implicit-std = false + +[dependencies] +std = { path = "../../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/abi_cast_nested_method/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/abi_cast_nested_method/src/main.sw new file mode 100644 index 00000000000..6f08f7204de --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/abi_cast_nested_method/src/main.sw @@ -0,0 +1,21 @@ +script; + +abi AMM { + fn pool() -> Option; +} +abi Exchange { + fn swap_exact_output(); +} + +fn main() { + let amm_contract = abi(AMM, 0x0000000000000000000000000000000000000000000000000000000000000000); + + let exchange_contract_id = amm_contract.pool(); + + // let a = exchange_contract_id.unwrap().into(); + // let exchange_contract = abi(Exchange, a); + + let exchange_contract = abi(Exchange, exchange_contract_id.unwrap().into()); + + exchange_contract.swap_exact_output(); +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/abi_cast_nested_method/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/abi_cast_nested_method/test.toml new file mode 100644 index 00000000000..2c5bf1ae09a --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/abi_cast_nested_method/test.toml @@ -0,0 +1,2 @@ +category = "compile" +expected_warnings = 0 From cc842e36d9a9f4f696065fdd700f977d6f3d0a29 Mon Sep 17 00:00:00 2001 From: Marcos Henrich Date: Thu, 24 Oct 2024 04:57:20 +0100 Subject: [PATCH 075/115] Fixes issue with nested method type args. (#6658) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description When a method application called another one that uses more type args than the impl trait type args the type substitution was not working. This was fixed by making a type substitution of placeholders of impl trait type parameters. ## 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: Sophie Dankel <47993817+sdankel@users.noreply.github.com> Co-authored-by: João Matos --- .../typed_expression/method_application.rs | 55 ++++++++++++++++--- sway-core/src/type_system/info.rs | 17 +++++- .../src/type_system/substitute/subst_map.rs | 27 ++++++++- .../method_nested_type_args/Forc.lock | 13 +++++ .../method_nested_type_args/Forc.toml | 8 +++ .../method_nested_type_args/src/main.sw | 26 +++++++++ .../method_nested_type_args/test.toml | 5 ++ 7 files changed, 138 insertions(+), 13 deletions(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/method_nested_type_args/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/method_nested_type_args/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/method_nested_type_args/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/method_nested_type_args/test.toml diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs index 7fb6d3eaff6..ec621b7e0b9 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs @@ -644,28 +644,65 @@ pub(crate) fn type_check_method_application( { fn_ref = cached_fn_ref; } else { - // This handles the case of substituting the generic blanket type by call_path_typeid. if let Some(TyDecl::ImplSelfOrTrait(t)) = method.clone().implementing_type { let t = &engines.de().get(&t.decl_id).implementing_for; if let TypeInfo::Custom { qualified_call_path, - type_arguments: _, + type_arguments, root_type_id: _, } = &*type_engine.get(t.initial_type_id) { + let mut subst_type_parameters = vec![]; + let mut subst_type_arguments = vec![]; + + let mut names_type_ids = HashMap::::new(); + if let Some(type_arguments) = type_arguments { + for t_arg in type_arguments.iter() { + if let TypeInfo::Custom { + qualified_call_path, + .. + } = &*type_engine.get(t_arg.initial_type_id) + { + names_type_ids.insert( + qualified_call_path.call_path.suffix.clone(), + t_arg.type_id, + ); + } + } + } + + // This handles the case of substituting the generic blanket type by call_path_typeid. for p in method.type_parameters.clone() { if p.name_ident.as_str() == qualified_call_path.call_path.suffix.as_str() { - let type_subst = TypeSubstMap::from_type_parameters_and_type_arguments( - vec![t.initial_type_id], - vec![call_path_typeid], - ); - method.subst(&SubstTypesContext::new( + subst_type_parameters.push(t.initial_type_id); + subst_type_arguments.push(call_path_typeid); + break; + } + } + + // This will subst inner method_application placeholders with the already resolved + // current method application type parameter + for p in method.type_parameters.clone() { + if names_type_ids.contains_key(&p.name_ident) { + subst_type_parameters.push(engines.te().insert( engines, - &type_subst, - !ctx.code_block_first_pass(), + TypeInfo::Placeholder(p.clone()), + p.span().source_id(), )); + subst_type_arguments.push(p.type_id); } } + + let type_subst = TypeSubstMap::from_type_parameters_and_type_arguments( + subst_type_parameters, + subst_type_arguments, + ); + + method.subst(&SubstTypesContext::new( + engines, + &type_subst, + !ctx.code_block_first_pass(), + )); } } diff --git a/sway-core/src/type_system/info.rs b/sway-core/src/type_system/info.rs index d3825e51b51..30b3af262a8 100644 --- a/sway-core/src/type_system/info.rs +++ b/sway-core/src/type_system/info.rs @@ -672,7 +672,22 @@ impl DebugWithEngines for TypeInfo { let s = match self { Unknown => "unknown".into(), Never => "!".into(), - UnknownGeneric { name, .. } => name.to_string(), + UnknownGeneric { + name, + trait_constraints, + .. + } => { + let tc_str = trait_constraints + .iter() + .map(|tc| engines.help_out(tc).to_string()) + .collect::>() + .join("+"); + if tc_str.is_empty() { + name.to_string() + } else { + format!("{}:{}", name, tc_str) + } + } Placeholder(t) => format!("placeholder({:?})", engines.help_out(t)), TypeParam(n) => format!("typeparam({n})"), StringSlice => "str".into(), diff --git a/sway-core/src/type_system/substitute/subst_map.rs b/sway-core/src/type_system/substitute/subst_map.rs index 7b70aade0aa..8020e1c4d63 100644 --- a/sway-core/src/type_system/substitute/subst_map.rs +++ b/sway-core/src/type_system/substitute/subst_map.rs @@ -538,13 +538,34 @@ fn iter_for_match( type_info: &TypeInfo, ) -> Option { let type_engine = engines.te(); + for (source_type, dest_type) in &type_mapping.mapping { - if type_engine - .get(*source_type) - .eq(type_info, &PartialEqWithEnginesContext::new(engines)) + let source_type_info = type_engine.get(*source_type); + + // Allows current placeholder(T:T1+T2) to match source placeholder(T:T1) + if let ( + TypeInfo::Placeholder(source_type_param), + TypeInfo::Placeholder(current_type_param), + ) = ((*source_type_info).clone(), type_info) { + if source_type_param.name_ident.as_str() == current_type_param.name_ident.as_str() + && current_type_param + .trait_constraints + .iter() + .all(|current_tc| { + source_type_param.trait_constraints.iter().any(|source_tc| { + source_tc.eq(current_tc, &PartialEqWithEnginesContext::new(engines)) + }) + }) + { + return Some(*dest_type); + } + } + + if source_type_info.eq(type_info, &PartialEqWithEnginesContext::new(engines)) { return Some(*dest_type); } } + None } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/method_nested_type_args/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/method_nested_type_args/Forc.lock new file mode 100644 index 00000000000..d279ad45f8d --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/method_nested_type_args/Forc.lock @@ -0,0 +1,13 @@ +[[package]] +name = "core" +source = "path+from-root-765123F2C684AE5A" + +[[package]] +name = "method_nested_type_args" +source = "member" +dependencies = ["std"] + +[[package]] +name = "std" +source = "path+from-root-765123F2C684AE5A" +dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/method_nested_type_args/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/method_nested_type_args/Forc.toml new file mode 100644 index 00000000000..9f43c4d89f5 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/method_nested_type_args/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +license = "Apache-2.0" +name = "method_nested_type_args" +entry = "main.sw" + +[dependencies] +std = { path = "../../../../reduced_std_libs/sway-lib-std-assert" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/method_nested_type_args/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/method_nested_type_args/src/main.sw new file mode 100644 index 00000000000..47e8fee5518 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/method_nested_type_args/src/main.sw @@ -0,0 +1,26 @@ +script; + +trait T1 {} +trait T2 {} + +struct S where T: T1 { + x: T, +} + +impl S where T: T1{ + fn not_just_t1(self) -> u64 where T: T2 { + Self::also_t2(self) + } + fn also_t2(self) -> u64 where T: T2 { + 42 + } +} + +impl T1 for u8 {} +impl T1 for u64 {} +impl T2 for u64 {} + +fn main() { + let a = S::{x: 42}; + assert_eq(a.not_just_t1(), 42); +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/method_nested_type_args/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/method_nested_type_args/test.toml new file mode 100644 index 00000000000..4bffac353e9 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/method_nested_type_args/test.toml @@ -0,0 +1,5 @@ +category = "run" +expected_result = { action = "return", value = 0 } +expected_result_new_encoding = { action = "return_data", value = "" } +validate_abi = false +expected_warnings = 1 From a110a95a7ff0bba814bc2f7511f1447c6a00f0d2 Mon Sep 17 00:00:00 2001 From: jjcnn <38888011+jjcnn@users.noreply.github.com> Date: Thu, 24 Oct 2024 10:03:32 +0200 Subject: [PATCH 076/115] Fix module ancestor check for imports (#6671) ## Description When importing items we allow imports from ancestor modules, even if the ancestor module is declared as private. The code that performs this check was moved from `module.rs` to `root.rs` as part of #5697. During this move the current module path (i.e., the path of the destination of the import) was mistakenly replaced with the module path of the root module of the destination module. Since root modules do not have ancestors this meant that no source module was ever considered an ancestor of the destination module. This PR fixes this problem, and adds an abscure test case that shows the issue. ## Checklist - [ ] 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. - [ ] 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). - [ ] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: Joshua Batty --- .../src/semantic_analysis/namespace/root.rs | 10 ++++---- .../import_from_private_ancestor/Forc.lock | 8 ++++++ .../import_from_private_ancestor/Forc.toml | 9 +++++++ .../json_abi_oracle.json | 25 +++++++++++++++++++ .../json_abi_oracle_new_encoding.json | 23 +++++++++++++++++ .../import_from_private_ancestor/src/foz.sw | 3 +++ .../src/foz/foo.sw | 3 +++ .../src/foz/foo/bar.sw | 3 +++ .../src/foz/foo/bar/baz.sw | 4 +++ .../import_from_private_ancestor/src/main.sw | 3 +++ .../import_from_private_ancestor/test.toml | 2 ++ 11 files changed, 88 insertions(+), 5 deletions(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/json_abi_oracle.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/json_abi_oracle_new_encoding.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/src/foz.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/src/foz/foo.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/src/foz/foo/bar.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/src/foz/foo/bar/baz.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/test.toml diff --git a/sway-core/src/semantic_analysis/namespace/root.rs b/sway-core/src/semantic_analysis/namespace/root.rs index 73a57a5203b..759a6a6e1ae 100644 --- a/sway-core/src/semantic_analysis/namespace/root.rs +++ b/sway-core/src/semantic_analysis/namespace/root.rs @@ -181,7 +181,7 @@ impl Root { dst: &ModulePath, visibility: Visibility, ) -> Result<(), ErrorEmitted> { - self.check_module_privacy(handler, engines, src)?; + self.check_module_privacy(handler, engines, src, dst)?; let src_mod = self.module.lookup_submodule(handler, engines, src)?; @@ -358,7 +358,7 @@ impl Root { alias: Option, visibility: Visibility, ) -> Result<(), ErrorEmitted> { - self.check_module_privacy(handler, engines, src)?; + self.check_module_privacy(handler, engines, src, dst)?; let src_mod = self.module.lookup_submodule(handler, engines, src)?; let (decl, path) = self.item_lookup(handler, engines, item, src, dst)?; @@ -445,7 +445,7 @@ impl Root { alias: Option, visibility: Visibility, ) -> Result<(), ErrorEmitted> { - self.check_module_privacy(handler, engines, src)?; + self.check_module_privacy(handler, engines, src, dst)?; let decl_engine = engines.de(); let parsed_decl_engine = engines.pe(); @@ -610,7 +610,7 @@ impl Root { enum_name: &Ident, visibility: Visibility, ) -> Result<(), ErrorEmitted> { - self.check_module_privacy(handler, engines, src)?; + self.check_module_privacy(handler, engines, src, dst)?; let parsed_decl_engine = engines.pe(); let decl_engine = engines.de(); @@ -689,8 +689,8 @@ impl Root { handler: &Handler, engines: &Engines, src: &ModulePath, + dst: &ModulePath, ) -> Result<(), ErrorEmitted> { - let dst = self.module.mod_path(); // you are always allowed to access your ancestor's symbols if !is_ancestor(src, dst) { // we don't check the first prefix because direct children are always accessible diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/Forc.lock new file mode 100644 index 00000000000..6a0e40e7180 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/Forc.lock @@ -0,0 +1,8 @@ +[[package]] +name = "core" +source = "path+from-root-044245A29CAD6C26" + +[[package]] +name = "import_from_private_ancestor" +source = "member" +dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/Forc.toml new file mode 100644 index 00000000000..91a266c2b48 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/Forc.toml @@ -0,0 +1,9 @@ +[project] +authors = ["Fuel Labs "] +license = "Apache-2.0" +name = "import_from_private_ancestor" +entry = "main.sw" +implicit-std = false + +[dependencies] +core = { path = "../../../../../../../sway-lib-core" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/json_abi_oracle.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/json_abi_oracle.json new file mode 100644 index 00000000000..03b2f150939 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/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": "bool", + "typeId": 0, + "typeParameters": null + } + ] +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/json_abi_oracle_new_encoding.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/json_abi_oracle_new_encoding.json new file mode 100644 index 00000000000..668a88f2e07 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/json_abi_oracle_new_encoding.json @@ -0,0 +1,23 @@ +{ + "concreteTypes": [ + { + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "type": "bool" + } + ], + "configurables": [], + "encodingVersion": "1", + "functions": [ + { + "attributes": null, + "inputs": [], + "name": "main", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + ], + "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/import_from_private_ancestor/src/foz.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/src/foz.sw new file mode 100644 index 00000000000..2580c25454e --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/src/foz.sw @@ -0,0 +1,3 @@ +library; + +mod foo; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/src/foz/foo.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/src/foz/foo.sw new file mode 100644 index 00000000000..871fba91f2b --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/src/foz/foo.sw @@ -0,0 +1,3 @@ +library; + +mod bar; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/src/foz/foo/bar.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/src/foz/foo/bar.sw new file mode 100644 index 00000000000..df6056f61ce --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/src/foz/foo/bar.sw @@ -0,0 +1,3 @@ +library; + +mod baz; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/src/foz/foo/bar/baz.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/src/foz/foo/bar/baz.sw new file mode 100644 index 00000000000..8ef39f15bcd --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/src/foz/foo/bar/baz.sw @@ -0,0 +1,4 @@ +library; + +// This is legal even though foo is a private module, because foo is an ancestor of the current module +use ::foz::foo::*; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/src/main.sw new file mode 100644 index 00000000000..bd91906df81 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/src/main.sw @@ -0,0 +1,3 @@ +library; + +mod foz; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/test.toml new file mode 100644 index 00000000000..2c5bf1ae09a --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/import_from_private_ancestor/test.toml @@ -0,0 +1,2 @@ +category = "compile" +expected_warnings = 0 From d6b9defa91a169b5222501206f1564aec8e2c19e Mon Sep 17 00:00:00 2001 From: Vaivaswatha N Date: Thu, 24 Oct 2024 17:10:58 +0530 Subject: [PATCH 077/115] [asmgen] generate code for stack argument access differently (#6651) To save excess arguments on the stack, previously we would 1. store the argument using SW with an immediate offset basing from locals-base register. This limits the offset to 12 bits. 2. Store the offset to the first excess argument to the last ARG register so that callee can access these. This PR reverses the order. It stores the offset to the last ARG register first. Then the store of argument to the stack slot can be made without requiring large immediate offsets, basing just on the last ARG register. Fixes #6646 --------- Co-authored-by: IGI-111 --- .../src/asm_generation/fuel/functions.rs | 87 +++++------ .../language/args_on_stack/src/main.sw | 137 +++++++++++++++++- .../src/main.sw | 2 +- 3 files changed, 183 insertions(+), 43 deletions(-) diff --git a/sway-core/src/asm_generation/fuel/functions.rs b/sway-core/src/asm_generation/fuel/functions.rs index a53860e4204..42577c543d6 100644 --- a/sway-core/src/asm_generation/fuel/functions.rs +++ b/sway-core/src/asm_generation/fuel/functions.rs @@ -84,49 +84,9 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> { )); } } else { - // Put NUM_ARG_REGISTERS - 1 arguments into arg registers and rest into the stack. - for (idx, arg_val) in args.iter().enumerate() { - let arg_reg = self.value_to_register(arg_val)?; - // Except for the last arg register, the others hold an argument. - if idx < compiler_constants::NUM_ARG_REGISTERS as usize - 1 { - self.cur_bytecode.push(Op::register_move( - VirtualRegister::Constant(ConstantRegister::ARG_REGS[idx]), - arg_reg, - format!("[call]: pass argument {idx}"), - self.md_mgr.val_to_span(self.context, *arg_val), - )); - } else { - // All arguments [NUM_ARG_REGISTERS - 1 ..] go into the stack. - assert!( - self.locals_size_bytes() % 8 == 0, - "The size of locals is not word aligned" - ); - let stack_offset_bytes = self.locals_size_bytes() - + (((idx as u64 + 1) - compiler_constants::NUM_ARG_REGISTERS as u64) * 8); - assert!( - stack_offset_bytes - < self.locals_size_bytes() + (self.max_num_extra_args() * 8) - ); - self.cur_bytecode.push(Op { - opcode: Either::Left(VirtualOp::SW( - VirtualRegister::Constant(ConstantRegister::LocalsBase), - arg_reg, - VirtualImmediate12::new( - // The VM multiples the offset by 8, so we divide it by 8. - stack_offset_bytes / 8, - self.md_mgr - .val_to_span(self.context, *arg_val) - .unwrap_or(Span::dummy()), - ) - .expect("Too many arguments, cannot handle."), - )), - comment: format!("[call]: pass argument {idx} via its stack slot"), - owning_span: self.md_mgr.val_to_span(self.context, *arg_val), - }); - } - } // Register ARG_REGS[NUM_ARG_REGISTERS-1] must contain LocalsBase + locals_size // so that the callee can index the stack arguments from there. + // It's also useful for us to save the arguments to the stack next. if self.locals_size_bytes() <= TWELVE_BITS { self.cur_bytecode.push(Op { opcode: Either::Left(VirtualOp::ADDI( @@ -172,6 +132,51 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> { owning_span: self.md_mgr.val_to_span(self.context, *instr_val), }); } + + // Put NUM_ARG_REGISTERS - 1 arguments into arg registers and rest into the stack. + for (idx, arg_val) in args.iter().enumerate() { + let arg_reg = self.value_to_register(arg_val)?; + // Except for the last arg register, the others hold an argument. + if idx < compiler_constants::NUM_ARG_REGISTERS as usize - 1 { + self.cur_bytecode.push(Op::register_move( + VirtualRegister::Constant(ConstantRegister::ARG_REGS[idx]), + arg_reg, + format!("[call]: pass argument {idx}"), + self.md_mgr.val_to_span(self.context, *arg_val), + )); + } else { + // All arguments [NUM_ARG_REGISTERS - 1 ..] go into the stack. + assert!( + self.locals_size_bytes() % 8 == 0, + "The size of locals is not word aligned" + ); + let stack_offset = + (idx as u64 + 1) - compiler_constants::NUM_ARG_REGISTERS as u64; + let stack_offset_bytes = self.locals_size_bytes() + (stack_offset * 8); + assert!( + stack_offset_bytes + < self.locals_size_bytes() + (self.max_num_extra_args() * 8) + ); + self.cur_bytecode.push(Op { + opcode: Either::Left(VirtualOp::SW( + VirtualRegister::Constant( + ConstantRegister::ARG_REGS + [compiler_constants::NUM_ARG_REGISTERS as usize - 1], + ), + arg_reg, + VirtualImmediate12::new( + stack_offset, + self.md_mgr + .val_to_span(self.context, *arg_val) + .unwrap_or(Span::dummy()), + ) + .expect("Too many arguments, cannot handle."), + )), + comment: format!("[call]: pass argument {idx} via its stack slot"), + owning_span: self.md_mgr.val_to_span(self.context, *arg_val), + }); + } + } } // Set a new return address. diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/args_on_stack/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/args_on_stack/src/main.sw index d755563c275..877225f59a6 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/args_on_stack/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/args_on_stack/src/main.sw @@ -15,8 +15,143 @@ fn foo(a: u64, b: A, c: u64, d: u256, e: b256, f: String, g: [u64; 2], h: b256, a + b.j + c + g[0] + j + f.as_bytes().len() + i.as_bytes().len() } +#[inline(never)] +fn bar(a: u64, b: A, c: u64, d: u256, e: b256, f: String, g: [u64; 2], h: b256, i: String, j: u64) -> u64 { + let a_arr : [u64; 4096] = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + foo(a_arr[a], b, c, d, e, f, g, h, i, j) +} + fn main() -> u64 { - foo( + bar( 11, A { i: 0, j: 2 }, 1, 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 bc2f5881cd6..a8ae0aaa993 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 = 0x514dae6ddad19623646033458f970d1286ef111806145daf80d06ca679604a96; // AUTO-CONTRACT-ID ../../test_contracts/contract_with_type_aliases --release +const CONTRACT_ID = 0x741e73148cf8c2f12b620adb9a15275eeabe703a5c058b0e786117e92024fde2; // AUTO-CONTRACT-ID ../../test_contracts/contract_with_type_aliases --release fn main() { let caller = abi(MyContract, CONTRACT_ID); From be707745454056a4ec4f874423bcb6035eed68d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Matos?= Date: Thu, 24 Oct 2024 13:13:59 +0100 Subject: [PATCH 078/115] Namespace module cleanups (#6660) ## Description This PR represents another round of cleanups, this time mostly around `Namespace` and `Root`. ## 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. --------- Co-authored-by: Joshua Batty --- .../ast_node/declaration/enum.rs | 2 +- .../function/function_parameter.rs | 4 +- .../ast_node/declaration/struct.rs | 2 +- .../ast_node/declaration/trait_type.rs | 2 +- .../ast_node/declaration/variable.rs | 2 +- .../ast_node/expression/intrinsic_function.rs | 14 +- .../ast_node/expression/typed_expression.rs | 26 +- .../typed_expression/method_application.rs | 2 +- .../src/semantic_analysis/namespace/mod.rs | 2 +- .../semantic_analysis/namespace/namespace.rs | 44 +--- .../src/semantic_analysis/namespace/root.rs | 225 +--------------- .../semantic_analysis/namespace/trait_map.rs | 8 +- .../semantic_analysis/type_check_context.rs | 9 +- .../src/semantic_analysis/type_resolve.rs | 247 +++++++++++++++--- .../src/type_system/ast_elements/binding.rs | 21 +- .../ast_elements/trait_constraint.rs | 2 +- sway-core/src/type_system/id.rs | 2 +- sway-core/src/type_system/monomorphization.rs | 29 +- 18 files changed, 288 insertions(+), 355 deletions(-) diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs b/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs index 58f69e92c93..0434857f18f 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs @@ -83,7 +83,7 @@ impl ty::TyEnumDecl { impl ty::TyEnumVariant { pub(crate) fn type_check( handler: &Handler, - mut ctx: TypeCheckContext, + ctx: TypeCheckContext, variant: EnumVariant, ) -> Result { let type_engine = ctx.engines.te(); diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/function/function_parameter.rs b/sway-core/src/semantic_analysis/ast_node/declaration/function/function_parameter.rs index 00b7cb87a77..324a2d14404 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/function/function_parameter.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/function/function_parameter.rs @@ -13,7 +13,7 @@ use sway_types::Spanned; impl ty::TyFunctionParameter { pub(crate) fn type_check( handler: &Handler, - mut ctx: TypeCheckContext, + ctx: TypeCheckContext, parameter: FunctionParameter, ) -> Result { let type_engine = ctx.engines.te(); @@ -67,7 +67,7 @@ impl ty::TyFunctionParameter { pub(crate) fn type_check_interface_parameter( handler: &Handler, - mut ctx: TypeCheckContext, + ctx: TypeCheckContext, parameter: &FunctionParameter, ) -> Result { let type_engine = ctx.engines.te(); diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs b/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs index 0716c8f4e52..0d3a7a25d34 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs @@ -79,7 +79,7 @@ impl ty::TyStructDecl { impl ty::TyStructField { pub(crate) fn type_check( handler: &Handler, - mut ctx: TypeCheckContext, + ctx: TypeCheckContext, field: StructField, ) -> Result { let type_engine = ctx.engines.te(); diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/trait_type.rs b/sway-core/src/semantic_analysis/ast_node/declaration/trait_type.rs index 937404b3f47..262c2a5ef36 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/trait_type.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/trait_type.rs @@ -36,7 +36,7 @@ impl ty::TyTraitType { pub(crate) fn type_check( handler: &Handler, - mut ctx: TypeCheckContext, + ctx: TypeCheckContext, trait_type: parsed::TraitTypeDeclaration, ) -> Result { let parsed::TraitTypeDeclaration { diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/variable.rs b/sway-core/src/semantic_analysis/ast_node/declaration/variable.rs index 3d69fb65aab..cd9bff70750 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/variable.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/variable.rs @@ -32,7 +32,7 @@ impl ty::TyVariableDecl { pub fn type_check( handler: &Handler, - mut ctx: TypeCheckContext, + ctx: TypeCheckContext, var_decl: VariableDeclaration, ) -> Result { let engines = &ctx.engines(); 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 46e46276f25..0219bec7d15 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 @@ -648,7 +648,7 @@ fn type_check_size_of_val( /// Constraints: None. fn type_check_size_of_type( handler: &Handler, - mut ctx: TypeCheckContext, + ctx: TypeCheckContext, kind: sway_ast::Intrinsic, arguments: &[Expression], type_arguments: &[TypeArgument], @@ -710,7 +710,7 @@ fn type_check_size_of_type( /// Constraints: None. fn type_check_is_reference_type( handler: &Handler, - mut ctx: TypeCheckContext, + ctx: TypeCheckContext, kind: sway_ast::Intrinsic, _arguments: &[Expression], type_arguments: &[TypeArgument], @@ -763,7 +763,7 @@ fn type_check_is_reference_type( /// Constraints: None. fn type_check_assert_is_str_array( handler: &Handler, - mut ctx: TypeCheckContext, + ctx: TypeCheckContext, kind: sway_ast::Intrinsic, _arguments: &[Expression], type_arguments: &[TypeArgument], @@ -1222,8 +1222,7 @@ fn type_check_state_store_word( None, )); let type_argument = type_arguments.first().map(|targ| { - let mut ctx = - ctx.with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + let ctx = ctx.with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); let initial_type_info = type_engine .to_typeinfo(targ.type_id, &targ.span) .map_err(|e| handler.emit_err(e.into())) @@ -1318,8 +1317,7 @@ fn type_check_state_quad( )); let number_of_slots_exp = ty::TyExpression::type_check(handler, ctx.by_ref(), &arguments[2])?; let type_argument = type_arguments.first().map(|targ| { - let mut ctx = - ctx.with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + let ctx = ctx.with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); let initial_type_info = type_engine .to_typeinfo(targ.type_id, &targ.span) .map_err(|e| handler.emit_err(e.into())) @@ -1812,7 +1810,7 @@ fn type_check_smo( // Type check the type argument let type_argument = type_arguments.first().map(|targ| { - let mut ctx = ctx + let ctx = ctx .by_ref() .with_help_text("") .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs index fc089206cfa..af790c3d2ed 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs @@ -1243,19 +1243,19 @@ impl ty::TyExpression { let storage_key_ident = Ident::new_with_override("StorageKey".into(), span.clone()); // Search for the struct declaration with the call path above. - let storage_key_decl_opt = ctx - .namespace() - .resolve_root_symbol( - handler, - engines, - &storage_key_mod_path, - &storage_key_ident, - None, - )? - .expect_typed(); - let storage_key_struct_decl_ref = storage_key_decl_opt.to_struct_decl(handler, engines)?; + let storage_key_decl = ctx.namespace().root().resolve_symbol( + handler, + engines, + &storage_key_mod_path, + &storage_key_ident, + None, + )?; + + let storage_key_struct_decl_id = storage_key_decl + .expect_typed() + .to_struct_decl(handler, engines)?; let mut storage_key_struct_decl = - (*decl_engine.get_struct(&storage_key_struct_decl_ref)).clone(); + (*decl_engine.get_struct(&storage_key_struct_decl_id)).clone(); // Set the type arguments to `StorageKey` to the `access_type`, which is represents the // type of the data that the `StorageKey` "points" to. @@ -1281,7 +1281,7 @@ impl ty::TyExpression { let storage_key_struct_decl_ref = decl_engine.insert( storage_key_struct_decl, decl_engine - .get_parsed_decl_id(&storage_key_struct_decl_ref) + .get_parsed_decl_id(&storage_key_struct_decl_id) .as_ref(), ); access_type = type_engine.insert( diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs index ec621b7e0b9..2619ab21664 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs @@ -855,7 +855,7 @@ pub(crate) fn resolve_method_name( let mut module_path = call_path.prefixes.clone(); if let (Some(root_mod), root_name) = ( module_path.first().cloned(), - ctx.namespace().root_module_name().clone(), + ctx.namespace().root_module().name().clone(), ) { if root_mod.as_str() == root_name.as_str() { module_path.remove(0); diff --git a/sway-core/src/semantic_analysis/namespace/mod.rs b/sway-core/src/semantic_analysis/namespace/mod.rs index 5b723fa193d..5fba8b2d90e 100644 --- a/sway-core/src/semantic_analysis/namespace/mod.rs +++ b/sway-core/src/semantic_analysis/namespace/mod.rs @@ -11,7 +11,6 @@ pub use contract_helpers::*; pub use lexical_scope::{Items, LexicalScope, LexicalScopeId, LexicalScopePath}; pub use module::Module; pub use namespace::Namespace; -pub use namespace::TryInsertingTraitImplOnFailure; pub use root::ResolvedDeclaration; pub use root::Root; pub(super) use trait_map::CodeBlockFirstPass; @@ -19,6 +18,7 @@ pub(super) use trait_map::IsExtendingExistingImpl; pub(super) use trait_map::IsImplSelf; pub(super) use trait_map::ResolvedTraitImplItem; pub(super) use trait_map::TraitMap; +pub use trait_map::TryInsertingTraitImplOnFailure; use sway_types::Ident; diff --git a/sway-core/src/semantic_analysis/namespace/namespace.rs b/sway-core/src/semantic_analysis/namespace/namespace.rs index 47bb53e3138..6ed7fe8007b 100644 --- a/sway-core/src/semantic_analysis/namespace/namespace.rs +++ b/sway-core/src/semantic_analysis/namespace/namespace.rs @@ -7,21 +7,12 @@ use super::{ module::Module, root::{ResolvedDeclaration, Root}, submodule_namespace::SubmoduleNamespace, - trait_map::ResolvedTraitImplItem, ModulePath, ModulePathBuf, }; use sway_error::handler::{ErrorEmitted, Handler}; use sway_types::span::Span; -/// Enum used to pass a value asking for insertion of type into trait map when an implementation -/// of the trait cannot be found. -#[derive(Debug)] -pub enum TryInsertingTraitImplOnFailure { - Yes, - No, -} - /// The set of items that represent the namespace context passed throughout type checking. #[derive(Clone, Debug, Default)] pub struct Namespace { @@ -117,11 +108,6 @@ impl Namespace { &self.root.module } - /// The name of the root module - pub fn root_module_name(&self) -> &Ident { - self.root.module.name() - } - /// Access to the current [Module], i.e. the module at the inner `mod_path`. pub fn module(&self, engines: &Engines) -> &Module { self.root @@ -142,7 +128,7 @@ impl Namespace { &self, handler: &Handler, engines: &Engines, - path: &[Ident], + path: &ModulePath, ) -> Result<&Module, ErrorEmitted> { self.root.module.lookup_submodule(handler, engines, path) } @@ -203,34 +189,6 @@ impl Namespace { root_name != &absolute_module_path[0] } - - pub fn get_root_trait_item_for_type( - &self, - handler: &Handler, - engines: &Engines, - name: &Ident, - type_id: TypeId, - as_trait: Option, - ) -> Result { - self.root - .module - .current_items() - .implemented_traits - .get_trait_item_for_type(handler, engines, name, type_id, as_trait) - } - - pub fn resolve_root_symbol( - &self, - handler: &Handler, - engines: &Engines, - mod_path: &ModulePath, - symbol: &Ident, - self_type: Option, - ) -> Result { - self.root - .resolve_symbol(handler, engines, mod_path, symbol, self_type) - } - /// Short-hand for calling [Root::resolve_symbol] on `root` with the `mod_path`. pub(crate) fn resolve_symbol( &self, diff --git a/sway-core/src/semantic_analysis/namespace/root.rs b/sway-core/src/semantic_analysis/namespace/root.rs index 759a6a6e1ae..7d4e22b7265 100644 --- a/sway-core/src/semantic_analysis/namespace/root.rs +++ b/sway-core/src/semantic_analysis/namespace/root.rs @@ -1,18 +1,17 @@ use std::fmt; -use super::{ - module::Module, namespace::Namespace, trait_map::TraitMap, Ident, ResolvedTraitImplItem, -}; +use super::{module::Module, trait_map::TraitMap, Ident}; use crate::{ decl_engine::{DeclEngine, DeclRef}, engine_threading::*, language::{ parsed::*, - ty::{self, StructDecl, TyDecl, TyTraitItem}, + ty::{self, StructDecl, TyDecl}, CallPath, Visibility, }, namespace::{ModulePath, ModulePathBuf}, - TypeId, TypeInfo, + semantic_analysis::type_resolve::{resolve_associated_item, resolve_associated_type}, + TypeId, }; use sway_error::{ error::CompileError, @@ -303,8 +302,8 @@ impl Root { (decl.clone(), path.clone(), *reexport) } else if decls.is_empty() { return Err(handler.emit_err(CompileError::Internal( - "The name {symbol} was bound in a star import, but no corresponding module paths were found", - item.span(), + "The name {symbol} was bound in a star import, but no corresponding module paths were found", + item.span(), ))); } else { return Err(handler.emit_err(CompileError::SymbolWithMultipleBindings { @@ -734,7 +733,7 @@ impl Root { mod_path: &ModulePath, call_path: &CallPath, self_type: Option, - ) -> Result<(ResolvedDeclaration, Vec), ErrorEmitted> { + ) -> Result<(ResolvedDeclaration, ModulePathBuf), ErrorEmitted> { let symbol_path: Vec<_> = mod_path .iter() .chain(&call_path.prefixes) @@ -749,74 +748,6 @@ impl Root { ) } - #[allow(clippy::too_many_arguments)] - pub(crate) fn resolve_call_path_and_root_type_id( - &self, - handler: &Handler, - engines: &Engines, - module: &Module, - root_type_id: TypeId, - mut as_trait: Option, - call_path: &CallPath, - self_type: Option, - ) -> Result { - // This block tries to resolve associated types - let mut decl_opt = None; - let mut type_id_opt = Some(root_type_id); - for ident in call_path.prefixes.iter() { - if let Some(type_id) = type_id_opt { - type_id_opt = None; - decl_opt = Some(self.resolve_associated_type_from_type_id( - handler, - engines, - module, - ident, - type_id, - as_trait.clone(), - self_type, - )?); - as_trait = None; - } else if let Some(decl) = decl_opt { - decl_opt = Some(self.resolve_associated_type( - handler, - engines, - module, - ident, - decl, - as_trait.clone(), - self_type, - )?); - as_trait = None; - } - } - if let Some(type_id) = type_id_opt { - let decl = self.resolve_associated_type_from_type_id( - handler, - engines, - module, - &call_path.suffix, - type_id, - as_trait, - self_type, - )?; - return Ok(decl); - } - if let Some(decl) = decl_opt { - let decl = self.resolve_associated_item( - handler, - engines, - module, - &call_path.suffix, - decl, - as_trait, - self_type, - )?; - Ok(decl) - } else { - Err(handler.emit_err(CompileError::Internal("Unexpected error", call_path.span()))) - } - } - /// Given a path to a module and the identifier of a symbol within that module, resolve its /// declaration. /// @@ -849,7 +780,7 @@ impl Root { let mut decl_opt = None; for ident in mod_path.iter() { if let Some(decl) = decl_opt { - decl_opt = Some(self.resolve_associated_type( + decl_opt = Some(resolve_associated_type( handler, engines, module, ident, decl, None, self_type, )?); } else { @@ -870,8 +801,8 @@ impl Root { } } if let Some(decl) = decl_opt { - let decl = self - .resolve_associated_item(handler, engines, module, symbol, decl, None, self_type)?; + let decl = + resolve_associated_item(handler, engines, module, symbol, decl, None, self_type)?; return Ok((decl, current_mod_path)); } @@ -885,136 +816,6 @@ impl Root { Ok((decl, mod_path.to_vec())) }) } - - #[allow(clippy::too_many_arguments)] - fn resolve_associated_type( - &self, - handler: &Handler, - engines: &Engines, - module: &Module, - symbol: &Ident, - decl: ResolvedDeclaration, - as_trait: Option, - self_type: Option, - ) -> Result { - let type_info = self.decl_to_type_info(handler, engines, symbol, decl)?; - let type_id = engines - .te() - .insert(engines, type_info, symbol.span().source_id()); - - self.resolve_associated_type_from_type_id( - handler, engines, module, symbol, type_id, as_trait, self_type, - ) - } - - #[allow(clippy::too_many_arguments)] - fn resolve_associated_item( - &self, - handler: &Handler, - engines: &Engines, - module: &Module, - symbol: &Ident, - decl: ResolvedDeclaration, - as_trait: Option, - self_type: Option, - ) -> Result { - let type_info = self.decl_to_type_info(handler, engines, symbol, decl)?; - let type_id = engines - .te() - .insert(engines, type_info, symbol.span().source_id()); - - self.resolve_associated_item_from_type_id( - handler, engines, module, symbol, type_id, as_trait, self_type, - ) - } - - fn decl_to_type_info( - &self, - handler: &Handler, - engines: &Engines, - symbol: &Ident, - decl: ResolvedDeclaration, - ) -> Result { - match decl { - ResolvedDeclaration::Parsed(_decl) => todo!(), - ResolvedDeclaration::Typed(decl) => Ok(match decl.clone() { - ty::TyDecl::StructDecl(struct_ty_decl) => TypeInfo::Struct(struct_ty_decl.decl_id), - ty::TyDecl::EnumDecl(enum_ty_decl) => TypeInfo::Enum(enum_ty_decl.decl_id), - ty::TyDecl::TraitTypeDecl(type_decl) => { - let type_decl = engines.de().get_type(&type_decl.decl_id); - if type_decl.ty.is_none() { - return Err(handler.emit_err(CompileError::Internal( - "Trait type declaration has no type", - symbol.span(), - ))); - } - (*engines.te().get(type_decl.ty.clone().unwrap().type_id)).clone() - } - _ => { - return Err(handler.emit_err(CompileError::SymbolNotFound { - name: symbol.clone(), - span: symbol.span(), - })) - } - }), - } - } - - #[allow(clippy::too_many_arguments)] - fn resolve_associated_type_from_type_id( - &self, - handler: &Handler, - engines: &Engines, - module: &Module, - symbol: &Ident, - type_id: TypeId, - as_trait: Option, - self_type: Option, - ) -> Result { - let item_decl = self.resolve_associated_item_from_type_id( - handler, engines, module, symbol, type_id, as_trait, self_type, - )?; - Ok(item_decl) - } - - #[allow(clippy::too_many_arguments)] - fn resolve_associated_item_from_type_id( - &self, - handler: &Handler, - engines: &Engines, - module: &Module, - symbol: &Ident, - type_id: TypeId, - as_trait: Option, - self_type: Option, - ) -> Result { - let type_id = if engines.te().get(type_id).is_self_type() { - if let Some(self_type) = self_type { - self_type - } else { - return Err(handler.emit_err(CompileError::Internal( - "Self type not provided.", - symbol.span(), - ))); - } - } else { - type_id - }; - let item_ref = module - .current_items() - .implemented_traits - .get_trait_item_for_type(handler, engines, symbol, type_id, as_trait)?; - match item_ref { - ResolvedTraitImplItem::Parsed(_item) => todo!(), - ResolvedTraitImplItem::Typed(item) => match item { - TyTraitItem::Fn(fn_ref) => Ok(ResolvedDeclaration::Typed(fn_ref.into())), - TyTraitItem::Constant(const_ref) => { - Ok(ResolvedDeclaration::Typed(const_ref.into())) - } - TyTraitItem::Type(type_ref) => Ok(ResolvedDeclaration::Typed(type_ref.into())), - }, - } - } } impl From for Root { @@ -1023,12 +824,6 @@ impl From for Root { } } -impl From for Root { - fn from(namespace: Namespace) -> Self { - namespace.root - } -} - fn is_ancestor(src: &ModulePath, dst: &ModulePath) -> bool { dst.len() >= src.len() && src.iter().zip(dst).all(|(src, dst)| src == dst) } diff --git a/sway-core/src/semantic_analysis/namespace/trait_map.rs b/sway-core/src/semantic_analysis/namespace/trait_map.rs index 483f090a9ea..d615b96e9ec 100644 --- a/sway-core/src/semantic_analysis/namespace/trait_map.rs +++ b/sway-core/src/semantic_analysis/namespace/trait_map.rs @@ -27,7 +27,13 @@ use crate::{ TypeSubstMap, UnifyCheck, }; -use super::TryInsertingTraitImplOnFailure; +/// Enum used to pass a value asking for insertion of type into trait map when an implementation +/// of the trait cannot be found. +#[derive(Debug)] +pub enum TryInsertingTraitImplOnFailure { + Yes, + No, +} #[derive(Clone)] pub enum CodeBlockFirstPass { diff --git a/sway-core/src/semantic_analysis/type_check_context.rs b/sway-core/src/semantic_analysis/type_check_context.rs index 3202ffaee53..0f515bccdf9 100644 --- a/sway-core/src/semantic_analysis/type_check_context.rs +++ b/sway-core/src/semantic_analysis/type_check_context.rs @@ -650,10 +650,9 @@ impl<'a> TypeCheckContext<'a> { ) } - /// Short-hand for calling [Root::resolve_type_with_self] on `root` with the `mod_path`. - #[allow(clippy::too_many_arguments)] // TODO: remove lint bypass once private modules are no longer experimental + /// Short-hand for calling [resolve_type] on `root` with the `mod_path`. pub(crate) fn resolve_type( - &mut self, + &self, handler: &Handler, type_id: TypeId, span: &Span, @@ -679,7 +678,7 @@ impl<'a> TypeCheckContext<'a> { &self, handler: &Handler, call_path: &CallPath, - ) -> Result { + ) -> Result { resolve_call_path( handler, self.engines(), @@ -694,7 +693,7 @@ impl<'a> TypeCheckContext<'a> { &mut self, handler: &Handler, qualified_call_path: &QualifiedCallPath, - ) -> Result { + ) -> Result { resolve_qualified_call_path( handler, self.engines(), diff --git a/sway-core/src/semantic_analysis/type_resolve.rs b/sway-core/src/semantic_analysis/type_resolve.rs index d29bcfd4952..f2498364acf 100644 --- a/sway-core/src/semantic_analysis/type_resolve.rs +++ b/sway-core/src/semantic_analysis/type_resolve.rs @@ -2,7 +2,7 @@ use sway_error::{ error::CompileError, handler::{ErrorEmitted, Handler}, }; -use sway_types::{Span, Spanned}; +use sway_types::{Ident, Span, Spanned}; use sway_utils::iter_prefixes; use crate::{ @@ -11,7 +11,7 @@ use crate::{ CallPath, QualifiedCallPath, }, monomorphization::type_decl_opt_to_type_id, - namespace::{ModulePath, ResolvedTraitImplItem}, + namespace::{Module, ModulePath, ResolvedDeclaration, ResolvedTraitImplItem}, type_system::SubstTypes, EnforceTypeArguments, Engines, Namespace, SubstTypesContext, TypeId, TypeInfo, }; @@ -41,19 +41,16 @@ pub fn resolve_type( root_type_id, } => { let type_decl_opt = if let Some(root_type_id) = root_type_id { - namespace - .root() - .resolve_call_path_and_root_type_id( - handler, - engines, - namespace.module(engines), - root_type_id, - None, - &qualified_call_path.clone().to_call_path(handler)?, - self_type, - ) - .map(|decl| decl.expect_typed()) - .ok() + resolve_call_path_and_root_type_id( + handler, + engines, + namespace.module(engines), + root_type_id, + None, + &qualified_call_path.clone().to_call_path(handler)?, + self_type, + ) + .ok() } else { resolve_qualified_call_path( handler, @@ -159,14 +156,14 @@ pub fn resolve_type( name, trait_type_id, } => { - let item_ref = namespace.get_root_trait_item_for_type( - handler, - engines, - &name, - trait_type_id, - None, - )?; - if let ResolvedTraitImplItem::Typed(TyTraitItem::Type(type_ref)) = item_ref { + let trait_item_ref = namespace + .root + .module + .current_items() + .implemented_traits + .get_trait_item_for_type(handler, engines, &name, trait_type_id, None)?; + + if let ResolvedTraitImplItem::Typed(TyTraitItem::Type(type_ref)) = trait_item_ref { let type_decl = engines.de().get_type(type_ref.id()); if let Some(ty) = &type_decl.ty { ty.type_id @@ -176,7 +173,7 @@ pub fn resolve_type( } else { return Err(handler.emit_err(CompileError::Internal( "Expecting associated type", - item_ref.span(engines), + trait_item_ref.span(engines), ))); } } @@ -228,7 +225,7 @@ pub fn resolve_qualified_call_path( qualified_call_path: &QualifiedCallPath, self_type: Option, subst_ctx: &SubstTypesContext, -) -> Result { +) -> Result { let type_engine = engines.te(); if let Some(qualified_path_root) = qualified_call_path.clone().qualified_path_root { let root_type_id = match &&*type_engine.get(qualified_path_root.ty.type_id) { @@ -275,18 +272,15 @@ pub fn resolve_qualified_call_path( _ => None, }; - namespace - .root - .resolve_call_path_and_root_type_id( - handler, - engines, - &namespace.root.module, - root_type_id, - as_trait_opt, - &qualified_call_path.call_path, - self_type, - ) - .map(|decl| decl.expect_typed()) + resolve_call_path_and_root_type_id( + handler, + engines, + &namespace.root.module, + root_type_id, + as_trait_opt, + &qualified_call_path.call_path, + self_type, + ) } else { resolve_call_path( handler, @@ -314,11 +308,10 @@ pub fn resolve_call_path( mod_path: &ModulePath, call_path: &CallPath, self_type: Option, -) -> Result { +) -> Result { let (decl, mod_path) = namespace .root .resolve_call_path_and_mod_path(handler, engines, mod_path, call_path, self_type)?; - let decl = decl.expect_typed(); // In case there is no mod path we don't need to check visibility if mod_path.is_empty() { @@ -344,7 +337,7 @@ pub fn resolve_call_path( } // check the visibility of the symbol itself - if !decl.visibility(engines.de()).is_public() { + if !decl.visibility(engines).is_public() { handler.emit_err(CompileError::ImportPrivateSymbol { name: call_path.suffix.clone(), span: call_path.suffix.span(), @@ -353,3 +346,177 @@ pub fn resolve_call_path( Ok(decl) } + +pub fn decl_to_type_info( + handler: &Handler, + engines: &Engines, + symbol: &Ident, + decl: ResolvedDeclaration, +) -> Result { + match decl { + ResolvedDeclaration::Parsed(_decl) => todo!(), + ResolvedDeclaration::Typed(decl) => Ok(match decl.clone() { + ty::TyDecl::StructDecl(struct_ty_decl) => TypeInfo::Struct(struct_ty_decl.decl_id), + ty::TyDecl::EnumDecl(enum_ty_decl) => TypeInfo::Enum(enum_ty_decl.decl_id), + ty::TyDecl::TraitTypeDecl(type_decl) => { + let type_decl = engines.de().get_type(&type_decl.decl_id); + if type_decl.ty.is_none() { + return Err(handler.emit_err(CompileError::Internal( + "Trait type declaration has no type", + symbol.span(), + ))); + } + (*engines.te().get(type_decl.ty.clone().unwrap().type_id)).clone() + } + _ => { + return Err(handler.emit_err(CompileError::SymbolNotFound { + name: symbol.clone(), + span: symbol.span(), + })) + } + }), + } +} + +#[allow(clippy::too_many_arguments)] +pub fn resolve_associated_item_from_type_id( + handler: &Handler, + engines: &Engines, + module: &Module, + symbol: &Ident, + type_id: TypeId, + as_trait: Option, + self_type: Option, +) -> Result { + let type_id = if engines.te().get(type_id).is_self_type() { + if let Some(self_type) = self_type { + self_type + } else { + return Err(handler.emit_err(CompileError::Internal( + "Self type not provided.", + symbol.span(), + ))); + } + } else { + type_id + }; + let item_ref = module + .current_items() + .implemented_traits + .get_trait_item_for_type(handler, engines, symbol, type_id, as_trait)?; + match item_ref { + ResolvedTraitImplItem::Parsed(_item) => todo!(), + ResolvedTraitImplItem::Typed(item) => match item { + TyTraitItem::Fn(fn_ref) => Ok(ResolvedDeclaration::Typed(fn_ref.into())), + TyTraitItem::Constant(const_ref) => Ok(ResolvedDeclaration::Typed(const_ref.into())), + TyTraitItem::Type(type_ref) => Ok(ResolvedDeclaration::Typed(type_ref.into())), + }, + } +} + +#[allow(clippy::too_many_arguments)] +pub fn resolve_associated_type( + handler: &Handler, + engines: &Engines, + module: &Module, + symbol: &Ident, + decl: ResolvedDeclaration, + as_trait: Option, + self_type: Option, +) -> Result { + let type_info = decl_to_type_info(handler, engines, symbol, decl)?; + let type_id = engines + .te() + .insert(engines, type_info, symbol.span().source_id()); + + resolve_associated_item_from_type_id( + handler, engines, module, symbol, type_id, as_trait, self_type, + ) +} + +#[allow(clippy::too_many_arguments)] +pub fn resolve_associated_item( + handler: &Handler, + engines: &Engines, + module: &Module, + symbol: &Ident, + decl: ResolvedDeclaration, + as_trait: Option, + self_type: Option, +) -> Result { + let type_info = decl_to_type_info(handler, engines, symbol, decl)?; + let type_id = engines + .te() + .insert(engines, type_info, symbol.span().source_id()); + + resolve_associated_item_from_type_id( + handler, engines, module, symbol, type_id, as_trait, self_type, + ) +} + +#[allow(clippy::too_many_arguments)] +pub(crate) fn resolve_call_path_and_root_type_id( + handler: &Handler, + engines: &Engines, + module: &Module, + root_type_id: TypeId, + mut as_trait: Option, + call_path: &CallPath, + self_type: Option, +) -> Result { + // This block tries to resolve associated types + let mut decl_opt = None; + let mut type_id_opt = Some(root_type_id); + for ident in call_path.prefixes.iter() { + if let Some(type_id) = type_id_opt { + type_id_opt = None; + decl_opt = Some(resolve_associated_item_from_type_id( + handler, + engines, + module, + ident, + type_id, + as_trait.clone(), + self_type, + )?); + as_trait = None; + } else if let Some(decl) = decl_opt { + decl_opt = Some(resolve_associated_type( + handler, + engines, + module, + ident, + decl, + as_trait.clone(), + self_type, + )?); + as_trait = None; + } + } + if let Some(type_id) = type_id_opt { + let decl = resolve_associated_item_from_type_id( + handler, + engines, + module, + &call_path.suffix, + type_id, + as_trait, + self_type, + )?; + return Ok(decl); + } + if let Some(decl) = decl_opt { + let decl = resolve_associated_item( + handler, + engines, + module, + &call_path.suffix, + decl, + as_trait, + self_type, + )?; + Ok(decl) + } else { + Err(handler.emit_err(CompileError::Internal("Unexpected error", call_path.span()))) + } +} diff --git a/sway-core/src/type_system/ast_elements/binding.rs b/sway-core/src/type_system/ast_elements/binding.rs index 07b543071be..9a4c7c1dd43 100644 --- a/sway-core/src/type_system/ast_elements/binding.rs +++ b/sway-core/src/type_system/ast_elements/binding.rs @@ -311,7 +311,9 @@ impl TypeCheckTypeBinding for TypeBinding { let decl_engine = ctx.engines.de(); let engines = ctx.engines(); // Grab the declaration. - let unknown_decl = ctx.resolve_call_path_with_visibility_check(handler, &self.inner)?; + let unknown_decl = ctx + .resolve_call_path_with_visibility_check(handler, &self.inner)? + .expect_typed(); // Check to see if this is a fn declaration. let fn_ref = unknown_decl.to_fn_ref(handler, ctx.engines())?; // Get a new copy from the declaration engine. @@ -389,7 +391,9 @@ impl TypeCheckTypeBinding for TypeBinding { let decl_engine = ctx.engines.de(); let engines = ctx.engines(); // Grab the declaration. - let unknown_decl = ctx.resolve_call_path_with_visibility_check(handler, &self.inner)?; + let unknown_decl = ctx + .resolve_call_path_with_visibility_check(handler, &self.inner)? + .expect_typed(); // Check to see if this is a struct declaration. let struct_id = unknown_decl.to_struct_decl(handler, engines)?; // Get a new copy from the declaration engine. @@ -433,7 +437,9 @@ impl TypeCheckTypeBinding for TypeBinding { let decl_engine = ctx.engines.de(); let engines = ctx.engines(); // Grab the declaration. - let unknown_decl = ctx.resolve_call_path_with_visibility_check(handler, &self.inner)?; + let unknown_decl = ctx + .resolve_call_path_with_visibility_check(handler, &self.inner)? + .expect_typed(); // Get a new copy from the declaration engine. let enum_id = if let ty::TyDecl::EnumVariantDecl(ty::EnumVariantDecl { enum_ref, .. }) = @@ -474,8 +480,9 @@ impl TypeBinding { ctx: &mut TypeCheckContext, ) -> Result>, ErrorEmitted> { // Grab the declaration. - let unknown_decl = - ctx.resolve_qualified_call_path_with_visibility_check(handler, &self.inner)?; + let unknown_decl = ctx + .resolve_qualified_call_path_with_visibility_check(handler, &self.inner)? + .expect_typed(); // Check to see if this is a const declaration. let const_ref = unknown_decl.to_const_ref(handler, ctx.engines())?; @@ -498,7 +505,9 @@ impl TypeCheckTypeBinding for TypeBinding { ErrorEmitted, > { // Grab the declaration. - let unknown_decl = ctx.resolve_call_path_with_visibility_check(handler, &self.inner)?; + let unknown_decl = ctx + .resolve_call_path_with_visibility_check(handler, &self.inner)? + .expect_typed(); // Check to see if this is a const declaration. let const_ref = unknown_decl.to_const_ref(handler, ctx.engines())?; diff --git a/sway-core/src/type_system/ast_elements/trait_constraint.rs b/sway-core/src/type_system/ast_elements/trait_constraint.rs index b725eabf3eb..e91411595bb 100644 --- a/sway-core/src/type_system/ast_elements/trait_constraint.rs +++ b/sway-core/src/type_system/ast_elements/trait_constraint.rs @@ -137,7 +137,7 @@ impl TraitConstraint { pub(crate) fn type_check( &mut self, handler: &Handler, - mut ctx: TypeCheckContext, + ctx: TypeCheckContext, ) -> Result<(), ErrorEmitted> { // Right now we don't have the ability to support defining a type for a // trait constraint using a callpath directly, so we check to see if the diff --git a/sway-core/src/type_system/id.rs b/sway-core/src/type_system/id.rs index 2b72ef23fe3..d341c150779 100644 --- a/sway-core/src/type_system/id.rs +++ b/sway-core/src/type_system/id.rs @@ -613,7 +613,7 @@ impl TypeId { fn check_trait_constraints_errors( self, handler: &Handler, - mut ctx: TypeCheckContext, + ctx: TypeCheckContext, structure_type_id: &TypeId, structure_trait_constraints: &Vec, f: impl Fn(&TraitConstraint), diff --git a/sway-core/src/type_system/monomorphization.rs b/sway-core/src/type_system/monomorphization.rs index 736e2bd3ad2..674650896db 100644 --- a/sway-core/src/type_system/monomorphization.rs +++ b/sway-core/src/type_system/monomorphization.rs @@ -7,10 +7,10 @@ use sway_types::{Ident, Span, Spanned}; use crate::{ decl_engine::{engine::DeclEngineGetParsedDeclId, DeclEngineInsert}, language::{ - ty::{self, TyDecl}, + ty::{self}, CallPath, }, - namespace::ModulePath, + namespace::{ModulePath, ResolvedDeclaration}, semantic_analysis::type_resolve::resolve_type, type_system::ast_elements::create_type_id::CreateTypeId, EnforceTypeArguments, Engines, Namespace, SubstTypes, SubstTypesContext, TypeArgument, TypeId, @@ -219,7 +219,7 @@ pub(crate) fn type_decl_opt_to_type_id( handler: &Handler, engines: &Engines, namespace: &Namespace, - type_decl_opt: Option, + type_decl_opt: Option, call_path: &CallPath, span: &Span, enforce_type_arguments: EnforceTypeArguments, @@ -231,10 +231,10 @@ pub(crate) fn type_decl_opt_to_type_id( let decl_engine = engines.de(); let type_engine = engines.te(); Ok(match type_decl_opt { - Some(ty::TyDecl::StructDecl(ty::StructDecl { + Some(ResolvedDeclaration::Typed(ty::TyDecl::StructDecl(ty::StructDecl { decl_id: original_id, .. - })) => { + }))) => { // get the copy from the declaration engine let mut new_copy = (*decl_engine.get_struct(&original_id)).clone(); @@ -265,10 +265,10 @@ pub(crate) fn type_decl_opt_to_type_id( new_decl_ref.span().source_id(), ) } - Some(ty::TyDecl::EnumDecl(ty::EnumDecl { + Some(ResolvedDeclaration::Typed(ty::TyDecl::EnumDecl(ty::EnumDecl { decl_id: original_id, .. - })) => { + }))) => { // get the copy from the declaration engine let mut new_copy = (*decl_engine.get_enum(&original_id)).clone(); @@ -299,10 +299,10 @@ pub(crate) fn type_decl_opt_to_type_id( new_decl_ref.span().source_id(), ) } - Some(ty::TyDecl::TypeAliasDecl(ty::TypeAliasDecl { + Some(ResolvedDeclaration::Typed(ty::TyDecl::TypeAliasDecl(ty::TypeAliasDecl { decl_id: original_id, .. - })) => { + }))) => { let new_copy = decl_engine.get_type_alias(&original_id); // TODO: monomorphize the copy, in place, when generic type aliases are @@ -310,11 +310,12 @@ pub(crate) fn type_decl_opt_to_type_id( new_copy.create_type_id(engines) } - Some(ty::TyDecl::GenericTypeForFunctionScope(ty::GenericTypeForFunctionScope { - type_id, - .. - })) => type_id, - Some(ty::TyDecl::TraitTypeDecl(ty::TraitTypeDecl { decl_id })) => { + Some(ResolvedDeclaration::Typed(ty::TyDecl::GenericTypeForFunctionScope( + ty::GenericTypeForFunctionScope { type_id, .. }, + ))) => type_id, + Some(ResolvedDeclaration::Typed(ty::TyDecl::TraitTypeDecl(ty::TraitTypeDecl { + decl_id, + }))) => { let decl_type = decl_engine.get_type(&decl_id); if let Some(ty) = &decl_type.ty { From c374a11d01744961d650e697e7362325e9e68dc1 Mon Sep 17 00:00:00 2001 From: jjcnn <38888011+jjcnn@users.noreply.github.com> Date: Thu, 24 Oct 2024 14:56:37 +0200 Subject: [PATCH 079/115] Simplify the return path analysis (#6541) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description The return path analysis ensures that if a method must return a value then the spine of the method returns a value. The analysis traverses a linearized version of the CFG (one which ignores branching expressions such as `if-then-else` and loops, and simply treats them as a single node) of each method from the (unique) entry point to the (unique) exit point. If there is ever a node in the graph that does not have outgoing edges, then an error is thrown. When constructing such a linearized CFG we have so far treated local `impl`s as branches, meaning that the spine was in fact not linear: ``` fn main() -> u64 { // This point has two outgoing edges // One goes to here impl core::ops::Eq for X { fn eq(self, other: Self) -> bool { asm(r1: self, r2: other, r3) { eq r3 r2 r1; r3: bool } } } // The other goes to here if X::Y(true) == X::Y(true) { a } else { a } } ``` This has been the case even though the edge into a local `impl` does not in fact represent legal control flow. This incorrect construction has made the traversal of the spine-CFG very convoluted and difficult to follow. This PR fixes the incorrect construction, and simplifies the traversal of the spine so that it is clear what is going on. I have also added an additional test to show that methods inside local `impl`s are in fact analyzed separately, even though there is no longer an edge going into the `impl` from the surrounding function. ## 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. --------- Co-authored-by: IGI-111 Co-authored-by: Joshua Batty Co-authored-by: João Matos --- .../analyze_return_paths.rs | 133 +++++++++--------- .../return_path_analysis/src/main.sw | 44 +++++- .../return_path_analysis/test.toml | 5 +- 3 files changed, 110 insertions(+), 72 deletions(-) diff --git a/sway-core/src/control_flow_analysis/analyze_return_paths.rs b/sway-core/src/control_flow_analysis/analyze_return_paths.rs index 863e5ccfc69..dc32308875f 100644 --- a/sway-core/src/control_flow_analysis/analyze_return_paths.rs +++ b/sway-core/src/control_flow_analysis/analyze_return_paths.rs @@ -23,11 +23,11 @@ impl<'cfg> ControlFlowGraph<'cfg> { let mut graph = ControlFlowGraph::new(engines); // do a depth first traversal and cover individual inner ast nodes - let mut leaves = vec![]; + let mut leaf_opt = None; for ast_entrypoint in module_nodes { - match connect_node(engines, ast_entrypoint, &mut graph, &leaves) { - Ok(NodeConnection::NextStep(nodes)) => { - leaves = nodes; + match connect_node(engines, ast_entrypoint, &mut graph, leaf_opt) { + Ok(NodeConnection::NextStep(node_opt)) => { + leaf_opt = node_opt; } Ok(_) => {} Err(mut e) => { @@ -72,6 +72,12 @@ impl<'cfg> ControlFlowGraph<'cfg> { errors } + /// Traverses the spine of a function to ensure that it does return if a return value is + /// expected. The spine of the function does not include branches such as if-then-elses and + /// loops. Those branches are ignored, and a branching expression is represented as a single + /// node in the graph. The analysis continues once the branches join again. This means that the + /// spine is linear, so every node has at most one outgoing edge. The graph is assumed to have + /// been constructed this way. fn ensure_all_paths_reach_exit( &self, engines: &Engines, @@ -80,32 +86,28 @@ impl<'cfg> ControlFlowGraph<'cfg> { function_name: &IdentUnique, return_ty: &TypeInfo, ) -> Vec { - let mut rovers = vec![entry_point]; - let mut visited = vec![]; + let mut rover = entry_point; let mut errors = vec![]; - while !rovers.is_empty() && rovers[0] != exit_point { - rovers.retain(|idx| *idx != exit_point); - let mut next_rovers = vec![]; - let mut last_discovered_span; - for rover in rovers { - visited.push(rover); - last_discovered_span = match &self.graph[rover] { - ControlFlowGraphNode::ProgramNode { node, .. } => Some(node.span.clone()), - ControlFlowGraphNode::MethodDeclaration { span, .. } => Some(span.clone()), - _ => None, - }; - let mut neighbors = self - .graph - .neighbors_directed(rover, petgraph::Direction::Outgoing) - .collect::>(); - if neighbors.is_empty() && !return_ty.is_unit() { - let span = match last_discovered_span { - Some(ref o) => o.clone(), - None => { + while rover != exit_point { + let neighbors = self + .graph + .neighbors_directed(rover, petgraph::Direction::Outgoing) + .collect::>(); + + // The graph is supposed to be a single path, so at most one outgoing neighbor is allowed. + assert!(neighbors.len() <= 1); + + if neighbors.is_empty() { + if !return_ty.is_unit() { + // A return is expected, but none is found. Report an error. + let span = match &self.graph[rover] { + ControlFlowGraphNode::ProgramNode { node, .. } => node.span.clone(), + ControlFlowGraphNode::MethodDeclaration { span, .. } => span.clone(), + _ => { errors.push(CompileError::Internal( "Attempted to construct return path error \ - but no source span was found.", + but no source span was found.", Span::dummy(), )); return errors; @@ -113,17 +115,17 @@ impl<'cfg> ControlFlowGraph<'cfg> { }; let function_name: Ident = function_name.into(); errors.push(CompileError::PathDoesNotReturn { - // TODO: unwrap_to_node is a shortcut. In reality, the graph type should be - // different. To save some code duplication, span, function_name: function_name.clone(), ty: engines.help_out(return_ty).to_string(), }); } - next_rovers.append(&mut neighbors); + + // No further neighbors, so we're done. + break; } - next_rovers.retain(|idx| !visited.contains(idx)); - rovers = next_rovers; + + rover = neighbors[0]; } errors @@ -133,7 +135,7 @@ impl<'cfg> ControlFlowGraph<'cfg> { /// The resulting edges from connecting a node to the graph. enum NodeConnection { /// This represents a node that steps on to the next node. - NextStep(Vec), + NextStep(Option), /// This represents a return or implicit return node, which aborts the stepwise flow. Return(NodeIndex), } @@ -142,7 +144,7 @@ fn connect_node<'eng: 'cfg, 'cfg>( engines: &'eng Engines, node: &ty::TyAstNode, graph: &mut ControlFlowGraph<'cfg>, - leaves: &[NodeIndex], + leaf_opt: Option, ) -> Result> { match &node.content { ty::TyAstNodeContent::Expression(ty::TyExpression { @@ -154,8 +156,8 @@ fn connect_node<'eng: 'cfg, 'cfg>( .. }) => { let this_index = graph.add_node(ControlFlowGraphNode::from_node(node)); - for leaf_ix in leaves { - graph.add_edge(*leaf_ix, this_index, "".into()); + if let Some(leaf_ix) = leaf_opt { + graph.add_edge(leaf_ix, this_index, "".into()); } Ok(NodeConnection::Return(this_index)) } @@ -167,25 +169,25 @@ fn connect_node<'eng: 'cfg, 'cfg>( // since we don't really care about what the loop body contains when detecting // divergent paths let node = graph.add_node(ControlFlowGraphNode::from_node(node)); - for leaf in leaves { - graph.add_edge(*leaf, node, "while loop entry".into()); + if let Some(leaf) = leaf_opt { + graph.add_edge(leaf, node, "while loop entry".into()); } - Ok(NodeConnection::NextStep(vec![node])) + Ok(NodeConnection::NextStep(Some(node))) } ty::TyAstNodeContent::Expression(ty::TyExpression { .. }) => { let entry = graph.add_node(ControlFlowGraphNode::from_node(node)); // insert organizational dominator node // connected to all current leaves - for leaf in leaves { - graph.add_edge(*leaf, entry, "".into()); + if let Some(leaf) = leaf_opt { + graph.add_edge(leaf, entry, "".into()); } - Ok(NodeConnection::NextStep(vec![entry])) + Ok(NodeConnection::NextStep(Some(entry))) } - ty::TyAstNodeContent::SideEffect(_) => Ok(NodeConnection::NextStep(leaves.to_vec())), + ty::TyAstNodeContent::SideEffect(_) => Ok(NodeConnection::NextStep(leaf_opt)), ty::TyAstNodeContent::Declaration(decl) => Ok(NodeConnection::NextStep( - connect_declaration(engines, node, decl, graph, leaves)?, + connect_declaration(engines, node, decl, graph, leaf_opt)?, )), - ty::TyAstNodeContent::Error(_, _) => Ok(NodeConnection::NextStep(vec![])), + ty::TyAstNodeContent::Error(_, _) => Ok(NodeConnection::NextStep(None)), } } @@ -194,8 +196,8 @@ fn connect_declaration<'eng: 'cfg, 'cfg>( node: &ty::TyAstNode, decl: &ty::TyDecl, graph: &mut ControlFlowGraph<'cfg>, - leaves: &[NodeIndex], -) -> Result, Vec> { + leaf_opt: Option, +) -> Result, Vec> { let decl_engine = engines.de(); match decl { ty::TyDecl::TraitDecl(_) @@ -206,39 +208,33 @@ fn connect_declaration<'eng: 'cfg, 'cfg>( | ty::TyDecl::StorageDecl(_) | ty::TyDecl::TypeAliasDecl(_) | ty::TyDecl::TraitTypeDecl(_) - | ty::TyDecl::GenericTypeForFunctionScope(_) => Ok(leaves.to_vec()), + | ty::TyDecl::GenericTypeForFunctionScope(_) => Ok(leaf_opt), ty::TyDecl::VariableDecl(_) | ty::TyDecl::ConstantDecl(_) | ty::TyDecl::ConfigurableDecl(_) => { let entry_node = graph.add_node(ControlFlowGraphNode::from_node(node)); - for leaf in leaves { - graph.add_edge(*leaf, entry_node, "".into()); + if let Some(leaf) = leaf_opt { + graph.add_edge(leaf, entry_node, "".into()); } - Ok(vec![entry_node]) + Ok(Some(entry_node)) } ty::TyDecl::FunctionDecl(ty::FunctionDecl { decl_id, .. }) => { let fn_decl = decl_engine.get_function(decl_id); let entry_node = graph.add_node(ControlFlowGraphNode::from_node(node)); - for leaf in leaves { - graph.add_edge(*leaf, entry_node, "".into()); - } + // Do not connect the leaves to the function entry point, since control cannot flow from them into the function. connect_typed_fn_decl(engines, &fn_decl, graph, entry_node)?; - Ok(leaves.to_vec()) + Ok(leaf_opt) } ty::TyDecl::ImplSelfOrTrait(ty::ImplSelfOrTrait { decl_id, .. }) => { let impl_trait = decl_engine.get_impl_self_or_trait(decl_id); let ty::TyImplSelfOrTrait { trait_name, items, .. } = &*impl_trait; - let entry_node = graph.add_node(ControlFlowGraphNode::from_node(node)); - for leaf in leaves { - graph.add_edge(*leaf, entry_node, "".into()); - } - - connect_impl_trait(engines, trait_name, graph, items, entry_node)?; - Ok(leaves.to_vec()) + // Do not connect the leaves to the impl entry point, since control cannot flow from them into the impl. + connect_impl_trait(engines, trait_name, graph, items)?; + Ok(leaf_opt) } - ty::TyDecl::ErrorRecovery(..) => Ok(leaves.to_vec()), + ty::TyDecl::ErrorRecovery(..) => Ok(leaf_opt), } } @@ -252,7 +248,6 @@ fn connect_impl_trait<'eng: 'cfg, 'cfg>( trait_name: &CallPath, graph: &mut ControlFlowGraph<'cfg>, items: &[TyImplItem], - entry_node: NodeIndex, ) -> Result<(), Vec> { let decl_engine = engines.de(); let mut methods_and_indexes = vec![]; @@ -267,7 +262,6 @@ fn connect_impl_trait<'eng: 'cfg, 'cfg>( method_decl_ref: method_decl_ref.clone(), engines, }); - graph.add_edge(entry_node, fn_decl_entry_node, "".into()); // connect the impl declaration node to the functions themselves, as all trait functions are // public if the trait is in scope connect_typed_fn_decl(engines, &fn_decl, graph, fn_decl_entry_node)?; @@ -306,7 +300,7 @@ fn connect_typed_fn_decl<'eng: 'cfg, 'cfg>( let type_engine = engines.te(); let fn_exit_node = graph.add_node(format!("\"{}\" fn exit", fn_decl.name.as_str()).into()); let return_nodes = - depth_first_insertion_code_block(engines, &fn_decl.body, graph, &[entry_node])?; + depth_first_insertion_code_block(engines, &fn_decl.body, graph, Some(entry_node))?; for node in return_nodes { graph.add_edge(node, fn_exit_node, "return".into()); } @@ -328,16 +322,15 @@ fn depth_first_insertion_code_block<'eng: 'cfg, 'cfg>( engines: &'eng Engines, node_content: &ty::TyCodeBlock, graph: &mut ControlFlowGraph<'cfg>, - leaves: &[NodeIndex], + init_leaf_opt: Option, ) -> Result> { let mut errors = vec![]; - - let mut leaves = leaves.to_vec(); + let mut leaf_opt = init_leaf_opt; let mut return_nodes = vec![]; for node in node_content.contents.iter() { - match connect_node(engines, node, graph, &leaves) { + match connect_node(engines, node, graph, leaf_opt) { Ok(this_node) => match this_node { - NodeConnection::NextStep(nodes) => leaves = nodes, + NodeConnection::NextStep(node_opt) => leaf_opt = node_opt, NodeConnection::Return(node) => { return_nodes.push(node); } diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/return_path_analysis/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/return_path_analysis/src/main.sw index 87ad204b7fc..4e40cf402b3 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/return_path_analysis/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_fail/return_path_analysis/src/main.sw @@ -517,9 +517,51 @@ fn f() -> bool { return false; }; - // No value returned here, which is an error. + // No value returned here. The return path analysis should report an error, even though the +} + + +// Check that return path analysis is applied to local impl methods. +fn g() -> bool { + + struct X { + y: bool, + } + + impl core::ops::Eq for X { + fn eq(self, other: Self) -> bool { + if true { + return true; + } else { + return false; + }; + } + } + + let x = X { y : false }; + let y = X { y : true } ; + + x == y +} + +// Check that return path analysis is applied to local functions. +// Local functions are currently not supported, but once they are added this test should fail for +// the same reason as for the local impl in the function g(). +fn h() -> bool { + + fn tester(other: bool) -> bool { + if true { + return true; + } else { + return false; + }; + } + + tester(true) } fn main() { let _ = f(); + let _ = g(); + let _ = h(); } diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/return_path_analysis/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/return_path_analysis/test.toml index 588a46a1294..1d5eb2f08b5 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/return_path_analysis/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/return_path_analysis/test.toml @@ -1,6 +1,9 @@ category = "fail" +# check: $()Declaring nested functions is currently not implemented. +# check: $()Could not find symbol "tester" in this scope. # check: $()This path must return a value of type "bool" from function "f", but it does not. -# check: $()Aborting due to 1 error. +# check: $()This path must return a value of type "bool" from function "eq", but it does not. +# check: $()Aborting due to 4 errors. From 31974b4e6153385c02bebfa18202ff3c40d79f6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Matos?= Date: Thu, 24 Oct 2024 23:59:59 +0100 Subject: [PATCH 080/115] Add `TypeInfo::UntypedEnum` and `TypeInfo::UntypedStruct`. (#6633) ## Description Adds `TypeInfo::UntypedEnum` and `TypeInfo::UntypedStruct`, which are used to represent untyped enums/structs pointing to a `ParsedDeclId`. These will be used for an upcoming PR that does name resolution as a standalone step before type checking. ## 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/abi_generation/abi_str.rs | 8 ++ sway-core/src/abi_generation/evm_abi.rs | 8 ++ sway-core/src/decl_engine/mod.rs | 1 + sway-core/src/decl_engine/parsed_engine.rs | 22 +++- sway-core/src/decl_engine/parsed_id.rs | 21 +++- sway-core/src/ir_generation/convert.rs | 2 + .../semantic_analysis/namespace/trait_map.rs | 4 +- .../semantic_analysis/node_dependencies.rs | 2 + .../semantic_analysis/type_check_context.rs | 2 +- sway-core/src/type_system/engine.rs | 49 ++++++-- sway-core/src/type_system/id.rs | 50 ++++++++ sway-core/src/type_system/info.rs | 111 +++++++++++++++--- .../src/type_system/substitute/subst_map.rs | 61 +++++++++- 13 files changed, 306 insertions(+), 35 deletions(-) diff --git a/sway-core/src/abi_generation/abi_str.rs b/sway-core/src/abi_generation/abi_str.rs index 2972c9cee0e..254b8a805ad 100644 --- a/sway-core/src/abi_generation/abi_str.rs +++ b/sway-core/src/abi_generation/abi_str.rs @@ -117,6 +117,14 @@ impl TypeInfo { Numeric => "u64".into(), // u64 is the default Contract => "contract".into(), ErrorRecovery(_) => "unknown due to error".into(), + UntypedEnum(decl_id) => { + let decl = engines.pe().get_enum(decl_id); + format!("untyped enum {}", decl.name) + } + UntypedStruct(decl_id) => { + let decl = engines.pe().get_struct(decl_id); + format!("untyped struct {}", decl.name) + } Enum(decl_ref) => { let decl = decl_engine.get_enum(decl_ref); let type_params = if (ctx.abi_root_type_without_generic_type_parameters && is_root) diff --git a/sway-core/src/abi_generation/evm_abi.rs b/sway-core/src/abi_generation/evm_abi.rs index f899e0de209..f723f36d14a 100644 --- a/sway-core/src/abi_generation/evm_abi.rs +++ b/sway-core/src/abi_generation/evm_abi.rs @@ -93,6 +93,14 @@ pub fn abi_str(type_info: &TypeInfo, engines: &Engines) -> String { Numeric => "u64".into(), // u64 is the default Contract => "contract".into(), ErrorRecovery(_) => "unknown due to error".into(), + UntypedEnum(decl_id) => { + let decl = engines.pe().get_enum(decl_id); + format!("untyped enum {}", decl.name) + } + UntypedStruct(decl_id) => { + let decl = engines.pe().get_struct(decl_id); + format!("untyped struct {}", decl.name) + } Enum(decl_ref) => { let decl = decl_engine.get_enum(decl_ref); format!("enum {}", decl.call_path.suffix) diff --git a/sway-core/src/decl_engine/mod.rs b/sway-core/src/decl_engine/mod.rs index 94f6e7987f7..78f4c3ab256 100644 --- a/sway-core/src/decl_engine/mod.rs +++ b/sway-core/src/decl_engine/mod.rs @@ -26,6 +26,7 @@ pub use engine::*; pub(crate) use id::*; pub use interface_decl_id::*; pub(crate) use mapping::*; +pub use parsed_engine::*; pub use r#ref::*; pub(crate) use replace_decls::*; use sway_types::Ident; diff --git a/sway-core/src/decl_engine/parsed_engine.rs b/sway-core/src/decl_engine/parsed_engine.rs index 2177131ceb4..5c330346fd9 100644 --- a/sway-core/src/decl_engine/parsed_engine.rs +++ b/sway-core/src/decl_engine/parsed_engine.rs @@ -1,6 +1,5 @@ use crate::{ concurrent_slab::ConcurrentSlab, - decl_engine::*, language::parsed::{ AbiDeclaration, ConfigurableDeclaration, ConstantDeclaration, EnumDeclaration, EnumVariant, FunctionDeclaration, ImplSelfOrTrait, StorageDeclaration, StructDeclaration, @@ -47,7 +46,7 @@ pub trait ParsedDeclEngineReplace { #[allow(unused)] pub trait ParsedDeclEngineIndex: - ParsedDeclEngineGet, T> + ParsedDeclEngineInsert + ParsedDeclEngineReplace + ParsedDeclEngineGet, T> + ParsedDeclEngineInsert + ParsedDeclEngineReplace { } @@ -136,6 +135,25 @@ macro_rules! decl_engine_clear { }; } +macro_rules! decl_engine_index { + ($slab:ident, $decl:ty) => { + impl ParsedDeclEngineIndex<$decl> for ParsedDeclEngine {} + }; +} +decl_engine_index!(variable_slab, VariableDeclaration); +decl_engine_index!(function_slab, FunctionDeclaration); +decl_engine_index!(trait_slab, TraitDeclaration); +decl_engine_index!(trait_fn_slab, TraitFn); +decl_engine_index!(trait_type_slab, TraitTypeDeclaration); +decl_engine_index!(impl_self_or_trait_slab, ImplSelfOrTrait); +decl_engine_index!(struct_slab, StructDeclaration); +decl_engine_index!(storage_slab, StorageDeclaration); +decl_engine_index!(abi_slab, AbiDeclaration); +decl_engine_index!(configurable_slab, ConfigurableDeclaration); +decl_engine_index!(constant_slab, ConstantDeclaration); +decl_engine_index!(enum_slab, EnumDeclaration); +decl_engine_index!(type_alias_slab, TypeAliasDeclaration); + decl_engine_clear!( variable_slab, VariableDeclaration; function_slab, FunctionDeclaration; diff --git a/sway-core/src/decl_engine/parsed_id.rs b/sway-core/src/decl_engine/parsed_id.rs index 561c811c1dd..3a97459aa75 100644 --- a/sway-core/src/decl_engine/parsed_id.rs +++ b/sway-core/src/decl_engine/parsed_id.rs @@ -2,8 +2,14 @@ use std::hash::{DefaultHasher, Hasher}; use std::marker::PhantomData; use std::{fmt, hash::Hash}; -use crate::engine_threading::{EqWithEngines, PartialEqWithEngines, PartialEqWithEnginesContext}; +use sway_types::{Named, Spanned}; +use crate::engine_threading::{ + EqWithEngines, HashWithEngines, PartialEqWithEngines, PartialEqWithEnginesContext, +}; +use crate::Engines; + +use super::parsed_engine::{ParsedDeclEngine, ParsedDeclEngineGet, ParsedDeclEngineIndex}; use super::DeclUniqueId; pub type ParsedDeclIdIndexType = usize; @@ -61,6 +67,19 @@ impl Hash for ParsedDeclId { } } +impl HashWithEngines for ParsedDeclId +where + ParsedDeclEngine: ParsedDeclEngineIndex, + T: Named + Spanned + HashWithEngines, +{ + fn hash(&self, state: &mut H, engines: &Engines) { + let decl_engine = engines.pe(); + let decl = decl_engine.get(self); + decl.name().hash(state); + decl.hash(state, engines); + } +} + impl PartialOrd for ParsedDeclId { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) diff --git a/sway-core/src/ir_generation/convert.rs b/sway-core/src/ir_generation/convert.rs index 3aa22401338..4d0ee1d20c7 100644 --- a/sway-core/src/ir_generation/convert.rs +++ b/sway-core/src/ir_generation/convert.rs @@ -177,6 +177,8 @@ fn convert_resolved_type_info( TypeInfo::Custom { .. } => reject_type!("Custom"), TypeInfo::Contract => reject_type!("Contract"), TypeInfo::ContractCaller { .. } => reject_type!("ContractCaller"), + TypeInfo::UntypedEnum(_) => reject_type!("UntypedEnum"), + TypeInfo::UntypedStruct(_) => reject_type!("UntypedStruct"), TypeInfo::Unknown => reject_type!("Unknown"), TypeInfo::UnknownGeneric { .. } => reject_type!("Generic"), TypeInfo::Placeholder(_) => reject_type!("Placeholder"), diff --git a/sway-core/src/semantic_analysis/namespace/trait_map.rs b/sway-core/src/semantic_analysis/namespace/trait_map.rs index d615b96e9ec..4d6999931b1 100644 --- a/sway-core/src/semantic_analysis/namespace/trait_map.rs +++ b/sway-core/src/semantic_analysis/namespace/trait_map.rs @@ -882,7 +882,7 @@ impl TraitMap { }, } in impls.iter() { - if !type_info.can_change(decl_engine) && *type_id == *map_type_id { + if !type_info.can_change(engines) && *type_id == *map_type_id { trait_map.insert_inner( map_trait_name.clone(), impl_span.clone(), @@ -1548,6 +1548,8 @@ impl TraitMap { Contract => TypeRootFilter::Contract, ErrorRecovery(_) => TypeRootFilter::ErrorRecovery, Tuple(fields) => TypeRootFilter::Tuple(fields.len()), + UntypedEnum(decl_id) => TypeRootFilter::Enum(*decl_id), + UntypedStruct(decl_id) => TypeRootFilter::Struct(*decl_id), Enum(decl_id) => { // TODO Remove unwrap once #6475 is fixed TypeRootFilter::Enum(engines.de().get_parsed_decl_id(decl_id).unwrap()) diff --git a/sway-core/src/semantic_analysis/node_dependencies.rs b/sway-core/src/semantic_analysis/node_dependencies.rs index 398c590566a..c34feeab4e6 100644 --- a/sway-core/src/semantic_analysis/node_dependencies.rs +++ b/sway-core/src/semantic_analysis/node_dependencies.rs @@ -1031,6 +1031,8 @@ fn type_info_name(type_info: &TypeInfo) -> String { TypeInfo::ContractCaller { abi_name, .. } => { return format!("contract caller {abi_name}"); } + TypeInfo::UntypedEnum(_) => "untyped enum", + TypeInfo::UntypedStruct(_) => "untyped struct", TypeInfo::Struct { .. } => "struct", TypeInfo::Enum { .. } => "enum", TypeInfo::Array(..) => "array", diff --git a/sway-core/src/semantic_analysis/type_check_context.rs b/sway-core/src/semantic_analysis/type_check_context.rs index 0f515bccdf9..455cc21fb4b 100644 --- a/sway-core/src/semantic_analysis/type_check_context.rs +++ b/sway-core/src/semantic_analysis/type_check_context.rs @@ -820,7 +820,7 @@ impl<'a> TypeCheckContext<'a> { let coercion_check = UnifyCheck::coercion(self.engines); // default numeric types to u64 - if type_engine.contains_numeric(decl_engine, type_id) { + if type_engine.contains_numeric(self.engines, type_id) { // While collecting unification we don't decay numeric and will ignore this error. if self.collecting_unifications { return Err(handler.emit_err(CompileError::MethodNotFound { diff --git a/sway-core/src/type_system/engine.rs b/sway-core/src/type_system/engine.rs index e85fb05a012..7dea1cbb281 100644 --- a/sway-core/src/type_system/engine.rs +++ b/sway-core/src/type_system/engine.rs @@ -84,9 +84,7 @@ impl TypeEngine { }); match raw_entry { RawEntryMut::Occupied(o) => return *o.get(), - RawEntryMut::Vacant(_) if ty.can_change(engines.de()) => { - TypeId::new(self.slab.insert(tsi)) - } + RawEntryMut::Vacant(_) if ty.can_change(engines) => TypeId::new(self.slab.insert(tsi)), RawEntryMut::Vacant(v) => { let type_id = TypeId::new(self.slab.insert(tsi.clone())); v.insert_with_hasher(ty_hash, tsi, type_id, make_hasher(&hash_builder, engines)); @@ -332,33 +330,48 @@ impl TypeEngine { } /// Return whether a given type still contains undecayed references to [TypeInfo::Numeric] - pub(crate) fn contains_numeric(&self, decl_engine: &DeclEngine, type_id: TypeId) -> bool { + pub(crate) fn contains_numeric(&self, engines: &Engines, type_id: TypeId) -> bool { + let decl_engine = engines.de(); match &&*self.get(type_id) { + TypeInfo::UntypedEnum(decl_id) => { + engines + .pe() + .get_enum(decl_id) + .variants + .iter() + .all(|variant_type| { + self.contains_numeric(engines, variant_type.type_argument.type_id) + }) + } + TypeInfo::UntypedStruct(decl_id) => engines + .pe() + .get_struct(decl_id) + .fields + .iter() + .any(|field| self.contains_numeric(engines, field.type_argument.type_id)), TypeInfo::Enum(decl_ref) => { decl_engine .get_enum(decl_ref) .variants .iter() .all(|variant_type| { - self.contains_numeric(decl_engine, variant_type.type_argument.type_id) + self.contains_numeric(engines, variant_type.type_argument.type_id) }) } TypeInfo::Struct(decl_ref) => decl_engine .get_struct(decl_ref) .fields .iter() - .any(|field| self.contains_numeric(decl_engine, field.type_argument.type_id)), + .any(|field| self.contains_numeric(engines, field.type_argument.type_id)), TypeInfo::Tuple(fields) => fields .iter() - .any(|field_type| self.contains_numeric(decl_engine, field_type.type_id)), - TypeInfo::Array(elem_ty, _length) => { - self.contains_numeric(decl_engine, elem_ty.type_id) - } - TypeInfo::Ptr(targ) => self.contains_numeric(decl_engine, targ.type_id), - TypeInfo::Slice(targ) => self.contains_numeric(decl_engine, targ.type_id), + .any(|field_type| self.contains_numeric(engines, field_type.type_id)), + TypeInfo::Array(elem_ty, _length) => self.contains_numeric(engines, elem_ty.type_id), + TypeInfo::Ptr(targ) => self.contains_numeric(engines, targ.type_id), + TypeInfo::Slice(targ) => self.contains_numeric(engines, targ.type_id), TypeInfo::Ref { referenced_type, .. - } => self.contains_numeric(decl_engine, referenced_type.type_id), + } => self.contains_numeric(engines, referenced_type.type_id), TypeInfo::Unknown | TypeInfo::Never | TypeInfo::UnknownGeneric { .. } @@ -393,6 +406,16 @@ impl TypeEngine { let decl_engine = engines.de(); match &&*self.get(type_id) { + TypeInfo::UntypedEnum(decl_id) => { + for variant_type in &engines.pe().get_enum(decl_id).variants { + self.decay_numeric(handler, engines, variant_type.type_argument.type_id, span)?; + } + } + TypeInfo::UntypedStruct(decl_id) => { + for field in &engines.pe().get_struct(decl_id).fields { + self.decay_numeric(handler, engines, field.type_argument.type_id, span)?; + } + } TypeInfo::Enum(decl_ref) => { for variant_type in &decl_engine.get_enum(decl_ref).variants { self.decay_numeric(handler, engines, variant_type.type_argument.type_id, span)?; diff --git a/sway-core/src/type_system/id.rs b/sway-core/src/type_system/id.rs index d341c150779..b1eda847745 100644 --- a/sway-core/src/type_system/id.rs +++ b/sway-core/src/type_system/id.rs @@ -228,6 +228,56 @@ impl TypeId { | TypeInfo::Contract | TypeInfo::ErrorRecovery(_) | TypeInfo::TraitType { .. } => {} + TypeInfo::UntypedEnum(decl_id) => { + let enum_decl = engines.pe().get_enum(decl_id); + for type_param in &enum_decl.type_parameters { + extend( + &mut found, + type_param.type_id.extract_any_including_self( + engines, + filter_fn, + type_param.trait_constraints.clone(), + depth + 1, + ), + ); + } + for variant in &enum_decl.variants { + extend( + &mut found, + variant.type_argument.type_id.extract_any_including_self( + engines, + filter_fn, + vec![], + depth + 1, + ), + ); + } + } + TypeInfo::UntypedStruct(decl_id) => { + let struct_decl = engines.pe().get_struct(decl_id); + for type_param in &struct_decl.type_parameters { + extend( + &mut found, + type_param.type_id.extract_any_including_self( + engines, + filter_fn, + type_param.trait_constraints.clone(), + depth + 1, + ), + ); + } + for field in &struct_decl.fields { + extend( + &mut found, + field.type_argument.type_id.extract_any_including_self( + engines, + filter_fn, + vec![], + depth + 1, + ), + ); + } + } TypeInfo::Enum(enum_ref) => { let enum_decl = decl_engine.get_enum(enum_ref); for type_param in &enum_decl.type_parameters { diff --git a/sway-core/src/type_system/info.rs b/sway-core/src/type_system/info.rs index 30b3af262a8..d4bcae5b8bf 100644 --- a/sway-core/src/type_system/info.rs +++ b/sway-core/src/type_system/info.rs @@ -1,10 +1,11 @@ use crate::{ - decl_engine::{DeclEngine, DeclEngineGet, DeclId}, + decl_engine::{parsed_id::ParsedDeclId, DeclEngine, DeclEngineGet, DeclId}, engine_threading::{ DebugWithEngines, DisplayWithEngines, Engines, EqWithEngines, HashWithEngines, OrdWithEngines, OrdWithEnginesContext, PartialEqWithEngines, PartialEqWithEnginesContext, }, language::{ + parsed::{EnumDeclaration, StructDeclaration}, ty::{self, TyEnumDecl, TyStructDecl}, CallPath, QualifiedCallPath, }, @@ -131,6 +132,8 @@ pub enum TypeInfo { StringSlice, StringArray(Length), UnsignedInteger(IntegerBits), + UntypedEnum(ParsedDeclId), + UntypedStruct(ParsedDeclId), Enum(DeclId), Struct(DeclId), Boolean, @@ -215,6 +218,8 @@ impl HashWithEngines for TypeInfo { TypeInfo::Struct(decl_id) => { HashWithEngines::hash(&decl_id, state, engines); } + TypeInfo::UntypedEnum(decl_id) => decl_id.unique_id().hash(state), + TypeInfo::UntypedStruct(decl_id) => decl_id.unique_id().hash(state), TypeInfo::ContractCaller { abi_name, address } => { abi_name.hash(state); let address = address @@ -612,6 +617,22 @@ impl DisplayWithEngines for TypeInfo { Numeric => "numeric".into(), Contract => "contract".into(), ErrorRecovery(_) => "unknown".into(), + UntypedEnum(decl_id) => { + let decl = engines.pe().get_enum(decl_id); + print_inner_types( + engines, + decl.name.as_str(), + decl.type_parameters.iter().map(|x| x.type_id), + ) + } + UntypedStruct(decl_id) => { + let decl = engines.pe().get_struct(decl_id); + print_inner_types( + engines, + decl.name.as_str(), + decl.type_parameters.iter().map(|x| x.type_id), + ) + } Enum(decl_ref) => { let decl = engines.de().get_enum(decl_ref); print_inner_types( @@ -663,12 +684,7 @@ impl DisplayWithEngines for TypeInfo { impl DebugWithEngines for TypeInfo { fn fmt(&self, f: &mut fmt::Formatter<'_>, engines: &Engines) -> fmt::Result { - use TypeInfo::{ - Alias, Array, Boolean, Contract, ContractCaller, Custom, Enum, ErrorRecovery, Never, - Numeric, Placeholder, Ptr, RawUntypedPtr, RawUntypedSlice, Ref, Slice, Storage, - StringArray, StringSlice, Struct, TraitType, Tuple, TypeParam, Unknown, UnknownGeneric, - UnsignedInteger, B256, - }; + use TypeInfo::*; let s = match self { Unknown => "unknown".into(), Never => "!".into(), @@ -732,6 +748,22 @@ impl DebugWithEngines for TypeInfo { Numeric => "numeric".into(), Contract => "contract".into(), ErrorRecovery(_) => "unknown due to error".into(), + UntypedEnum(decl_id) => { + let decl = engines.pe().get_enum(decl_id); + print_inner_types_debug( + engines, + decl.name.as_str(), + decl.type_parameters.iter().map(|x| x.type_id), + ) + } + UntypedStruct(decl_id) => { + let decl = engines.pe().get_struct(decl_id); + print_inner_types_debug( + engines, + decl.name.as_str(), + decl.type_parameters.iter().map(|x| x.type_id), + ) + } Enum(decl_ref) => { let decl = engines.de().get_enum(decl_ref); print_inner_types_debug( @@ -826,6 +858,8 @@ impl TypeInfo { TypeInfo::TraitType { .. } => 24, TypeInfo::Ref { .. } => 25, TypeInfo::Never => 26, + TypeInfo::UntypedEnum(_) => 27, + TypeInfo::UntypedStruct(_) => 28, } } @@ -1242,12 +1276,13 @@ impl TypeInfo { return Ok(self); } match self { - TypeInfo::Enum { .. } | TypeInfo::Struct { .. } => { - Err(handler.emit_err(CompileError::Internal( - "did not expect to apply type arguments to this type", - span.clone(), - ))) - } + TypeInfo::UntypedEnum(_) + | TypeInfo::UntypedStruct(_) + | TypeInfo::Enum { .. } + | TypeInfo::Struct { .. } => Err(handler.emit_err(CompileError::Internal( + "did not expect to apply type arguments to this type", + span.clone(), + ))), TypeInfo::Custom { qualified_call_path: call_path, type_arguments: other_type_arguments, @@ -1316,6 +1351,8 @@ impl TypeInfo { match self { TypeInfo::UnsignedInteger(_) + | TypeInfo::UntypedEnum(_) + | TypeInfo::UntypedStruct(_) | TypeInfo::Enum { .. } | TypeInfo::Struct { .. } | TypeInfo::Boolean @@ -1392,6 +1429,8 @@ impl TypeInfo { } match self { TypeInfo::UnsignedInteger(_) + | TypeInfo::UntypedEnum { .. } + | TypeInfo::UntypedStruct { .. } | TypeInfo::Enum { .. } | TypeInfo::Struct { .. } | TypeInfo::Boolean @@ -1434,16 +1473,24 @@ impl TypeInfo { } } - pub(crate) fn can_change(&self, decl_engine: &DeclEngine) -> bool { + pub(crate) fn can_change(&self, engines: &Engines) -> bool { // TODO: there might be an optimization here that if the type params hold // only non-dynamic types, then it doesn't matter that there are type params match self { + TypeInfo::UntypedEnum(decl_id) => { + let decl = engines.pe().get_enum(decl_id); + !decl.type_parameters.is_empty() + } + TypeInfo::UntypedStruct(decl_id) => { + let decl = engines.pe().get_struct(decl_id); + !decl.type_parameters.is_empty() + } TypeInfo::Enum(decl_ref) => { - let decl = decl_engine.get_enum(decl_ref); + let decl = engines.de().get_enum(decl_ref); !decl.type_parameters.is_empty() } TypeInfo::Struct(decl_ref) => { - let decl = decl_engine.get_struct(decl_ref); + let decl = engines.de().get_struct(decl_ref); !decl.type_parameters.is_empty() } TypeInfo::StringArray(_) @@ -1702,6 +1749,38 @@ impl TypeInfo { Numeric => "u64".into(), // u64 is the default Contract => "contract".into(), ErrorRecovery(_) => "unknown due to error".into(), + UntypedEnum(decl_id) => { + let decl = engines.pe().get_enum(decl_id); + let type_params = if decl.type_parameters.is_empty() { + "".into() + } else { + format!( + "<{}>", + decl.type_parameters + .iter() + .map(|p| p.type_id.get_type_str(engines)) + .collect::>() + .join(",") + ) + }; + format!("untyped enum {}{}", &decl.name, type_params) + } + UntypedStruct(decl_id) => { + let decl = engines.pe().get_struct(decl_id); + let type_params = if decl.type_parameters.is_empty() { + "".into() + } else { + format!( + "<{}>", + decl.type_parameters + .iter() + .map(|p| p.type_id.get_type_str(engines)) + .collect::>() + .join(",") + ) + }; + format!("untyped struct {}{}", &decl.name, type_params) + } Enum(decl_ref) => { let decl = engines.de().get_enum(decl_ref); let type_params = if decl.type_parameters.is_empty() { diff --git a/sway-core/src/type_system/substitute/subst_map.rs b/sway-core/src/type_system/substitute/subst_map.rs index 8020e1c4d63..4b1a9fa93c7 100644 --- a/sway-core/src/type_system/substitute/subst_map.rs +++ b/sway-core/src/type_system/substitute/subst_map.rs @@ -1,5 +1,7 @@ use crate::{ - decl_engine::{DeclEngine, DeclEngineGetParsedDeclId, DeclEngineInsert}, + decl_engine::{ + DeclEngine, DeclEngineGetParsedDeclId, DeclEngineInsert, ParsedDeclEngineInsert, + }, engine_threading::{ DebugWithEngines, Engines, PartialEqWithEngines, PartialEqWithEnginesContext, }, @@ -357,12 +359,69 @@ impl TypeSubstMap { pub(crate) fn find_match(&self, type_id: TypeId, engines: &Engines) -> Option { let type_engine = engines.te(); let decl_engine = engines.de(); + let parsed_decl_engine = engines.pe(); let type_info = type_engine.get(type_id); match (*type_info).clone() { TypeInfo::Custom { .. } => iter_for_match(engines, self, &type_info), TypeInfo::UnknownGeneric { .. } => iter_for_match(engines, self, &type_info), TypeInfo::Placeholder(_) => iter_for_match(engines, self, &type_info), TypeInfo::TypeParam(_) => None, + TypeInfo::UntypedEnum(decl_id) => { + let mut decl = (*parsed_decl_engine.get_enum(&decl_id)).clone(); + let mut need_to_create_new = false; + + for variant in &mut decl.variants { + if let Some(type_id) = self.find_match(variant.type_argument.type_id, engines) { + need_to_create_new = true; + variant.type_argument.type_id = type_id; + } + } + + for type_param in &mut decl.type_parameters { + if let Some(type_id) = self.find_match(type_param.type_id, engines) { + need_to_create_new = true; + type_param.type_id = type_id; + } + } + if need_to_create_new { + let source_id = decl.span.source_id().copied(); + let new_decl_id = engines.pe().insert(decl); + Some(type_engine.insert( + engines, + TypeInfo::UntypedEnum(new_decl_id), + source_id.as_ref(), + )) + } else { + None + } + } + TypeInfo::UntypedStruct(decl_id) => { + let mut decl = (*parsed_decl_engine.get_struct(&decl_id)).clone(); + let mut need_to_create_new = false; + for field in &mut decl.fields { + if let Some(type_id) = self.find_match(field.type_argument.type_id, engines) { + need_to_create_new = true; + field.type_argument.type_id = type_id; + } + } + for type_param in &mut decl.type_parameters { + if let Some(type_id) = self.find_match(type_param.type_id, engines) { + need_to_create_new = true; + type_param.type_id = type_id; + } + } + if need_to_create_new { + let source_id = decl.span.source_id().copied(); + let new_decl_id = parsed_decl_engine.insert(decl); + Some(type_engine.insert( + engines, + TypeInfo::UntypedStruct(new_decl_id), + source_id.as_ref(), + )) + } else { + None + } + } TypeInfo::Struct(decl_id) => { let mut decl = (*decl_engine.get_struct(&decl_id)).clone(); let mut need_to_create_new = false; From 058f4e2afe5dcc52a4dba1fa04f4c73edb323bf0 Mon Sep 17 00:00:00 2001 From: zees-dev Date: Fri, 25 Oct 2024 13:11:06 +1300 Subject: [PATCH 081/115] forc-crypto: vanity address generation (#6661) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description Support for Bech32 case-insensitive vanity address generation via `forc-crypto` CLI tool. Usage: ```sh forc-crypto vanity --help ``` CLI options: ``` Generate a vanity address Usage: forc-crypto vanity [OPTIONS] Options: --starts-with Desired hex string prefix for the address --ends-with Desired hex string suffix for the address --regex Desired regex pattern to match the entire address (case-insensitive) --timeout Timeout in seconds for address generation --mnemonic Return mnemonic with address (default false) --save-path Path to save the generated vanity address to -h, --help Print help -V, --version Print version Generate vanity addresses for the Fuel blockchain ``` ## Example outputs ```sh # > forc-crypto vanity --starts-with 0 --ends-with F Starting to generate vanity address... Successfully found vanity address in 0.012 seconds. Address: 0d3c399e756dee9f7312215882f92685fdae25449bc74f33c31063000d68afdf PrivateKey: cec536d4f5aae64685856ad36818777ba0aed349bdef848b487d6ebb1cc2a0a4 ``` ```sh # > forc-crypto vanity --starts-with 0 --ends-with F --mnemonic Starting to generate vanity address... Successfully found vanity address in 0.141 seconds. Address: 030b8484305c9f3af7b662d9fdd88dc75bdceb29f42d0f5ea5f72d3dfaf9380f Mnemonic: found broccoli trap left thought attack quality smooth patrol enrich fault flavor legend amused monitor shoulder legend blast elbow custom dirt cotton tackle much PrivateKey: 269ee26dd810a4a2df72969ed8941fe92ddc0bab236715535b867448c3ffa25e ``` ## Relevant issues - https://github.com/FuelLabs/sway/issues/6664 --------- Co-authored-by: Sophie Dankel <47993817+sdankel@users.noreply.github.com> Co-authored-by: Kaya Gökalp --- Cargo.lock | 5 + forc-plugins/forc-crypto/Cargo.toml | 11 + .../forc-crypto/benches/bench_main.rs | 73 +++ forc-plugins/forc-crypto/src/args.rs | 16 +- forc-plugins/forc-crypto/src/keys/mod.rs | 1 + forc-plugins/forc-crypto/src/keys/vanity.rs | 457 ++++++++++++++++++ forc-plugins/forc-crypto/src/lib.rs | 37 ++ forc-plugins/forc-crypto/src/main.rs | 40 +- 8 files changed, 595 insertions(+), 45 deletions(-) create mode 100644 forc-plugins/forc-crypto/benches/bench_main.rs create mode 100644 forc-plugins/forc-crypto/src/keys/vanity.rs create mode 100644 forc-plugins/forc-crypto/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index a858d89ffa4..4b067e99ad1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2765,19 +2765,24 @@ dependencies = [ "async-trait", "atty", "clap 4.5.20", + "criterion", "forc-tracing 0.66.2", "forc-util", "fuel-core-types", "fuel-crypto", + "fuels-accounts", "fuels-core", "futures", "hex", "libp2p-identity", "rand", + "rayon", + "regex", "serde", "serde_json", "serde_yaml", "sha3", + "tempfile", "termion 4.0.3", "tokio", "tracing", diff --git a/forc-plugins/forc-crypto/Cargo.toml b/forc-plugins/forc-crypto/Cargo.toml index 1faf2be8a23..bea4711b7d5 100644 --- a/forc-plugins/forc-crypto/Cargo.toml +++ b/forc-plugins/forc-crypto/Cargo.toml @@ -17,11 +17,14 @@ forc-tracing.workspace = true forc-util.workspace = true fuel-core-types.workspace = true fuel-crypto = { workspace = true, features = ["random"] } +fuels-accounts.workspace = true fuels-core.workspace = true futures.workspace = true hex.workspace = true libp2p-identity = { workspace = true, features = ["peerid", "secp256k1"] } rand.workspace = true +rayon.workspace = true +regex.workspace = true serde.workspace = true serde_json.workspace = true serde_yaml.workspace = true @@ -29,3 +32,11 @@ sha3.workspace = true termion.workspace = true tokio = { workspace = true, features = ["macros", "rt-multi-thread", "process"] } tracing.workspace = true + +[dev-dependencies] +criterion = "0.5" +tempfile.workspace = true + +[[bench]] +name = "bench_main" +harness = false diff --git a/forc-plugins/forc-crypto/benches/bench_main.rs b/forc-plugins/forc-crypto/benches/bench_main.rs new file mode 100644 index 00000000000..675923911cb --- /dev/null +++ b/forc-plugins/forc-crypto/benches/bench_main.rs @@ -0,0 +1,73 @@ +use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use forc_crypto::keys::vanity::{find_vanity_address_with_timeout, HexMatcher, RegexMatcher}; +use rayon::iter::Either; + +fn benchmark_vanity_address(c: &mut Criterion) { + let mut group = c.benchmark_group("Vanity Address Generation"); + + // Benchmark HexMatcher with prefix + group.bench_function("HexMatcher (starts with 'a')", |b| { + b.iter(|| { + let matcher = Either::Right(HexMatcher::new("a", "").unwrap()); + find_vanity_address_with_timeout(black_box(matcher), false, None) + }) + }); + + // Benchmark HexMatcher with suffix + group.bench_function("HexMatcher (ends with 'f')", |b| { + b.iter(|| { + let matcher = Either::Right(HexMatcher::new("", "f").unwrap()); + find_vanity_address_with_timeout(black_box(matcher), false, None) + }) + }); + + // Benchmark HexMatcher with both prefix and suffix + group.bench_function("HexMatcher (starts with 'a' ends with 'f')", |b| { + b.iter(|| { + let matcher = Either::Right(HexMatcher::new("a", "f").unwrap()); + find_vanity_address_with_timeout(black_box(matcher), false, None) + }) + }); + + // Benchmark RegexMatcher with simple pattern + group.bench_function("RegexMatcher (starts with 'a')", |b| { + b.iter(|| { + let matcher = Either::Left(RegexMatcher::new("^a.*").unwrap()); + find_vanity_address_with_timeout(black_box(matcher), false, None) + }) + }); + + // Benchmark RegexMatcher with complex pattern + group.bench_function("RegexMatcher (contains two consecutive digits)", |b| { + b.iter(|| { + let matcher = Either::Left(RegexMatcher::new(r"[0-9]{2}").unwrap()); + find_vanity_address_with_timeout(black_box(matcher), false, None) + }) + }); + + // Benchmark with mnemonic generation + group.bench_function("HexMatcher with Mnemonic (starts with 'a')", |b| { + b.iter(|| { + let matcher = Either::Right(HexMatcher::new("a", "").unwrap()); + find_vanity_address_with_timeout(black_box(matcher), true, None) + }) + }); + + group.bench_function("RegexMatcher with Mnemonic (starts with 'a')", |b| { + b.iter(|| { + let matcher = Either::Left(RegexMatcher::new("^a.*").unwrap()); + find_vanity_address_with_timeout(black_box(matcher), true, None) + }) + }); + + group.finish(); +} + +criterion_group! { + name = benches; + config = Criterion::default() + .sample_size(10) // Reduced sample size due to potentially long-running benchmarks + .measurement_time(std::time::Duration::from_secs(20)); + targets = benchmark_vanity_address +} +criterion_main!(benches); diff --git a/forc-plugins/forc-crypto/src/args.rs b/forc-plugins/forc-crypto/src/args.rs index 8e4bcee25fd..4201894632c 100644 --- a/forc-plugins/forc-crypto/src/args.rs +++ b/forc-plugins/forc-crypto/src/args.rs @@ -24,17 +24,17 @@ forc_util::cli_examples! { pub struct HashArgs { /// This argument is optional, it can be either: /// - /// 1. A path to a file. If that is the case, the content of the file is - /// loaded. + /// 1. A path to a file. If that is the case, the content of the file is + /// loaded /// - /// 2. A binary string encoded as a hex string. If that is the case, the - /// hex is decoded and passed as a Vec + /// 2. A binary string encoded as a hex string. If that is the case, the + /// hex is decoded and passed as a Vec /// - /// 3. A string. This is the last option, if the string is "-", `stdin` - /// is read instead. Otherwise the raw string is converted to a Vec - /// and passed + /// 3. A string. This is the last option, if the string is "-", "stdin" + /// is read instead. Otherwise the raw string is converted to a Vec + /// and passed /// - /// 4. If it nos not provided, `stdin` is read + /// 4. If it is not provided, "stdin" is read content_or_filepath: Option, } diff --git a/forc-plugins/forc-crypto/src/keys/mod.rs b/forc-plugins/forc-crypto/src/keys/mod.rs index 9741e32623c..8935b5f366e 100644 --- a/forc-plugins/forc-crypto/src/keys/mod.rs +++ b/forc-plugins/forc-crypto/src/keys/mod.rs @@ -3,6 +3,7 @@ use clap::ValueEnum; pub mod get_public_key; pub mod new_key; pub mod parse_secret; +pub mod vanity; #[derive(Clone, Debug, Default, ValueEnum)] pub enum KeyType { diff --git a/forc-plugins/forc-crypto/src/keys/vanity.rs b/forc-plugins/forc-crypto/src/keys/vanity.rs new file mode 100644 index 00000000000..640165dc818 --- /dev/null +++ b/forc-plugins/forc-crypto/src/keys/vanity.rs @@ -0,0 +1,457 @@ +use fuel_crypto::{fuel_types::Address, PublicKey, SecretKey}; +use fuels_accounts::wallet::{generate_mnemonic_phrase, DEFAULT_DERIVATION_PATH_PREFIX}; +use fuels_core::types::{ + bech32::{Bech32Address, FUEL_BECH32_HRP}, + checksum_address::checksum_encode, +}; +use rayon::iter::{self, Either, ParallelIterator}; +use regex::Regex; +use serde_json::json; +use std::{ + path::PathBuf, + time::{Duration, Instant}, +}; +use tokio::runtime::Runtime; + +forc_util::cli_examples! { + crate::Command { + [ Generate a checksummed vanity address with a given prefix => "forc crypto vanity --starts-with \"aaa\"" ] + [ Generate a checksummed vanity address with a given suffix => "forc crypto vanity --ends-with \"aaa\"" ] + [ Generate a checksummed vanity address with a given prefix and suffix => "forc crypto vanity --starts-with \"00\" --ends-with \"ff\"" ] + [ Generate a checksummed vanity address with a given regex pattern => "forc crypto vanity --regex \"^00.*ff$\"" ] + } +} + +fn validate_hex_string(s: &str) -> Result { + if !s.chars().all(|c| c.is_ascii_hexdigit()) { + return Err("Pattern must contain only hex characters (0-9, a-f)".to_string()); + } + Ok(s.to_string()) +} + +fn validate_regex_pattern(s: &str) -> Result { + if s.len() > 128 { + return Err("Regex pattern too long: max 128 characters".to_string()); + } + + if let Err(e) = Regex::new(&format!("(?i){}", s)) { + return Err(format!("Invalid regex pattern: {}", e)); + } + + Ok(s.to_string()) +} + +#[derive(Debug, clap::Parser)] +#[clap( + version, + about = "Generate a vanity address", + after_help = "Generate vanity addresses for the Fuel blockchain" +)] +pub struct Arg { + /// Desired hex string prefix for the address + #[arg( + long, + value_name = "HEX_STRING", + required_unless_present = "ends_with", + required_unless_present = "regex", + conflicts_with = "regex", + value_parser = validate_hex_string, + )] + pub starts_with: Option, + + /// Desired hex string suffix for the address + #[arg(long, value_name = "HEX_STRING", conflicts_with = "regex", value_parser = validate_hex_string)] + pub ends_with: Option, + + /// Desired regex pattern to match the entire address (case-insensitive) + #[arg(long, value_name = "PATTERN", conflicts_with = "starts_with", value_parser = validate_regex_pattern)] + pub regex: Option, + + /// Timeout in seconds for address generation + #[arg(long, value_name = "SECONDS")] + pub timeout: Option, + + /// Return mnemonic with address (default false) + #[arg(long)] + pub mnemonic: bool, + + /// Path to save the generated vanity address to. + #[arg(long, value_hint = clap::ValueHint::FilePath, value_name = "PATH")] + pub save_path: Option, +} + +impl Arg { + pub fn validate(&self) -> anyhow::Result<()> { + let total_length = self.starts_with.as_ref().map_or(0, |s| s.len()) + + self.ends_with.as_ref().map_or(0, |s| s.len()); + if total_length > 64 { + return Err(anyhow::anyhow!( + "Combined pattern length exceeds 64 characters" + )); + } + Ok(()) + } +} + +pub fn handler(args: Arg) -> anyhow::Result { + args.validate()?; + + let Arg { + starts_with, + ends_with, + regex, + mnemonic, + timeout, + save_path, + } = args; + + let matcher = if let Some(pattern) = regex { + Either::Left(RegexMatcher::new(&pattern)?) + } else { + let starts_with = starts_with.as_deref().unwrap_or(""); + let ends_with = ends_with.as_deref().unwrap_or(""); + Either::Right(HexMatcher::new(starts_with, ends_with)?) + }; + + println!("Starting to generate vanity address..."); + let start_time = Instant::now(); + + let result = find_vanity_address_with_timeout(matcher, mnemonic, timeout)?; + let (address, secret_key, mnemonic) = result; + + let duration = start_time.elapsed(); + println!( + "Successfully found vanity address in {:.3} seconds.\n", + duration.as_secs_f64() + ); + + let checksum_address = checksum_encode(&address.to_string())?; + let result = if let Some(mnemonic) = mnemonic { + json!({ + "Address": checksum_address, + "PrivateKey": hex::encode(secret_key.as_ref()), + "Mnemonic": mnemonic, + }) + } else { + json!({ + "Address": checksum_address, + "PrivateKey": hex::encode(secret_key.as_ref()), + }) + }; + + if let Some(path) = save_path { + std::fs::write(path, serde_json::to_string_pretty(&result)?)?; + } + + Ok(result) +} + +pub trait VanityMatcher: Send + Sync + 'static { + fn is_match(&self, addr: &Address) -> bool; +} + +pub struct HexMatcher { + prefix: String, + suffix: String, +} + +impl HexMatcher { + pub fn new(prefix: &str, suffix: &str) -> anyhow::Result { + Ok(Self { + prefix: prefix.to_lowercase(), + suffix: suffix.to_lowercase(), + }) + } +} + +impl VanityMatcher for HexMatcher { + fn is_match(&self, addr: &Address) -> bool { + let hex_addr = hex::encode(addr.as_ref()).to_lowercase(); + hex_addr.starts_with(&self.prefix) && hex_addr.ends_with(&self.suffix) + } +} + +pub struct RegexMatcher { + re: Regex, +} + +impl RegexMatcher { + pub fn new(pattern: &str) -> anyhow::Result { + let re = Regex::new(&format!("(?i){}", pattern))?; + Ok(Self { re }) + } +} + +impl VanityMatcher for RegexMatcher { + fn is_match(&self, addr: &Address) -> bool { + let addr = hex::encode(addr.as_ref()); + self.re.is_match(&addr) + } +} + +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Arc; + +pub fn find_vanity_address_with_timeout( + matcher: Either, + use_mnemonic: bool, + timeout_secs: Option, +) -> anyhow::Result<(Address, SecretKey, Option)> { + let should_stop = Arc::new(AtomicBool::new(false)); + let should_stop_clone = should_stop.clone(); + + let generate_wallet = move || { + let breakpoint = if use_mnemonic { 1_000 } else { 100_000 }; + let start = Instant::now(); + let attempts = std::sync::atomic::AtomicUsize::new(0); + + wallet_generator(use_mnemonic) + .find_any(|result| { + // Check if we should stop due to timeout + if should_stop.load(Ordering::Relaxed) { + return true; // This will cause find_any to return the current result + } + + let current = attempts.fetch_add(1, std::sync::atomic::Ordering::Relaxed); + if current != 0 && current % breakpoint == 0 { + let elapsed = start.elapsed().as_secs_f64(); + let rate = current as f64 / elapsed; + println!( + "└─ tried {} addresses ({:.2} addresses/sec)...", + current, rate + ); + } + + if let Ok((addr, _, _)) = result { + match &matcher { + Either::Left(regex_matcher) => regex_matcher.is_match(addr), + Either::Right(hex_matcher) => hex_matcher.is_match(addr), + } + } else { + false + } + }) + .ok_or_else(|| anyhow::anyhow!("No matching address found"))? + }; + + let Some(secs) = timeout_secs else { + return generate_wallet(); + }; + + Runtime::new()?.block_on(async { + let generation_task = tokio::task::spawn_blocking(generate_wallet); + + tokio::select! { + result = generation_task => { + match result { + Ok(wallet_result) => wallet_result, + Err(_) => Err(anyhow::anyhow!("No matching address found")), + } + } + _ = tokio::time::sleep(Duration::from_secs(secs)) => { + // Signal all threads to stop + should_stop_clone.store(true, Ordering::Relaxed); + // Wait a short time for threads to notice the stop signal + tokio::time::sleep(Duration::from_millis(100)).await; + Err(anyhow::anyhow!("Vanity address generation timed out after {} seconds", secs)) + } + } + }) +} + +#[inline] +fn wallet_generator( + use_mnemonic: bool, +) -> impl ParallelIterator)>> { + iter::repeat(()).map(move |()| generate_wallet(use_mnemonic)) +} + +fn generate_wallet(use_mnemonic: bool) -> anyhow::Result<(Address, SecretKey, Option)> { + let mut rng = rand::thread_rng(); + + let (private_key, mnemonic) = if use_mnemonic { + let mnemonic = generate_mnemonic_phrase(&mut rng, 24)?; + let account_ix = 0; + let derivation_path = format!("{DEFAULT_DERIVATION_PATH_PREFIX}/{account_ix}'/0/0"); + let private_key = + SecretKey::new_from_mnemonic_phrase_with_path(&mnemonic, &derivation_path)?; + (private_key, Some(mnemonic)) + } else { + (SecretKey::random(&mut rng), None) + }; + + let public = PublicKey::from(&private_key); + let hashed = public.hash(); + let address = Bech32Address::new(FUEL_BECH32_HRP, hashed); + + Ok((address.into(), private_key, mnemonic)) +} + +#[cfg(test)] +mod tests { + use super::*; + use clap::Parser; + + // Helper function to parse args and get validation errors + fn parse_args(args: Vec<&str>) -> Result { + let args = + Arg::try_parse_from(std::iter::once("test").chain(args)).map_err(|e| e.to_string())?; + args.validate().map_err(|e| e.to_string())?; + Ok(args) + } + + #[test] + fn test_invalid_hex_characters() { + let result = parse_args(vec!["--starts-with", "xyz"]); + assert!(result.is_err()); + assert_eq!(result.unwrap_err(), "error: invalid value 'xyz' for '--starts-with ': Pattern must contain only hex characters (0-9, a-f)\n\nFor more information, try '--help'.\n"); + } + + #[test] + fn test_pattern_too_long() { + let result = parse_args(vec![ + "--starts-with", + &"a".repeat(32), + "--ends-with", + &"b".repeat(33), + ]); + assert!(result.is_err()); + assert_eq!( + result.unwrap_err(), + "Combined pattern length exceeds 64 characters" + ); + } + + #[test] + fn test_invalid_regex_syntax() { + let result = parse_args(vec!["--regex", "["]); + assert!(result.is_err()); + assert_eq!(result.unwrap_err(), "error: invalid value '[' for '--regex ': Invalid regex pattern: regex parse error:\n (?i)[\n ^\nerror: unclosed character class\n\nFor more information, try '--help'.\n"); + } + + #[test] + fn test_regex_too_long() { + let result = parse_args(vec!["--regex", &"a".repeat(129)]); + assert!(result.is_err()); + assert_eq!(result.unwrap_err(), "error: invalid value 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' for '--regex ': Regex pattern too long: max 128 characters\n\nFor more information, try '--help'.\n"); + } + + #[test] + fn test_conflicting_args() { + let result = parse_args(vec!["--starts-with", "aa", "--regex", "^aa"]); + assert!(result.is_err()); + assert_eq!(result.unwrap_err(), "error: the argument '--starts-with ' cannot be used with '--regex '\n\nUsage: test --starts-with \n\nFor more information, try '--help'.\n"); + } + + #[test] + fn test_timeout_respected() { + // This pattern should take a long time to generate + let args = parse_args(vec!["--starts-with", "fffffffffffff", "--timeout", "1"]).unwrap(); + + let result = handler(args); + assert!(result.is_err()); + assert_eq!( + result.unwrap_err().to_string(), + "Vanity address generation timed out after 1 seconds" + ); + } + + // Test actual functionality with minimal patterns + #[test] + fn test_valid_short_prefix() { + let args = parse_args(vec!["--starts-with", "a"]).unwrap(); + let result = handler(args).unwrap(); + let address = result["Address"].as_str().unwrap(); + assert!( + address.to_lowercase().starts_with("0xa"), + "Address should start with 'a'" + ); + } + + #[test] + fn test_valid_short_suffix() { + let args = parse_args(vec!["--ends-with", "a"]).unwrap(); + let result = handler(args).unwrap(); + let address = result["Address"].as_str().unwrap(); + assert!( + address.to_lowercase().ends_with('a'), + "Address should end with 'a'" + ); + } + + #[test] + fn test_both_prefix_and_suffix() { + let args = parse_args(vec!["--starts-with", "a", "--ends-with", "b"]).unwrap(); + let result = handler(args).unwrap(); + let address = result["Address"].as_str().unwrap().to_lowercase(); + assert!(address.starts_with("0xa"), "Address should start with 'a'"); + assert!(address.ends_with('b'), "Address should end with 'b'"); + } + + #[test] + fn test_simple_regex() { + let args = parse_args(vec!["--regex", "^a.*b$"]).unwrap(); + let result = handler(args).unwrap(); + let address = result["Address"].as_str().unwrap().to_lowercase(); + assert!(address.starts_with("0xa"), "Address should start with 'a'"); + assert!(address.ends_with('b'), "Address should end with 'b'"); + } + + #[test] + fn test_simple_regex_uppercase() { + let args = parse_args(vec!["--regex", "^A.*B$"]).unwrap(); + let result = handler(args).unwrap(); + let address = result["Address"].as_str().unwrap().to_lowercase(); + assert!(address.starts_with("0xa"), "Address should start with 'a'"); + assert!(address.ends_with('b'), "Address should end with 'b'"); + } + + #[test] + fn test_mnemonic_generation() { + let args = parse_args(vec!["--starts-with", "a", "--mnemonic"]).unwrap(); + let result = handler(args).unwrap(); + + assert!(result["Mnemonic"].is_string(), "Mnemonic should be present"); + assert_eq!( + result["Mnemonic"] + .as_str() + .unwrap() + .split_whitespace() + .count(), + 24, + "Mnemonic should have 24 words" + ); + + let address = result["Address"].as_str().unwrap(); + assert!( + address.to_lowercase().starts_with("0xa"), + "Address should start with 'a'" + ); + } + + #[test] + fn test_save_path() { + let tmp = tempfile::NamedTempFile::new().unwrap(); + let args = parse_args(vec![ + "--starts-with", + "a", + "--save-path", + tmp.path().to_str().unwrap(), + ]) + .unwrap(); + + handler(args).unwrap(); + + assert!(tmp.path().exists(), "File should exist"); + let content = std::fs::read_to_string(tmp.path()).unwrap(); + let saved_result: serde_json::Value = serde_json::from_str(&content).unwrap(); + assert!( + saved_result["Address"].is_string(), + "Saved result should contain an Address" + ); + assert!( + saved_result["PrivateKey"].is_string(), + "Saved result should contain a PrivateKey" + ); + } +} diff --git a/forc-plugins/forc-crypto/src/lib.rs b/forc-plugins/forc-crypto/src/lib.rs new file mode 100644 index 00000000000..7c89d848120 --- /dev/null +++ b/forc-plugins/forc-crypto/src/lib.rs @@ -0,0 +1,37 @@ +pub mod address; +pub mod args; +pub mod keccak256; +pub mod keys; +pub mod sha256; + +pub(crate) fn help() -> &'static str { + Box::leak( + format!( + "EXAMPLES:\n{}{}{}{}{}{}", + args::examples(), + address::examples(), + keys::new_key::examples(), + keys::parse_secret::examples(), + keys::get_public_key::examples(), + keys::vanity::examples(), + ) + .into_boxed_str(), + ) +} + +/// Forc plugin for hashing arbitrary data +#[derive(Debug, clap::Parser)] +#[clap( + name = "forc-crypto", + after_help = help(), + version +)] +pub enum Command { + Keccak256(args::HashArgs), + Sha256(args::HashArgs), + Address(address::Args), + GetPublicKey(keys::get_public_key::Arg), + NewKey(keys::new_key::Arg), + ParseSecret(keys::parse_secret::Arg), + Vanity(keys::vanity::Arg), +} diff --git a/forc-plugins/forc-crypto/src/main.rs b/forc-plugins/forc-crypto/src/main.rs index fba619b2b59..c9ae55b23f0 100644 --- a/forc-plugins/forc-crypto/src/main.rs +++ b/forc-plugins/forc-crypto/src/main.rs @@ -3,6 +3,7 @@ use anyhow::Result; use atty::Stream; use clap::Parser; +use forc_crypto::{address, keccak256, keys, sha256, Command}; use forc_tracing::{init_tracing_subscriber, println_error}; use std::{ default::Default, @@ -10,42 +11,6 @@ use std::{ }; use termion::screen::IntoAlternateScreen; -mod address; -mod args; -mod keccak256; -mod keys; -mod sha256; - -fn help() -> &'static str { - Box::leak( - format!( - "EXAMPLES:\n{}{}{}{}{}", - args::examples(), - address::examples(), - keys::new_key::examples(), - keys::parse_secret::examples(), - keys::get_public_key::examples(), - ) - .into_boxed_str(), - ) -} - -/// Forc plugin for hashing arbitrary data -#[derive(Debug, Parser)] -#[clap( - name = "forc-crypto", - after_help = help(), - version -)] -pub enum Command { - Keccak256(args::HashArgs), - Sha256(args::HashArgs), - Address(address::Args), - GetPublicKey(keys::get_public_key::Arg), - NewKey(keys::new_key::Arg), - ParseSecret(keys::parse_secret::Arg), -} - fn main() { init_tracing_subscriber(Default::default()); if let Err(err) = run() { @@ -59,6 +24,7 @@ fn run() -> Result<()> { let content = match app { Command::Keccak256(arg) => keccak256::hash(arg)?, Command::GetPublicKey(arg) => keys::get_public_key::handler(arg)?, + Command::Vanity(arg) => keys::vanity::handler(arg)?, Command::Sha256(arg) => sha256::hash(arg)?, Command::Address(arg) => address::dump_address(arg.address)?, Command::NewKey(arg) => keys::new_key::handler(arg)?, @@ -83,7 +49,7 @@ where } } -pub(crate) fn display_output(message: T) -> anyhow::Result<()> +pub fn display_output(message: T) -> anyhow::Result<()> where T: serde::Serialize, { From 6b05844fe098834dc6ad6f067e4069d2ada8af20 Mon Sep 17 00:00:00 2001 From: Joshua Batty Date: Sat, 26 Oct 2024 00:49:00 +1100 Subject: [PATCH 082/115] Add parallel garbage collection test runner (#6665) ## Description Adds a comprehensive test suite that exercises garbage collection across all language test examples. The test: - Runs each example in its own isolated process to prevent cross-contamination - Uses rayon for parallel execution, reducing total test time to ~60s for all 267 tests - Provides a clear summary of passing/failing tests with specific error cases - Continues running all tests even when individual tests fail The test identified 26 examples that need investigation for proper garbage collection handling, particularly around: - Constants and their declarations - Module dependencies - Type system (arrays, slices, strings) - Associated constants - References and self implementations By running tests in isolation, we can now identify all problematic cases rather than stopping at the first failure. The current projects that have garbage collection failures are: ``` associated_const_trait_const references reexport main_args fixing_generic_type shadowing far_jumps str_slice match_expressions slice const_decl_literal raw_ptr import_star_name_clash module_dep_self module_dep_multiple self_impl_reassignment const_decl associated_const_abi_default string_slice fix_opcode_bug tuple_field_reassignment const_decl_with_call_path module_dep array_basics u256 associated_const_impl_self_order ``` Note: I've temporarily disabled the `run_all_garbage_collection_tests` so this PR can be reviewed and pass CI. Then #6613 can rebase and reenable the test to ensure that PR allows these failing tests to pass. ## 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. - [ ] 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-lsp/tests/lib.rs | 213 +++++++++++++++++++++++++------- sway-lsp/tests/utils/src/lib.rs | 23 ++-- 2 files changed, 173 insertions(+), 63 deletions(-) diff --git a/sway-lsp/tests/lib.rs b/sway-lsp/tests/lib.rs index ef383c9ddba..c377db53bf5 100644 --- a/sway-lsp/tests/lib.rs +++ b/sway-lsp/tests/lib.rs @@ -4,7 +4,8 @@ pub mod integration; use crate::integration::{code_actions, lsp}; use lsp_types::*; -use std::{fs, path::PathBuf}; +use rayon::prelude::*; +use std::{fs, panic, path::PathBuf, process::Command, sync::Mutex}; use sway_lsp::{ config::LspClient, handlers::{notification, request}, @@ -69,7 +70,7 @@ async fn init_and_open(service: &mut LspService, entry_point: PathB uri } -async fn shutdown_and_exit(service: &mut LspService) { +pub async fn shutdown_and_exit(service: &mut LspService) { let _ = lsp::shutdown_request(service).await; lsp::exit_notification(service).await; } @@ -257,52 +258,6 @@ fn did_change_stress_test_random_wait() { }); } -fn garbage_collection_runner(path: PathBuf) { - run_async!({ - setup_panic_hook(); - let (mut service, _) = LspService::new(ServerState::new); - let uri = init_and_open(&mut service, path).await; - let times = 60; - - // Initialize cursor position - let mut cursor_line = 20; - - for version in 1..times { - //eprintln!("version: {}", version); - let params = lsp::simulate_keypress(&uri, version, &mut cursor_line); - let _ = lsp::did_change_request(&mut service, &uri, version, Some(params)).await; - if version == 0 { - service.inner().wait_for_parsing().await; - } - // wait for a random amount of time to simulate typing - random_delay().await; - } - shutdown_and_exit(&mut service).await; - }); -} - -#[test] -fn garbage_collection_storage() { - let p = sway_workspace_dir() - .join("sway-lsp/tests/fixtures/garbage_collection/storage_contract") - .join("src/main.sw"); - garbage_collection_runner(p); -} - -#[test] -fn garbage_collection_paths() { - let p = test_fixtures_dir().join("tokens/paths/src/main.sw"); - garbage_collection_runner(p); -} - -#[test] -fn garbage_collection_minimal_script() { - let p = sway_workspace_dir() - .join("sway-lsp/tests/fixtures/garbage_collection/minimal_script") - .join("src/main.sw"); - garbage_collection_runner(p); -} - #[test] fn lsp_syncs_with_workspace_edits() { run_async!({ @@ -2181,3 +2136,165 @@ fn test_url_to_session_existing_session() { shutdown_and_exit(&mut service).await; }); } + +//------------------- GARBAGE COLLECTION TESTS -------------------// + +async fn garbage_collection_runner(path: PathBuf) { + setup_panic_hook(); + let (mut service, _) = LspService::new(ServerState::new); + let uri = init_and_open(&mut service, path).await; + let times = 20; + + // Initialize cursor position + let mut cursor_line = 1; + + for version in 1..times { + //eprintln!("version: {}", version); + let params = lsp::simulate_keypress(&uri, version, &mut cursor_line); + let _ = lsp::did_change_request(&mut service, &uri, version, Some(params)).await; + if version == 0 { + service.inner().wait_for_parsing().await; + } + // wait for a random amount of time to simulate typing + random_delay().await; + } + shutdown_and_exit(&mut service).await; +} + +#[test] +fn garbage_collection_storage() { + let p = sway_workspace_dir() + .join("sway-lsp/tests/fixtures/garbage_collection/storage_contract") + .join("src/main.sw"); + run_async!({ + garbage_collection_runner(p).await; + }); +} + +#[test] +fn garbage_collection_paths() { + let p = test_fixtures_dir().join("tokens/paths/src/main.sw"); + run_async!({ + garbage_collection_runner(p).await; + }); +} + +#[test] +fn garbage_collection_minimal_script() { + let p = sway_workspace_dir() + .join("sway-lsp/tests/fixtures/garbage_collection/minimal_script") + .join("src/main.sw"); + run_async!({ + garbage_collection_runner(p).await; + }); +} + +/// Tests garbage collection across all language test examples in parallel. +/// +/// # Overview +/// This test suite takes a unique approach to handling test isolation and error reporting: +/// +/// 1. Process Isolation: Each test is run in its own process to ensure complete isolation +/// between test runs. This allows us to catch all failures rather than stopping at +/// the first panic or error. +/// +/// 2. Parallel Execution: Uses rayon to run tests concurrently, significantly reducing +/// total test time from several minutes to under a minute. +/// +/// 3. Full Coverage: Unlike traditional test approaches that stop at the first failure, +/// this runner continues through all tests, providing a complete picture of which +/// examples need garbage collection fixes. +/// +/// # Implementation Details +/// - Uses std::process::Command to spawn each test in isolation +/// - Collects results through a thread-safe Mutex +/// - Provides detailed error reporting for failed tests +/// - Categorizes different types of failures (exit codes vs signals) +// #[test] +#[allow(dead_code)] +fn run_all_garbage_collection_tests() { + let base_dir = sway_workspace_dir().join(e2e_language_dir()); + let entries: Vec<_> = std::fs::read_dir(base_dir) + .unwrap() + .filter_map(|e| e.ok()) + .filter(|e| e.file_type().map(|ft| ft.is_dir()).unwrap_or(false)) + .collect(); + + let results = Mutex::new(Vec::new()); + + println!("\n=== Starting Garbage Collection Tests ===\n"); + + entries.par_iter().for_each(|entry| { + let project_dir = entry.path(); + let project_name = project_dir + .file_name() + .unwrap() + .to_string_lossy() + .to_string(); + let main_file = project_dir.join("src/main.sw"); + + println!("▶ Testing: {}", project_name); + println!(" Path: {}", main_file.display()); + + let status = Command::new(std::env::current_exe().unwrap()) + .args(["--test", "test_single_project", "--exact", "--nocapture"]) + .env("TEST_FILE", main_file.to_string_lossy().to_string()) + .status() + .unwrap(); + + let test_result = if status.success() { + println!(" ✅ Passed: {}\n", project_name); + (project_name, true, None) + } else { + println!(" ❌ Failed: {} ({})\n", project_name, status); + (project_name, false, Some(format!("Exit code: {}", status))) + }; + + results.lock().unwrap().push(test_result); + }); + + let results = results.into_inner().unwrap(); + + // Print final results + println!("=== Garbage Collection Test Results ===\n"); + + let total = results.len(); + let passed = results.iter().filter(|r| r.1).count(); + let failed = total - passed; + + println!("Total tests: {}", total); + println!("✅ Passed: {}", passed); + println!("❌ Failed: {}", failed); + + if failed > 0 { + println!("\nFailed Projects:"); + for (name, _, error) in results.iter().filter(|r| !r.1) { + println!("- {} (Error: {})", name, error.as_ref().unwrap()); + } + + panic!("{} projects failed garbage collection testing", failed); + } +} + +/// Individual test runner executed in a separate process for each test. +/// +/// This function is called by the main test runner through a new process invocation +/// for each test file. The file path is passed via the TEST_FILE environment +/// variable to maintain process isolation. +/// +/// # Process Isolation +/// Running each test in its own process ensures that: +/// 1. Tests are completely isolated from each other +/// 2. Panics in one test don't affect others +/// 3. Resource cleanup happens automatically on process exit +// #[tokio::test] +#[allow(dead_code)] +async fn test_single_project() { + if let Ok(file) = std::env::var("TEST_FILE") { + println!("Running single test for file: {}", file); + let path = PathBuf::from(file); + garbage_collection_runner(path).await; + } else { + panic!("TEST_FILE environment variable not set"); + } +} diff --git a/sway-lsp/tests/utils/src/lib.rs b/sway-lsp/tests/utils/src/lib.rs index 3124481ca06..be741f8798b 100644 --- a/sway-lsp/tests/utils/src/lib.rs +++ b/sway-lsp/tests/utils/src/lib.rs @@ -1,7 +1,7 @@ use assert_json_diff::assert_json_include; use futures::StreamExt; use lsp_types::Url; -use rand::Rng; +use rand::{rngs::SmallRng, Rng, SeedableRng}; use serde_json::Value; use std::{ env, fs, @@ -117,23 +117,16 @@ pub async fn assert_server_requests( /// Introduces a random delay between 1 to 30 milliseconds with a chance of additional longer delays based on predefined probabilities. pub async fn random_delay() { + // Create a thread-safe RNG + let mut rng = SmallRng::from_entropy(); + // wait for a random amount of time between 1-30ms - tokio::time::sleep(tokio::time::Duration::from_millis( - rand::thread_rng().gen_range(1..=30), - )) - .await; + tokio::time::sleep(tokio::time::Duration::from_millis(rng.gen_range(1..=30))).await; - // there is a 10% chance that a longer 100-800ms wait will be added - if rand::thread_rng().gen_ratio(1, 10) { - tokio::time::sleep(tokio::time::Duration::from_millis( - rand::thread_rng().gen_range(100..=1200), - )) - .await; - } - // 20% chance to introduce a longer delay of 200 to 1500 milliseconds. - if rand::thread_rng().gen_ratio(2, 10) { + // 20% chance to introduce a longer delay of 100 to 1200 milliseconds. + if rng.gen_ratio(2, 10) { tokio::time::sleep(tokio::time::Duration::from_millis( - rand::thread_rng().gen_range(400..=2800), + rng.gen_range(100..=1200), )) .await; } From 34b70f2beb67f076bef09499a8e3a120444538dc Mon Sep 17 00:00:00 2001 From: Marcos Henrich Date: Fri, 25 Oct 2024 23:15:55 +0100 Subject: [PATCH 083/115] Adds type inference from trait implementations. (#6590) ## Description When we have a type annotation with placeholders and we assign to it the result of a trait implementation call, if there is a single possible trait implementation we can use its type in the type annotation type. Fixes #5299 ## 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 Co-authored-by: Joshua Batty --- .../semantic_analysis/namespace/trait_map.rs | 45 +++++++++++++++++++ .../ast_elements/type_parameter.rs | 44 ++++++++++++++++++ sway-error/src/error.rs | 20 +++++++++ .../Forc.lock | 13 ------ .../src/main.sw | 32 ------------- .../test.toml | 7 --- .../Forc.lock | 13 ++++++ .../Forc.toml | 5 ++- .../src/main.sw | 40 +++++++++++++++++ .../test.toml | 6 +++ .../language/trait_inference/Forc.lock | 13 ++++++ .../language/trait_inference/Forc.toml | 8 ++++ .../language/trait_inference/src/main.sw | 41 +++++++++++++++++ .../language/trait_inference/test.toml | 5 +++ 14 files changed, 238 insertions(+), 54 deletions(-) delete mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/generic_trait_tuple_without_type_ascription/Forc.lock delete mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/generic_trait_tuple_without_type_ascription/src/main.sw delete mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/generic_trait_tuple_without_type_ascription/test.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/trait_inference_multiple_options/Forc.lock rename test/src/e2e_vm_tests/test_programs/should_fail/{generic_trait_tuple_without_type_ascription => trait_inference_multiple_options}/Forc.toml (73%) create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/trait_inference_multiple_options/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/trait_inference_multiple_options/test.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/trait_inference/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/trait_inference/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/trait_inference/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/trait_inference/test.toml diff --git a/sway-core/src/semantic_analysis/namespace/trait_map.rs b/sway-core/src/semantic_analysis/namespace/trait_map.rs index 4d6999931b1..1fb39cf2982 100644 --- a/sway-core/src/semantic_analysis/namespace/trait_map.rs +++ b/sway-core/src/semantic_analysis/namespace/trait_map.rs @@ -1492,6 +1492,51 @@ impl TraitMap { }) } + pub fn get_trait_constraints_are_satisfied_for_types( + &self, + _handler: &Handler, + type_id: TypeId, + constraints: &[TraitConstraint], + engines: &Engines, + ) -> Result, ErrorEmitted> { + let _decl_engine = engines.de(); + let unify_check = UnifyCheck::coercion(engines); + let unify_check_equality = UnifyCheck::non_dynamic_equality(engines); + + let impls = self.get_impls(engines, type_id); + let impld_traits_type_ids: Vec<(TypeId, String)> = impls + .iter() + .filter_map(|e| { + let key = &e.key; + let mut res = None; + for constraint in constraints { + if key.name.suffix.name == constraint.trait_name.suffix + && key + .name + .suffix + .args + .iter() + .zip(constraint.type_arguments.iter()) + .all(|(a1, a2)| unify_check_equality.check(a1.type_id, a2.type_id)) + && unify_check.check(type_id, key.type_id) + { + let name_type_args = if !key.name.suffix.args.is_empty() { + format!("<{}>", engines.help_out(key.name.suffix.args.clone())) + } else { + "".to_string() + }; + let name = format!("{}{}", key.name.suffix.name.as_str(), name_type_args); + res = Some((key.type_id, name)); + break; + } + } + res + }) + .collect(); + + Ok(impld_traits_type_ids) + } + fn get_impls_mut(&mut self, engines: &Engines, type_id: TypeId) -> &mut im::Vector { let type_root_filter = Self::get_type_root_filter(engines, type_id); if !self.trait_impls.contains_key(&type_root_filter) { diff --git a/sway-core/src/type_system/ast_elements/type_parameter.rs b/sway-core/src/type_system/ast_elements/type_parameter.rs index e79a4bfce64..fb008336f4d 100644 --- a/sway-core/src/type_system/ast_elements/type_parameter.rs +++ b/sway-core/src/type_system/ast_elements/type_parameter.rs @@ -509,6 +509,50 @@ impl TypeParameter { let code_block_first_pass = ctx.code_block_first_pass(); if !code_block_first_pass { + // Tries to unify type id with a single existing trait implementation. + // If more than one implementation exists we throw an error. + // We only try to do the type inference from trait with a single trait constraint. + if !type_id.is_concrete(engines, TreatNumericAs::Concrete) && trait_constraints.len() == 1 { + let concrete_trait_type_ids : Vec<(TypeId, String)>= ctx + .namespace_mut() + .module(engines) + .current_items() + .implemented_traits + .get_trait_constraints_are_satisfied_for_types( + handler, *type_id, trait_constraints, engines, + )? + .into_iter() + .filter_map(|t| { + if t.0.is_concrete(engines, TreatNumericAs::Concrete) { + Some(t) + } else { + None + } + }).collect(); + + match concrete_trait_type_ids.len().cmp(&1) { + Ordering::Equal => { + ctx.engines.te().unify_with_generic( + handler, + engines, + *type_id, + concrete_trait_type_ids.first().unwrap().0, + access_span, + "Type parameter type does not match up with matched trait implementing type.", + None, + ); + } + Ordering::Greater => { + return Err(handler.emit_err(CompileError::MultipleImplsSatisfyingTraitForType{ + span:access_span.clone(), + type_annotation: engines.help_out(type_id).to_string(), + trait_names: trait_constraints.iter().map(|t| engines.help_out(t).to_string()).collect(), + trait_types_and_names: concrete_trait_type_ids.iter().map(|t| (engines.help_out(t.0).to_string(), t.1.clone())).collect::>() + })); + } + Ordering::Less => {} + } + } // Check to see if the trait constraints are satisfied. match ctx .namespace_mut() diff --git a/sway-error/src/error.rs b/sway-error/src/error.rs index ec85cf3298b..20fc0e02235 100644 --- a/sway-error/src/error.rs +++ b/sway-error/src/error.rs @@ -1019,6 +1019,13 @@ pub enum CompileError { }, #[error("Type must be known at this point")] TypeMustBeKnownAtThisPoint { span: Span, internal: String }, + #[error("Multiple impls satisfying trait for type.")] + MultipleImplsSatisfyingTraitForType { + span: Span, + type_annotation: String, + trait_names: Vec, + trait_types_and_names: Vec<(String, String)>, + }, } impl std::convert::From for CompileError { @@ -1237,6 +1244,7 @@ impl Spanned for CompileError { ABIHashCollision { span, .. } => span.clone(), InvalidRangeEndGreaterThanStart { span, .. } => span.clone(), TypeMustBeKnownAtThisPoint { span, .. } => span.clone(), + MultipleImplsSatisfyingTraitForType { span, .. } => span.clone(), } } } @@ -2748,6 +2756,18 @@ impl ToDiagnostic for CompileError { ), ], }, + MultipleImplsSatisfyingTraitForType { span, type_annotation , trait_names, trait_types_and_names: trait_types_and_spans } => Diagnostic { + reason: Some(Reason::new(code(1), format!("Multiple impls satisfying {} for {}", trait_names.join("+"), type_annotation))), + issue: Issue::error( + source_engine, + span.clone(), + String::new() + ), + hints: vec![], + help: vec![format!("Trait{} implemented for types:\n{}", if trait_names.len() > 1 {"s"} else {""}, trait_types_and_spans.iter().enumerate().map(|(e, (type_id, name))| + format!("#{} {} for {}", e, name, type_id.clone()) + ).collect::>().join("\n"))], + }, _ => Diagnostic { // TODO: Temporary we use self here to achieve backward compatibility. // In general, self must not be used and will not be used once we diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/generic_trait_tuple_without_type_ascription/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_fail/generic_trait_tuple_without_type_ascription/Forc.lock deleted file mode 100644 index 78dab8d06cf..00000000000 --- a/test/src/e2e_vm_tests/test_programs/should_fail/generic_trait_tuple_without_type_ascription/Forc.lock +++ /dev/null @@ -1,13 +0,0 @@ -[[package]] -name = "core" -source = "path+from-root-B089E2A459F9A9B9" - -[[package]] -name = "generic_trait_tuple_without_type_ascription" -source = "member" -dependencies = ["std"] - -[[package]] -name = "std" -source = "path+from-root-B089E2A459F9A9B9" -dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/generic_trait_tuple_without_type_ascription/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/generic_trait_tuple_without_type_ascription/src/main.sw deleted file mode 100644 index 939b3a0c66e..00000000000 --- a/test/src/e2e_vm_tests/test_programs/should_fail/generic_trait_tuple_without_type_ascription/src/main.sw +++ /dev/null @@ -1,32 +0,0 @@ -script; - -pub trait MyFrom { - fn from(b: T) -> Self; -} - - -pub trait MyInto { - fn my_into(self) -> T; -} - - -impl MyInto for T -where - U: MyFrom, -{ - fn my_into(self) -> U { - U::from(self) - } -} - -impl MyFrom for (u64, u64, u64, u64) { - fn from(_val: u256) -> (u64, u64, u64, u64) { - (42, 0, 0, 0) - } -} - -fn main() -> bool { - let (_a, _b, _c, _d) = u256::min().my_into(); - - true -} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/generic_trait_tuple_without_type_ascription/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/generic_trait_tuple_without_type_ascription/test.toml deleted file mode 100644 index 9223a110521..00000000000 --- a/test/src/e2e_vm_tests/test_programs/should_fail/generic_trait_tuple_without_type_ascription/test.toml +++ /dev/null @@ -1,7 +0,0 @@ -category = "fail" - -# check: $()let (_a, _b, _c, _d) = u256::min().my_into(); -# nextln: $()Trait "MyFrom" is not implemented for type "(_, _, _, _)". - -# check: $()let (_a, _b, _c, _d) = u256::min().my_into(); -# nextln: $()Cannot infer type for type parameter "_". Insufficient type information provided. Try annotating its type. diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/trait_inference_multiple_options/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_fail/trait_inference_multiple_options/Forc.lock new file mode 100644 index 00000000000..67d2281e1fb --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/trait_inference_multiple_options/Forc.lock @@ -0,0 +1,13 @@ +[[package]] +name = "core" +source = "path+from-root-599A6910FBBA5980" + +[[package]] +name = "std" +source = "path+from-root-599A6910FBBA5980" +dependencies = ["core"] + +[[package]] +name = "trait_inference_multiple_options" +source = "member" +dependencies = ["std"] diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/generic_trait_tuple_without_type_ascription/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/trait_inference_multiple_options/Forc.toml similarity index 73% rename from test/src/e2e_vm_tests/test_programs/should_fail/generic_trait_tuple_without_type_ascription/Forc.toml rename to test/src/e2e_vm_tests/test_programs/should_fail/trait_inference_multiple_options/Forc.toml index 3f28e085114..fb872d12ccd 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/generic_trait_tuple_without_type_ascription/Forc.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/trait_inference_multiple_options/Forc.toml @@ -2,7 +2,8 @@ authors = ["Fuel Labs "] entry = "main.sw" license = "Apache-2.0" -name = "generic_trait_tuple_without_type_ascription" +name = "trait_inference_multiple_options" +implicit-std = false [dependencies] -std = { path = "../../../reduced_std_libs/sway-lib-std-assert" } +std = { path = "../../../reduced_std_libs/sway-lib-std-assert" } \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/trait_inference_multiple_options/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/trait_inference_multiple_options/src/main.sw new file mode 100644 index 00000000000..d1b3a111451 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/trait_inference_multiple_options/src/main.sw @@ -0,0 +1,40 @@ +script; + +pub trait MyFrom { + fn from(b: T) -> Self; +} + + +pub trait MyInto { + fn into(self) -> T; +} + + +impl MyInto for T +where + U: MyFrom, +{ + fn into(self) -> U { + U::from(self) + } +} + +impl MyFrom for (u64, u64, u64, u64) { + fn from(val: u256) -> (u64, u64, u64, u64) { + (42, 0, 0, 0) + } +} + +impl MyFrom for (u64, u64, u64, u32) { + fn from(val: u256) -> (u64, u64, u64, u32) { + (42, 0, 0, 0) + } +} + +fn main() -> bool { + let (a, _b, _c, _d) = u256::min().into(); + + assert_eq(a, 42); + + true +} diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/trait_inference_multiple_options/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/trait_inference_multiple_options/test.toml new file mode 100644 index 00000000000..05ebf7976f4 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/trait_inference_multiple_options/test.toml @@ -0,0 +1,6 @@ +category = "fail" + +# check: $()Multiple impls satisfying MyFrom for (numeric, _, _, _) +# check: $()Trait implemented for types: +# nextln: $()#0 MyFrom for (u64, u64, u64, u64) +# nextln: $()#1 MyFrom for (u64, u64, u64, u32) diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/trait_inference/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/trait_inference/Forc.lock new file mode 100644 index 00000000000..883e47a2785 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/trait_inference/Forc.lock @@ -0,0 +1,13 @@ +[[package]] +name = "core" +source = "path+from-root-3903213068BE1E4C" + +[[package]] +name = "std" +source = "path+from-root-3903213068BE1E4C" +dependencies = ["core"] + +[[package]] +name = "trait_inference" +source = "member" +dependencies = ["std"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/trait_inference/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/trait_inference/Forc.toml new file mode 100644 index 00000000000..56507e6db8f --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/trait_inference/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "trait_inference" + +[dependencies] +std = { path = "../../../../reduced_std_libs/sway-lib-std-assert" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/trait_inference/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/trait_inference/src/main.sw new file mode 100644 index 00000000000..31144e281c8 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/trait_inference/src/main.sw @@ -0,0 +1,41 @@ +script; + +pub trait MyFrom { + fn from(b: T) -> Self; +} + + +pub trait MyInto { + fn into(self) -> T; +} + + +impl MyInto for T +where + U: MyFrom, +{ + fn into(self) -> U { + U::from(self) + } +} + +impl MyFrom for (u64, u64, u64, u64) { + fn from(val: u256) -> (u64, u64, u64, u64) { + (42, 0, 0, 0) + } +} + +// Should not interfere with trait inference +impl MyFrom for (u64, u64, u64, u32) { + fn from(val: u64) -> (u64, u64, u64, u32) { + (42, 0, 0, 0) + } +} + +fn main() -> bool { + let (a, _b, _c, _d) = u256::min().into(); + + assert_eq(a, 42); + + true +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/trait_inference/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/trait_inference/test.toml new file mode 100644 index 00000000000..a4d4f4bade7 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/trait_inference/test.toml @@ -0,0 +1,5 @@ +category = "run" +expected_result = { action = "return", value = 1 } +expected_result_new_encoding = { action = "return_data", value = "01" } +validate_abi = false +expected_warnings = 3 From ddb505d263f81a49cc8f788519ec003949f944d9 Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite Date: Mon, 28 Oct 2024 10:34:03 +0000 Subject: [PATCH 084/115] migrate encoding v1 to sway-features (#6586) ## Description This PR starts the implementation of https://github.com/FuelLabs/sway-rfcs/blob/master/rfcs/0013-changes-lifecycle.md. ## CLI flags Now, all `CLI`s, including our tests, support two new arguments ``` ... --experimental Comma separated list of all experimental features that will be enabled [possible values: new_encoding, storage_domains] --no-experimental Comma separated list of all experimental features that will be disabled [possible values: new_encoding, storage_domains] ... ``` Experimental features can also be enabled inside `Forc.toml` for workspaces and individual projects. ``` experimental = { encoding-v1 = true } ``` And can be enabled using environment variables: ``` FORC_NO_EXPERIMENTAL=feature_a,feature_b FORC_EXPERIMENTAL=feature_c forc build ... ``` These configurations are applied in a very specific order to allow them to be overwritten. The order from the weakest to the strongest is: 1 - Workspace `TOML` 2 - Project `TOML` 3 - CLI 4 - Environment variables. The rationale is: 1 - We want an easy way to enable and/or disable a feature for the whole workspace; 2 - But we want to allow projects to overwrite these features, when needed. These two are the suggested approach to configure experimental features, but we also want to allow someone to easily turn on or off features to test something in particular. For that one can use the CLI flags; and in the specific case one does not have access to the CLI, for example, when one of the `SDK` is compiling the code, one can still completely overwrite the `TOML` files using environment variables. We are also applying the "no experimental" first. This is to allow the use case of exactly controlling which features will be enabled and disabled. In this case one can use the "meta-feature" `all` to disable everything and enable only the desired features. For example: ``` FORC_NO_EXPERIMENTAL=all FORC_EXPERIMENTAL=new_encoding your_command.... ``` ## Test for "-h" This PR also introduces snapshot tests for "-h" for all forc commands at https://github.com/FuelLabs/sway/pull/6586/files#diff-20a5e677d2ae9266a2247739b6a473d2ad0c627955187d668822e7d194f8e940 ## Multiple test.toml This PR also enables the use of multiple `test.toml`. Now each `test.toml` will be a different test, allowing the same code to be compiled and asserted differently. For example, `main_args_empty` has two files: the normal `test.toml` and a new `test.encoding_v1.toml`. One has `new_encoding` enabled and the other disabled. When a `test.toml` file has the `experimental` field, we do not use fields with `_new_encoding` suffix anymore, making these files simpler: test.toml: ```toml category = "run" # (1336, 1) script_data = "0000000000000538 0000000000000001" expected_result = { action = "return", value = 1337 } validate_abi = true experimental = { encoding_v1 = false } ``` test.encoding_v1.toml ``` script_data = "0000000000000538 0000000000000001" expected_result = { action = "return_data", value = "0000000000000539" } experimental = { new_encoding = true } ``` Test tomls with a suffix use `test.toml` as a base. So we do not need to repeat every field in them. Now when we run a test, we will see two tests instead of just one: ``` ... Testing should_pass/language/main_args/main_args_empty (test.encoding_v1.toml) ... ok Testing should_pass/language/main_args/main_args_empty (test.toml) ... ok ... ``` ## Conditional compilation It is also possible to use conditional compilation using these experimental features. Examples can be found inside `sway-lib-std`. ```sway #[cfg(experimental_new_encoding = true)] pub fn assert_eq(v1: T, v2: T) { ... } ``` ## Checklist - [ ] 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. - [ ] 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). - [ ] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: IGI-111 --- .github/workflows/ci.yml | 2 +- Cargo.lock | 18 + Cargo.toml | 3 + forc-pkg/Cargo.toml | 6 +- forc-pkg/src/manifest/build_profile.rs | 18 +- forc-pkg/src/manifest/mod.rs | 2 + forc-pkg/src/pkg.rs | 77 ++- forc-pkg/tests/sections/Forc.toml | 9 +- forc-plugins/forc-client/Cargo.toml | 7 +- forc-plugins/forc-client/src/cmd/deploy.rs | 5 +- forc-plugins/forc-client/src/cmd/run.rs | 5 +- forc-plugins/forc-client/src/op/deploy.rs | 10 +- forc-plugins/forc-client/src/op/run/mod.rs | 7 +- forc-plugins/forc-debug/Cargo.toml | 1 + .../src/server/handlers/handle_launch.rs | 7 +- forc-plugins/forc-doc/Cargo.toml | 1 + forc-plugins/forc-doc/src/cli.rs | 5 +- forc-plugins/forc-doc/src/lib.rs | 4 +- forc-plugins/forc-doc/src/main.rs | 8 +- .../src/tests/expects/impl_trait/mod.rs | 28 +- forc-plugins/forc-doc/tests/lib.rs | 8 +- forc-test/Cargo.toml | 1 + forc-test/src/lib.rs | 9 +- forc/Cargo.toml | 1 + forc/src/cli/commands/build.rs | 5 +- forc/src/cli/commands/check.rs | 5 +- forc/src/cli/commands/contract_id.rs | 5 +- forc/src/cli/commands/predicate_root.rs | 5 +- forc/src/cli/commands/test.rs | 11 +- forc/src/ops/forc_build.rs | 7 +- forc/src/ops/forc_check.rs | 10 +- forc/src/ops/forc_contract_id.rs | 6 +- forc/src/ops/forc_predicate_root.rs | 6 +- sway-core/Cargo.toml | 1 + .../asm_generation/fuel/fuel_asm_builder.rs | 4 +- .../asm_generation/fuel/programs/abstract.rs | 6 +- sway-core/src/build_config.rs | 16 - sway-core/src/ir_generation.rs | 12 +- sway-core/src/ir_generation/const_eval.rs | 9 +- sway-core/src/language/ty/program.rs | 5 +- sway-core/src/lib.rs | 70 +- .../ast_node/expression/typed_expression.rs | 12 +- .../namespace/contract_helpers.rs | 4 +- sway-core/src/semantic_analysis/program.rs | 10 +- .../semantic_analysis/type_check_context.rs | 10 +- sway-core/src/transform/attribute.rs | 16 +- .../src/transform/to_parsed_lang/context.rs | 7 +- .../to_parsed_lang/convert_parse_tree.rs | 49 +- sway-core/src/types/collect_types_metadata.rs | 7 +- sway-error/src/convert_parse_tree_error.rs | 6 +- sway-features/Cargo.toml | 13 + sway-features/src/lib.rs | 245 +++++++ sway-ir/Cargo.toml | 1 + sway-ir/src/bin/opt.rs | 14 +- sway-ir/src/context.rs | 10 +- sway-ir/src/irtype.rs | 10 +- sway-ir/src/optimize.rs | 7 +- sway-ir/src/parser.rs | 11 +- sway-ir/tests/tests.rs | 35 +- sway-lsp/Cargo.toml | 1 + sway-lsp/benches/lsp_benchmarks/compile.rs | 17 +- sway-lsp/benches/lsp_benchmarks/mod.rs | 5 - sway-lsp/src/core/session.rs | 19 +- sway-lsp/src/handlers/notification.rs | 1 - sway-lsp/src/server_state.rs | 19 +- sway-types/src/constants.rs | 1 - test/Cargo.toml | 3 +- test/src/e2e_vm_tests/harness.rs | 63 +- test/src/e2e_vm_tests/mod.rs | 165 +++-- .../should_fail/invalid_cfg_arg/snapshot.toml | 1 + .../should_fail/invalid_cfg_arg/stdout.snap | 37 ++ .../should_fail/invalid_cfg_arg/test.toml | 10 - .../should_pass/forc/help/snapshot.toml | 16 + .../should_pass/forc/help/stdout.snap | 597 ++++++++++++++++++ ....json => json_abi_oracle.encoding_v1.json} | 0 .../main_args_empty/json_abi_oracle.json | 24 +- .../main_args_empty/test.encoding_v1.toml | 4 + .../main_args/main_args_empty/test.toml | 6 +- test/src/ir_generation/mod.rs | 40 +- test/src/main.rs | 35 +- test/tests/tests.rs | 26 +- 81 files changed, 1462 insertions(+), 520 deletions(-) create mode 100644 sway-features/Cargo.toml create mode 100644 sway-features/src/lib.rs create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/snapshot.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/stdout.snap delete mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/test.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/forc/help/snapshot.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/forc/help/stdout.snap rename test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/{json_abi_oracle_new_encoding.json => json_abi_oracle.encoding_v1.json} (100%) create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/test.encoding_v1.toml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 58be69c8e88..6a0372ca1f9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -412,7 +412,7 @@ jobs: with: cache-provider: "buildjet" - name: Cargo Run E2E Tests (EVM) - run: cargo run --locked --release --bin test -- --target evm --locked --no-encoding-v1 + run: cargo run --locked --release --bin test -- --target evm --locked --no-experimental new_encoding # TODO: Remove this upon merging std tests with the rest of the E2E tests. cargo-test-lib-std: diff --git a/Cargo.lock b/Cargo.lock index 4b067e99ad1..32887369fb4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2696,6 +2696,7 @@ dependencies = [ "serde_json", "sway-core", "sway-error", + "sway-features", "sway-ir", "sway-types", "sway-utils", @@ -2749,6 +2750,7 @@ dependencies = [ "serde", "serde_json", "sway-core", + "sway-features", "sway-types", "sway-utils", "tempfile", @@ -2809,6 +2811,7 @@ dependencies = [ "serde_json", "shellfish", "sway-core", + "sway-features", "sway-types", "thiserror", "tokio", @@ -2834,6 +2837,7 @@ dependencies = [ "serde_json", "sway-ast", "sway-core", + "sway-features", "sway-lsp", "sway-types", "swayfmt", @@ -2893,6 +2897,7 @@ dependencies = [ "serde_with", "sway-core", "sway-error", + "sway-features", "sway-types", "sway-utils", "sysinfo", @@ -2917,6 +2922,7 @@ dependencies = [ "rand", "rayon", "sway-core", + "sway-features", "sway-types", ] @@ -7622,6 +7628,7 @@ dependencies = [ "strum 0.26.3", "sway-ast", "sway-error", + "sway-features", "sway-ir", "sway-parse", "sway-types", @@ -7647,6 +7654,14 @@ dependencies = [ "uwuify", ] +[[package]] +name = "sway-features" +version = "0.66.2" +dependencies = [ + "clap 4.5.20", + "paste", +] + [[package]] name = "sway-ir" version = "0.66.2" @@ -7661,6 +7676,7 @@ dependencies = [ "prettydiff 0.7.0", "rustc-hash 1.1.0", "slotmap", + "sway-features", "sway-ir-macros", "sway-types", "sway-utils", @@ -7709,6 +7725,7 @@ dependencies = [ "sway-ast", "sway-core", "sway-error", + "sway-features", "sway-lsp-test-utils", "sway-parse", "sway-types", @@ -8117,6 +8134,7 @@ dependencies = [ "serde_json", "sway-core", "sway-error", + "sway-features", "sway-ir", "sway-types", "sway-utils", diff --git a/Cargo.toml b/Cargo.toml index 760055fc845..21e63609454 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ members = [ "sway-ast", "sway-core", "sway-error", + "sway-features", "sway-ir", "sway-ir/sway-ir-macros", "sway-lsp", @@ -60,6 +61,7 @@ forc-tx = { path = "forc-plugins/forc-tx/", version = "0.66.2" } sway-ast = { path = "sway-ast/", version = "0.66.2" } sway-core = { path = "sway-core/", version = "0.66.2" } sway-error = { path = "sway-error/", version = "0.66.2" } +sway-features = { path = "sway-features/", version = "0.66.2" } sway-lsp = { path = "sway-lsp/", version = "0.66.2" } sway-parse = { path = "sway-parse/", version = "0.66.2" } sway-types = { path = "sway-types/", version = "0.66.2" } @@ -164,6 +166,7 @@ libtest-mimic = "0.7" lsp-types = "0.94" mdbook = { version = "0.4", default-features = false } minifier = "0.3" +normalize-path = "0.2.1" notify = "6.1" notify-debouncer-mini = "0.4" num-bigint = "0.4" diff --git a/forc-pkg/Cargo.toml b/forc-pkg/Cargo.toml index 7c5618d4a4e..7b1bc68587b 100644 --- a/forc-pkg/Cargo.toml +++ b/forc-pkg/Cargo.toml @@ -17,10 +17,7 @@ forc-tracing.workspace = true forc-util.workspace = true fuel-abi-types.workspace = true futures.workspace = true -git2 = { workspace = true, features = [ - "vendored-libgit2", - "vendored-openssl", -] } +git2 = { workspace = true, features = ["vendored-libgit2", "vendored-openssl"] } gix-url = { workspace = true, features = ["serde"] } hex.workspace = true ipfs-api-backend-hyper = { workspace = true, features = ["with-builder"] } @@ -33,6 +30,7 @@ serde_json.workspace = true serde_with.workspace = true sway-core.workspace = true sway-error.workspace = true +sway-features.workspace = true sway-types.workspace = true sway-utils.workspace = true tar.workspace = true diff --git a/forc-pkg/src/manifest/build_profile.rs b/forc-pkg/src/manifest/build_profile.rs index 59610ee8bf9..af5822ec693 100644 --- a/forc-pkg/src/manifest/build_profile.rs +++ b/forc-pkg/src/manifest/build_profile.rs @@ -1,12 +1,6 @@ use serde::{Deserialize, Serialize}; use sway_core::{OptLevel, PrintAsm, PrintIr}; -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Default)] -#[serde(rename_all = "kebab-case")] -pub struct ExperimentalFlags { - pub new_encoding: bool, -} - /// Parameters to pass through to the `sway_core::BuildConfig` during compilation. #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] #[serde(rename_all = "kebab-case")] @@ -39,8 +33,6 @@ pub struct BuildProfile { pub reverse_results: bool, #[serde(default)] pub optimization_level: OptLevel, - #[serde(default)] - pub experimental: ExperimentalFlags, } impl BuildProfile { @@ -65,9 +57,6 @@ impl BuildProfile { error_on_warnings: false, reverse_results: false, optimization_level: OptLevel::Opt0, - experimental: ExperimentalFlags { - new_encoding: false, - }, } } @@ -88,9 +77,6 @@ impl BuildProfile { error_on_warnings: false, reverse_results: false, optimization_level: OptLevel::Opt1, - experimental: ExperimentalFlags { - new_encoding: false, - }, } } } @@ -103,10 +89,9 @@ impl Default for BuildProfile { #[cfg(test)] mod tests { + use crate::{BuildProfile, PackageManifest}; use sway_core::{OptLevel, PrintAsm, PrintIr}; - use crate::{manifest::build_profile::ExperimentalFlags, BuildProfile, PackageManifest}; - #[test] fn test_build_profiles() { let manifest = PackageManifest::from_dir("./tests/sections").expect("manifest"); @@ -160,7 +145,6 @@ mod tests { error_on_warnings: true, reverse_results: true, optimization_level: OptLevel::Opt0, - experimental: ExperimentalFlags { new_encoding: true }, }; let profile = build_profiles.get("release").expect("release profile"); assert_eq!(*profile, expected); diff --git a/forc-pkg/src/manifest/mod.rs b/forc-pkg/src/manifest/mod.rs index 28729aff757..009b770f590 100644 --- a/forc-pkg/src/manifest/mod.rs +++ b/forc-pkg/src/manifest/mod.rs @@ -200,6 +200,8 @@ pub struct Project { pub entry: String, pub implicit_std: Option, pub forc_version: Option, + #[serde(default)] + pub experimental: HashMap, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] diff --git a/forc-pkg/src/pkg.rs b/forc-pkg/src/pkg.rs index 9467b483b2e..5a693613b68 100644 --- a/forc-pkg/src/pkg.rs +++ b/forc-pkg/src/pkg.rs @@ -1,10 +1,7 @@ use crate::manifest::GenericManifestFile; use crate::{ lock::Lock, - manifest::{ - build_profile::ExperimentalFlags, Dependency, ManifestFile, MemberManifestFiles, - PackageManifestFile, - }, + manifest::{Dependency, ManifestFile, MemberManifestFiles, PackageManifestFile}, source::{self, IPFSNode, Source}, BuildProfile, }; @@ -51,6 +48,7 @@ use sway_core::{ }; use sway_core::{PrintAsm, PrintIr}; use sway_error::{error::CompileError, handler::Handler, warning::CompileWarning}; +use sway_features::ExperimentalFeatures; use sway_types::constants::{CORE, PRELUDE, STD}; use sway_types::{Ident, Span, Spanned}; use sway_utils::{constants, time_expr, PerformanceData, PerformanceMetric}; @@ -310,8 +308,10 @@ pub struct BuildOpts { pub tests: bool, /// The set of options to filter by member project kind. pub member_filter: MemberFilter, - /// Set of experimental flags - pub experimental: ExperimentalFlags, + /// Set of enabled experimental flags + pub experimental: Vec, + /// Set of disabled experimental flags + pub no_experimental: Vec, } /// The set of options to filter type of projects to build in a workspace. @@ -1565,10 +1565,7 @@ pub fn sway_build_config( .with_include_tests(build_profile.include_tests) .with_time_phases(build_profile.time_phases) .with_metrics(build_profile.metrics_outfile.clone()) - .with_optimization_level(build_profile.optimization_level) - .with_experimental(sway_core::ExperimentalFlags { - new_encoding: build_profile.experimental.new_encoding, - }); + .with_optimization_level(build_profile.optimization_level); Ok(build_config) } @@ -1594,7 +1591,7 @@ pub fn dependency_namespace( node: NodeIx, engines: &Engines, contract_id_value: Option, - experimental: sway_core::ExperimentalFlags, + experimental: ExperimentalFeatures, ) -> Result> { // TODO: Clean this up when config-time constants v1 are removed. let node_idx = &graph[node]; @@ -1760,6 +1757,7 @@ pub fn compile( engines: &Engines, namespace: &mut namespace::Root, source_map: &mut SourceMap, + experimental: ExperimentalFeatures, ) -> Result { let mut metrics = PerformanceData::default(); @@ -1795,6 +1793,7 @@ pub fn compile( Some(&sway_build_config), &pkg.name, None, + experimental ), Some(sway_build_config.clone()), metrics @@ -1825,13 +1824,19 @@ pub fn compile( let asm_res = time_expr!( "compile ast to asm", "compile_ast_to_asm", - sway_core::ast_to_asm(&handler, engines, &programs, &sway_build_config), + sway_core::ast_to_asm( + &handler, + engines, + &programs, + &sway_build_config, + experimental + ), Some(sway_build_config.clone()), metrics ); - const OLD_ENCODING_VERSION: &str = "0"; - const NEW_ENCODING_VERSION: &str = "1"; + const ENCODING_V0: &str = "0"; + const ENCODING_V1: &str = "1"; const SPEC_VERSION: &str = "1"; let mut program_abi = match pkg.target { @@ -1847,11 +1852,11 @@ pub fn compile( type_ids_to_full_type_str: HashMap::::new(), }, engines, - profile - .experimental - .new_encoding - .then(|| NEW_ENCODING_VERSION.into()) - .unwrap_or(OLD_ENCODING_VERSION.into()), + if experimental.new_encoding { + ENCODING_V1.into() + } else { + ENCODING_V0.into() + }, SPEC_VERSION.into(), ), Some(sway_build_config.clone()), @@ -2065,7 +2070,6 @@ fn build_profile_from_opts( metrics_outfile, tests, error_on_warnings, - experimental, .. } = build_options; @@ -2106,9 +2110,7 @@ fn build_profile_from_opts( } profile.include_tests |= tests; profile.error_on_warnings |= error_on_warnings; - profile.experimental = ExperimentalFlags { - new_encoding: experimental.new_encoding, - }; + // profile.experimental = *experimental; Ok(profile) } @@ -2147,6 +2149,7 @@ pub fn build_with_options(build_options: &BuildOpts) -> Result { build_target, member_filter, experimental, + no_experimental, .. } = &build_options; @@ -2192,9 +2195,8 @@ pub fn build_with_options(build_options: &BuildOpts) -> Result { *build_target, &build_profile, &outputs, - sway_core::ExperimentalFlags { - new_encoding: experimental.new_encoding, - }, + experimental, + no_experimental, )?; let output_dir = pkg.output_directory.as_ref().map(PathBuf::from); let total_size = built_packages @@ -2305,7 +2307,8 @@ pub fn build( target: BuildTarget, profile: &BuildProfile, outputs: &HashSet, - experimental: sway_core::ExperimentalFlags, + experimental: &[sway_features::Feature], + no_experimental: &[sway_features::Feature], ) -> anyhow::Result> { let mut built_packages = Vec::new(); @@ -2340,6 +2343,13 @@ pub fn build( &pkg.source.display_compiling(manifest.dir()), ); + let experimental = ExperimentalFeatures::new( + &manifest.project.experimental, + experimental, + no_experimental, + ) + .map_err(|err| anyhow!("{err}"))?; + let descriptor = PackageDescriptor { name: pkg.name.clone(), target, @@ -2397,6 +2407,7 @@ pub fn build( &engines, &mut dep_namespace, &mut source_map, + experimental, )?; if let Some(outfile) = profile.metrics_outfile { @@ -2470,6 +2481,7 @@ pub fn build( &engines, &mut dep_namespace, &mut source_map, + experimental, )?; if let Some(outfile) = profile.metrics_outfile { @@ -2515,7 +2527,8 @@ pub fn check( include_tests: bool, engines: &Engines, retrigger_compilation: Option>, - experimental: sway_core::ExperimentalFlags, + experimental: &[sway_features::Feature], + no_experimental: &[sway_features::Feature], ) -> anyhow::Result, Handler)>> { let mut lib_namespace_map = HashMap::default(); let mut source_map = SourceMap::new(); @@ -2527,6 +2540,13 @@ pub fn check( let pkg = &plan.graph[node]; let manifest = &plan.manifest_map()[&pkg.id()]; + let experimental = ExperimentalFeatures::new( + &manifest.project.experimental, + experimental, + no_experimental, + ) + .map_err(|err| anyhow!("{err}"))?; + // This is necessary because `CONTRACT_ID` is a special constant that's injected into the // compiler's namespace. Although we only know the contract id during building, we are // inserting a dummy value here to avoid false error signals being reported in LSP. @@ -2574,6 +2594,7 @@ pub fn check( Some(&build_config), &pkg.name, retrigger_compilation.clone(), + experimental, ); if retrigger_compilation diff --git a/forc-pkg/tests/sections/Forc.toml b/forc-pkg/tests/sections/Forc.toml index 88b012cd138..4c65994f702 100644 --- a/forc-pkg/tests/sections/Forc.toml +++ b/forc-pkg/tests/sections/Forc.toml @@ -10,7 +10,7 @@ name = "sections" print-ast = true print-dca-graph = "dca_graph" print-dca-graph-url-format = "print_dca_graph_url_format" -print-ir = { initial = false, final = true, modified = true, passes = []} +print-ir = { initial = false, final = true, modified = true, passes = [] } print-asm = { virtual = true, allocated = true, final = true } print-bytecode = true terse = true @@ -20,10 +20,13 @@ include-tests = true error-on-warnings = true reverse-results = true optimization-level = 0 -experimental = { new-encoding = true } +experimental = { encoding-v1 = true } [build-profile.custom_asm] print-asm = { virtual = false, allocated = false, final = true } [build-profile.custom_ir] -print-ir = { initial = true, final = false, modified = true, passes = ["dce", "sroa"]} +print-ir = { initial = true, final = false, modified = true, passes = [ + "dce", + "sroa", +] } diff --git a/forc-plugins/forc-client/Cargo.toml b/forc-plugins/forc-client/Cargo.toml index ee1b03ea173..c3c5d5d57da 100644 --- a/forc-plugins/forc-client/Cargo.toml +++ b/forc-plugins/forc-client/Cargo.toml @@ -40,9 +40,14 @@ rpassword.workspace = true serde.workspace = true serde_json.workspace = true sway-core.workspace = true +sway-features.workspace = true sway-types.workspace = true sway-utils.workspace = true -tokio = { workspace = true, features = ["macros", "process", "rt-multi-thread"] } +tokio = { workspace = true, features = [ + "macros", + "process", + "rt-multi-thread", +] } toml_edit.workspace = true tracing.workspace = true diff --git a/forc-plugins/forc-client/src/cmd/deploy.rs b/forc-plugins/forc-client/src/cmd/deploy.rs index 87428dfbca7..a30a40b3b0b 100644 --- a/forc-plugins/forc-client/src/cmd/deploy.rs +++ b/forc-plugins/forc-client/src/cmd/deploy.rs @@ -84,9 +84,8 @@ pub struct Command { #[clap(long, verbatim_doc_comment, name = "JSON_FILE_PATH")] pub override_storage_slots: Option, - /// Disable the "new encoding" feature - #[clap(long)] - pub no_encoding_v1: bool, + #[clap(flatten)] + pub experimental: sway_features::CliFields, /// AWS KMS signer arn. If present forc-deploy will automatically use AWS KMS signer instead of forc-wallet. #[clap(long)] diff --git a/forc-plugins/forc-client/src/cmd/run.rs b/forc-plugins/forc-client/src/cmd/run.rs index 5875b270adc..85b5ec31fe9 100644 --- a/forc-plugins/forc-client/src/cmd/run.rs +++ b/forc-plugins/forc-client/src/cmd/run.rs @@ -56,7 +56,6 @@ pub struct Command { #[clap(long)] pub args: Option>, - /// Disable the "new encoding" feature - #[clap(long)] - pub no_encoding_v1: bool, + #[clap(flatten)] + pub experimental: sway_features::CliFields, } diff --git a/forc-plugins/forc-client/src/op/deploy.rs b/forc-plugins/forc-client/src/op/deploy.rs index cdc5d35162c..ace89c3ddae 100644 --- a/forc-plugins/forc-client/src/op/deploy.rs +++ b/forc-plugins/forc-client/src/op/deploy.rs @@ -38,7 +38,7 @@ use fuels::{ use fuels_accounts::{provider::Provider, Account, ViewOnlyAccount}; use fuels_core::types::{transaction::TxPolicies, transaction_builders::CreateTransactionBuilder}; use futures::FutureExt; -use pkg::{manifest::build_profile::ExperimentalFlags, BuildProfile, BuiltPackage}; +use pkg::{BuildProfile, BuiltPackage}; use serde::{Deserialize, Serialize}; use std::{ collections::BTreeMap, @@ -47,8 +47,7 @@ use std::{ sync::Arc, time::Duration, }; -use sway_core::BuildTarget; -use sway_core::{asm_generation::ProgramABI, language::parsed::TreeType}; +use sway_core::{asm_generation::ProgramABI, language::parsed::TreeType, BuildTarget}; /// Default maximum contract size allowed for a single contract. If the target /// contract size is bigger than this amount, forc-deploy will automatically @@ -927,9 +926,8 @@ fn build_opts_from_cmd(cmd: &cmd::Deploy, member_filter: pkg::MemberFilter) -> p build_target: BuildTarget::default(), tests: false, member_filter, - experimental: ExperimentalFlags { - new_encoding: !cmd.no_encoding_v1, - }, + experimental: cmd.experimental.experimental.clone(), + no_experimental: cmd.experimental.no_experimental.clone(), } } diff --git a/forc-plugins/forc-client/src/op/run/mod.rs b/forc-plugins/forc-client/src/op/run/mod.rs index 5e58835fca0..debf0579c19 100644 --- a/forc-plugins/forc-client/src/op/run/mod.rs +++ b/forc-plugins/forc-client/src/op/run/mod.rs @@ -23,7 +23,7 @@ use fuels::{ }, }; use fuels_accounts::{provider::Provider, Account}; -use pkg::{manifest::build_profile::ExperimentalFlags, BuiltPackage}; +use pkg::BuiltPackage; use std::time::Duration; use std::{path::PathBuf, str::FromStr}; use sway_core::language::parsed::TreeType; @@ -272,8 +272,7 @@ fn build_opts_from_cmd(cmd: &cmd::Run) -> pkg::BuildOpts { debug_outfile: cmd.build_output.debug_file.clone(), tests: false, member_filter: pkg::MemberFilter::only_scripts(), - experimental: ExperimentalFlags { - new_encoding: !cmd.no_encoding_v1, - }, + experimental: cmd.experimental.experimental.clone(), + no_experimental: cmd.experimental.no_experimental.clone(), } } diff --git a/forc-plugins/forc-debug/Cargo.toml b/forc-plugins/forc-debug/Cargo.toml index 4911d214c2e..84c3d05797d 100644 --- a/forc-plugins/forc-debug/Cargo.toml +++ b/forc-plugins/forc-debug/Cargo.toml @@ -23,6 +23,7 @@ serde.workspace = true serde_json.workspace = true shellfish = { workspace = true, features = ["async", "rustyline", "tokio"] } sway-core.workspace = true +sway-features.workspace = true sway-types.workspace = true thiserror.workspace = true tokio = { workspace = true, features = [ diff --git a/forc-plugins/forc-debug/src/server/handlers/handle_launch.rs b/forc-plugins/forc-debug/src/server/handlers/handle_launch.rs index fd281261347..3ae3c2f3539 100644 --- a/forc-plugins/forc-debug/src/server/handlers/handle_launch.rs +++ b/forc-plugins/forc-debug/src/server/handlers/handle_launch.rs @@ -54,10 +54,6 @@ impl DapServer { } } - let experimental = sway_core::ExperimentalFlags { - new_encoding: false, - }; - // 1. Build the packages let manifest_file = forc_pkg::manifest::ManifestFile::from_dir(&self.state.program_path) .map_err(|err| AdapterError::BuildFailed { @@ -110,7 +106,8 @@ impl DapServer { ..Default::default() }, &outputs, - experimental, + &[], + &[], ) .map_err(|err| AdapterError::BuildFailed { reason: format!("build packages: {:?}", err), diff --git a/forc-plugins/forc-doc/Cargo.toml b/forc-plugins/forc-doc/Cargo.toml index e6780e0fe80..ebfd2bc7197 100644 --- a/forc-plugins/forc-doc/Cargo.toml +++ b/forc-plugins/forc-doc/Cargo.toml @@ -23,6 +23,7 @@ serde.workspace = true serde_json.workspace = true sway-ast.workspace = true sway-core.workspace = true +sway-features.workspace = true sway-lsp.workspace = true sway-types.workspace = true swayfmt.workspace = true diff --git a/forc-plugins/forc-doc/src/cli.rs b/forc-plugins/forc-doc/src/cli.rs index 8ba9906203f..309bfb880d6 100644 --- a/forc-plugins/forc-doc/src/cli.rs +++ b/forc-plugins/forc-doc/src/cli.rs @@ -53,7 +53,6 @@ pub struct Command { #[cfg(test)] pub(crate) doc_path: Option, - /// Disable the "new encoding" feature - #[clap(long)] - pub no_encoding_v1: bool, + #[clap(flatten)] + pub experimental: sway_features::CliFields, } diff --git a/forc-plugins/forc-doc/src/lib.rs b/forc-plugins/forc-doc/src/lib.rs index d629b606563..4043cfde1f2 100644 --- a/forc-plugins/forc-doc/src/lib.rs +++ b/forc-plugins/forc-doc/src/lib.rs @@ -55,7 +55,6 @@ pub struct ProgramInfo<'a> { pub fn compile_html( build_instructions: &Command, get_doc_dir: &dyn Fn(&Command) -> String, - experimental: sway_core::ExperimentalFlags, ) -> Result<(PathBuf, Box)> { // get manifest directory let dir = if let Some(ref path) = build_instructions.manifest_path { @@ -108,7 +107,8 @@ pub fn compile_html( tests_enabled, &engines, None, - experimental, + &build_instructions.experimental.experimental, + &build_instructions.experimental.no_experimental, )?; let raw_docs = if build_instructions.no_deps { diff --git a/forc-plugins/forc-doc/src/main.rs b/forc-plugins/forc-doc/src/main.rs index ab990727d7f..5b3082fd1a7 100644 --- a/forc-plugins/forc-doc/src/main.rs +++ b/forc-plugins/forc-doc/src/main.rs @@ -12,13 +12,7 @@ use std::{ pub fn main() -> Result<()> { let build_instructions = Command::parse(); - let (doc_path, pkg_manifest) = compile_html( - &build_instructions, - &get_doc_dir, - sway_core::ExperimentalFlags { - new_encoding: !build_instructions.no_encoding_v1, - }, - )?; + let (doc_path, pkg_manifest) = compile_html(&build_instructions, &get_doc_dir)?; // CSS, icons and logos static ASSETS_DIR: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/src/static.files"); diff --git a/forc-plugins/forc-doc/src/tests/expects/impl_trait/mod.rs b/forc-plugins/forc-doc/src/tests/expects/impl_trait/mod.rs index 8f96a41e856..9ead7b2f1dc 100644 --- a/forc-plugins/forc-doc/src/tests/expects/impl_trait/mod.rs +++ b/forc-plugins/forc-doc/src/tests/expects/impl_trait/mod.rs @@ -10,7 +10,6 @@ use std::{ collections::HashSet, path::{Path, PathBuf}, }; -use sway_core::ExperimentalFlags; /// The path to the generated HTML of the type the traits are implemented on. const IMPL_FOR: &str = "bar/struct.Bar.html"; @@ -26,19 +25,12 @@ fn test_impl_traits_default() { doc_path: Some(doc_dir_name.into()), ..Default::default() }; - let (doc_path, _) = compile_html( - &command, - &get_doc_dir, - ExperimentalFlags { - new_encoding: false, - }, - ) - .unwrap(); + let (doc_path, _) = compile_html(&command, &get_doc_dir).unwrap(); assert_index_html( &doc_path, project_name, &expect![[r##" - Bar in bar - Sway
pub struct Bar {}

Implementations

fn foo_bar()

Trait Implementations

fn foo()

something more about foo();

+ Bar in bar - Sway
pub struct Bar {}

Implementations

fn foo_bar()

Trait Implementations

fn abi_encode(self, buffer: Buffer) -> Buffer

fn abi_decode(refmut _buffer: BufferReader) -> Self

fn foo()

something more about foo();

fn add(self, other: Self) -> Self

fn subtract(self, other: Self) -> Self

"##]], ); assert_search_js( @@ -183,21 +175,13 @@ fn test_impl_traits_no_deps() { no_deps: true, ..Default::default() }; - let (doc_path, _) = compile_html( - &command, - &get_doc_dir, - ExperimentalFlags { - new_encoding: false, - }, - ) - .unwrap(); + let (doc_path, _) = compile_html(&command, &get_doc_dir).unwrap(); assert_index_html( &doc_path, project_name, - &expect![[ - r##"Bar in bar - Sway
pub struct Bar {}

Implementations

fn foo_bar()

Trait Implementations

fn foo()

something more about foo();

-

fn add(self, other: Self) -> Self

fn subtract(self, other: Self) -> Self

"## - ]], + &expect![[r##" + Bar in bar - Sway
pub struct Bar {}

Implementations

fn foo_bar()

Trait Implementations

fn abi_encode(self, buffer: Buffer) -> Buffer

fn abi_decode(refmut _buffer: BufferReader) -> Self

fn foo()

something more about foo();

+

fn add(self, other: Self) -> Self

fn subtract(self, other: Self) -> Self

"##]], ); assert_search_js( &doc_path, diff --git a/forc-plugins/forc-doc/tests/lib.rs b/forc-plugins/forc-doc/tests/lib.rs index 158a6c2613e..9624b656a4f 100644 --- a/forc-plugins/forc-doc/tests/lib.rs +++ b/forc-plugins/forc-doc/tests/lib.rs @@ -9,12 +9,6 @@ fn builds_lib_std_docs() { ..Default::default() }; println!("Building docs for {:?}", build_instructions.manifest_path); - let res = compile_html( - &build_instructions, - &get_doc_dir, - sway_core::ExperimentalFlags { - new_encoding: !build_instructions.no_encoding_v1, - }, - ); + let res = compile_html(&build_instructions, &get_doc_dir); assert!(res.is_ok()); } diff --git a/forc-test/Cargo.toml b/forc-test/Cargo.toml index 3034b60dfbf..1a012d6fdc1 100644 --- a/forc-test/Cargo.toml +++ b/forc-test/Cargo.toml @@ -18,4 +18,5 @@ fuels-core.workspace = true rand.workspace = true rayon.workspace = true sway-core.workspace = true +sway-features.workspace = true sway-types.workspace = true diff --git a/forc-test/src/lib.rs b/forc-test/src/lib.rs index 58394055d75..c7bd19e95fd 100644 --- a/forc-test/src/lib.rs +++ b/forc-test/src/lib.rs @@ -12,7 +12,6 @@ use fuel_vm::checked_transaction::builder::TransactionBuilderExt; use fuel_vm::{self as vm}; use fuels_core::codec::ABIDecoder; use fuels_core::types::param_types::ParamType; -use pkg::manifest::build_profile::ExperimentalFlags; use pkg::TestPassCondition; use pkg::{Built, BuiltPackage}; use rand::{Rng, SeedableRng}; @@ -154,8 +153,10 @@ pub struct TestOpts { pub time_phases: bool, /// Output compilation metrics into file. pub metrics_outfile: Option, - /// Set of experimental flags - pub experimental: ExperimentalFlags, + /// Set of enabled experimental flags + pub experimental: Vec, + /// Set of disabled experimental flags + pub no_experimental: Vec, } /// The set of options provided for controlling logs printed for each test. @@ -456,6 +457,7 @@ impl From for pkg::BuildOpts { tests: true, member_filter: Default::default(), experimental: val.experimental, + no_experimental: val.no_experimental, } } } @@ -478,6 +480,7 @@ impl TestOpts { tests: true, member_filter: Default::default(), experimental: self.experimental, + no_experimental: self.no_experimental, } } } diff --git a/forc/Cargo.toml b/forc/Cargo.toml index 2f5d6dda481..578e427cee8 100644 --- a/forc/Cargo.toml +++ b/forc/Cargo.toml @@ -34,6 +34,7 @@ serde = { workspace = true, features = ["derive"] } serde_json.workspace = true sway-core.workspace = true sway-error.workspace = true +sway-features.workspace = true sway-ir.workspace = true sway-types.workspace = true sway-utils.workspace = true diff --git a/forc/src/cli/commands/build.rs b/forc/src/cli/commands/build.rs index ae88dfebfdc..38662dd9240 100644 --- a/forc/src/cli/commands/build.rs +++ b/forc/src/cli/commands/build.rs @@ -33,9 +33,8 @@ pub struct Command { #[clap(long)] pub tests: bool, - /// Disable the "new encoding" feature - #[clap(long)] - pub no_encoding_v1: bool, + #[clap(flatten)] + pub experimental: sway_features::CliFields, } pub(crate) fn exec(command: Command) -> ForcResult<()> { diff --git a/forc/src/cli/commands/check.rs b/forc/src/cli/commands/check.rs index 4d5f41e76a3..3a3406ac9e8 100644 --- a/forc/src/cli/commands/check.rs +++ b/forc/src/cli/commands/check.rs @@ -45,9 +45,8 @@ pub struct Command { #[clap(long)] pub ipfs_node: Option, - /// Disable the "new encoding" feature - #[clap(long)] - pub no_encoding_v1: bool, + #[clap(flatten)] + pub experimental: sway_features::CliFields, } pub(crate) fn exec(command: Command) -> ForcResult<()> { diff --git a/forc/src/cli/commands/contract_id.rs b/forc/src/cli/commands/contract_id.rs index 55848428aa8..85640937943 100644 --- a/forc/src/cli/commands/contract_id.rs +++ b/forc/src/cli/commands/contract_id.rs @@ -29,9 +29,8 @@ pub struct Command { #[clap(flatten)] pub salt: Salt, - /// Disable the "new encoding" feature - #[clap(long)] - pub no_encoding_v1: bool, + #[clap(flatten)] + pub experimental: sway_features::CliFields, } pub(crate) fn exec(cmd: Command) -> ForcResult<()> { diff --git a/forc/src/cli/commands/predicate_root.rs b/forc/src/cli/commands/predicate_root.rs index 5c9cbb6bf04..676c85e998f 100644 --- a/forc/src/cli/commands/predicate_root.rs +++ b/forc/src/cli/commands/predicate_root.rs @@ -26,9 +26,8 @@ pub struct Command { #[clap(flatten)] pub build_profile: BuildProfile, - /// Disable the "new encoding" feature - #[clap(long)] - pub no_encoding_v1: bool, + #[clap(flatten)] + pub experimental: sway_features::CliFields, } pub(crate) fn exec(cmd: Command) -> ForcResult<()> { diff --git a/forc/src/cli/commands/test.rs b/forc/src/cli/commands/test.rs index 5ffa1c51d75..d556af6b790 100644 --- a/forc/src/cli/commands/test.rs +++ b/forc/src/cli/commands/test.rs @@ -5,7 +5,6 @@ use forc_pkg as pkg; use forc_test::{decode_log_data, TestFilter, TestRunnerCount, TestedPackage}; use forc_tracing::println_action_green; use forc_util::{tx_utils::format_log_receipts, ForcError, ForcResult}; -use pkg::manifest::build_profile::ExperimentalFlags; use sway_core::fuel_prelude::fuel_tx::Receipt; use tracing::info; @@ -52,9 +51,8 @@ pub struct Command { /// threads available in your system. pub test_threads: Option, - /// Disable the "new encoding" feature - #[clap(long)] - pub no_encoding_v1: bool, + #[clap(flatten)] + pub experimental: sway_features::CliFields, } /// The set of options provided for controlling output of a test. @@ -256,9 +254,8 @@ fn opts_from_cmd(cmd: Command) -> forc_test::TestOpts { binary_outfile: cmd.build.output.bin_file, debug_outfile: cmd.build.output.debug_file, build_target: cmd.build.build_target, - experimental: ExperimentalFlags { - new_encoding: !cmd.no_encoding_v1, - }, + experimental: cmd.experimental.experimental, + no_experimental: cmd.experimental.no_experimental, } } diff --git a/forc/src/ops/forc_build.rs b/forc/src/ops/forc_build.rs index 49c0c27f955..1118bdb5d54 100644 --- a/forc/src/ops/forc_build.rs +++ b/forc/src/ops/forc_build.rs @@ -1,7 +1,7 @@ use crate::cli::BuildCommand; use forc_pkg as pkg; use forc_util::ForcResult; -use pkg::{manifest::build_profile::ExperimentalFlags, MemberFilter}; +use pkg::MemberFilter; pub fn build(cmd: BuildCommand) -> ForcResult { let opts = opts_from_cmd(cmd); @@ -43,8 +43,7 @@ fn opts_from_cmd(cmd: BuildCommand) -> pkg::BuildOpts { build_target: cmd.build.build_target, tests: cmd.tests, member_filter: MemberFilter::default(), - experimental: ExperimentalFlags { - new_encoding: !cmd.no_encoding_v1, - }, + experimental: cmd.experimental.experimental, + no_experimental: cmd.experimental.no_experimental, } } diff --git a/forc/src/ops/forc_check.rs b/forc/src/ops/forc_check.rs index e1419c90982..116b27ace6d 100644 --- a/forc/src/ops/forc_check.rs +++ b/forc/src/ops/forc_check.rs @@ -4,7 +4,7 @@ use forc_pkg as pkg; use forc_pkg::manifest::GenericManifestFile; use pkg::manifest::ManifestFile; use std::path::PathBuf; -use sway_core::{language::ty, Engines, ExperimentalFlags}; +use sway_core::{language::ty, Engines}; use sway_error::handler::Handler; pub fn check(command: CheckCommand, engines: &Engines) -> Result<(Option, Handler)> { @@ -16,7 +16,8 @@ pub fn check(command: CheckCommand, engines: &Engines) -> Result<(Option Result<(Option pkg::BuildOpts { build_target: BuildTarget::default(), tests: false, member_filter: pkg::MemberFilter::only_contracts(), - experimental: ExperimentalFlags { - new_encoding: !cmd.no_encoding_v1, - }, + experimental: cmd.experimental.experimental.clone(), + no_experimental: cmd.experimental.no_experimental.clone(), } } diff --git a/forc/src/ops/forc_predicate_root.rs b/forc/src/ops/forc_predicate_root.rs index 1381aec392e..34be42c4117 100644 --- a/forc/src/ops/forc_predicate_root.rs +++ b/forc/src/ops/forc_predicate_root.rs @@ -1,7 +1,6 @@ use crate::cli::PredicateRootCommand; use anyhow::Result; use forc_pkg::{self as pkg, build_with_options}; -use pkg::manifest::build_profile::ExperimentalFlags; use sway_core::BuildTarget; pub fn predicate_root(command: PredicateRootCommand) -> Result<()> { @@ -47,8 +46,7 @@ fn build_opts_from_cmd(cmd: PredicateRootCommand) -> pkg::BuildOpts { build_target: BuildTarget::default(), tests: false, member_filter: pkg::MemberFilter::only_predicates(), - experimental: ExperimentalFlags { - new_encoding: !cmd.no_encoding_v1, - }, + experimental: cmd.experimental.experimental, + no_experimental: cmd.experimental.no_experimental, } } diff --git a/sway-core/Cargo.toml b/sway-core/Cargo.toml index 668959fab61..3a351390cbb 100644 --- a/sway-core/Cargo.toml +++ b/sway-core/Cargo.toml @@ -38,6 +38,7 @@ sha2.workspace = true strum = { workspace = true, features = ["derive"] } sway-ast.workspace = true sway-error.workspace = true +sway-features.workspace = true sway-ir.workspace = true sway-parse.workspace = true sway-types.workspace = true diff --git a/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs b/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs index b08361476c2..0e56e87d33f 100644 --- a/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs +++ b/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs @@ -238,9 +238,7 @@ impl<'ir, 'eng> AsmBuilder for FuelAsmBuilder<'ir, 'eng> { entries, non_entries, reg_seqr, - crate::ExperimentalFlags { - new_encoding: context.experimental.new_encoding, - }, + context.experimental, ); // Compiled dependencies will not have any content and we diff --git a/sway-core/src/asm_generation/fuel/programs/abstract.rs b/sway-core/src/asm_generation/fuel/programs/abstract.rs index 17b6240a95d..ab5aa19147b 100644 --- a/sway-core/src/asm_generation/fuel/programs/abstract.rs +++ b/sway-core/src/asm_generation/fuel/programs/abstract.rs @@ -17,10 +17,10 @@ use crate::{ VirtualImmediate18, VirtualImmediate24, }, decl_engine::DeclRefFunction, - ExperimentalFlags, }; use either::Either; use sway_error::error::CompileError; +use sway_features::ExperimentalFeatures; /// The entry point of an abstract program. pub(crate) struct AbstractEntry { @@ -44,7 +44,7 @@ pub(crate) struct AbstractProgram { entries: Vec, non_entries: Vec, reg_seqr: RegisterSequencer, - experimental: ExperimentalFlags, + experimental: ExperimentalFeatures, } impl AbstractProgram { @@ -57,7 +57,7 @@ impl AbstractProgram { entries: Vec, non_entries: Vec, reg_seqr: RegisterSequencer, - experimental: ExperimentalFlags, + experimental: ExperimentalFeatures, ) -> Self { AbstractProgram { kind, diff --git a/sway-core/src/build_config.rs b/sway-core/src/build_config.rs index ba96971d4a7..711ceb014d4 100644 --- a/sway-core/src/build_config.rs +++ b/sway-core/src/build_config.rs @@ -189,7 +189,6 @@ pub struct BuildConfig { pub(crate) optimization_level: OptLevel, pub time_phases: bool, pub metrics_outfile: Option, - pub experimental: ExperimentalFlags, pub lsp_mode: Option, } @@ -237,9 +236,6 @@ impl BuildConfig { time_phases: false, metrics_outfile: None, optimization_level: OptLevel::Opt0, - experimental: ExperimentalFlags { - new_encoding: false, - }, lsp_mode: None, } } @@ -310,13 +306,6 @@ impl BuildConfig { } } - pub fn with_experimental(self, experimental: ExperimentalFlags) -> Self { - Self { - experimental, - ..self - } - } - pub fn with_lsp_mode(self, lsp_mode: Option) -> Self { Self { lsp_mode, ..self } } @@ -326,11 +315,6 @@ impl BuildConfig { } } -#[derive(Debug, Clone, Copy)] -pub struct ExperimentalFlags { - pub new_encoding: bool, -} - #[derive(Clone, Debug, Default)] pub struct LspConfig { // This is set to true if compilation was triggered by a didChange LSP event. In this case, we diff --git a/sway-core/src/ir_generation.rs b/sway-core/src/ir_generation.rs index dc08281c82e..10df2f19a9b 100644 --- a/sway-core/src/ir_generation.rs +++ b/sway-core/src/ir_generation.rs @@ -13,6 +13,7 @@ use std::{ }; use sway_error::error::CompileError; +use sway_features::ExperimentalFeatures; use sway_ir::{Context, Function, Kind, Module}; use sway_types::{span::Span, Ident}; @@ -23,7 +24,7 @@ use crate::{ language::ty, metadata::MetadataManager, types::{LogId, MessageId}, - Engines, ExperimentalFlags, TypeId, + Engines, TypeId, }; type FnKey = u64; @@ -120,7 +121,7 @@ pub fn compile_program<'eng>( program: &ty::TyProgram, include_tests: bool, engines: &'eng Engines, - experimental: ExperimentalFlags, + experimental: ExperimentalFeatures, ) -> Result, Vec> { let declaration_engine = engines.de(); @@ -148,12 +149,7 @@ pub fn compile_program<'eng>( .map(|(message_id, type_id)| (*type_id, *message_id)) .collect(); - let mut ctx = Context::new( - engines.se(), - sway_ir::ExperimentalFlags { - new_encoding: experimental.new_encoding, - }, - ); + let mut ctx = Context::new(engines.se(), experimental); ctx.program_kind = match kind { ty::TyProgramKind::Script { .. } => Kind::Script, ty::TyProgramKind::Predicate { .. } => Kind::Predicate, diff --git a/sway-core/src/ir_generation/const_eval.rs b/sway-core/src/ir_generation/const_eval.rs index ed6b6d70970..ad2d5a307ff 100644 --- a/sway-core/src/ir_generation/const_eval.rs +++ b/sway-core/src/ir_generation/const_eval.rs @@ -1370,6 +1370,7 @@ fn const_eval_intrinsic( mod tests { use super::*; use sway_error::handler::Handler; + use sway_features::ExperimentalFeatures; use sway_ir::Kind; /// This function validates if an expression can be converted to [Constant]. @@ -1388,12 +1389,7 @@ mod tests { fn assert_is_constant(is_constant: bool, prefix: &str, expr: &str) { let engines = Engines::default(); let handler = Handler::default(); - let mut context = Context::new( - engines.se(), - sway_ir::ExperimentalFlags { - new_encoding: false, - }, - ); + let mut context = Context::new(engines.se(), ExperimentalFeatures::default()); let mut md_mgr = MetadataManager::default(); let mut core_lib = namespace::Root::from(namespace::Module::new( sway_types::Ident::new_no_span("assert_is_constant_test".to_string()), @@ -1409,6 +1405,7 @@ mod tests { None, "test", None, + ExperimentalFeatures::default(), ); let (errors, _warnings) = handler.consume(); diff --git a/sway-core/src/language/ty/program.rs b/sway-core/src/language/ty/program.rs index b2257451574..5a7bd193e42 100644 --- a/sway-core/src/language/ty/program.rs +++ b/sway-core/src/language/ty/program.rs @@ -7,13 +7,14 @@ use crate::{ transform::AllowDeprecatedState, type_system::*, types::*, - Engines, ExperimentalFlags, + Engines, }; use sway_error::{ error::{CompileError, TypeNotAllowedReason}, handler::{ErrorEmitted, Handler}, }; +use sway_features::ExperimentalFeatures; use sway_types::*; #[derive(Debug, Clone)] @@ -64,7 +65,7 @@ impl TyProgram { root: &TyModule, kind: parsed::TreeType, package_name: &str, - experimental: ExperimentalFlags, + experimental: ExperimentalFeatures, ) -> Result<(TyProgramKind, Vec, Vec), ErrorEmitted> { // Extract program-kind-specific properties from the root nodes. diff --git a/sway-core/src/lib.rs b/sway-core/src/lib.rs index fcc524ce8a0..d66b8e779eb 100644 --- a/sway-core/src/lib.rs +++ b/sway-core/src/lib.rs @@ -43,6 +43,7 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use sway_ast::AttributeDecl; use sway_error::handler::{ErrorEmitted, Handler}; +use sway_features::ExperimentalFeatures; use sway_ir::{ create_o1_pass_group, register_known_passes, Context, Kind, Module, PassGroup, PassManager, PrintPassesOpts, ARG_DEMOTION_NAME, CONST_DEMOTION_NAME, DCE_NAME, FN_DCE_NAME, @@ -70,7 +71,6 @@ pub mod fuel_prelude { pub use fuel_vm::{self, fuel_asm, fuel_crypto, fuel_tx, fuel_types}; } -pub use build_config::ExperimentalFlags; pub use engine_threading::Engines; /// Given an input `Arc` and an optional [BuildConfig], parse the input into a [lexed::LexedProgram] and [parsed::ParseProgram]. @@ -91,16 +91,10 @@ pub fn parse( handler: &Handler, engines: &Engines, config: Option<&BuildConfig>, + experimental: ExperimentalFeatures, ) -> Result<(lexed::LexedProgram, parsed::ParseProgram), ErrorEmitted> { match config { - None => parse_in_memory( - handler, - engines, - input, - ExperimentalFlags { - new_encoding: false, - }, - ), + None => parse_in_memory(handler, engines, input, experimental), // When a `BuildConfig` is given, // the module source may declare `dep`s that must be parsed from other files. Some(config) => parse_module_tree( @@ -111,7 +105,7 @@ pub fn parse( None, config.build_target, config.include_tests, - config.experimental, + experimental, config.lsp_mode.as_ref(), ) .map( @@ -200,7 +194,7 @@ fn parse_in_memory( handler: &Handler, engines: &Engines, src: Arc, - experimental: ExperimentalFlags, + experimental: ExperimentalFeatures, ) -> Result<(lexed::LexedProgram, parsed::ParseProgram), ErrorEmitted> { let mut hasher = DefaultHasher::new(); src.hash(&mut hasher); @@ -256,7 +250,7 @@ fn parse_submodules( module_dir: &Path, build_target: BuildTarget, include_tests: bool, - experimental: ExperimentalFlags, + experimental: ExperimentalFeatures, lsp_mode: Option<&LspConfig>, ) -> Submodules { // Assume the happy path, so there'll be as many submodules as dependencies, but no more. @@ -341,7 +335,7 @@ fn parse_module_tree( module_name: Option<&str>, build_target: BuildTarget, include_tests: bool, - experimental: ExperimentalFlags, + experimental: ExperimentalFeatures, lsp_mode: Option<&LspConfig>, ) -> Result { let query_engine = engines.qe(); @@ -549,6 +543,7 @@ pub fn build_module_dep_graph( pub struct CompiledAsm(pub FinalizedAsm); +#[allow(clippy::too_many_arguments)] pub fn parsed_to_ast( handler: &Handler, engines: &Engines, @@ -557,12 +552,8 @@ pub fn parsed_to_ast( build_config: Option<&BuildConfig>, package_name: &str, retrigger_compilation: Option>, + experimental: ExperimentalFeatures, ) -> Result { - let experimental = build_config - .map(|x| x.experimental) - .unwrap_or(ExperimentalFlags { - new_encoding: false, - }); let lsp_config = build_config.map(|x| x.lsp_mode.clone()).unwrap_or_default(); // Build the dependency graph for the submodules. @@ -582,6 +573,7 @@ pub fn parsed_to_ast( namespace, package_name, build_config, + experimental, ); check_should_abort(handler, retrigger_compilation.clone())?; @@ -661,12 +653,7 @@ pub fn parsed_to_ast( }; // Evaluate const declarations, to allow storage slots initialization with consts. - let mut ctx = Context::new( - engines.se(), - sway_ir::ExperimentalFlags { - new_encoding: experimental.new_encoding, - }, - ); + let mut ctx = Context::new(engines.se(), experimental); let mut md_mgr = MetadataManager::default(); let module = Module::new(&mut ctx, Kind::Contract); if let Err(e) = ir_generation::compile::compile_constants( @@ -721,6 +708,7 @@ pub fn parsed_to_ast( Ok(typed_program_with_storage_slots) } +#[allow(clippy::too_many_arguments)] pub fn compile_to_ast( handler: &Handler, engines: &Engines, @@ -729,6 +717,7 @@ pub fn compile_to_ast( build_config: Option<&BuildConfig>, package_name: &str, retrigger_compilation: Option>, + experimental: ExperimentalFeatures, ) -> Result { check_should_abort(handler, retrigger_compilation.clone())?; @@ -753,7 +742,7 @@ pub fn compile_to_ast( let parse_program_opt = time_expr!( "parse the program to a concrete syntax tree (CST)", "parse_cst", - parse(input, handler, engines, build_config), + parse(input, handler, engines, build_config, experimental), build_config, metrics ); @@ -785,6 +774,7 @@ pub fn compile_to_ast( build_config, package_name, retrigger_compilation.clone(), + experimental ), build_config, metrics @@ -820,6 +810,7 @@ pub fn compile_to_asm( initial_namespace: &mut namespace::Root, build_config: &BuildConfig, package_name: &str, + experimental: ExperimentalFeatures, ) -> Result { let ast_res = compile_to_ast( handler, @@ -829,8 +820,9 @@ pub fn compile_to_asm( Some(build_config), package_name, None, + experimental, )?; - ast_to_asm(handler, engines, &ast_res, build_config) + ast_to_asm(handler, engines, &ast_res, build_config, experimental) } /// Given an AST compilation result, try compiling to a `CompiledAsm`, @@ -840,19 +832,22 @@ pub fn ast_to_asm( engines: &Engines, programs: &Programs, build_config: &BuildConfig, + experimental: ExperimentalFeatures, ) -> Result { let typed_program = match &programs.typed { Ok(typed_program) => typed_program, Err(err) => return Err(*err), }; - let asm = match compile_ast_to_ir_to_asm(handler, engines, typed_program, build_config) { - Ok(res) => res, - Err(err) => { - handler.dedup(); - return Err(err); - } - }; + let asm = + match compile_ast_to_ir_to_asm(handler, engines, typed_program, build_config, experimental) + { + Ok(res) => res, + Err(err) => { + handler.dedup(); + return Err(err); + } + }; Ok(CompiledAsm(asm)) } @@ -861,6 +856,7 @@ pub(crate) fn compile_ast_to_ir_to_asm( engines: &Engines, program: &ty::TyProgram, build_config: &BuildConfig, + experimental: ExperimentalFeatures, ) -> Result { // The IR pipeline relies on type information being fully resolved. // If type information is found to still be generic or unresolved inside of @@ -877,7 +873,7 @@ pub(crate) fn compile_ast_to_ir_to_asm( program, build_config.include_tests, engines, - build_config.experimental, + experimental, ) { Ok(ir) => ir, Err(errors) => { @@ -982,6 +978,7 @@ pub fn compile_to_bytecode( build_config: &BuildConfig, source_map: &mut SourceMap, package_name: &str, + experimental: ExperimentalFeatures, ) -> Result { let asm_res = compile_to_asm( handler, @@ -990,6 +987,7 @@ pub fn compile_to_bytecode( initial_namespace, build_config, package_name, + experimental, )?; asm_to_bytecode(handler, asm_res, source_map, engines.se(), build_config) } @@ -1210,6 +1208,7 @@ fn test_basic_prog() { &handler, &engines, None, + ExperimentalFeatures::default(), ); prog.unwrap(); } @@ -1229,6 +1228,7 @@ fn test_parenthesized() { &handler, &engines, None, + ExperimentalFeatures::default(), ); prog.unwrap(); } @@ -1250,6 +1250,7 @@ fn test_unary_ordering() { &handler, &engines, None, + ExperimentalFeatures::default(), ); let (.., prog) = prog.unwrap(); // this should parse as `(!a) && b`, not `!(a && b)`. So, the top level @@ -1298,6 +1299,7 @@ fn test_parser_recovery() { &handler, &engines, None, + ExperimentalFeatures::default(), ); let (_, _) = prog.unwrap(); assert!(handler.has_errors()); diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs index af790c3d2ed..e27b0425cf2 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs @@ -2899,7 +2899,7 @@ fn check_asm_block_validity( #[cfg(test)] mod tests { use super::*; - use crate::{Engines, ExperimentalFlags}; + use crate::{Engines, ExperimentalFeatures}; use sway_error::type_error::TypeError; use symbol_collection_context::SymbolCollectionContext; @@ -2908,7 +2908,7 @@ mod tests { engines: &Engines, expr: &Expression, type_annotation: TypeId, - experimental: ExperimentalFlags, + experimental: ExperimentalFeatures, ) -> Result { let collection_ctx_ns = Namespace::new(); let mut collection_ctx = SymbolCollectionContext::new(collection_ctx_ns); @@ -2952,9 +2952,7 @@ mod tests { ), None, ), - ExperimentalFlags { - new_encoding: false, - }, + ExperimentalFeatures::default(), )?; expr.type_check_analyze(handler, &mut TypeCheckAnalysisContext::new(&engines))?; Ok(expr) @@ -3094,9 +3092,7 @@ mod tests { ), None, ), - ExperimentalFlags { - new_encoding: false, - }, + ExperimentalFeatures::default(), ); let (errors, warnings) = handler.consume(); assert!(comp_res.is_ok()); diff --git a/sway-core/src/semantic_analysis/namespace/contract_helpers.rs b/sway-core/src/semantic_analysis/namespace/contract_helpers.rs index 822d4262156..af8a84cbac6 100644 --- a/sway-core/src/semantic_analysis/namespace/contract_helpers.rs +++ b/sway-core/src/semantic_analysis/namespace/contract_helpers.rs @@ -29,7 +29,7 @@ pub fn default_with_contract_id( name: Ident, visibility: Visibility, contract_id_value: String, - experimental: crate::ExperimentalFlags, + experimental: crate::ExperimentalFeatures, ) -> Result> { let handler = <_>::default(); default_with_contract_id_inner( @@ -55,7 +55,7 @@ fn default_with_contract_id_inner( ns_name: Ident, visibility: Visibility, contract_id_value: String, - experimental: crate::ExperimentalFlags, + experimental: crate::ExperimentalFeatures, ) -> Result { // it would be nice to one day maintain a span from the manifest file, but // we don't keep that around so we just use the span from the generated const decl instead. diff --git a/sway-core/src/semantic_analysis/program.rs b/sway-core/src/semantic_analysis/program.rs index 581a630d9b6..8a12705d021 100644 --- a/sway-core/src/semantic_analysis/program.rs +++ b/sway-core/src/semantic_analysis/program.rs @@ -11,6 +11,7 @@ use crate::{ BuildConfig, Engines, }; use sway_error::handler::{ErrorEmitted, Handler}; +use sway_features::ExperimentalFeatures; use sway_ir::{Context, Module}; use super::{ @@ -40,6 +41,7 @@ impl TyProgram { /// /// The given `namespace` acts as an initial state for each module within this program. /// It should contain a submodule for each library package dependency. + #[allow(clippy::too_many_arguments)] pub fn type_check( handler: &Handler, engines: &Engines, @@ -48,14 +50,8 @@ impl TyProgram { mut namespace: namespace::Namespace, package_name: &str, build_config: Option<&BuildConfig>, + experimental: ExperimentalFeatures, ) -> Result { - let experimental = - build_config - .map(|x| x.experimental) - .unwrap_or(crate::ExperimentalFlags { - new_encoding: false, - }); - let mut ctx = TypeCheckContext::from_root(&mut namespace, collection_ctx, engines, experimental) .with_kind(parsed.kind); diff --git a/sway-core/src/semantic_analysis/type_check_context.rs b/sway-core/src/semantic_analysis/type_check_context.rs index 455cc21fb4b..a2071b34c84 100644 --- a/sway-core/src/semantic_analysis/type_check_context.rs +++ b/sway-core/src/semantic_analysis/type_check_context.rs @@ -1,7 +1,6 @@ use std::collections::{HashMap, VecDeque}; use crate::{ - build_config::ExperimentalFlags, decl_engine::{DeclEngineGet, DeclRefFunction}, engine_threading::*, language::{ @@ -25,6 +24,7 @@ use sway_error::{ error::CompileError, handler::{ErrorEmitted, Handler}, }; +use sway_features::ExperimentalFeatures; use sway_types::{span::Span, Ident, Spanned}; use super::{ @@ -48,7 +48,7 @@ pub struct TypeCheckContext<'a> { pub(crate) engines: &'a Engines, /// Set of experimental flags. - pub(crate) experimental: ExperimentalFlags, + pub(crate) experimental: ExperimentalFeatures, /// Keeps the accumulated symbols previously collected. pub(crate) collection_ctx: &'a mut SymbolCollectionContext, @@ -117,7 +117,7 @@ impl<'a> TypeCheckContext<'a> { namespace: &'a mut Namespace, collection_ctx: &'a mut SymbolCollectionContext, engines: &'a Engines, - experimental: ExperimentalFlags, + experimental: ExperimentalFeatures, ) -> Self { Self { namespace, @@ -152,7 +152,7 @@ impl<'a> TypeCheckContext<'a> { root_namespace: &'a mut Namespace, collection_ctx: &'a mut SymbolCollectionContext, engines: &'a Engines, - experimental: ExperimentalFlags, + experimental: ExperimentalFeatures, ) -> Self { Self::from_module_namespace(root_namespace, collection_ctx, engines, experimental) } @@ -161,7 +161,7 @@ impl<'a> TypeCheckContext<'a> { namespace: &'a mut Namespace, collection_ctx: &'a mut SymbolCollectionContext, engines: &'a Engines, - experimental: ExperimentalFlags, + experimental: ExperimentalFeatures, ) -> Self { Self { collection_ctx, diff --git a/sway-core/src/transform/attribute.rs b/sway-core/src/transform/attribute.rs index 46d2acde691..d29978205c8 100644 --- a/sway-core/src/transform/attribute.rs +++ b/sway-core/src/transform/attribute.rs @@ -24,8 +24,7 @@ use indexmap::IndexMap; use sway_ast::Literal; use sway_types::{ constants::{ - ALLOW_DEAD_CODE_NAME, ALLOW_DEPRECATED_NAME, CFG_EXPERIMENTAL_NEW_ENCODING, - CFG_PROGRAM_TYPE_ARG_NAME, CFG_TARGET_ARG_NAME, + ALLOW_DEAD_CODE_NAME, ALLOW_DEPRECATED_NAME, CFG_PROGRAM_TYPE_ARG_NAME, CFG_TARGET_ARG_NAME, }, Ident, Span, Spanned, }; @@ -92,11 +91,14 @@ impl AttributeKind { ALLOW_DEAD_CODE_NAME.to_string(), ALLOW_DEPRECATED_NAME.to_string(), ]), - Cfg => Some(vec![ - CFG_TARGET_ARG_NAME.to_string(), - CFG_PROGRAM_TYPE_ARG_NAME.to_string(), - CFG_EXPERIMENTAL_NEW_ENCODING.to_string(), - ]), + Cfg => { + let mut cfgs = vec![ + CFG_TARGET_ARG_NAME.to_string(), + CFG_PROGRAM_TYPE_ARG_NAME.to_string(), + ]; + cfgs.extend(sway_features::CFG.iter().map(|x| x.to_string())); + Some(cfgs) + } } } } diff --git a/sway-core/src/transform/to_parsed_lang/context.rs b/sway-core/src/transform/to_parsed_lang/context.rs index f450eb5257f..efdf030e3ae 100644 --- a/sway-core/src/transform/to_parsed_lang/context.rs +++ b/sway-core/src/transform/to_parsed_lang/context.rs @@ -1,11 +1,12 @@ +use sway_features::ExperimentalFeatures; + use crate::{ - build_config::ExperimentalFlags, language::parsed::{Declaration, TreeType}, BuildTarget, }; pub struct Context { - pub experimental: ExperimentalFlags, + pub experimental: ExperimentalFeatures, /// Indicates whether the module being parsed has a `configurable` block. module_has_configurable_block: bool, @@ -35,7 +36,7 @@ pub struct Context { impl Context { /// Create a new context. - pub fn new(build_target: BuildTarget, experimental: ExperimentalFlags) -> Self { + pub fn new(build_target: BuildTarget, experimental: ExperimentalFeatures) -> Self { Self { build_target, experimental, diff --git a/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs b/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs index b48cce083eb..eda5d23a533 100644 --- a/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs +++ b/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs @@ -7,7 +7,7 @@ use crate::{ language::{parsed::*, *}, transform::{attribute::*, to_parsed_lang::context::Context}, type_system::*, - BuildTarget, Engines, ExperimentalFlags, + BuildTarget, Engines, }; use indexmap::IndexMap; @@ -29,14 +29,14 @@ use sway_ast::{ use sway_error::handler::{ErrorEmitted, Handler}; use sway_error::warning::{CompileWarning, Warning}; use sway_error::{convert_parse_tree_error::ConvertParseTreeError, error::CompileError}; +use sway_features::ExperimentalFeatures; use sway_types::{ constants::{ - ALLOW_ATTRIBUTE_NAME, CFG_ATTRIBUTE_NAME, CFG_EXPERIMENTAL_NEW_ENCODING, - CFG_PROGRAM_TYPE_ARG_NAME, CFG_TARGET_ARG_NAME, DEPRECATED_ATTRIBUTE_NAME, - DOC_ATTRIBUTE_NAME, DOC_COMMENT_ATTRIBUTE_NAME, FALLBACK_ATTRIBUTE_NAME, - INLINE_ATTRIBUTE_NAME, PAYABLE_ATTRIBUTE_NAME, STORAGE_PURITY_ATTRIBUTE_NAME, - STORAGE_PURITY_READ_NAME, STORAGE_PURITY_WRITE_NAME, TEST_ATTRIBUTE_NAME, - VALID_ATTRIBUTE_NAMES, + ALLOW_ATTRIBUTE_NAME, CFG_ATTRIBUTE_NAME, CFG_PROGRAM_TYPE_ARG_NAME, CFG_TARGET_ARG_NAME, + DEPRECATED_ATTRIBUTE_NAME, DOC_ATTRIBUTE_NAME, DOC_COMMENT_ATTRIBUTE_NAME, + FALLBACK_ATTRIBUTE_NAME, INLINE_ATTRIBUTE_NAME, PAYABLE_ATTRIBUTE_NAME, + STORAGE_PURITY_ATTRIBUTE_NAME, STORAGE_PURITY_READ_NAME, STORAGE_PURITY_WRITE_NAME, + TEST_ATTRIBUTE_NAME, VALID_ATTRIBUTE_NAMES, }, integer_bits::IntegerBits, BaseIdent, @@ -4862,7 +4862,7 @@ pub fn cfg_eval( context: &Context, handler: &Handler, attrs_map: &AttributesMap, - experimental: ExperimentalFlags, + experimental: ExperimentalFeatures, ) -> Result { if let Some(cfg_attrs) = attrs_map.get(&AttributeKind::Cfg) { for cfg_attr in cfg_attrs { @@ -4928,19 +4928,28 @@ pub fn cfg_eval( return Err(handler.emit_err(error.into())); } } - CFG_EXPERIMENTAL_NEW_ENCODING => match &arg.value { - Some(sway_ast::Literal::Bool(v)) => { - let is_true = matches!(v.kind, sway_ast::literal::LitBoolType::True); - return Ok(experimental.new_encoding == is_true); - } - _ => { - let error = - ConvertParseTreeError::ExpectedExperimentalNewEncodingArgValue { - span: arg.span(), - }; - return Err(handler.emit_err(error.into())); + // Check if this is a known experimental feature + cfg_experimental + if sway_features::CFG.iter().any(|x| *x == cfg_experimental) => + { + match &arg.value { + Some(sway_ast::Literal::Bool(v)) => { + let is_true = + matches!(v.kind, sway_ast::literal::LitBoolType::True); + return Ok(experimental + .is_enabled_for_cfg(cfg_experimental) + .unwrap() + == is_true); + } + _ => { + let error = + ConvertParseTreeError::UnexpectedValueForCfgExperimental { + span: arg.span(), + }; + return Err(handler.emit_err(error.into())); + } } - }, + } _ => { return Err(handler.emit_err( ConvertParseTreeError::InvalidCfgArg { diff --git a/sway-core/src/types/collect_types_metadata.rs b/sway-core/src/types/collect_types_metadata.rs index 7f535787f9a..6e5fff30385 100644 --- a/sway-core/src/types/collect_types_metadata.rs +++ b/sway-core/src/types/collect_types_metadata.rs @@ -8,9 +8,10 @@ use std::{ sync::{Arc, Mutex}, }; -use crate::{type_system::TypeId, Engines, ExperimentalFlags}; +use crate::{type_system::TypeId, Engines}; use sha2::{Digest, Sha256}; use sway_error::handler::{ErrorEmitted, Handler}; +use sway_features::ExperimentalFeatures; use sway_types::{Ident, Span}; /// If any types contained by this node are unresolved or have yet to be inferred, throw an @@ -69,7 +70,7 @@ pub struct CollectTypesMetadataContext<'cx> { pub(crate) program_name: String, - pub experimental: ExperimentalFlags, + pub experimental: ExperimentalFeatures, } impl<'cx> CollectTypesMetadataContext<'cx> { @@ -111,7 +112,7 @@ impl<'cx> CollectTypesMetadataContext<'cx> { pub fn new( engines: &'cx Engines, - experimental: ExperimentalFlags, + experimental: ExperimentalFeatures, program_name: String, ) -> Self { let mut ctx = Self { diff --git a/sway-error/src/convert_parse_tree_error.rs b/sway-error/src/convert_parse_tree_error.rs index 6c909e2016e..8b8a96528a0 100644 --- a/sway-error/src/convert_parse_tree_error.rs +++ b/sway-error/src/convert_parse_tree_error.rs @@ -117,8 +117,8 @@ pub enum ConvertParseTreeError { InvalidCfgProgramTypeArgValue { span: Span, value: String }, #[error("Expected a value for the program_type argument")] ExpectedCfgProgramTypeArgValue { span: Span }, - #[error("Expected \"true\" or \"false\" for experimental_new_encoding")] - ExpectedExperimentalNewEncodingArgValue { span: Span }, + #[error("Expected \"true\" or \"false\" for experimental conditional compilation")] + UnexpectedValueForCfgExperimental { span: Span }, #[error("Unexpected attribute value: \"{value}\" for attribute: \"cfg\"")] InvalidCfgArg { span: Span, value: String }, } @@ -183,7 +183,7 @@ impl Spanned for ConvertParseTreeError { ConvertParseTreeError::ExpectedCfgTargetArgValue { span } => span.clone(), ConvertParseTreeError::InvalidCfgProgramTypeArgValue { span, .. } => span.clone(), ConvertParseTreeError::ExpectedCfgProgramTypeArgValue { span } => span.clone(), - ConvertParseTreeError::ExpectedExperimentalNewEncodingArgValue { span } => span.clone(), + ConvertParseTreeError::UnexpectedValueForCfgExperimental { span } => span.clone(), ConvertParseTreeError::InvalidCfgArg { span, .. } => span.clone(), } } diff --git a/sway-features/Cargo.toml b/sway-features/Cargo.toml new file mode 100644 index 00000000000..2c2ed28f414 --- /dev/null +++ b/sway-features/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "sway-features" +description = "Sway's experimental features" +version.workspace = true +authors.workspace = true +edition.workspace = true +homepage.workspace = true +license.workspace = true +repository.workspace = true + +[dependencies] +clap = { workspace = true, features = ["derive"] } +paste.workspace = true diff --git a/sway-features/src/lib.rs b/sway-features/src/lib.rs new file mode 100644 index 00000000000..55d50920891 --- /dev/null +++ b/sway-features/src/lib.rs @@ -0,0 +1,245 @@ +use std::collections::HashMap; + +use clap::{Parser, ValueEnum}; + +macro_rules! features { + ($($name:ident = $enabled:literal, $url:literal),* $(,)?) => { + paste::paste! { + pub const CFG: &[&str] = &[ + $( + stringify!([]), + )* + ]; + + #[derive(Copy, Clone, Debug, ValueEnum)] + #[value(rename_all = "snake")] + pub enum Feature { + $( + [<$name:camel>], + )* + } + + impl std::str::FromStr for Feature { + type Err = Error; + + fn from_str(s: &str) -> Result { + match s { + $( + stringify!([<$name:snake>]) => { + Ok(Self::[<$name:camel>]) + }, + )* + _ => Err(Error::UnknownFeature(s.to_string())), + } + } + } + + #[derive(Copy, Clone, Debug, PartialEq, Eq)] + pub struct ExperimentalFeatures { + $( + pub [<$name:snake>]: bool, + )* + } + + impl std::default::Default for ExperimentalFeatures { + fn default() -> Self { + Self { + $( + [<$name:snake>]: $enabled, + )* + } + } + } + + impl ExperimentalFeatures { + pub fn set_enabled_by_name(&mut self, feature: &str, enabled: bool) -> Result<(), Error> { + let feature = feature.trim(); + match feature { + $( + stringify!([<$name:snake>]) => { + self.[<$name:snake>] = enabled; + Ok(()) + }, + )* + "" => Ok(()), + _ => Err(Error::UnknownFeature(feature.to_string())), + } + } + + pub fn set_enabled(&mut self, feature: Feature, enabled: bool) { + match feature { + $( + Feature::[<$name:camel>] => { + self.[<$name:snake>] = enabled + }, + )* + } + } + + /// Used for testing if a `#[cfg(...)]` feature is enabled. + /// Already prepends "experimental_" to the feature name. + pub fn is_enabled_for_cfg(&self, cfg: &str) -> Result { + match cfg { + $( + stringify!([]) => Ok(self.[<$name:snake>]), + )* + _ => Err(Error::UnknownFeature(cfg.to_string())) + } + } + + $( + pub fn [](mut self, enabled: bool) -> Self { + self.[<$name:snake>] = enabled; + self + } + )* + } + } + }; +} + +impl ExperimentalFeatures { + /// Experimental features will be applied in the following order: + /// 1 - manifest (no specific order) + /// 2 - cli_no_experimental + /// 3 - cli_experimental + /// 4 - FORC_NO_EXPERIMENTAL (env var) + /// 5 - FORC_EXPERIMENTAL (env var) + pub fn new( + manifest: &HashMap, + cli_experimental: &[Feature], + cli_no_experimental: &[Feature], + ) -> Result { + let mut experimental = ExperimentalFeatures::default(); + + experimental.parse_from_package_manifest(manifest)?; + + for f in cli_no_experimental { + experimental.set_enabled(*f, false); + } + + for f in cli_experimental { + experimental.set_enabled(*f, true); + } + + experimental.parse_from_environment_variables()?; + + Ok(experimental) + } +} + +features! { + new_encoding = true, + "https://github.com/FuelLabs/sway/issues/5727", +} + +#[derive(Clone, Debug, Default, Parser)] +pub struct CliFields { + /// Comma separated list of all experimental features that will be enabled + #[clap(long, value_delimiter = ',')] + pub experimental: Vec, + + /// Comma separated list of all experimental features that will be disabled + #[clap(long, value_delimiter = ',')] + pub no_experimental: Vec, +} + +#[derive(Debug)] +pub enum Error { + ParseError(String), + UnknownFeature(String), +} + +impl std::fmt::Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Error::ParseError(feature) => f.write_fmt(format_args!( + "Experimental feature \"{feature}\" cannot be parsed." + )), + Error::UnknownFeature(feature) => { + f.write_fmt(format_args!("Unknown experimental feature: \"{feature}\".")) + } + } + } +} + +impl ExperimentalFeatures { + pub fn parse_from_package_manifest( + &mut self, + experimental: &std::collections::HashMap, + ) -> Result<(), Error> { + for (feature, enabled) in experimental { + self.set_enabled_by_name(feature, *enabled)?; + } + Ok(()) + } + + /// Enable and disable features using comma separated feature names from + /// environment variables "FORC_EXPERIMENTAL" and "FORC_NO_EXPERIMENTAL". + pub fn parse_from_environment_variables(&mut self) -> Result<(), Error> { + if let Ok(features) = std::env::var("FORC_NO_EXPERIMENTAL") { + self.parse_comma_separated_list(&features, false)?; + } + + if let Ok(features) = std::env::var("FORC_EXPERIMENTAL") { + self.parse_comma_separated_list(&features, true)?; + } + + Ok(()) + } + + pub fn parse_comma_separated_list( + &mut self, + features: impl AsRef, + enabled: bool, + ) -> Result<(), Error> { + for feature in features.as_ref().split(',') { + self.set_enabled_by_name(feature, enabled)?; + } + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + struct RollbackEnvVar(String, Option); + + impl RollbackEnvVar { + pub fn new(name: &str) -> Self { + let old = std::env::var(name).ok(); + RollbackEnvVar(name.to_string(), old) + } + } + + impl Drop for RollbackEnvVar { + fn drop(&mut self) { + if let Some(old) = self.1.take() { + std::env::set_var(&self.0, old); + } + } + } + + #[test] + fn ok_parse_experimental_features() { + let _old = RollbackEnvVar::new("FORC_EXPERIMENTAL"); + let _old = RollbackEnvVar::new("FORC_NO_EXPERIMENTAL"); + + let mut features = ExperimentalFeatures { + new_encoding: false, + }; + + std::env::set_var("FORC_EXPERIMENTAL", "new_encoding"); + std::env::set_var("FORC_NO_EXPERIMENTAL", ""); + assert!(!features.new_encoding); + let _ = features.parse_from_environment_variables(); + assert!(features.new_encoding); + + std::env::set_var("FORC_EXPERIMENTAL", ""); + std::env::set_var("FORC_NO_EXPERIMENTAL", "new_encoding"); + assert!(features.new_encoding); + let _ = features.parse_from_environment_variables(); + assert!(!features.new_encoding); + } +} diff --git a/sway-ir/Cargo.toml b/sway-ir/Cargo.toml index a3c4b58f722..331302af16b 100644 --- a/sway-ir/Cargo.toml +++ b/sway-ir/Cargo.toml @@ -19,6 +19,7 @@ peg.workspace = true prettydiff.workspace = true rustc-hash.workspace = true slotmap.workspace = true +sway-features.workspace = true sway-ir-macros.workspace = true sway-types.workspace = true sway-utils.workspace = true diff --git a/sway-ir/src/bin/opt.rs b/sway-ir/src/bin/opt.rs index a687f3a2cd5..4615849a55e 100644 --- a/sway-ir/src/bin/opt.rs +++ b/sway-ir/src/bin/opt.rs @@ -4,9 +4,10 @@ use std::{ }; use anyhow::anyhow; +use sway_features::ExperimentalFeatures; use sway_ir::{ - insert_after_each, register_known_passes, ExperimentalFlags, PassGroup, PassManager, - MODULE_PRINTER_NAME, MODULE_VERIFIER_NAME, + insert_after_each, register_known_passes, PassGroup, PassManager, MODULE_PRINTER_NAME, + MODULE_VERIFIER_NAME, }; use sway_types::SourceEngine; @@ -26,13 +27,8 @@ fn main() -> Result<(), anyhow::Error> { let source_engine = SourceEngine::default(); // Parse it. XXX Improve this error message too. - let mut ir = sway_ir::parser::parse( - &input_str, - &source_engine, - ExperimentalFlags { - new_encoding: false, - }, - )?; + let mut ir = + sway_ir::parser::parse(&input_str, &source_engine, ExperimentalFeatures::default())?; // Perform optimisation passes in order. let mut passes = PassGroup::default(); diff --git a/sway-ir/src/context.rs b/sway-ir/src/context.rs index aae892bff79..a9e707336fd 100644 --- a/sway-ir/src/context.rs +++ b/sway-ir/src/context.rs @@ -8,6 +8,7 @@ use rustc_hash::FxHashMap; use slotmap::{DefaultKey, SlotMap}; +use sway_features::ExperimentalFeatures; use sway_types::SourceEngine; use crate::{ @@ -40,16 +41,11 @@ pub struct Context<'eng> { next_unique_sym_tag: u64, - pub experimental: ExperimentalFlags, -} - -#[derive(Copy, Clone)] -pub struct ExperimentalFlags { - pub new_encoding: bool, + pub experimental: ExperimentalFeatures, } impl<'eng> Context<'eng> { - pub fn new(source_engine: &'eng SourceEngine, experimental: ExperimentalFlags) -> Self { + pub fn new(source_engine: &'eng SourceEngine, experimental: ExperimentalFeatures) -> Self { let mut def = Self { source_engine, modules: Default::default(), diff --git a/sway-ir/src/irtype.rs b/sway-ir/src/irtype.rs index 1211c1da6fe..1771ca954bc 100644 --- a/sway-ir/src/irtype.rs +++ b/sway-ir/src/irtype.rs @@ -691,8 +691,9 @@ mod tests { /// Unit tests in this module document and assert decisions on memory layout. mod memory_layout { use super::*; - use crate::{Context, ExperimentalFlags}; + use crate::Context; use once_cell::sync::Lazy; + use sway_features::ExperimentalFeatures; use sway_types::SourceEngine; #[test] @@ -975,12 +976,7 @@ mod tests { static SOURCE_ENGINE: Lazy = Lazy::new(SourceEngine::default); fn create_context() -> Context<'static> { - Context::new( - &SOURCE_ENGINE, - ExperimentalFlags { - new_encoding: false, - }, - ) + Context::new(&SOURCE_ENGINE, ExperimentalFeatures::default()) } /// Creates sample types that are not aggregates and do not point to diff --git a/sway-ir/src/optimize.rs b/sway-ir/src/optimize.rs index 564002fff13..299c51c0332 100644 --- a/sway-ir/src/optimize.rs +++ b/sway-ir/src/optimize.rs @@ -46,7 +46,8 @@ mod target_fuel; #[cfg(test)] pub mod tests { - use crate::{ExperimentalFlags, PassGroup, PassManager}; + use crate::{PassGroup, PassManager}; + use sway_features::ExperimentalFeatures; use sway_types::SourceEngine; /// This function parses the IR text representation and run the specified optimizers passes. @@ -85,9 +86,7 @@ pub mod tests { " ), &source_engine, - ExperimentalFlags { - new_encoding: false, - }, + ExperimentalFeatures::default(), ) .unwrap(); diff --git a/sway-ir/src/parser.rs b/sway-ir/src/parser.rs index bb77348cf81..fb577d05e15 100644 --- a/sway-ir/src/parser.rs +++ b/sway-ir/src/parser.rs @@ -1,15 +1,16 @@ //! A parser for the printed IR, useful mostly for testing. +use sway_features::ExperimentalFeatures; use sway_types::SourceEngine; -use crate::{context::Context, error::IrError, ExperimentalFlags}; +use crate::{context::Context, error::IrError}; // ------------------------------------------------------------------------------------------------- /// Parse a string produced by [`crate::printer::to_string`] into a new [`Context`]. pub fn parse<'eng>( input: &str, source_engine: &'eng SourceEngine, - experimental: ExperimentalFlags, + experimental: ExperimentalFeatures, ) -> Result, IrError> { let irmod = ir_builder::parser::ir_descrs(input).map_err(|err| { let found = if input.len() - err.location.offset <= 20 { @@ -26,6 +27,7 @@ pub fn parse<'eng>( mod ir_builder { use slotmap::KeyData; + use sway_features::ExperimentalFeatures; use sway_types::{ident::Ident, span::Span, u256::U256, SourceEngine}; type MdIdxRef = u64; @@ -686,8 +688,7 @@ mod ir_builder { metadata::{MetadataIndex, Metadatum}, module::{Kind, Module}, value::Value, - BinaryOpKind, BlockArgument, ConfigContent, ExperimentalFlags, Instruction, UnaryOpKind, - B256, + BinaryOpKind, BlockArgument, ConfigContent, Instruction, UnaryOpKind, B256, }; #[derive(Debug)] @@ -961,7 +962,7 @@ mod ir_builder { pub(super) fn build_context( ir_ast_mod: IrAstModule, source_engine: &SourceEngine, - experimental: ExperimentalFlags, + experimental: ExperimentalFeatures, ) -> Result { let mut ctx = Context::new(source_engine, experimental); let md_map = build_metadata_map(&mut ctx, ir_ast_mod.metadata); diff --git a/sway-ir/tests/tests.rs b/sway-ir/tests/tests.rs index 197d67d400e..743b3523977 100644 --- a/sway-ir/tests/tests.rs +++ b/sway-ir/tests/tests.rs @@ -1,15 +1,16 @@ use std::path::PathBuf; use itertools::Itertools; +use sway_features::ExperimentalFeatures; use sway_ir::{ create_arg_demotion_pass, create_ccp_pass, create_const_demotion_pass, create_const_folding_pass, create_cse_pass, create_dce_pass, create_dom_fronts_pass, create_dominators_pass, create_escaped_symbols_pass, create_mem2reg_pass, create_memcpyopt_pass, create_misc_demotion_pass, create_postorder_pass, create_ret_demotion_pass, create_simplify_cfg_pass, metadata_to_inline, optimize as opt, - register_known_passes, Context, ExperimentalFlags, Function, IrError, PassGroup, PassManager, - Value, DCE_NAME, FN_DCE_NAME, FN_DEDUP_DEBUG_PROFILE_NAME, FN_DEDUP_RELEASE_PROFILE_NAME, - MEM2REG_NAME, SROA_NAME, + register_known_passes, Context, Function, IrError, PassGroup, PassManager, Value, DCE_NAME, + FN_DCE_NAME, FN_DEDUP_DEBUG_PROFILE_NAME, FN_DEDUP_RELEASE_PROFILE_NAME, MEM2REG_NAME, + SROA_NAME, }; use sway_types::SourceEngine; @@ -26,17 +27,16 @@ fn run_tests bool>(sub_dir: &str, opt_fn: F) { let input_bytes = std::fs::read(&path).unwrap(); let input = String::from_utf8_lossy(&input_bytes); - let mut ir = sway_ir::parser::parse( - &input, - &source_engine, - ExperimentalFlags { - new_encoding: false, + let experimental = ExperimentalFeatures { + new_encoding: false, + }; + + let mut ir = sway_ir::parser::parse(&input, &source_engine, experimental).unwrap_or_else( + |parse_err| { + println!("{}: {parse_err}", path.display()); + panic!() }, - ) - .unwrap_or_else(|parse_err| { - println!("{}: {parse_err}", path.display()); - panic!() - }); + ); let first_line = input.split('\n').next().unwrap(); @@ -122,13 +122,8 @@ fn run_ir_verifier_tests(sub_dir: &str) { } }; - let parse_result = sway_ir::parser::parse( - &input, - &source_engine, - ExperimentalFlags { - new_encoding: false, - }, - ); + let parse_result = + sway_ir::parser::parse(&input, &source_engine, ExperimentalFeatures::default()); match parse_result { Ok(_) => { diff --git a/sway-lsp/Cargo.toml b/sway-lsp/Cargo.toml index f9648768eb5..20e1f3f646c 100644 --- a/sway-lsp/Cargo.toml +++ b/sway-lsp/Cargo.toml @@ -30,6 +30,7 @@ serde_json.workspace = true sway-ast.workspace = true sway-core.workspace = true sway-error.workspace = true +sway-features.workspace = true sway-parse.workspace = true sway-types.workspace = true sway-utils.workspace = true diff --git a/sway-lsp/benches/lsp_benchmarks/compile.rs b/sway-lsp/benches/lsp_benchmarks/compile.rs index 315d562b55a..7668d69f246 100644 --- a/sway-lsp/benches/lsp_benchmarks/compile.rs +++ b/sway-lsp/benches/lsp_benchmarks/compile.rs @@ -1,6 +1,6 @@ use codspeed_criterion_compat::{black_box, criterion_group, Criterion}; use std::sync::Arc; -use sway_core::{Engines, ExperimentalFlags}; +use sway_core::Engines; use sway_lsp::core::session; use tokio::runtime::Runtime; @@ -21,25 +21,19 @@ fn benchmarks(c: &mut Criterion) { file_versions: Default::default(), }); - let experimental = ExperimentalFlags { - new_encoding: false, - }; - c.bench_function("compile", |b| { b.iter(|| { let engines = Engines::default(); let _ = black_box( - session::compile(&build_plan, &engines, None, lsp_mode.as_ref(), experimental) - .unwrap(), + session::compile(&build_plan, &engines, None, lsp_mode.as_ref()).unwrap(), ); }) }); c.bench_function("traverse", |b| { let engines = Engines::default(); - let results = black_box( - session::compile(&build_plan, &engines, None, lsp_mode.as_ref(), experimental).unwrap(), - ); + let results = + black_box(session::compile(&build_plan, &engines, None, lsp_mode.as_ref()).unwrap()); let session = Arc::new(session::Session::new()); b.iter(|| { let _ = black_box( @@ -60,8 +54,7 @@ fn benchmarks(c: &mut Criterion) { b.iter(|| { for _ in 0..NUM_DID_CHANGE_ITERATIONS { let _ = black_box( - session::compile(&build_plan, &engines, None, lsp_mode.as_ref(), experimental) - .unwrap(), + session::compile(&build_plan, &engines, None, lsp_mode.as_ref()).unwrap(), ); } }) diff --git a/sway-lsp/benches/lsp_benchmarks/mod.rs b/sway-lsp/benches/lsp_benchmarks/mod.rs index d8847eda1c3..5e5ed0c93cf 100644 --- a/sway-lsp/benches/lsp_benchmarks/mod.rs +++ b/sway-lsp/benches/lsp_benchmarks/mod.rs @@ -4,16 +4,12 @@ pub mod token_map; use lsp_types::Url; use std::{path::PathBuf, sync::Arc}; -use sway_core::ExperimentalFlags; use sway_lsp::core::{ document::Documents, session::{self, Session}, }; pub async fn compile_test_project() -> (Url, Arc, Documents) { - let experimental = ExperimentalFlags { - new_encoding: false, - }; let session = Arc::new(Session::new()); let documents = Documents::new(); let lsp_mode = Some(sway_core::LspConfig { @@ -30,7 +26,6 @@ pub async fn compile_test_project() -> (Url, Arc, Documents) { None, lsp_mode, session.clone(), - experimental, ) .unwrap(); (uri, session, documents) diff --git a/sway-lsp/src/core/session.rs b/sway-lsp/src/core/session.rs index c55869d5f66..fe5d59a8c9f 100644 --- a/sway-lsp/src/core/session.rs +++ b/sway-lsp/src/core/session.rs @@ -298,7 +298,6 @@ pub fn compile( engines: &Engines, retrigger_compilation: Option>, lsp_mode: Option<&LspConfig>, - experimental: sway_core::ExperimentalFlags, ) -> Result, Handler)>, LanguageServerError> { let _p = tracing::trace_span!("compile").entered(); pkg::check( @@ -309,7 +308,8 @@ pub fn compile( true, engines, retrigger_compilation, - experimental, + &[], + &[sway_features::Feature::NewEncoding], ) .map_err(LanguageServerError::FailedToCompile) } @@ -442,7 +442,6 @@ pub fn parse_project( retrigger_compilation: Option>, lsp_mode: Option, session: Arc, - experimental: sway_core::ExperimentalFlags, ) -> Result<(), LanguageServerError> { let _p = tracing::trace_span!("parse_project").entered(); let build_plan = session @@ -454,7 +453,6 @@ pub fn parse_project( engines, retrigger_compilation, lsp_mode.as_ref(), - experimental, )?; // Check if the last result is None or if results is empty, indicating an error occurred in the compiler. @@ -716,17 +714,8 @@ mod tests { let uri = get_url(&dir); let engines = Engines::default(); let session = Arc::new(Session::new()); - let result = parse_project( - &uri, - &engines, - None, - None, - session, - sway_core::ExperimentalFlags { - new_encoding: false, - }, - ) - .expect_err("expected ManifestFileNotFound"); + let result = parse_project(&uri, &engines, None, None, session) + .expect_err("expected ManifestFileNotFound"); assert!(matches!( result, LanguageServerError::DocumentError( diff --git a/sway-lsp/src/handlers/notification.rs b/sway-lsp/src/handlers/notification.rs index 7c7dfddf7cc..5298869216d 100644 --- a/sway-lsp/src/handlers/notification.rs +++ b/sway-lsp/src/handlers/notification.rs @@ -39,7 +39,6 @@ pub async fn handle_did_open_text_document( file_versions: BTreeMap::new(), })); state.is_compiling.store(true, Ordering::SeqCst); - state.wait_for_parsing().await; state .publish_diagnostics(uri, params.text_document.uri, session) diff --git a/sway-lsp/src/server_state.rs b/sway-lsp/src/server_state.rs index 2c39abddeac..5e2a227f3f5 100644 --- a/sway-lsp/src/server_state.rs +++ b/sway-lsp/src/server_state.rs @@ -126,16 +126,17 @@ impl ServerState { let finished_compilation = self.finished_compilation.clone(); let rx = self.cb_rx.clone(); let last_compilation_state = self.last_compilation_state.clone(); - let experimental = sway_core::ExperimentalFlags { - new_encoding: false, - }; std::thread::spawn(move || { while let Ok(msg) = rx.recv() { match msg { TaskMessage::CompilationContext(ctx) => { + dbg!(); let uri = ctx.uri.as_ref().unwrap().clone(); + dbg!(); let session = ctx.session.as_ref().unwrap().clone(); + dbg!(); let mut engines_clone = session.engines.read().clone(); + dbg!(); // Perform garbage collection if enabled to manage memory usage. if ctx.gc_options.gc_enabled { @@ -150,20 +151,22 @@ impl ServerState { ); } } - + dbg!(); let lsp_mode = Some(LspConfig { optimized_build: ctx.optimized_build, file_versions: ctx.file_versions, }); + + dbg!(); // Set the is_compiling flag to true so that the wait_for_parsing function knows that we are compiling is_compiling.store(true, Ordering::SeqCst); + dbg!(); match session::parse_project( &uri, &engines_clone, Some(retrigger_compilation.clone()), lsp_mode, session.clone(), - experimental, ) { Ok(()) => { let path = uri.to_file_path().unwrap(); @@ -199,21 +202,26 @@ impl ServerState { } } Err(_err) => { + dbg!(_err); *last_compilation_state.write() = LastCompilationState::Failed; } } + dbg!(); // Reset the flags to false is_compiling.store(false, Ordering::SeqCst); retrigger_compilation.store(false, Ordering::SeqCst); + dbg!(); // Make sure there isn't any pending compilation work if rx.is_empty() { // finished compilation, notify waiters finished_compilation.notify_waiters(); } + dbg!(); } TaskMessage::Terminate => { + dbg!(); // If we receive a terminate message, we need to exit the thread return; } @@ -297,6 +305,7 @@ impl ServerState { session: Arc, ) { let diagnostics = self.diagnostics(&uri, session.clone()); + dbg!(&diagnostics); // Note: Even if the computed diagnostics vec is empty, we still have to push the empty Vec // in order to clear former diagnostics. Newly pushed diagnostics always replace previously pushed diagnostics. if let Some(client) = self.client.as_ref() { diff --git a/sway-types/src/constants.rs b/sway-types/src/constants.rs index 7d1cc136cef..01a3199cb1e 100644 --- a/sway-types/src/constants.rs +++ b/sway-types/src/constants.rs @@ -49,7 +49,6 @@ pub const ALLOW_DEPRECATED_NAME: &str = "deprecated"; pub const CFG_ATTRIBUTE_NAME: &str = "cfg"; pub const CFG_TARGET_ARG_NAME: &str = "target"; pub const CFG_PROGRAM_TYPE_ARG_NAME: &str = "program_type"; -pub const CFG_EXPERIMENTAL_NEW_ENCODING: &str = "experimental_new_encoding"; pub const DEPRECATED_ATTRIBUTE_NAME: &str = "deprecated"; diff --git a/test/Cargo.toml b/test/Cargo.toml index 3854b55f458..809116ad79f 100644 --- a/test/Cargo.toml +++ b/test/Cargo.toml @@ -24,7 +24,7 @@ glob.workspace = true hex.workspace = true insta.workspace = true libtest-mimic.workspace = true -normalize-path = "0.2.1" +normalize-path.workspace = true prettydiff.workspace = true rand.workspace = true regex.workspace = true @@ -32,6 +32,7 @@ revm.workspace = true serde_json.workspace = true sway-core.workspace = true sway-error.workspace = true +sway-features.workspace = true sway-ir.workspace = true sway-types.workspace = true sway-utils.workspace = true diff --git a/test/src/e2e_vm_tests/harness.rs b/test/src/e2e_vm_tests/harness.rs index 6168b1f4236..164d442e7bf 100644 --- a/test/src/e2e_vm_tests/harness.rs +++ b/test/src/e2e_vm_tests/harness.rs @@ -1,3 +1,4 @@ +use super::RunConfig; use anyhow::{anyhow, bail, Result}; use colored::Colorize; use forc_client::{ @@ -5,9 +6,7 @@ use forc_client::{ op::{deploy, run, DeployedPackage}, NodeTarget, }; -use forc_pkg::{ - manifest::build_profile::ExperimentalFlags, BuildProfile, Built, BuiltPackage, PrintOpts, -}; +use forc_pkg::{BuildProfile, Built, BuiltPackage, PrintOpts}; use fuel_tx::TransactionBuilder; use fuel_vm::fuel_tx::{self, consensus_parameters::ConsensusParametersV1}; use fuel_vm::interpreter::Interpreter; @@ -20,8 +19,6 @@ use regex::{Captures, Regex}; use std::{fs, io::Read, path::PathBuf, str::FromStr}; use sway_core::{asm_generation::ProgramABI, BuildTarget}; -use super::RunConfig; - pub const NODE_URL: &str = "http://127.0.0.1:4000"; pub const SECRET_KEY: &str = "de97d8624a438121b86a1956544bd72ed68cd69f2c99555b08b1e8c51ffd511c"; @@ -82,7 +79,7 @@ pub(crate) async fn deploy_contract(file_name: &str, run_config: &RunConfig) -> true => BuildProfile::RELEASE.to_string(), false => BuildProfile::DEBUG.to_string(), }, - no_encoding_v1: !run_config.experimental.new_encoding, + experimental: run_config.experimental.clone(), ..Default::default() }) .await?; @@ -132,7 +129,7 @@ pub(crate) async fn runs_on_node( }, contract: Some(contracts), signing_key: Some(SecretKey::from_str(SECRET_KEY).unwrap()), - no_encoding_v1: !run_config.experimental.new_encoding, + experimental: run_config.experimental.clone(), ..Default::default() }; run(command).await.map(|ran_scripts| { @@ -261,6 +258,7 @@ pub(crate) fn runs_in_vm( /// Returns a tuple with the result of the compilation, as well as the output. pub(crate) async fn compile_to_bytes(file_name: &str, run_config: &RunConfig) -> Result { println!("Compiling {} ...", file_name.bold()); + let manifest_dir = env!("CARGO_MANIFEST_DIR"); let build_opts = forc_pkg::BuildOpts { build_target: run_config.build_target, @@ -284,9 +282,8 @@ pub(crate) async fn compile_to_bytes(file_name: &str, run_config: &RunConfig) -> terse: false, ..Default::default() }, - experimental: ExperimentalFlags { - new_encoding: run_config.experimental.new_encoding, - }, + experimental: run_config.experimental.experimental.clone(), + no_experimental: run_config.experimental.no_experimental.clone(), ..Default::default() }; match std::panic::catch_unwind(|| forc_pkg::build_with_options(&build_opts)) { @@ -329,9 +326,8 @@ pub(crate) async fn compile_and_run_unit_tests( terse: !(capture_output || run_config.verbose), ..Default::default() }, - experimental: ExperimentalFlags { - new_encoding: run_config.experimental.new_encoding, - }, + experimental: run_config.experimental.experimental.clone(), + no_experimental: run_config.experimental.no_experimental.clone(), ..Default::default() }) }) { @@ -355,19 +351,40 @@ pub(crate) fn test_json_abi( built_package: &BuiltPackage, experimental_new_encoding: bool, update_output_files: bool, + suffix: &Option, + has_experimental_field: bool, ) -> Result<()> { emit_json_abi(file_name, built_package)?; let manifest_dir = env!("CARGO_MANIFEST_DIR"); - let oracle_path = if experimental_new_encoding { - format!( - "{}/src/e2e_vm_tests/test_programs/{}/{}", - manifest_dir, file_name, "json_abi_oracle_new_encoding.json" - ) - } else { - format!( - "{}/src/e2e_vm_tests/test_programs/{}/{}", - manifest_dir, file_name, "json_abi_oracle.json" - ) + + let oracle_path = match (has_experimental_field, experimental_new_encoding) { + (true, _) => { + format!( + "{}/src/e2e_vm_tests/test_programs/{}/json_abi_oracle.{}json", + manifest_dir, + file_name, + suffix + .as_ref() + .unwrap() + .strip_prefix("test") + .unwrap() + .strip_suffix("toml") + .unwrap() + .trim_start_matches('.') + ) + } + (false, true) => { + format!( + "{}/src/e2e_vm_tests/test_programs/{}/{}", + manifest_dir, file_name, "json_abi_oracle_new_encoding.json" + ) + } + (false, false) => { + format!( + "{}/src/e2e_vm_tests/test_programs/{}/{}", + manifest_dir, file_name, "json_abi_oracle.json" + ) + } }; let output_path = format!( diff --git a/test/src/e2e_vm_tests/mod.rs b/test/src/e2e_vm_tests/mod.rs index 7eaca4d658b..62dc360fea1 100644 --- a/test/src/e2e_vm_tests/mod.rs +++ b/test/src/e2e_vm_tests/mod.rs @@ -27,6 +27,7 @@ use std::{ sync::Arc, }; use sway_core::BuildTarget; +use sway_features::{CliFields, ExperimentalFeatures}; use tokio::sync::Mutex; use tracing::Instrument; @@ -101,6 +102,8 @@ struct TestDescription { unsupported_profiles: Vec<&'static str>, checker: FileCheck, run_config: RunConfig, + experimental: ExperimentalFeatures, + has_experimental_field: bool, } #[derive(PartialEq, Eq, Hash)] @@ -280,9 +283,16 @@ impl TestContext { run_config: &RunConfig, contract_path: String, ) -> Result { + let experimental = ExperimentalFeatures::new( + &HashMap::default(), + &run_config.experimental.experimental, + &run_config.experimental.no_experimental, + ) + .unwrap(); + let key = DeployedContractKey { contract_path: contract_path.clone(), - new_encoding: run_config.experimental.new_encoding, + new_encoding: experimental.new_encoding, }; let mut deployed_contracts = self.deployed_contracts.lock().await; @@ -298,6 +308,7 @@ impl TestContext { async fn run(&self, test: TestDescription, output: &mut String, verbose: bool) -> Result<()> { let TestDescription { name, + suffix, category, script_data, script_data_new_encoding, @@ -311,18 +322,20 @@ impl TestContext { checker, run_config, expected_decoded_test_logs, + experimental, + has_experimental_field, .. } = test; let checker = checker.build().unwrap(); - let script_data = if run_config.experimental.new_encoding { + let script_data = if !has_experimental_field && experimental.new_encoding { script_data_new_encoding } else { script_data }; - let expected_result = if run_config.experimental.new_encoding { + let expected_result = if !has_experimental_field && experimental.new_encoding { expected_result_new_encoding } else { expected_result @@ -438,11 +451,14 @@ impl TestContext { harness::test_json_abi( &name, &compiled, - run_config.experimental.new_encoding, + experimental.new_encoding, run_config.update_output_files, + &suffix, + has_experimental_field, ) }) .await; + output.push_str(&out); result?; } @@ -484,8 +500,10 @@ impl TestContext { harness::test_json_abi( name, built_pkg, - run_config.experimental.new_encoding, + experimental.new_encoding, run_config.update_output_files, + &suffix, + has_experimental_field, ) }) .await; @@ -686,7 +704,7 @@ impl TestContext { pub async fn run(filter_config: &FilterConfig, run_config: &RunConfig) -> Result<()> { // Discover tests - let mut tests = discover_test_configs(run_config)?; + let mut tests = discover_test_tomls(run_config)?; let total_number_of_tests = tests.len(); // Filter tests @@ -882,36 +900,23 @@ fn exclude_tests_dependency(t: &TestDescription, dep: &str) -> bool { } } -fn discover_test_configs(run_config: &RunConfig) -> Result> { - fn recursive_search( - path: &Path, - run_config: &RunConfig, - configs: &mut Vec, - ) -> Result<()> { - let wrap_err = |e| { - let relative_path = path - .iter() - .skip_while(|part| part.to_string_lossy() != "test_programs") - .skip(1) - .collect::(); - anyhow!("{}: {}", relative_path.display(), e) - }; - if path.is_dir() { - for entry in std::fs::read_dir(path).unwrap() { - recursive_search(&entry.unwrap().path(), run_config, configs)?; - } - } else if path.is_file() && path.file_name().map(|f| f == "test.toml").unwrap_or(false) { - configs.push(parse_test_toml(path, run_config).map_err(wrap_err)?); - } - Ok(()) - } +fn discover_test_tomls(run_config: &RunConfig) -> Result> { + let mut descriptions = vec![]; - let manifest_dir = env!("CARGO_MANIFEST_DIR"); - let tests_root_dir = format!("{manifest_dir}/src/e2e_vm_tests/test_programs"); + let pattern = format!( + "{}/src/e2e_vm_tests/test_programs/**/test*.toml", + env!("CARGO_MANIFEST_DIR") + ); + + for entry in glob::glob(&pattern) + .expect("Failed to read glob pattern") + .flatten() + { + let t = parse_test_toml(&entry, run_config)?; + descriptions.push(t); + } - let mut configs = Vec::new(); - recursive_search(&PathBuf::from(tests_root_dir), run_config, &mut configs)?; - Ok(configs) + Ok(descriptions) } /// This functions gets passed the previously built FileCheck-based file checker, @@ -936,22 +941,78 @@ fn parse_test_toml(path: &Path, run_config: &RunConfig) -> Result()?; + let mut toml_content = toml_content_str.parse::()?; if !toml_content.is_table() { bail!("Malformed test description."); } + // use test.toml as base if this test has a suffix + { + let toml_content_map = toml_content.as_table_mut().unwrap(); + if path.file_name().and_then(|x| x.to_str()) != Some("test.toml") { + let base_test_toml = path.parent().unwrap().join("test.toml"); + let base_test_toml = std::fs::read_to_string(base_test_toml)?; + let base_toml_content = base_test_toml.parse::()?; + match base_toml_content { + toml::Value::Table(map) => { + for (k, v) in map { + let _ = toml_content_map.entry(&k).or_insert(v); + } + } + _ => bail!("Malformed base test description (see test.toml)."), + } + }; + } + + let mut run_config = run_config.clone(); + + // To keep the current test.toml compatible we check if a field named "experimental" exists + // or not. If it does not, we keep the current behaviour. + // If it does, we ignore the experimental flags from the CLI and use the one from the toml file. + // TODO: this backwards compatibility can be removed after all tests migrate to new version + let (has_experimental_field, experimental) = + if let Some(toml_experimental) = toml_content.get("experimental") { + run_config.experimental = CliFields::default(); + + let mut experimental = ExperimentalFeatures::default(); + for (k, v) in toml_experimental.as_table().unwrap() { + let v = v.as_bool().unwrap(); + experimental.set_enabled_by_name(k, v).unwrap(); + + if v { + run_config + .experimental + .experimental + .push(k.parse().unwrap()); + } else { + run_config + .experimental + .no_experimental + .push(k.parse().unwrap()); + } + } + (true, experimental) + } else { + let mut experimental = ExperimentalFeatures::default(); + for f in &run_config.experimental.no_experimental { + experimental.set_enabled(*f, false); + } + for f in &run_config.experimental.experimental { + experimental.set_enabled(*f, true); + } + (false, experimental) + }; + // if new encoding is on, allow a "category_new_encoding" // for tests that should have different categories - let category = if run_config.experimental.new_encoding { + let category = if !has_experimental_field && experimental.new_encoding { toml_content .get("category_new_encoding") .or_else(|| toml_content.get("category")) } else { toml_content.get("category") }; - let category = category .ok_or_else(|| anyhow!("Missing mandatory 'category' entry.")) .and_then(|category_val| match category_val.as_str() { @@ -991,7 +1052,8 @@ fn parse_test_toml(path: &Path, run_config: &RunConfig) -> Result Result { - bail!("Expected 'script_data' to be a hex string."); + bail!("Expected 'script_data_new_encoding' to be a hex string."); } _ => None, }; - (script_data, script_data_new_encoding) + ( + script_data, + if has_experimental_field { + None + } else { + script_data_new_encoding + }, + ) } TestCategory::Compiles | TestCategory::FailsToCompile @@ -1077,7 +1146,11 @@ fn parse_test_toml(path: &Path, run_config: &RunConfig) -> Result Some(value), + (TestCategory::Runs | TestCategory::RunsWithContract, Some(value)) + if !has_experimental_field => + { + Some(value) + } _ => None, }; @@ -1158,11 +1231,7 @@ fn parse_test_toml(path: &Path, run_config: &RunConfig) -> Result Result forc build --path test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg +exit status: 1 +output: + Building test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg + Compiling predicate invalid_cfg_arg (test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg) +warning + --> test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/src/main.sw:2:3 + | +1 | predicate; +2 | #[cfg(c)] a + | --- Unexpected attribute value: "c" for attribute: "cfg" expected value "target" or "program_type" or "experimental_new_encoding" + | +____ + +error + --> test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/src/main.sw:2:11 + | +1 | predicate; +2 | #[cfg(c)] a + | ^ Expected an item. + | +____ + +error + --> test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/src/main.sw:2:7 + | +1 | predicate; +2 | #[cfg(c)] a + | ^ Unexpected attribute value: "c" for attribute: "cfg" + | +____ + + Aborting due to 2 errors. +error: Failed to compile invalid_cfg_arg diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/test.toml deleted file mode 100644 index 1f48bdf0556..00000000000 --- a/test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/test.toml +++ /dev/null @@ -1,10 +0,0 @@ -category = "fail" - -# check: $()#[cfg(c)] a -# nextln: $()Unexpected attribute value: "c" for attribute: "cfg" expected value "target" or "program_type" or "experimental_new_encoding" - -# check: $()#[cfg(c)] a -# nextln: $()Expected an item. - -# check: $()#[cfg(c)] a -# nextln: $()Unexpected attribute value: "c" for attribute: "cfg" \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/forc/help/snapshot.toml b/test/src/e2e_vm_tests/test_programs/should_pass/forc/help/snapshot.toml new file mode 100644 index 00000000000..b9151f7a736 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/forc/help/snapshot.toml @@ -0,0 +1,16 @@ +cmds = [ + "forc addr2line -h", + "forc build -h", + "forc check -h", + "forc clean -h", + "forc completions -h", + "forc new -h", + "forc init -h", + "forc parse-bytecode -h", + "forc test -h", + "forc update -h", + "forc plugins -h", + "forc template -h", + "forc contract-id -h", + "forc predicate-root -h", +] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/forc/help/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/forc/help/stdout.snap new file mode 100644 index 00000000000..8dd4a804aae --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/forc/help/stdout.snap @@ -0,0 +1,597 @@ +--- +source: test/tests/tests.rs +--- +> forc addr2line -h +exit status: 0 +output: +Show location and context of an opcode address in its source file + +Usage: forc addr2line [OPTIONS] --sourcemap-path --opcode-index + +Options: + -S, --search-dir Where to search for the project root [default: .] + -g, --sourcemap-path Source file mapping in JSON format + -c, --context How many lines of context to show [default: 2] + -i, --opcode-index Opcode index + -v, --verbose... Use verbose output + -s, --silent Silence all output + -L, --log-level Set the log level + -h, --help Print help + +> forc build -h +exit status: 0 +output: +Compile the current or target project + +Usage: forc build [OPTIONS] + +Options: + -p, --path + Path to the project + --offline + Offline mode + -t, --terse + Terse mode + --output-directory + The directory in which Forc output artifacts are placed + --locked + Requires that the Forc.lock file is up-to-date + --ipfs-node + The IPFS node to use for fetching IPFS sources + --ast + Print the generated Sway AST (Abstract Syntax Tree) + --dca-graph + Print the computed Sway DCA (Dead Code Analysis) graph + --dca-graph-url-format + URL format to be used in the generated DCA graph .dot file. + --asm ... + Print the generated ASM (assembler). [possible values: virtual, allocated, abstract, final, all] + --bytecode + Print the bytecode + --ir ... + Print the generated Sway IR (Intermediate Representation). [possible values: initial, final, all, modified, inline, simplify-cfg, sroa, dce, fn-dce, fn-dedup-release, fn-dedup-debug, mem2reg, memcpyopt, const-folding, arg-demotion, const-demotion, ret-demotion, misc-demotion] + --time-phases + Output the time elapsed over each part of the compilation process + --reverse-order + Output build errors and warnings in reverse order + --metrics-outfile + Output compilation metrics into the specified file + -v, --verbose... + Use verbose output + --json-abi + Minify JSON ABI files + -s, --silent + Silence all output + --json-storage-slots + Minify JSON storage slot files + -L, --log-level + Set the log level + -o, --output-bin + Create a binary file at the provided path representing the final bytecode + -g, --output-debug + Create a file at the provided path containing debug information + --build-profile + The name of the build profile to use [default: debug] + --release + Use the release build profile + --error-on-warnings + Treat warnings as errors + --build-target + Build target to use for code generation [default: fuel] [possible values: fuel, evm] + --tests + Also build all tests within the project + --experimental + Comma separated list of all experimental features that will be enabled [possible values: new_encoding] + --no-experimental + Comma separated list of all experimental features that will be disabled [possible values: new_encoding] + -h, --help + Print help (see more with '--help') + -V, --version + Print version + +EXAMPLES: + # Compile the current projectx + forc build + + # Compile the current project from a different path + forc build --path + + # Compile the current project without updating dependencies + forc build --path --locked + +> forc check -h +exit status: 0 +output: +Check the current or target project and all of its dependencies for errors + +Usage: forc check [OPTIONS] [BUILD_TARGET] + +Arguments: + [BUILD_TARGET] Build target to use for code generation [default: fuel] [possible values: fuel, evm] + +Options: + -p, --path + Path to the project, if not specified, current working directory will be used + --offline + Offline mode, prevents Forc from using the network when managing dependencies. Meaning it will only try to use previously downloaded dependencies + --locked + Requires that the Forc.lock file is up-to-date. If the lock file is missing, or it needs to be updated, Forc will exit with an error + -t, --terse + Terse mode. Limited warning and error output + --disable-tests + Disable checking unit tests + --ipfs-node + The IPFS Node to use for fetching IPFS sources + --experimental + Comma separated list of all experimental features that will be enabled [possible values: new_encoding] + --no-experimental + Comma separated list of all experimental features that will be disabled [possible values: new_encoding] + -v, --verbose... + Use verbose output + -s, --silent + Silence all output + -L, --log-level + Set the log level + -h, --help + Print help (see more with '--help') + -V, --version + Print version + +EXAMPLES: + # Check the current project + forc check + + # Check the current project with a different path + forc check --path + + # Check the current project without updating dependencies + forc check --locked + +> forc clean -h +exit status: 0 +output: +Removes the default forc compiler output artifact directory, i.e. `/out` + +Usage: forc clean [OPTIONS] + +Options: + -p, --path Path to the project, if not specified, current working directory will be used + -v, --verbose... Use verbose output + -s, --silent Silence all output + -L, --log-level Set the log level + -h, --help Print help + -V, --version Print version + +EXAMPLES: + # Clean project + forc clean + + # Clean project with a custom path + forc clean --path + +> forc completions -h +exit status: 0 +output: +Generate tab-completion scripts for your shell + +Usage: forc completions [OPTIONS] --target + +Options: + -T, --target Specify shell to enable tab-completion for [possible values: bash, elvish, fish, power-shell, zsh, fig] + -v, --verbose... Use verbose output + -s, --silent Silence all output + -L, --log-level Set the log level + -h, --help Print help (see more with '--help') + +> forc new -h +exit status: 0 +output: +Create a new Forc project at `` + +Usage: forc new [OPTIONS] + +Arguments: + The path at which the project directory will be created + +Options: + --contract The default program type. Excluding all flags or adding this flag creates a basic contract program + --script Adding this flag creates an empty script program + --predicate Adding this flag creates an empty predicate program + --library Adding this flag creates an empty library program + --workspace Adding this flag creates an empty workspace + --name Set the package name. Defaults to the directory name + -v, --verbose... Use verbose output + -s, --silent Silence all output + -L, --log-level Set the log level + -h, --help Print help + -V, --version Print version + +EXAMPLES: + # Create a new project + forc new --contract --name my_project + + # Create a new workspace + forc new --workspace --name my_workspace + + # Create a new Forc project with a predicate + forc new --predicate + + # Create a new Forc library project + forc new --library + +> forc init -h +exit status: 0 +output: +Create a new Forc project in an existing directory + +Usage: forc init [OPTIONS] + +Options: + --path The directory in which the forc project will be initialized + --contract The default program type, excluding all flags or adding this flag creates a basic contract program + --script Create a package with a script target (src/main.sw) + --predicate Create a package with a predicate target (src/predicate.rs) + --library Create a package with a library target (src/lib.sw) + --workspace Adding this flag creates an empty workspace + --name Set the package name. Defaults to the directory name + -v, --verbose... Use verbose output + -s, --silent Silence all output + -L, --log-level Set the log level + -h, --help Print help + -V, --version Print version + +EXAMPLES: + # Initialize a new Forc project + forc init --path + + # Initialize a new Forc project as workspace + forc init --path --workspace + + # Initialize a new Forc project with a predicate + forc init --path --predicate + + # Initialize a new Forc library project + forc init --path --library + +> forc parse-bytecode -h +exit status: 0 +output: +Parse bytecode file into a debug format + +Usage: forc parse-bytecode [OPTIONS] + +Arguments: + + +Options: + -v, --verbose... Use verbose output + -s, --silent Silence all output + -L, --log-level Set the log level + -h, --help Print help + -V, --version Print version + +EXAMPLES: + # Parse bytecode + forc parse-bytecode + +> forc test -h +exit status: 0 +output: +Run the Sway unit tests for the current project + +Usage: forc test [OPTIONS] [FILTER] + +Arguments: + [FILTER] When specified, only tests containing the given string will be executed + +Options: + -p, --path + Path to the project + --offline + Offline mode + -t, --terse + Terse mode + --output-directory + The directory in which Forc output artifacts are placed + --locked + Requires that the Forc.lock file is up-to-date + --ipfs-node + The IPFS node to use for fetching IPFS sources + --ast + Print the generated Sway AST (Abstract Syntax Tree) + --dca-graph + Print the computed Sway DCA (Dead Code Analysis) graph + --dca-graph-url-format + URL format to be used in the generated DCA graph .dot file. + --asm ... + Print the generated ASM (assembler). [possible values: virtual, allocated, abstract, final, all] + --bytecode + Print the bytecode + --ir ... + Print the generated Sway IR (Intermediate Representation). [possible values: initial, final, all, modified, inline, simplify-cfg, sroa, dce, fn-dce, fn-dedup-release, fn-dedup-debug, mem2reg, memcpyopt, const-folding, arg-demotion, const-demotion, ret-demotion, misc-demotion] + --time-phases + Output the time elapsed over each part of the compilation process + --reverse-order + Output build errors and warnings in reverse order + --metrics-outfile + Output compilation metrics into the specified file + -v, --verbose... + Use verbose output + --json-abi + Minify JSON ABI files + -s, --silent + Silence all output + --json-storage-slots + Minify JSON storage slot files + -L, --log-level + Set the log level + -o, --output-bin + Create a binary file at the provided path representing the final bytecode + -g, --output-debug + Create a file at the provided path containing debug information + --build-profile + The name of the build profile to use [default: debug] + --release + Use the release build profile + --error-on-warnings + Treat warnings as errors + --build-target + Build target to use for code generation [default: fuel] [possible values: fuel, evm] + --pretty + Pretty-print the logs emitted from tests + -l, --logs + Print `Log` and `LogData` receipts for tests + --raw-logs + Print the raw logs for tests + --filter-exact + When specified, only the test exactly matching the given string will be executed + --test-threads + Number of threads to utilize when running the tests. By default, this is the number of threads available in your system + --experimental + Comma separated list of all experimental features that will be enabled [possible values: new_encoding] + --no-experimental + Comma separated list of all experimental features that will be disabled [possible values: new_encoding] + -h, --help + Print help (see more with '--help') + -V, --version + Print version + +EXAMPLES: + # Run test + forc test + + # Run test with a filter + forc test $filter + + # Run test without any output + forc test --silent + + # Run test without creating or update the lock file + forc test --locked + +> forc update -h +exit status: 0 +output: +Update dependencies in the Forc dependencies directory + +Usage: forc update [OPTIONS] + +Options: + -p, --path Path to the project, if not specified, current working directory will be used + -d Dependency to be updated. If not set, all dependencies will be updated + -c, --check Checks if the dependencies have newer versions. Won't actually perform the update, will output which ones are up-to-date and outdated + --ipfs-node The IPFS Node to use for fetching IPFS sources + -v, --verbose... Use verbose output + -s, --silent Silence all output + -L, --log-level Set the log level + -h, --help Print help (see more with '--help') + -V, --version Print version + +EXAMPLES: + # Update dependencies + forc update + + # Update a specific dependency + forc update -d std + + # Check if dependencies have newer versions + forc update --check + +> forc plugins -h +exit status: 0 +output: +List all forc plugins + +Usage: forc plugins [OPTIONS] + +Options: + -p, --paths Prints the absolute path to each discovered plugin + -d, --describe Prints the long description associated with each listed plugin + -v, --verbose... Use verbose output + -s, --silent Silence all output + -L, --log-level Set the log level + -h, --help Print help (see more with '--help') + -V, --version Print version + +EXAMPLES: + # List all plugins + forc plugins + + # List all plugins with their paths + forc plugins --paths + + # List all plugins with their descriptions + forc plugins --describe + + # List all plugins with their paths and descriptions + forc plugins --paths --describe + +> forc template -h +exit status: 0 +output: +Create a new Forc project from a git template + +Usage: forc template [OPTIONS] + +Arguments: + The name of the project that will be created + +Options: + -u, --url The template url, should be a git repo [default: https://github.com/fuellabs/sway] + -t, --template-name The name of the template that needs to be fetched and used from git repo provided + -v, --verbose... Use verbose output + -s, --silent Silence all output + -L, --log-level Set the log level + -h, --help Print help + -V, --version Print version + +EXAMPLES: + # Create a new Forc project from an option template + forc template new-path --template-name option + +> forc contract-id -h +exit status: 0 +output: +Determine contract-id for a contract. For workspaces outputs all contract ids in the workspace + +Usage: forc contract-id [OPTIONS] + +Options: + -p, --path + Path to the project + --offline + Offline mode + -t, --terse + Terse mode + --output-directory + The directory in which Forc output artifacts are placed + --locked + Requires that the Forc.lock file is up-to-date + --ipfs-node + The IPFS node to use for fetching IPFS sources + --json-abi + Minify JSON ABI files + --json-storage-slots + Minify JSON storage slot files + --ast + Print the generated Sway AST (Abstract Syntax Tree) + --dca-graph + Print the computed Sway DCA (Dead Code Analysis) graph + --dca-graph-url-format + URL format to be used in the generated DCA graph .dot file. + --asm ... + Print the generated ASM (assembler). [possible values: virtual, allocated, abstract, final, all] + --bytecode + Print the bytecode + --ir ... + Print the generated Sway IR (Intermediate Representation). [possible values: initial, final, all, modified, inline, simplify-cfg, sroa, dce, fn-dce, fn-dedup-release, fn-dedup-debug, mem2reg, memcpyopt, const-folding, arg-demotion, const-demotion, ret-demotion, misc-demotion] + --time-phases + Output the time elapsed over each part of the compilation process + -v, --verbose... + Use verbose output + --reverse-order + Output build errors and warnings in reverse order + -s, --silent + Silence all output + -L, --log-level + Set the log level + --metrics-outfile + Output compilation metrics into the specified file + -o, --output-bin + Create a binary file at the provided path representing the final bytecode + -g, --output-debug + Create a file at the provided path containing debug information + --build-profile + The name of the build profile to use [default: debug] + --release + Use the release build profile + --error-on-warnings + Treat warnings as errors + --salt + Added salt used to derive the contract ID + --experimental + Comma separated list of all experimental features that will be enabled [possible values: new_encoding] + --no-experimental + Comma separated list of all experimental features that will be disabled [possible values: new_encoding] + -h, --help + Print help (see more with '--help') + -V, --version + Print version + +EXAMPLES: + # Get contract id + forc contract-id + + # Get contract id from a different path + forc contract-id --path + +> forc predicate-root -h +exit status: 0 +output: +Determine predicate-root for a predicate. For workspaces outputs all predicate roots in the workspace + +Usage: forc predicate-root [OPTIONS] + +Options: + -p, --path + Path to the project + --offline + Offline mode + -t, --terse + Terse mode + --output-directory + The directory in which Forc output artifacts are placed + --locked + Requires that the Forc.lock file is up-to-date + --ipfs-node + The IPFS node to use for fetching IPFS sources + --json-abi + Minify JSON ABI files + --json-storage-slots + Minify JSON storage slot files + --ast + Print the generated Sway AST (Abstract Syntax Tree) + --dca-graph + Print the computed Sway DCA (Dead Code Analysis) graph + --dca-graph-url-format + URL format to be used in the generated DCA graph .dot file. + --asm ... + Print the generated ASM (assembler). [possible values: virtual, allocated, abstract, final, all] + --bytecode + Print the bytecode + --ir ... + Print the generated Sway IR (Intermediate Representation). [possible values: initial, final, all, modified, inline, simplify-cfg, sroa, dce, fn-dce, fn-dedup-release, fn-dedup-debug, mem2reg, memcpyopt, const-folding, arg-demotion, const-demotion, ret-demotion, misc-demotion] + --time-phases + Output the time elapsed over each part of the compilation process + -v, --verbose... + Use verbose output + --reverse-order + Output build errors and warnings in reverse order + -s, --silent + Silence all output + -L, --log-level + Set the log level + --metrics-outfile + Output compilation metrics into the specified file + -o, --output-bin + Create a binary file at the provided path representing the final bytecode + -g, --output-debug + Create a file at the provided path containing debug information + --build-profile + The name of the build profile to use [default: debug] + --release + Use the release build profile + --error-on-warnings + Treat warnings as errors + --experimental + Comma separated list of all experimental features that will be enabled [possible values: new_encoding] + --no-experimental + Comma separated list of all experimental features that will be disabled [possible values: new_encoding] + -h, --help + Print help (see more with '--help') + -V, --version + Print version + +EXAMPLES: + # Get predicate root + forc predicate-root diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/json_abi_oracle_new_encoding.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/json_abi_oracle.encoding_v1.json similarity index 100% rename from test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/json_abi_oracle_new_encoding.json rename to test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/json_abi_oracle.encoding_v1.json diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/json_abi_oracle.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/json_abi_oracle.json index ad50b55d54c..e88285b3d48 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/json_abi_oracle.json +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/json_abi_oracle.json @@ -1,25 +1,23 @@ { + "concreteTypes": [ + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "type": "u64" + } + ], "configurables": [], + "encodingVersion": "0", "functions": [ { "attributes": null, "inputs": [], "name": "main", - "output": { - "name": "", - "type": 0, - "typeArguments": null - } + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" } ], "loggedTypes": [], "messagesTypes": [], - "types": [ - { - "components": null, - "type": "u64", - "typeId": 0, - "typeParameters": null - } - ] + "metadataTypes": [], + "programType": "script", + "specVersion": "1" } \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/test.encoding_v1.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/test.encoding_v1.toml new file mode 100644 index 00000000000..3917453e712 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/test.encoding_v1.toml @@ -0,0 +1,4 @@ +script_data = "0000000000000538 0000000000000001" +expected_result = { action = "return_data", value = "0000000000000539" } + +experimental = { new_encoding = true } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/test.toml index 1074072af31..733091ba093 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/test.toml @@ -1,9 +1,9 @@ category = "run" + # (1336, 1) script_data = "0000000000000538 0000000000000001" expected_result = { action = "return", value = 1337 } -script_data_new_encoding = "0000000000000538 0000000000000001" -expected_result_new_encoding = { action = "return_data", value = "0000000000000539" } - validate_abi = true + +experimental = { new_encoding = false } diff --git a/test/src/ir_generation/mod.rs b/test/src/ir_generation/mod.rs index 9de1ab9f2e1..8313845fe39 100644 --- a/test/src/ir_generation/mod.rs +++ b/test/src/ir_generation/mod.rs @@ -13,12 +13,14 @@ use sway_core::{ }; use sway_error::handler::Handler; +use sway_features::ExperimentalFeatures; use sway_ir::{ - create_fn_inline_pass, register_known_passes, ExperimentalFlags, PassGroup, PassManager, - ARG_DEMOTION_NAME, CONST_DEMOTION_NAME, DCE_NAME, MEMCPYOPT_NAME, MISC_DEMOTION_NAME, - RET_DEMOTION_NAME, + create_fn_inline_pass, register_known_passes, PassGroup, PassManager, ARG_DEMOTION_NAME, + CONST_DEMOTION_NAME, DCE_NAME, MEMCPYOPT_NAME, MISC_DEMOTION_NAME, RET_DEMOTION_NAME, }; +use crate::RunConfig; + enum Checker { Ir, Asm, @@ -166,11 +168,8 @@ fn pretty_print_error_report(error: &str) { pub(super) async fn run( filter_regex: Option<®ex::Regex>, verbose: bool, - mut experimental: ExperimentalFlags, + run_config: &RunConfig, ) -> Result<()> { - // TODO the way modules are built for these tests, new_encoding is not working. - experimental.new_encoding = false; - // Create new initial namespace for every test by reusing the precompiled // standard libraries. The namespace, thus its root module, must have the // name set. @@ -180,7 +179,7 @@ pub(super) async fn run( // Compile core library and reuse it when compiling tests. let engines = Engines::default(); let build_target = BuildTarget::default(); - let core_lib = compile_core(core_lib_name, build_target, &engines, experimental); + let core_lib = compile_core(core_lib_name, build_target, &engines, run_config); // Find all the tests. let all_tests = discover_test_files(); @@ -223,15 +222,17 @@ pub(super) async fn run( let test_file_name = path.file_name().unwrap().to_string_lossy().to_string(); tracing::info!("Testing {} ...", test_file_name.bold()); + let experimental = ExperimentalFeatures { + new_encoding: false, // IR tests still need encoding v1 off + }; + // Compile to AST. We need to provide a faux build config otherwise the IR will have // no span metadata. let bld_cfg = sway_core::BuildConfig::root_from_file_name_and_manifest_path( path.clone(), PathBuf::from("/"), build_target, - ).with_experimental(sway_core::ExperimentalFlags { - new_encoding: experimental.new_encoding, - }); + ); // Include unit tests in the build. let bld_cfg = bld_cfg.with_include_tests(true); @@ -247,6 +248,7 @@ pub(super) async fn run( Some(&bld_cfg), PACKAGE_NAME, None, + experimental ); let (errors, _warnings) = handler.consume(); if !errors.is_empty() { @@ -274,9 +276,7 @@ pub(super) async fn run( // Compile to IR. let include_tests = true; - let mut ir = compile_program(typed_program, include_tests, &engines, sway_core::ExperimentalFlags { - new_encoding: experimental.new_encoding, - }) + let mut ir = compile_program(typed_program, include_tests, &engines, experimental) .unwrap_or_else(|e| { use sway_types::span::Spanned; let e = e[0].clone(); @@ -372,9 +372,7 @@ pub(super) async fn run( let mut ir = sway_ir::parser::parse( &ir_output, engines.se(), - sway_ir::ExperimentalFlags { - new_encoding: experimental.new_encoding, - } + experimental, ) .unwrap_or_else(|e| panic!("{}: {e}\n{ir_output}", path.display())); @@ -469,9 +467,7 @@ pub(super) async fn run( } // Parse the IR again, and print it yet again to make sure that IR de/serialisation works. - let parsed_ir = sway_ir::parser::parse(&ir_output, engines.se(), sway_ir::ExperimentalFlags { - new_encoding: experimental.new_encoding, - }) + let parsed_ir = sway_ir::parser::parse(&ir_output, engines.se(), experimental) .unwrap_or_else(|e| panic!("{}: {e}\n{ir_output}", path.display())); let parsed_ir_output = sway_ir::printer::to_string(&parsed_ir); if ir_output != parsed_ir_output { @@ -530,7 +526,7 @@ fn compile_core( lib_name: sway_types::Ident, build_target: BuildTarget, engines: &Engines, - experimental: ExperimentalFlags, + run_config: &RunConfig, ) -> namespace::Module { let manifest_dir = env!("CARGO_MANIFEST_DIR"); let libcore_root_dir = format!("{manifest_dir}/../sway-lib-core"); @@ -543,7 +539,7 @@ fn compile_core( disable_tests: false, locked: false, ipfs_node: None, - no_encoding_v1: !experimental.new_encoding, + experimental: run_config.experimental.clone(), }; let res = match forc::test::forc_check::check(check_cmd, engines) { diff --git a/test/src/main.rs b/test/src/main.rs index 22a6c01c0e1..662e95e83f0 100644 --- a/test/src/main.rs +++ b/test/src/main.rs @@ -8,7 +8,7 @@ use clap::Parser; use forc::cli::shared::{PrintAsmCliOpt, PrintIrCliOpt}; use forc_tracing::init_tracing_subscriber; use std::str::FromStr; -use sway_core::{BuildTarget, ExperimentalFlags, PrintAsm, PrintIr}; +use sway_core::{BuildTarget, PrintAsm, PrintIr}; use tracing::Instrument; #[derive(Parser)] @@ -61,10 +61,6 @@ struct Cli { #[arg(long, visible_alias = "target")] build_target: Option, - /// Disable the "new encoding" feature - #[arg(long)] - no_encoding_v1: bool, - /// Update all output files #[arg(long)] update_output_files: bool, @@ -80,6 +76,9 @@ struct Cli { /// Print out the final bytecode, if the verbose option is on #[arg(long)] print_bytecode: bool, + + #[command(flatten)] + experimental: sway_features::CliFields, } #[derive(Debug, Clone)] @@ -100,11 +99,11 @@ pub struct RunConfig { pub locked: bool, pub verbose: bool, pub release: bool, - pub experimental: ExperimentalFlags, pub update_output_files: bool, pub print_ir: PrintIr, pub print_asm: PrintAsm, pub print_bytecode: bool, + pub experimental: sway_features::CliFields, } #[tokio::main] @@ -114,7 +113,7 @@ async fn main() -> Result<()> { // Parse args let cli = Cli::parse(); let filter_config = FilterConfig { - include: cli.include, + include: cli.include.clone(), exclude: cli.exclude, skip_until: cli.skip_until, abi_only: cli.abi_only, @@ -135,9 +134,7 @@ async fn main() -> Result<()> { verbose: cli.verbose, release: cli.release, build_target, - experimental: sway_core::ExperimentalFlags { - new_encoding: !cli.no_encoding_v1, - }, + experimental: cli.experimental.clone(), update_output_files: cli.update_output_files, print_ir: cli .print_ir @@ -164,19 +161,17 @@ async fn main() -> Result<()> { // Run IR tests if !filter_config.first_only { println!("\n"); - ir_generation::run( - filter_config.include.as_ref(), - cli.verbose, - sway_ir::ExperimentalFlags { - new_encoding: run_config.experimental.new_encoding, - }, - ) - .instrument(tracing::trace_span!("IR")) - .await?; + ir_generation::run(filter_config.include.as_ref(), cli.verbose, &run_config) + .instrument(tracing::trace_span!("IR")) + .await?; } // Run snapshot tests - let args = vec!["t", "--release", "-p", "test"]; + let mut args = vec!["t", "--release", "-p", "test", "--"]; + if let Some(include) = cli.include.as_ref().map(|x| x.as_str()) { + args.push(include); + } + let mut t = std::process::Command::new("cargo") .args(args) .spawn() diff --git a/test/tests/tests.rs b/test/tests/tests.rs index 626864f2e74..b62be61a28b 100644 --- a/test/tests/tests.rs +++ b/test/tests/tests.rs @@ -4,6 +4,7 @@ use regex::Regex; use std::{path::PathBuf, str::FromStr, sync::Once}; static FORC_COMPILATION: Once = Once::new(); +static FORC_DOC_COMPILATION: Once = Once::new(); fn compile_forc() { let args = vec!["b", "--release", "-p", "forc"]; @@ -14,6 +15,15 @@ fn compile_forc() { assert!(o.status.success()); } +fn compile_forc_doc() { + let args = vec!["b", "--release", "-p", "forc-doc"]; + let o = std::process::Command::new("cargo") + .args(args) + .output() + .unwrap(); + assert!(o.status.success()); +} + pub fn main() { let repo_root: PathBuf = PathBuf::from_str(&std::env::var("CARGO_MANIFEST_DIR").unwrap()).unwrap(); @@ -34,10 +44,6 @@ pub fn main() { let repo_root = repo_root.clone(); Trial::test(name, move || { - FORC_COMPILATION.call_once(|| { - compile_forc(); - }); - let snapshot_toml = std::fs::read_to_string(format!("{}/snapshot.toml", dir.display()))?; let snapshot_toml = toml::from_str::(&snapshot_toml)?; @@ -61,7 +67,16 @@ pub fn main() { let _ = writeln!(&mut snapshot, "> {}", cmd); - let cmd = if let Some(cmd) = cmd.strip_prefix("forc ") { + // known commands + let cmd = if let Some(cmd) = cmd.strip_prefix("forc doc ") { + FORC_DOC_COMPILATION.call_once(|| { + compile_forc_doc(); + }); + format!("target/release/forc-doc {cmd} 1>&2") + } else if let Some(cmd) = cmd.strip_prefix("forc ") { + FORC_COMPILATION.call_once(|| { + compile_forc(); + }); format!("target/release/forc {cmd} 1>&2") } else { panic!("Not supported. Possible commands: forc") @@ -71,6 +86,7 @@ pub fn main() { .dir(repo_root.clone()) .stderr_to_stdout() .stdout_capture() + .env("COLUMNS", "10") .unchecked() .start() .unwrap(); From 7e499fe24d808dad44d275e4779ee55019b55398 Mon Sep 17 00:00:00 2001 From: 0x77 <42128352+0x0077@users.noreply.github.com> Date: Mon, 28 Oct 2024 21:48:26 +0800 Subject: [PATCH 085/115] [docs] Update `::call_frames::ContractId` to `::contract_id::ContractId` in Native Assets Documentation (#6141) ## Description The syntax `std::call_frames::ContractId` has been updated in the latest version of Sway. The new syntax is `std::contract_id::ContractId`. To ensure the documentation is accurate and consistent with the latest version, this update is necessary. ## Reason for Change: - The `std::call_frames::ContractId` syntax has been deprecated or modified in the latest version of Sway. - Using the latest `std::contract_id::ContractId` syntax ensures the documentation is accurate and helps developers avoid using outdated syntax. ## Reference #5867 ## 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). - [ ] I have requested a review from the relevant team or maintainers. Co-authored-by: IGI-111 --- docs/book/src/blockchain-development/native_assets.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/book/src/blockchain-development/native_assets.md b/docs/book/src/blockchain-development/native_assets.md index bc589ccda85..7f1298326f9 100644 --- a/docs/book/src/blockchain-development/native_assets.md +++ b/docs/book/src/blockchain-development/native_assets.md @@ -223,6 +223,7 @@ use std::{ constants::DEFAULT_SUB_ID, context::msg_amount, string::String, + contract_id::ContractId }; configurable { @@ -408,7 +409,8 @@ use std::{ }, context::this_balance, storage::storage_string::*, - string::String + string::String, + contract_id::ContractId }; storage { From 4efd248e362f9c9c143e4772159b463e41d337d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaya=20G=C3=B6kalp?= Date: Mon, 28 Oct 2024 07:41:25 -0700 Subject: [PATCH 086/115] chore: bump rust version to 1.82 (#6672) ## Description Bumps sway version used in CI to v1.82 --------- Co-authored-by: IGI-111 --- .github/workflows/ci.yml | 4 +-- forc-pkg/src/manifest/mod.rs | 2 +- forc-pkg/src/pkg.rs | 27 +++++++++---------- forc/src/cli/commands/build.rs | 6 ++--- sway-core/src/asm_generation/fuel/analyses.rs | 4 +-- .../asm_generation/fuel/programs/abstract.rs | 14 +++++----- .../asm_generation/fuel/register_allocator.rs | 7 ++--- .../language/ty/expression/reassignment.rs | 1 + .../ast_node/declaration/impl_trait.rs | 1 + .../expression/match_expression/typed/mod.rs | 10 +++---- .../typed/typed_match_branch.rs | 10 +++---- .../ast_node/expression/typed_expression.rs | 1 + .../semantic_analysis/type_check_context.rs | 1 + sway-core/src/type_system/id.rs | 1 + .../src/type_system/unify/occurs_check.rs | 1 + sway-lsp/src/utils/markdown.rs | 11 +++----- swayfmt/src/comments.rs | 2 +- 17 files changed, 52 insertions(+), 51 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6a0372ca1f9..a6b251402bc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,8 +15,8 @@ concurrency: env: CARGO_TERM_COLOR: always REGISTRY: ghcr.io - RUST_VERSION: 1.79.0 - NIGHTLY_RUST_VERSION: nightly-2024-07-16 + RUST_VERSION: 1.82.0 + NIGHTLY_RUST_VERSION: nightly-2024-10-21 jobs: get-fuel-core-version: diff --git a/forc-pkg/src/manifest/mod.rs b/forc-pkg/src/manifest/mod.rs index 009b770f590..5ce50d65804 100644 --- a/forc-pkg/src/manifest/mod.rs +++ b/forc-pkg/src/manifest/mod.rs @@ -773,7 +773,7 @@ impl std::ops::Deref for PackageManifestFile { /// This can be configured using environment variables: /// - use `FORC_IMPLICIT_STD_PATH` for the path for the std-lib; /// - use `FORC_IMPLICIT_STD_GIT`, `FORC_IMPLICIT_STD_GIT_TAG` and/or `FORC_IMPLICIT_STD_GIT_BRANCH` to configure -/// the git repo of the std-lib. +/// the git repo of the std-lib. fn implicit_std_dep() -> Dependency { if let Ok(path) = std::env::var("FORC_IMPLICIT_STD_PATH") { return Dependency::Detailed(DependencyDetails { diff --git a/forc-pkg/src/pkg.rs b/forc-pkg/src/pkg.rs index 5a693613b68..19291e0d0ce 100644 --- a/forc-pkg/src/pkg.rs +++ b/forc-pkg/src/pkg.rs @@ -893,22 +893,19 @@ fn validate_version(member_manifests: &MemberManifestFiles) -> Result<()> { /// If required minimum forc version is higher than current forc version return an error with /// upgrade instructions fn validate_pkg_version(pkg_manifest: &PackageManifestFile) -> Result<()> { - match &pkg_manifest.project.forc_version { - Some(min_forc_version) => { - // Get the current version of the toolchain - let crate_version = env!("CARGO_PKG_VERSION"); - let toolchain_version = semver::Version::parse(crate_version)?; - if toolchain_version < *min_forc_version { - bail!( - "{:?} requires forc version {} but current forc version is {}\nUpdate the toolchain by following: https://fuellabs.github.io/sway/v{}/introduction/installation.html", - pkg_manifest.project.name, - min_forc_version, - crate_version, - crate_version - ); - } + if let Some(min_forc_version) = &pkg_manifest.project.forc_version { + // Get the current version of the toolchain + let crate_version = env!("CARGO_PKG_VERSION"); + let toolchain_version = semver::Version::parse(crate_version)?; + if toolchain_version < *min_forc_version { + bail!( + "{:?} requires forc version {} but current forc version is {}\nUpdate the toolchain by following: https://fuellabs.github.io/sway/v{}/introduction/installation.html", + pkg_manifest.project.name, + min_forc_version, + crate_version, + crate_version + ); } - None => {} }; Ok(()) } diff --git a/forc/src/cli/commands/build.rs b/forc/src/cli/commands/build.rs index 38662dd9240..c83242d43df 100644 --- a/forc/src/cli/commands/build.rs +++ b/forc/src/cli/commands/build.rs @@ -17,13 +17,13 @@ forc_util::cli_examples! { /// - `script`, `predicate` and `contract` projects will produce their bytecode in binary format `.bin`. /// /// - `script` projects will also produce a file containing the hash of the bytecode binary -/// `-bin-hash` (using `fuel_cypto::Hasher`). +/// `-bin-hash` (using `fuel_cypto::Hasher`). /// /// - `predicate` projects will also produce a file containing the **root** hash of the bytecode binary -/// `-bin-root` (using `fuel_tx::Contract::root_from_code`). +/// `-bin-root` (using `fuel_tx::Contract::root_from_code`). /// /// - `contract` and `library` projects will also produce the public ABI in JSON format -/// `-abi.json`. +/// `-abi.json`. #[derive(Debug, Default, Parser)] #[clap(bin_name = "forc build", version, after_help = help())] pub struct Command { diff --git a/sway-core/src/asm_generation/fuel/analyses.rs b/sway-core/src/asm_generation/fuel/analyses.rs index cfd4cb931d6..9bdcac0d489 100644 --- a/sway-core/src/asm_generation/fuel/analyses.rs +++ b/sway-core/src/asm_generation/fuel/analyses.rs @@ -17,9 +17,9 @@ use crate::asm_lang::{ControlFlowOp, Label, Op, VirtualRegister}; /// Two tables are generated: `live_in` and `live_out`. Each row in the tables corresponds to an /// instruction in the program. /// * A virtual register is in the `live_out` table for a given instruction if it is live on any -/// of that node's out-edges +/// of that node's out-edges /// * A virtual register is in the `live_in` table for a given instruction if it is live on any -/// of that node's in-edges +/// of that node's in-edges /// /// /// Algorithm: diff --git a/sway-core/src/asm_generation/fuel/programs/abstract.rs b/sway-core/src/asm_generation/fuel/programs/abstract.rs index ab5aa19147b..b5a8a12e302 100644 --- a/sway-core/src/asm_generation/fuel/programs/abstract.rs +++ b/sway-core/src/asm_generation/fuel/programs/abstract.rs @@ -164,13 +164,13 @@ impl AbstractProgram { /// Right now, it looks like this: /// /// WORD OP - /// 1 MOV $scratch $pc - /// - JMPF $zero i2 - /// 2 DATA_START (0-32) (in bytes, offset from $is) - /// - DATA_START (32-64) - /// 3 LW $ds $scratch 1 - /// - ADD $ds $ds $scratch - /// 4 .program_start: + /// [1] MOV $scratch $pc + /// [-] JMPF $zero i2 + /// [2] DATA_START (0-32) (in bytes, offset from $is) + /// [-] DATA_START (32-64) + /// [3] LW $ds $scratch 1 + /// [-] ADD $ds $ds $scratch + /// [4] .program_start: fn build_prologue(&mut self) -> AllocatedAbstractInstructionSet { let label = self.reg_seqr.get_label(); AllocatedAbstractInstructionSet { diff --git a/sway-core/src/asm_generation/fuel/register_allocator.rs b/sway-core/src/asm_generation/fuel/register_allocator.rs index 8e02d2d29fa..b3304563222 100644 --- a/sway-core/src/asm_generation/fuel/register_allocator.rs +++ b/sway-core/src/asm_generation/fuel/register_allocator.rs @@ -121,8 +121,8 @@ impl RegisterPool { /// add edges (v, b_1), ..., (v, b_n) for any b_i different from c. /// 3. for non-MOVE def of virtual register v with live_out virtual registers b_1, ..., b_n: /// add edges (v, b_1), ..., (v, b_n) -/// =============================================================================================== /// +/// =============================================================================================== pub(crate) fn create_interference_graph( ops: &[Op], live_out: &[BTreeSet], @@ -191,8 +191,8 @@ pub(crate) fn create_interference_graph( /// * When two registers are coalesced, a new node with a new virtual register (generated using the /// register sequencer) is created in the interference graph. /// * When a MOVE instruction is removed, the offset of each subsequent instruction has to be -/// updated, as well as the immediate values for some or all jump instructions (`ji`, `jnei`, and -/// `jnzi for now). +/// updated, as well as the immediate values for some or all jump instructions (`ji`, `jnei`, and +/// `jnzi for now). /// pub(crate) fn coalesce_registers( ops: &[Op], @@ -386,6 +386,7 @@ fn compute_def_use_points(ops: &[Op]) -> FxHashMap, /// 3. If some vertex n still has k or more neighbors, then the graph may not be k colorable. /// We still add it to the stack as is, as a potential spill. When popping, if we still /// can't colour it, then it becomes an actual spill. +/// /// =============================================================================================== /// pub(crate) fn color_interference_graph( diff --git a/sway-core/src/language/ty/expression/reassignment.rs b/sway-core/src/language/ty/expression/reassignment.rs index 358855a0102..54a8e740c5c 100644 --- a/sway-core/src/language/ty/expression/reassignment.rs +++ b/sway-core/src/language/ty/expression/reassignment.rs @@ -47,6 +47,7 @@ pub enum TyReassignmentTarget { /// E.g.: /// - *my_ref /// - **if x > 0 { &mut &mut a } else { &mut &mut b } + /// /// The [TyExpression] is guaranteed to be of [TyExpressionVariant::Deref]. Deref(Box), } diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs b/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs index 033fe5cff9b..8d88a8989d8 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs @@ -1,3 +1,4 @@ +#![allow(clippy::mutable_key_type)] use std::{ collections::{BTreeMap, HashMap, HashSet}, sync::Arc, diff --git a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/mod.rs b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/mod.rs index c974226d2b7..b547768d094 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/mod.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/mod.rs @@ -20,12 +20,12 @@ //! for a particular match branch (arm): //! - branch condition: Overall condition that must be `true` for the branch to match. //! - result variable declarations: Variable declarations that needs to be added to the -//! match branch result, before the actual body. Here we distinguish between the variables -//! actually declared in the match arm pattern and so called "tuple variables" that are -//! compiler generated and contain values for variables extracted out of individual OR variants. +//! match branch result, before the actual body. Here we distinguish between the variables +//! actually declared in the match arm pattern and so called "tuple variables" that are +//! compiler generated and contain values for variables extracted out of individual OR variants. //! - OR variant index variables: Variable declarations that are generated in case of having -//! variables in OR patterns. Index variables hold 1-based index of the OR variant being matched -//! or zero if non of the OR variants has matched. +//! variables in OR patterns. Index variables hold 1-based index of the OR variant being matched +//! or zero if non of the OR variants has matched. //! //! Afterwards, these three artifacts coming from every individual branch are glued together in the //! [crate::ty::TyMatchExpression] to form the final desugaring. diff --git a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_match_branch.rs b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_match_branch.rs index f8b530e2107..7e110b86e49 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_match_branch.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_match_branch.rs @@ -252,12 +252,12 @@ type CarryOverTupleDeclarations = Vec; /// via [ty::TyMatchBranch]: /// - branch condition: Overall condition that must be `true` for the branch to match. /// - result variable declarations: Variable declarations that needs to be added to the -/// match branch result, before the actual body. Here we distinguish between the variables -/// actually declared in the match arm pattern and so called "tuple variables" that are -/// compiler generated and contain values for variables extracted out of individual OR variants. +/// match branch result, before the actual body. Here we distinguish between the variables +/// actually declared in the match arm pattern and so called "tuple variables" that are +/// compiler generated and contain values for variables extracted out of individual OR variants. /// - OR variant index variables: Variable declarations that are generated in case of having -/// variables in OR patterns. Index variables hold 1-based index of the OR variant being matched -/// or zero if non of the OR variants has matched. +/// variables in OR patterns. Index variables hold 1-based index of the OR variant being matched +/// or zero if non of the OR variants has matched. /// /// ## Algorithm Overview /// The algorithm traverses the `req_decl_tree` bottom up from left to right and collects the diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs index e27b0425cf2..ac4941bcb70 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs @@ -995,6 +995,7 @@ impl ty::TyExpression { /// Returns the position of the first match arm that is an "interior" arm, meaning: /// - arm is a catch-all arm /// - arm is not the last match arm + /// /// or `None` if such arm does not exist. /// Note that the arm can be the first arm. fn interior_catch_all_arm_position(arms_reachability: &[ReachableReport]) -> Option { diff --git a/sway-core/src/semantic_analysis/type_check_context.rs b/sway-core/src/semantic_analysis/type_check_context.rs index a2071b34c84..c0340715571 100644 --- a/sway-core/src/semantic_analysis/type_check_context.rs +++ b/sway-core/src/semantic_analysis/type_check_context.rs @@ -1,3 +1,4 @@ +#![allow(clippy::mutable_key_type)] use std::collections::{HashMap, VecDeque}; use crate::{ diff --git a/sway-core/src/type_system/id.rs b/sway-core/src/type_system/id.rs index b1eda847745..2f5c0ec0ed8 100644 --- a/sway-core/src/type_system/id.rs +++ b/sway-core/src/type_system/id.rs @@ -1,3 +1,4 @@ +#![allow(clippy::mutable_key_type)] use indexmap::IndexMap; use sway_error::{ error::CompileError, diff --git a/sway-core/src/type_system/unify/occurs_check.rs b/sway-core/src/type_system/unify/occurs_check.rs index 003878f3fb7..af893ad7cfe 100644 --- a/sway-core/src/type_system/unify/occurs_check.rs +++ b/sway-core/src/type_system/unify/occurs_check.rs @@ -1,3 +1,4 @@ +#![allow(clippy::mutable_key_type)] use crate::{engine_threading::Engines, type_system::priv_prelude::*}; /// Helper struct to perform the occurs check. diff --git a/sway-lsp/src/utils/markdown.rs b/sway-lsp/src/utils/markdown.rs index fd9056a8deb..115f6c9bba3 100644 --- a/sway-lsp/src/utils/markdown.rs +++ b/sway-lsp/src/utils/markdown.rs @@ -50,13 +50,10 @@ fn is_sway_fence(s: &str) -> bool { let mut seen_sway_tags = false; let mut seen_other_tags = false; - let tokens = s - .trim() - .split(|c| matches!(c, ',' | ' ' | '\t')) - .filter_map(|t| { - let t = t.trim(); - (!t.is_empty()).then_some(t) - }); + let tokens = s.trim().split([',', ' ', '\t']).filter_map(|t| { + let t = t.trim(); + (!t.is_empty()).then_some(t) + }); for token in tokens { match token { diff --git a/swayfmt/src/comments.rs b/swayfmt/src/comments.rs index aa6b4848aaf..e891ca15666 100644 --- a/swayfmt/src/comments.rs +++ b/swayfmt/src/comments.rs @@ -103,7 +103,7 @@ pub fn write_comments( // If the already formatted code ends with some pattern and doesn't already end with a newline, // we want to add a newline here. - if formatted_code.ends_with(&['{', '}']) && !formatted_code.ends_with('\n') { + if formatted_code.ends_with(['{', '}']) && !formatted_code.ends_with('\n') { writeln!(formatted_code)?; } From 759bb9ed6211d55e4041491358ff3f28a66c44b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Matos?= Date: Mon, 28 Oct 2024 22:21:26 +0000 Subject: [PATCH 087/115] Remove `root_type_id` from `TypeInfo::Custom`. (#6676) ## Description This PR removes `root_type_id` from `TypeInfo::Custom`. This was used for resolving `Self` in associated types, but it's not needed, we can resolve those using the regular `self_type` we pass to name resolution. ## 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. Co-authored-by: IGI-111 --- .../language/parsed/expression/scrutinee.rs | 2 - .../ast_node/expression/typed_expression.rs | 3 -- .../typed_expression/method_application.rs | 1 - .../typed_expression/struct_instantiation.rs | 2 - .../semantic_analysis/namespace/trait_map.rs | 3 -- .../semantic_analysis/node_dependencies.rs | 9 +---- .../semantic_analysis/type_check_context.rs | 1 - .../src/semantic_analysis/type_resolve.rs | 37 +++++++------------ .../to_parsed_lang/convert_parse_tree.rs | 16 +------- sway-core/src/type_system/id.rs | 1 - sway-core/src/type_system/info.rs | 18 +-------- .../src/type_system/unify/unify_check.rs | 15 +------- sway-lsp/src/traverse/parsed_tree.rs | 2 - sway-lsp/src/traverse/typed_tree.rs | 1 - 14 files changed, 17 insertions(+), 94 deletions(-) diff --git a/sway-core/src/language/parsed/expression/scrutinee.rs b/sway-core/src/language/parsed/expression/scrutinee.rs index 20384fb446b..e700c60e7d8 100644 --- a/sway-core/src/language/parsed/expression/scrutinee.rs +++ b/sway-core/src/language/parsed/expression/scrutinee.rs @@ -250,7 +250,6 @@ impl Scrutinee { let name = vec![TypeInfo::Custom { qualified_call_path: struct_name.clone().into(), type_arguments: None, - root_type_id: None, }]; let fields = fields .iter() @@ -271,7 +270,6 @@ impl Scrutinee { let name = vec![TypeInfo::Custom { qualified_call_path: enum_name.clone().into(), type_arguments: None, - root_type_id: None, }]; let value = value.gather_approximate_typeinfo_dependencies(); [name, value].concat() diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs index ac4941bcb70..51672758fba 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs @@ -1358,7 +1358,6 @@ impl ty::TyExpression { let type_info = TypeInfo::Custom { qualified_call_path: qualified_call_path.clone(), type_arguments: None, - root_type_id: None, }; TypeBinding { @@ -1491,7 +1490,6 @@ impl ty::TyExpression { let type_info = type_name_to_type_info_opt(&type_name).unwrap_or(TypeInfo::Custom { qualified_call_path: type_name.clone().into(), type_arguments: None, - root_type_id: None, }); let method_name_binding = TypeBinding { @@ -1733,7 +1731,6 @@ impl ty::TyExpression { type_name_to_type_info_opt(type_name).unwrap_or(TypeInfo::Custom { qualified_call_path: type_name.clone().into(), type_arguments: None, - root_type_id: None, }) }); diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs index 2619ab21664..3c118c43536 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs @@ -649,7 +649,6 @@ pub(crate) fn type_check_method_application( if let TypeInfo::Custom { qualified_call_path, type_arguments, - root_type_id: _, } = &*type_engine.get(t.initial_type_id) { let mut subst_type_parameters = vec![]; diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_instantiation.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_instantiation.rs index 23ff00f7894..1d84a623fbd 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_instantiation.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_instantiation.rs @@ -69,12 +69,10 @@ pub(crate) fn struct_instantiation( (_, true) => TypeInfo::Custom { qualified_call_path: suffix.clone().into(), type_arguments: None, - root_type_id: None, }, (_, false) => TypeInfo::Custom { qualified_call_path: suffix.clone().into(), type_arguments: Some(type_arguments), - root_type_id: None, }, }; diff --git a/sway-core/src/semantic_analysis/namespace/trait_map.rs b/sway-core/src/semantic_analysis/namespace/trait_map.rs index 1fb39cf2982..6b966d16b5a 100644 --- a/sway-core/src/semantic_analysis/namespace/trait_map.rs +++ b/sway-core/src/semantic_analysis/namespace/trait_map.rs @@ -1404,7 +1404,6 @@ impl TraitMap { } else { Some(suffix.args.to_vec()) }, - root_type_id: None, }, suffix.name.span().source_id(), ); @@ -1431,7 +1430,6 @@ impl TraitMap { } else { Some(constraint_type_arguments.clone()) }, - root_type_id: None, }, constraint_trait_name.span().source_id(), ); @@ -1472,7 +1470,6 @@ impl TraitMap { if let TypeInfo::Custom { qualified_call_path: _, type_arguments: Some(type_arguments), - root_type_id: _, } = &*type_engine.get(*constraint_type_id) { type_arguments_string = format!("<{}>", engines.help_out(type_arguments)); diff --git a/sway-core/src/semantic_analysis/node_dependencies.rs b/sway-core/src/semantic_analysis/node_dependencies.rs index c34feeab4e6..e0a5b5b3f0b 100644 --- a/sway-core/src/semantic_analysis/node_dependencies.rs +++ b/sway-core/src/semantic_analysis/node_dependencies.rs @@ -791,21 +791,14 @@ impl Dependencies { TypeInfo::Custom { qualified_call_path: name, type_arguments, - root_type_id, } => { self.deps .insert(DependentSymbol::Symbol(name.clone().call_path.suffix)); - let s = match type_arguments { + match type_arguments { Some(type_arguments) => { self.gather_from_type_arguments(engines, type_arguments) } None => self, - }; - match root_type_id { - Some(root_type_id) => { - s.gather_from_typeinfo(engines, &engines.te().get(*root_type_id)) - } - None => s, } } TypeInfo::Tuple(elems) => self.gather_from_iter(elems.iter(), |deps, elem| { diff --git a/sway-core/src/semantic_analysis/type_check_context.rs b/sway-core/src/semantic_analysis/type_check_context.rs index c0340715571..4a7e6ccf852 100644 --- a/sway-core/src/semantic_analysis/type_check_context.rs +++ b/sway-core/src/semantic_analysis/type_check_context.rs @@ -881,7 +881,6 @@ impl<'a> TypeCheckContext<'a> { if let TypeInfo::Custom { qualified_call_path: call_path, type_arguments, - root_type_id: _, } = &*type_engine.get(as_trait) { qualified_call_path = Some(call_path.clone()); diff --git a/sway-core/src/semantic_analysis/type_resolve.rs b/sway-core/src/semantic_analysis/type_resolve.rs index f2498364acf..e4c676fda1e 100644 --- a/sway-core/src/semantic_analysis/type_resolve.rs +++ b/sway-core/src/semantic_analysis/type_resolve.rs @@ -38,31 +38,17 @@ pub fn resolve_type( TypeInfo::Custom { qualified_call_path, type_arguments, - root_type_id, } => { - let type_decl_opt = if let Some(root_type_id) = root_type_id { - resolve_call_path_and_root_type_id( - handler, - engines, - namespace.module(engines), - root_type_id, - None, - &qualified_call_path.clone().to_call_path(handler)?, - self_type, - ) - .ok() - } else { - resolve_qualified_call_path( - handler, - engines, - namespace, - module_path, - &qualified_call_path, - self_type, - subst_ctx, - ) - .ok() - }; + let type_decl_opt = resolve_qualified_call_path( + handler, + engines, + namespace, + module_path, + &qualified_call_path, + self_type, + subst_ctx, + ) + .ok(); type_decl_opt_to_type_id( handler, engines, @@ -368,6 +354,9 @@ pub fn decl_to_type_info( } (*engines.te().get(type_decl.ty.clone().unwrap().type_id)).clone() } + ty::TyDecl::GenericTypeForFunctionScope(decl) => { + (*engines.te().get(decl.type_id)).clone() + } _ => { return Err(handler.emit_err(CompileError::SymbolNotFound { name: symbol.clone(), diff --git a/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs b/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs index eda5d23a533..e40c9148fda 100644 --- a/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs +++ b/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs @@ -1260,7 +1260,6 @@ fn generic_params_opt_to_type_parameters_with_parent( TypeInfo::Custom { qualified_call_path: ident.clone().into(), type_arguments: None, - root_type_id: None, }, ident.span().source_id(), ); @@ -4341,7 +4340,6 @@ fn ty_to_type_parameter( TypeInfo::Custom { qualified_call_path: name_ident.clone().into(), type_arguments: None, - root_type_id: None, }, name_ident.span().source_id(), ); @@ -4625,23 +4623,12 @@ fn path_type_to_type_info( } if !suffix.is_empty() { - let (mut call_path, type_arguments) = path_type_to_call_path_and_type_arguments( + let (call_path, type_arguments) = path_type_to_call_path_and_type_arguments( context, handler, engines, path_type, )?; - - let mut root_type_id = None; - if name.as_str() == "Self" { - call_path.call_path.prefixes.remove(0); - root_type_id = Some(engines.te().insert( - engines, - type_info, - name.span().source_id(), - )); - } TypeInfo::Custom { qualified_call_path: call_path, type_arguments: Some(type_arguments), - root_type_id, } } else { type_info @@ -4686,7 +4673,6 @@ fn path_type_to_type_info( TypeInfo::Custom { qualified_call_path: call_path, type_arguments: Some(type_arguments), - root_type_id: None, } } } diff --git a/sway-core/src/type_system/id.rs b/sway-core/src/type_system/id.rs index 2f5c0ec0ed8..7a7480fe838 100644 --- a/sway-core/src/type_system/id.rs +++ b/sway-core/src/type_system/id.rs @@ -361,7 +361,6 @@ impl TypeId { TypeInfo::Custom { qualified_call_path: _, type_arguments, - root_type_id: _, } => { if let Some(type_arguments) = type_arguments { for type_arg in type_arguments { diff --git a/sway-core/src/type_system/info.rs b/sway-core/src/type_system/info.rs index d4bcae5b8bf..29767d81fc0 100644 --- a/sway-core/src/type_system/info.rs +++ b/sway-core/src/type_system/info.rs @@ -152,11 +152,6 @@ pub enum TypeInfo { Custom { qualified_call_path: QualifiedCallPath, type_arguments: Option>, - /// When root_type_id contains some type id then the call path applies - /// to the specified root_type_id as root. - /// This is used by associated types which should produce a TypeInfo::Custom - /// such as Self::T. - root_type_id: Option, }, B256, /// This means that specific type of a number is not yet known. It will be @@ -243,11 +238,9 @@ impl HashWithEngines for TypeInfo { TypeInfo::Custom { qualified_call_path: call_path, type_arguments, - root_type_id, } => { call_path.hash(state, engines); type_arguments.as_deref().hash(state, engines); - root_type_id.hash(state); } TypeInfo::Storage { fields } => { fields.hash(state, engines); @@ -325,12 +318,10 @@ impl PartialEqWithEngines for TypeInfo { Self::Custom { qualified_call_path: l_name, type_arguments: l_type_args, - root_type_id: l_root_type_id, }, Self::Custom { qualified_call_path: r_name, type_arguments: r_type_args, - root_type_id: r_root_type_id, }, ) => { l_name.call_path.suffix == r_name.call_path.suffix @@ -338,7 +329,6 @@ impl PartialEqWithEngines for TypeInfo { .qualified_path_root .eq(&r_name.qualified_path_root, ctx) && l_type_args.as_deref().eq(&r_type_args.as_deref(), ctx) - && l_root_type_id.eq(r_root_type_id) } (Self::StringSlice, Self::StringSlice) => true, (Self::StringArray(l), Self::StringArray(r)) => l.val() == r.val(), @@ -477,12 +467,10 @@ impl OrdWithEngines for TypeInfo { Self::Custom { qualified_call_path: l_call_path, type_arguments: l_type_args, - root_type_id: l_root_type_id, }, Self::Custom { qualified_call_path: r_call_path, type_arguments: r_type_args, - root_type_id: r_root_type_id, }, ) => l_call_path .call_path @@ -493,8 +481,7 @@ impl OrdWithEngines for TypeInfo { .qualified_path_root .cmp(&r_call_path.qualified_path_root, ctx) }) - .then_with(|| l_type_args.as_deref().cmp(&r_type_args.as_deref(), ctx)) - .then_with(|| l_root_type_id.cmp(r_root_type_id)), + .then_with(|| l_type_args.as_deref().cmp(&r_type_args.as_deref(), ctx)), (Self::StringArray(l), Self::StringArray(r)) => l.val().cmp(&r.val()), (Self::UnsignedInteger(l), Self::UnsignedInteger(r)) => l.cmp(r), (Self::Enum(l_decl_id), Self::Enum(r_decl_id)) => { @@ -874,7 +861,6 @@ impl TypeInfo { qualified_path_root: None, }, type_arguments: None, - root_type_id: None, } } @@ -1286,7 +1272,6 @@ impl TypeInfo { TypeInfo::Custom { qualified_call_path: call_path, type_arguments: other_type_arguments, - root_type_id, } => { if other_type_arguments.is_some() { Err(handler @@ -1295,7 +1280,6 @@ impl TypeInfo { let type_info = TypeInfo::Custom { qualified_call_path: call_path, type_arguments: Some(type_arguments), - root_type_id, }; Ok(type_info) } diff --git a/sway-core/src/type_system/unify/unify_check.rs b/sway-core/src/type_system/unify/unify_check.rs index 7479a4142ac..b1e1a9db62a 100644 --- a/sway-core/src/type_system/unify/unify_check.rs +++ b/sway-core/src/type_system/unify/unify_check.rs @@ -269,12 +269,10 @@ impl<'a> UnifyCheck<'a> { Custom { qualified_call_path: l_name, type_arguments: l_type_args, - root_type_id: l_root_type_id, }, Custom { qualified_call_path: r_name, type_arguments: r_type_args, - root_type_id: r_root_type_id, }, ) => { let l_types = l_type_args @@ -289,16 +287,6 @@ impl<'a> UnifyCheck<'a> { .iter() .map(|x| x.type_id) .collect::>(); - let l_root_type_ids = if let Some(l_root_type_id) = l_root_type_id { - vec![*l_root_type_id] - } else { - vec![] - }; - let r_root_type_ids = if let Some(r_root_type_id) = r_root_type_id { - vec![*r_root_type_id] - } else { - vec![] - }; let same_qualified_path_root = match ( l_name.qualified_path_root.clone(), r_name.qualified_path_root.clone(), @@ -318,8 +306,7 @@ impl<'a> UnifyCheck<'a> { return l_name.call_path.suffix == r_name.call_path.suffix && same_qualified_path_root - && self.check_multiple(&l_types, &r_types) - && self.check_multiple(&l_root_type_ids, &r_root_type_ids); + && self.check_multiple(&l_types, &r_types); } (Enum(l_decl_ref), Enum(r_decl_ref)) => { let l_decl = self.engines.de().get_enum(l_decl_ref); diff --git a/sway-lsp/src/traverse/parsed_tree.rs b/sway-lsp/src/traverse/parsed_tree.rs index 880915f915b..04e7750fa69 100644 --- a/sway-lsp/src/traverse/parsed_tree.rs +++ b/sway-lsp/src/traverse/parsed_tree.rs @@ -798,7 +798,6 @@ impl Parse for ParsedDeclId { if let TypeInfo::Custom { qualified_call_path, type_arguments, - root_type_id: _, } = &&*ctx .engines .te() @@ -1099,7 +1098,6 @@ fn collect_type_info_token(ctx: &ParseContext, type_info: &TypeInfo, type_span: TypeInfo::Custom { qualified_call_path, type_arguments, - root_type_id: _, } => { collect_qualified_path_root(ctx, qualified_call_path.qualified_path_root.clone()); let ident = qualified_call_path.call_path.suffix.clone(); diff --git a/sway-lsp/src/traverse/typed_tree.rs b/sway-lsp/src/traverse/typed_tree.rs index 3c6098cc43d..0c2745c6f21 100644 --- a/sway-lsp/src/traverse/typed_tree.rs +++ b/sway-lsp/src/traverse/typed_tree.rs @@ -1321,7 +1321,6 @@ fn collect_type_id( TypeInfo::Custom { type_arguments, qualified_call_path: name, - root_type_id: _, } => { collect_qualified_path_root(ctx, name.qualified_path_root.clone()); if let Some(token) = ctx From 5ff7c39ec15b5ef7cdc9e663d7d6e858dd73567b Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite Date: Tue, 29 Oct 2024 11:21:02 +0000 Subject: [PATCH 088/115] return type checked trait constraints (#6604) ## Description This PR fixes https://github.com/FuelLabs/sway/issues/6382. The issue was that `TypeParameter::type_check_trait_constraints(...)` mutates the type inside the `TypeEngine`, but it was not returning the new type-checked trait constraints. ## Checklist - [ ] 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. - [ ] 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). - [ ] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: IGI-111 --- .../type_system/ast_elements/type_parameter.rs | 6 ++++-- .../generic_where_in_impl_self/src/main.sw | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/sway-core/src/type_system/ast_elements/type_parameter.rs b/sway-core/src/type_system/ast_elements/type_parameter.rs index fb008336f4d..2b2ca658d23 100644 --- a/sway-core/src/type_system/ast_elements/type_parameter.rs +++ b/sway-core/src/type_system/ast_elements/type_parameter.rs @@ -213,7 +213,7 @@ impl TypeParameter { // Type check trait constraints only after type checking all type parameters. // This is required because a trait constraint may use other type parameters. // Ex: `struct Struct2 where A : MyAdd` - for type_param in &new_type_params { + for type_param in new_type_params.iter_mut() { TypeParameter::type_check_trait_constraints(handler, ctx.by_ref(), type_param)?; } @@ -327,7 +327,7 @@ impl TypeParameter { fn type_check_trait_constraints( handler: &Handler, mut ctx: TypeCheckContext, - type_parameter: &TypeParameter, + type_parameter: &mut TypeParameter, ) -> Result<(), ErrorEmitted> { let type_engine = ctx.engines.te(); @@ -372,6 +372,8 @@ impl TypeParameter { }, ); + type_parameter.trait_constraints = trait_constraints_with_supertraits; + // Insert the trait constraints into the namespace. type_parameter.insert_into_namespace_constraints(handler, ctx.by_ref())?; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_where_in_impl_self/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_where_in_impl_self/src/main.sw index 4c3e852777f..474043af251 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_where_in_impl_self/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_where_in_impl_self/src/main.sw @@ -27,9 +27,27 @@ impl CallTrait where K: Trait { } } +// https://github.com/FuelLabs/sway/issues/6382 +trait Devour { fn eat(t: T); } +struct Brain { } +struct Zombie { } + +impl Devour for Zombie { + fn eat(_b: Brain) { } +} + +fn feed(t: T) where U: Devour { + U::eat(t); +} + fn main() -> bool { let _ = call_trait(1); let ct = CallTrait:: {}; assert(ct.call_trait(1) == 42); + + // https://github.com/FuelLabs/sway/issues/6382 + let b = Brain{}; + feed::(b); + true } From 055597339314bac3b4ad3ba2c1424d5574872550 Mon Sep 17 00:00:00 2001 From: Vaivaswatha N Date: Wed, 30 Oct 2024 00:46:33 +0530 Subject: [PATCH 089/115] Add configurables section offset in the preamble (#6522) The preamble now contains 8 bytes of offset to the configurables section. If there is no configurable const in the data-section, then the value of this integer will be equal to the size of the binary itself. This also means that we now sort the data-section to have all the non-configurables first, and then the configurables. The preamble final asm looks like this (the offset to configurables is 0'd out here in the example): ``` ;; ASM: Final program ;; Program kind: Script .program: move $$tmp $pc jmpf $zero i10 DATA_SECTION_OFFSET[0..32] DATA_SECTION_OFFSET[32..64] CONFIGURABLES_OFFSET[0..32] CONFIGURABLES_OFFSET[32..64] lw $$ds $$tmp i1 add $$ds $$ds $$tmp ``` The preamble bytecode looks like this: ``` 0x00000000 MOVE R60 $pc ;; [26, 240, 48, 0] 0x00000004 JMPF $zero 0xa ;; [116, 0, 0, 10] 0x00000008 ;; [0, 0, 0, 0, 0, 0, 2, 40] 0x00000010 ;; [0, 0, 0, 0, 0, 0, 0, 0] 0x00000030 LW R63 R60 0x1 ;; [93, 255, 192, 1] 0x00000034 ADD R63 R63 R60 ;; [16, 255, 255, 0] ... ``` --------- Co-authored-by: Sophie Dankel <47993817+sdankel@users.noreply.github.com> Co-authored-by: IGI-111 --- forc-pkg/src/pkg.rs | 23 ++- .../deployed_script-loader-abi.json | 24 +-- forc-plugins/forc-client/tests/deploy.rs | 8 +- forc-test/src/execute.rs | 25 ++- forc/src/cli/commands/parse_bytecode.rs | 8 + forc/tests/cli_integration.rs | 8 +- sway-core/src/asm_generation/finalized_asm.rs | 66 ++++-- .../allocated_abstract_instruction_set.rs | 27 ++- .../src/asm_generation/fuel/data_section.rs | 191 +++++++++++++----- .../asm_generation/fuel/fuel_asm_builder.rs | 23 ++- .../src/asm_generation/fuel/functions.rs | 22 +- .../asm_generation/fuel/programs/abstract.rs | 46 +++-- sway-core/src/asm_lang/allocated_ops.rs | 42 ++-- sway-core/src/asm_lang/mod.rs | 11 + sway-core/src/asm_lang/virtual_ops.rs | 8 + sway-core/src/lib.rs | 22 ++ .../json_abi_oracle_new_encoding.json | 32 +-- .../configurable_dedup_decode/stdout.snap | 3 +- .../json_abi_oracle_new_encoding.json | 2 +- .../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 +- .../src/sdk-harness/test_projects/auth/mod.rs | 4 +- 32 files changed, 442 insertions(+), 179 deletions(-) diff --git a/forc-pkg/src/pkg.rs b/forc-pkg/src/pkg.rs index 19291e0d0ce..50d8b24c703 100644 --- a/forc-pkg/src/pkg.rs +++ b/forc-pkg/src/pkg.rs @@ -46,7 +46,7 @@ use sway_core::{ transform::AttributeKind, write_dwarf, BuildTarget, Engines, FinalizedEntry, LspConfig, }; -use sway_core::{PrintAsm, PrintIr}; +use sway_core::{set_bytecode_configurables_offset, PrintAsm, PrintIr}; use sway_error::{error::CompileError, handler::Handler, warning::CompileWarning}; use sway_features::ExperimentalFeatures; use sway_types::constants::{CORE, PRELUDE, STD}; @@ -1914,7 +1914,7 @@ pub fn compile( let errored = handler.has_errors() || (handler.has_warnings() && profile.error_on_warnings); - let compiled = match bc_res { + let mut compiled = match bc_res { Ok(compiled) if !errored => compiled, _ => return fail(handler), }; @@ -1923,9 +1923,12 @@ pub fn compile( print_warnings(engines.se(), terse_mode, &pkg.name, &warnings, &tree_type); + // Metadata to be placed into the binary. + let mut md = [0u8, 0, 0, 0, 0, 0, 0, 0]; // TODO: This should probably be in `fuel_abi_json::generate_json_abi_program`? // If ABI requires knowing config offsets, they should be inputs to ABI gen. if let ProgramABI::Fuel(ref mut program_abi) = program_abi { + let mut configurables_offset = compiled.bytecode.len() as u64; if let Some(ref mut configurables) = program_abi.configurables { // Filter out all dead configurables (i.e. ones without offsets in the bytecode) configurables.retain(|c| { @@ -1934,12 +1937,22 @@ pub fn compile( .contains_key(&c.name) }); // Set the actual offsets in the JSON object - for (config, offset) in compiled.named_data_section_entries_offsets { - if let Some(idx) = configurables.iter().position(|c| c.name == config) { - configurables[idx].offset = offset; + for (config, offset) in &compiled.named_data_section_entries_offsets { + if *offset < configurables_offset { + configurables_offset = *offset; + } + if let Some(idx) = configurables.iter().position(|c| &c.name == config) { + configurables[idx].offset = *offset; } } } + + md = configurables_offset.to_be_bytes(); + } + + // We know to set the metadata only for fuelvm right now. + if let BuildTarget::Fuel = pkg.target { + set_bytecode_configurables_offset(&mut compiled, &md); } metrics.bytecode_size = compiled.bytecode.len(); diff --git a/forc-plugins/forc-client/test/data/deployed_script/deployed_script-loader-abi.json b/forc-plugins/forc-client/test/data/deployed_script/deployed_script-loader-abi.json index 81b65c43cd7..c51c80ae2e9 100644 --- a/forc-plugins/forc-client/test/data/deployed_script/deployed_script-loader-abi.json +++ b/forc-plugins/forc-client/test/data/deployed_script/deployed_script-loader-abi.json @@ -251,62 +251,62 @@ { "name": "BOOL", "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", - "offset": 136 + "offset": 240 }, { "name": "U8", "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", - "offset": 248 + "offset": 352 }, { "name": "U16", "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", - "offset": 192 + "offset": 296 }, { "name": "U32", "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", - "offset": 232 + "offset": 336 }, { "name": "U64", "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", - "offset": 240 + "offset": 344 }, { "name": "U256", "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", - "offset": 200 + "offset": 304 }, { "name": "B256", "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", - "offset": 104 + "offset": 208 }, { "name": "STR_4", "concreteTypeId": "94f0fa95c830be5e4f711963e83259fe7e8bc723278ab6ec34449e791a99b53a", - "offset": 176 + "offset": 280 }, { "name": "TUPLE", "concreteTypeId": "e0128f7be9902d1fe16326cafe703b52038064a7997b03ebfc1c9dd607e1536c", - "offset": 184 + "offset": 288 }, { "name": "ARRAY", "concreteTypeId": "d9fac01ab38fe10950758ae9604da330d6406a71fda3ef1ea818121261132d56", - "offset": 88 + "offset": 192 }, { "name": "STRUCT", "concreteTypeId": "563310524b4f4447a10d0e50556310253dfb3b5eb4b29c3773222b737c8b7075", - "offset": 160 + "offset": 264 }, { "name": "ENUM", "concreteTypeId": "37cd1cba311039a851ac8bfa614cc41359b4ad95c8656fcef2e8f504fe7a1272", - "offset": 144 + "offset": 248 } ] } \ No newline at end of file diff --git a/forc-plugins/forc-client/tests/deploy.rs b/forc-plugins/forc-client/tests/deploy.rs index dae3c123f51..8f428a6aa6e 100644 --- a/forc-plugins/forc-client/tests/deploy.rs +++ b/forc-plugins/forc-client/tests/deploy.rs @@ -373,7 +373,7 @@ async fn test_simple_deploy() { node.kill().unwrap(); let expected = vec![DeployedPackage::Contract(DeployedContract { id: ContractId::from_str( - "e50f0b4b396504398c0aff45951b1e44e108399c856cb92257dfa58fe96d53eb", + "adcd0480deb735ffd8f5bd0683b66c55465e0841076efca4c28be25c767ede5b", ) .unwrap(), proxy: None, @@ -416,7 +416,7 @@ async fn test_deploy_submit_only() { node.kill().unwrap(); let expected = vec![DeployedPackage::Contract(DeployedContract { id: ContractId::from_str( - "e50f0b4b396504398c0aff45951b1e44e108399c856cb92257dfa58fe96d53eb", + "adcd0480deb735ffd8f5bd0683b66c55465e0841076efca4c28be25c767ede5b", ) .unwrap(), proxy: None, @@ -462,12 +462,12 @@ async fn test_deploy_fresh_proxy() { node.kill().unwrap(); let impl_contract = DeployedPackage::Contract(DeployedContract { id: ContractId::from_str( - "e50f0b4b396504398c0aff45951b1e44e108399c856cb92257dfa58fe96d53eb", + "adcd0480deb735ffd8f5bd0683b66c55465e0841076efca4c28be25c767ede5b", ) .unwrap(), proxy: Some( ContractId::from_str( - "1c50e2d4d602fdd88b47fb7b84b7f87bbdefcf9b7e5985bb7ceeee9266a8e977", + "5297238a1d867c9d7c8fa83c700e2d0d1c57e1874ec95ff4a67063e222ab1880", ) .unwrap(), ), diff --git a/forc-test/src/execute.rs b/forc-test/src/execute.rs index 3436261af94..76e89324903 100644 --- a/forc-test/src/execute.rs +++ b/forc-test/src/execute.rs @@ -9,7 +9,7 @@ use fuel_vm::{ self as vm, checked_transaction::builder::TransactionBuilderExt, interpreter::{Interpreter, NotSupportedEcal}, - prelude::{Instruction, SecretKey}, + prelude::SecretKey, storage::MemoryStorage, }; use rand::{Rng, SeedableRng}; @@ -246,18 +246,21 @@ impl TestExecutor { /// The following is how the beginning of the bytecode is laid out: /// /// ```ignore -/// [0] ji i4 ; Jumps to the data section setup. -/// [1] noop -/// [2] DATA_SECTION_OFFSET[0..32] -/// [3] DATA_SECTION_OFFSET[32..64] -/// [4] lw $ds $is 1 ; The data section setup, i.e. where the first ji lands. -/// [5] add $$ds $$ds $is -/// [6] ; This is where we want to jump from to our test code! +/// [ 0] ji i(4 + 2) ; Jumps to the data section setup. +/// [ 1] noop +/// [ 2] DATA_SECTION_OFFSET[0..32] +/// [ 3] DATA_SECTION_OFFSET[32..64] +/// [ 4] CONFIGURABLES_OFFSET[0..32] +/// [ 5] CONFIGURABLES_OFFSET[32..64] +/// [ 6] lw $ds $is 1 ; The data section setup, i.e. where the first ji lands. +/// [ 7] add $$ds $$ds $is +/// [ 8] ; This is where we want to jump from to our test code! /// ``` fn patch_test_bytecode(bytecode: &[u8], test_offset: u32) -> std::borrow::Cow<[u8]> { - // TODO: Standardize this or add metadata to bytecode. - const PROGRAM_START_INST_OFFSET: u32 = 6; - const PROGRAM_START_BYTE_OFFSET: usize = PROGRAM_START_INST_OFFSET as usize * Instruction::SIZE; + // Each instruction is 4 bytes, + // so we divide the total byte-size by 4 to get the instruction offset. + const PROGRAM_START_INST_OFFSET: u32 = (sway_core::PRELUDE_SIZE_IN_BYTES / 4) as u32; + const PROGRAM_START_BYTE_OFFSET: usize = sway_core::PRELUDE_SIZE_IN_BYTES; // If our desired entry point is the program start, no need to jump. if test_offset == PROGRAM_START_INST_OFFSET { diff --git a/forc/src/cli/commands/parse_bytecode.rs b/forc/src/cli/commands/parse_bytecode.rs index f4a30c82d6d..4d5ecf0bdb6 100644 --- a/forc/src/cli/commands/parse_bytecode.rs +++ b/forc/src/cli/commands/parse_bytecode.rs @@ -59,6 +59,14 @@ pub(crate) fn exec(command: Command) -> ForcResult<()> { parsed_raw ) } + Err(fuel_asm::InvalidOpcode) if word_ix == 4 || word_ix == 5 => { + let parsed_raw = u32::from_be_bytes([raw[0], raw[1], raw[2], raw[3]]); + format!( + "configurables offset {} ({})", + if word_ix == 4 { "lo" } else { "hi" }, + parsed_raw + ) + } Ok(_) | Err(fuel_asm::InvalidOpcode) => "".into(), }; table.add_row(Row::new(vec![ diff --git a/forc/tests/cli_integration.rs b/forc/tests/cli_integration.rs index 407cda7489d..7aaf4f054de 100644 --- a/forc/tests/cli_integration.rs +++ b/forc/tests/cli_integration.rs @@ -49,10 +49,10 @@ fn test_forc_test_raw_logs() -> Result<(), rexpect::error::Error> { // Assert that the output is correct process.exp_string(" test test_log_4")?; process.exp_string("Raw logs:")?; - process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12652,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; + process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12660,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; process.exp_string(" test test_log_2")?; process.exp_string("Raw logs:")?; - process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12652,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; + process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12660,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; process.process.exit()?; Ok(()) @@ -74,11 +74,11 @@ fn test_forc_test_both_logs() -> Result<(), rexpect::error::Error> { process.exp_string(" test test_log_4")?; process.exp_string("Decoded log value: 4, log rb: 1515152261580153489")?; process.exp_string("Raw logs:")?; - process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12652,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; + process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12660,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; process.exp_string(" test test_log_2")?; process.exp_string("Decoded log value: 2, log rb: 1515152261580153489")?; process.exp_string("Raw logs:")?; - process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12652,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; + process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12660,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; process.process.exit()?; Ok(()) } diff --git a/sway-core/src/asm_generation/finalized_asm.rs b/sway-core/src/asm_generation/finalized_asm.rs index ce3c81e3a56..c132d687855 100644 --- a/sway-core/src/asm_generation/finalized_asm.rs +++ b/sway-core/src/asm_generation/finalized_asm.rs @@ -3,8 +3,8 @@ use super::{ fuel::{checks, data_section::DataSection}, ProgramABI, ProgramKind, }; -use crate::asm_generation::fuel::data_section::{DataId, Datum, Entry}; -use crate::asm_lang::allocated_ops::{AllocatedOp, AllocatedOpcode}; +use crate::asm_generation::fuel::data_section::{Datum, Entry, EntryName}; +use crate::asm_lang::allocated_ops::{AllocatedOp, AllocatedOpcode, FuelAsmData}; use crate::decl_engine::DeclRefFunction; use crate::source_map::SourceMap; use crate::BuildConfig; @@ -16,7 +16,6 @@ use sway_error::handler::{ErrorEmitted, Handler}; use sway_types::span::Span; use sway_types::SourceEngine; -use either::Either; use std::{collections::BTreeMap, fmt}; /// Represents an ASM set which has had register allocation, jump elimination, and optimization @@ -112,6 +111,7 @@ fn to_bytecode_mut( { 8 } + AllocatedOpcode::ConfigurablesOffsetPlaceholder => 8, AllocatedOpcode::DataSectionOffsetPlaceholder => 8, AllocatedOpcode::BLOB(count) => count.value as u64 * 4, AllocatedOpcode::CFEI(i) | AllocatedOpcode::CFSI(i) if i.value == 0 => 0, @@ -141,6 +141,29 @@ fn to_bytecode_mut( &ops_padded }; + let mut offset_from_instr_start = 0; + for op in ops.iter() { + match &op.opcode { + AllocatedOpcode::LoadDataId(_reg, data_label) + if !data_section + .has_copy_type(data_label) + .expect("data label references non existent data -- internal error") => + { + // For non-copy type loads, pre-insert pointers into the data_section so that + // from this point on, the data_section remains immutable. This is necessary + // so that when we take addresses of configurables, that address doesn't change + // later on if a non-configurable is added to the data-section. + let offset_bytes = data_section.data_id_to_offset(data_label) as u64; + // The -4 is because $pc is added in the *next* instruction. + let pointer_offset_from_current_instr = + offset_to_data_section_in_bytes - offset_from_instr_start + offset_bytes - 4; + data_section.append_pointer(pointer_offset_from_current_instr); + } + _ => (), + } + offset_from_instr_start += op_size_in_bytes(data_section, op); + } + let mut bytecode = Vec::with_capacity(offset_to_data_section_in_bytes as usize); if build_config.print_bytecode { @@ -166,7 +189,7 @@ fn to_bytecode_mut( offset_from_instr_start += op_size_in_bytes(data_section, op); match fuel_op { - Either::Right(data) => { + FuelAsmData::DatasectionOffset(data) => { if build_config.print_bytecode { print!("{}{:#010x} ", " ".repeat(indentation), bytecode.len()); println!( @@ -182,7 +205,23 @@ fn to_bytecode_mut( bytecode.extend(data.iter().cloned()); half_word_ix += 2; } - Either::Left(instructions) => { + FuelAsmData::ConfigurablesOffset(data) => { + if build_config.print_bytecode { + print!("{}{:#010x} ", " ".repeat(indentation), bytecode.len()); + println!( + " ;; {:?}", + data + ); + } + + // Static assert to ensure that we're only dealing with ConfigurablesOffsetPlaceholder, + // a 1-word (8 bytes) data within the code. No other uses are known. + let _: [u8; 8] = data; + + bytecode.extend(data.iter().cloned()); + half_word_ix += 2; + } + FuelAsmData::Instructions(instructions) => { for instruction in instructions { // Print original source span only once if build_config.print_bytecode_spans { @@ -295,9 +334,9 @@ fn to_bytecode_mut( }; } - for (i, entry) in data_section.value_pairs.iter().enumerate() { - let entry_offset = data_section.data_id_to_offset(&DataId(i as u32)); - print_entry(indentation, offset + entry_offset, entry); + for (i, entry) in data_section.iter_all_entries().enumerate() { + let entry_offset = data_section.absolute_idx_to_offset(i); + print_entry(indentation, offset + entry_offset, &entry); } println!(";; --- END OF TARGET BYTECODE ---\n"); @@ -306,16 +345,19 @@ fn to_bytecode_mut( assert_eq!(half_word_ix * 4, offset_to_data_section_in_bytes as usize); assert_eq!(bytecode.len(), offset_to_data_section_in_bytes as usize); + let num_nonconfigurables = data_section.non_configurables.len(); let named_data_section_entries_offsets = data_section - .value_pairs + .configurables .iter() .enumerate() - .filter(|entry| entry.1.name.is_some()) .map(|(id, entry)| { + let EntryName::Configurable(name) = &entry.name else { + panic!("Non-configurable in configurables part of datasection"); + }; ( - entry.name.as_ref().unwrap().clone(), + name.clone(), offset_to_data_section_in_bytes - + data_section.raw_data_id_to_offset(id as u32) as u64, + + data_section.absolute_idx_to_offset(id + num_nonconfigurables) as u64, ) }) .collect::>(); diff --git a/sway-core/src/asm_generation/fuel/allocated_abstract_instruction_set.rs b/sway-core/src/asm_generation/fuel/allocated_abstract_instruction_set.rs index 0865687f5c8..a0e53c98cce 100644 --- a/sway-core/src/asm_generation/fuel/allocated_abstract_instruction_set.rs +++ b/sway-core/src/asm_generation/fuel/allocated_abstract_instruction_set.rs @@ -1,7 +1,10 @@ -use crate::asm_lang::{ - allocated_ops::{AllocatedOpcode, AllocatedRegister}, - AllocatedAbstractOp, ConstantRegister, ControlFlowOp, Label, RealizedOp, VirtualImmediate12, - VirtualImmediate18, VirtualImmediate24, +use crate::{ + asm_generation::fuel::data_section::EntryName, + asm_lang::{ + allocated_ops::{AllocatedOpcode, AllocatedRegister}, + AllocatedAbstractOp, ConstantRegister, ControlFlowOp, Label, RealizedOp, + VirtualImmediate12, VirtualImmediate18, VirtualImmediate24, + }, }; use super::{ @@ -348,6 +351,13 @@ impl AllocatedAbstractInstructionSet { comment: String::new(), }); } + ControlFlowOp::ConfigurablesOffsetPlaceholder => { + realized_ops.push(RealizedOp { + opcode: AllocatedOpcode::ConfigurablesOffsetPlaceholder, + owning_span: None, + comment: String::new(), + }); + } ControlFlowOp::LoadLabel(r1, ref lab) => { // LoadLabel ops are inserted by `rewrite_far_jumps`. // So the next instruction must be a relative jump. @@ -363,8 +373,11 @@ impl AllocatedAbstractInstructionSet { // We compute the relative offset w.r.t the actual jump. // Sub 1 because the relative jumps add a 1. let offset = rel_offset(curr_offset + 1, lab) - 1; - let data_id = - data_section.insert_data_value(Entry::new_word(offset, None, None)); + let data_id = data_section.insert_data_value(Entry::new_word( + offset, + EntryName::NonConfigurable, + None, + )); realized_ops.push(RealizedOp { opcode: AllocatedOpcode::LoadDataId(r1, data_id), owning_span, @@ -473,6 +486,8 @@ impl AllocatedAbstractInstructionSet { 2 } + Either::Right(ConfigurablesOffsetPlaceholder) => 2, + Either::Right(PushAll(_)) | Either::Right(PopAll(_)) => unreachable!( "fix me, pushall and popall don't really belong in control flow ops \ since they're not about control flow" diff --git a/sway-core/src/asm_generation/fuel/data_section.rs b/sway-core/src/asm_generation/fuel/data_section.rs index 3db12443f4f..e442dcf5ac1 100644 --- a/sway-core/src/asm_generation/fuel/data_section.rs +++ b/sway-core/src/asm_generation/fuel/data_section.rs @@ -1,16 +1,30 @@ +use rustc_hash::FxHashMap; use sway_ir::{size_bytes_round_up_to_word_alignment, Constant, ConstantValue, Context, Padding}; use std::{fmt, iter::repeat}; +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum EntryName { + NonConfigurable, + Configurable(String), +} + +impl fmt::Display for EntryName { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + EntryName::NonConfigurable => write!(f, "NonConfigurable"), + EntryName::Configurable(name) => write!(f, "", name), + } + } +} + // An entry in the data section. It's important for the size to be correct, especially for unions // where the size could be larger than the represented value. #[derive(Clone, Debug)] pub struct Entry { pub value: Datum, pub padding: Padding, - // It is assumed, for now, that only configuration-time constants have a name. Otherwise, this - // is `None`. - pub name: Option, + pub name: EntryName, } #[derive(Clone, Debug)] @@ -23,7 +37,7 @@ pub enum Datum { } impl Entry { - pub(crate) fn new_byte(value: u8, name: Option, padding: Option) -> Entry { + pub(crate) fn new_byte(value: u8, name: EntryName, padding: Option) -> Entry { Entry { value: Datum::Byte(value), padding: padding.unwrap_or(Padding::default_for_u8(value)), @@ -31,7 +45,7 @@ impl Entry { } } - pub(crate) fn new_word(value: u64, name: Option, padding: Option) -> Entry { + pub(crate) fn new_word(value: u64, name: EntryName, padding: Option) -> Entry { Entry { value: Datum::Word(value), padding: padding.unwrap_or(Padding::default_for_u64(value)), @@ -41,7 +55,7 @@ impl Entry { pub(crate) fn new_byte_array( bytes: Vec, - name: Option, + name: EntryName, padding: Option, ) -> Entry { Entry { @@ -51,11 +65,7 @@ impl Entry { } } - pub(crate) fn new_slice( - bytes: Vec, - name: Option, - padding: Option, - ) -> Entry { + pub(crate) fn new_slice(bytes: Vec, name: EntryName, padding: Option) -> Entry { Entry { padding: padding.unwrap_or(Padding::default_for_byte_array(&bytes)), value: Datum::Slice(bytes), @@ -65,7 +75,7 @@ impl Entry { pub(crate) fn new_collection( elements: Vec, - name: Option, + name: EntryName, padding: Option, ) -> Entry { Entry { @@ -80,7 +90,7 @@ impl Entry { pub(crate) fn from_constant( context: &Context, constant: &Constant, - name: Option, + name: EntryName, padding: Option, ) -> Entry { // We need a special handling in case of enums. @@ -89,8 +99,9 @@ impl Entry { .enum_tag_and_value_with_paddings(context) .expect("Constant is an enum."); - let tag_entry = Entry::from_constant(context, tag.0, None, tag.1); - let value_entry = Entry::from_constant(context, value.0, None, value.1); + let tag_entry = Entry::from_constant(context, tag.0, EntryName::NonConfigurable, tag.1); + let value_entry = + Entry::from_constant(context, value.0, EntryName::NonConfigurable, value.1); return Entry::new_collection(vec![tag_entry, value_entry], name, padding); } @@ -118,7 +129,9 @@ impl Entry { .array_elements_with_padding(context) .expect("Constant is an array.") .into_iter() - .map(|(elem, padding)| Entry::from_constant(context, elem, None, padding)) + .map(|(elem, padding)| { + Entry::from_constant(context, elem, EntryName::NonConfigurable, padding) + }) .collect(), name, padding, @@ -128,7 +141,9 @@ impl Entry { .struct_fields_with_padding(context) .expect("Constant is a struct.") .into_iter() - .map(|(elem, padding)| Entry::from_constant(context, elem, None, padding)) + .map(|(elem, padding)| { + Entry::from_constant(context, elem, EntryName::NonConfigurable, padding) + }) .collect(), name, padding, @@ -198,45 +213,92 @@ impl Entry { } } +#[derive(Clone, Debug)] +pub enum DataIdEntryKind { + NonConfigurable, + Configurable, +} + +impl fmt::Display for DataIdEntryKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + DataIdEntryKind::NonConfigurable => write!(f, "NonConfigurable"), + DataIdEntryKind::Configurable => write!(f, "Configurable"), + } + } +} + /// An address which refers to a value in the data section of the asm. #[derive(Clone, Debug)] -pub(crate) struct DataId(pub(crate) u32); +pub(crate) struct DataId { + pub(crate) idx: u32, + pub(crate) kind: DataIdEntryKind, +} impl fmt::Display for DataId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "data_{}", self.0) + write!(f, "data_{}_{}", self.kind, self.idx) } } +/// The data to be put in the data section of the asm #[derive(Default, Clone, Debug)] pub struct DataSection { - /// the data to be put in the data section of the asm - pub value_pairs: Vec, + pub non_configurables: Vec, + pub configurables: Vec, + pub(crate) pointer_id: FxHashMap, } impl DataSection { + /// Get the number of entries + pub(crate) fn num_entries(&self) -> usize { + self.non_configurables.len() + self.configurables.len() + } + + /// Iterate over all entries, non-configurables followed by configurables + pub(crate) fn iter_all_entries(&self) -> impl Iterator + '_ { + self.non_configurables + .iter() + .chain(self.configurables.iter()) + .cloned() + } + + /// Get the absolute index of an id + fn absolute_idx(&self, id: &DataId) -> usize { + match id.kind { + DataIdEntryKind::NonConfigurable => id.idx as usize, + DataIdEntryKind::Configurable => id.idx as usize + self.non_configurables.len(), + } + } + + /// Get entry at id + fn get(&self, id: &DataId) -> Option<&Entry> { + match id.kind { + DataIdEntryKind::NonConfigurable => self.non_configurables.get(id.idx as usize), + DataIdEntryKind::Configurable => self.configurables.get(id.idx as usize), + } + } + /// Given a [DataId], calculate the offset _from the beginning of the data section_ to the data /// in bytes. pub(crate) fn data_id_to_offset(&self, id: &DataId) -> usize { - self.raw_data_id_to_offset(id.0) + let idx = self.absolute_idx(id); + self.absolute_idx_to_offset(idx) } - /// Given a [DataId], calculate the offset _from the beginning of the data section_ to the data + /// Given an absolute index, calculate the offset _from the beginning of the data section_ to the data /// in bytes. - pub(crate) fn raw_data_id_to_offset(&self, id: u32) -> usize { - self.value_pairs - .iter() - .take(id as usize) - .fold(0, |offset, entry| { - //entries must be word aligned - size_bytes_round_up_to_word_alignment!(offset + entry.to_bytes().len()) - }) + pub(crate) fn absolute_idx_to_offset(&self, idx: usize) -> usize { + self.iter_all_entries().take(idx).fold(0, |offset, entry| { + //entries must be word aligned + size_bytes_round_up_to_word_alignment!(offset + entry.to_bytes().len()) + }) } pub(crate) fn serialize_to_bytes(&self) -> Vec { // not the exact right capacity but serves as a lower bound - let mut buf = Vec::with_capacity(self.value_pairs.len()); - for entry in &self.value_pairs { + let mut buf = Vec::with_capacity(self.num_entries()); + for entry in self.iter_all_entries() { buf.append(&mut entry.to_bytes()); //entries must be word aligned @@ -248,16 +310,12 @@ impl DataSection { /// Returns whether a specific [DataId] value has a copy type (fits in a register). pub(crate) fn has_copy_type(&self, id: &DataId) -> Option { - self.value_pairs - .get(id.0 as usize) - .map(|entry| entry.has_copy_type()) + self.get(id).map(|entry| entry.has_copy_type()) } /// Returns whether a specific [DataId] value is a byte entry. pub(crate) fn is_byte(&self, id: &DataId) -> Option { - self.value_pairs - .get(id.0 as usize) - .map(|entry| entry.is_byte()) + self.get(id).map(|entry| entry.is_byte()) } /// When generating code, sometimes a hard-coded data pointer is needed to reference @@ -268,31 +326,57 @@ impl DataSection { /// relative to the current (load) instruction. pub(crate) fn append_pointer(&mut self, pointer_value: u64) -> DataId { // The 'pointer' is just a literal 64 bit address. - self.insert_data_value(Entry::new_word(pointer_value, None, None)) + let data_id = self.insert_data_value(Entry::new_word( + pointer_value, + EntryName::NonConfigurable, + None, + )); + self.pointer_id.insert(pointer_value, data_id.clone()); + data_id + } + + /// Get the [DataId] for a pointer, if it exists. + /// The pointer must've been inserted with append_pointer. + pub(crate) fn data_id_of_pointer(&self, pointer_value: u64) -> Option { + self.pointer_id.get(&pointer_value).cloned() } /// Given any data in the form of a [Literal] (using this type mainly because it includes type - /// information and debug spans), insert it into the data section and return its offset as a + /// information and debug spans), insert it into the data section and return its handle as /// [DataId]. pub(crate) fn insert_data_value(&mut self, new_entry: Entry) -> DataId { // if there is an identical data value, use the same id - match self - .value_pairs - .iter() - .position(|entry| entry.equiv(&new_entry)) - { - Some(num) => DataId(num as u32), + + let (value_pairs, kind) = match new_entry.name { + EntryName::NonConfigurable => ( + &mut self.non_configurables, + DataIdEntryKind::NonConfigurable, + ), + EntryName::Configurable(_) => (&mut self.configurables, DataIdEntryKind::Configurable), + }; + match value_pairs.iter().position(|entry| entry.equiv(&new_entry)) { + Some(num) => DataId { + idx: num as u32, + kind, + }, None => { - self.value_pairs.push(new_entry); + value_pairs.push(new_entry); // the index of the data section where the value is stored - DataId((self.value_pairs.len() - 1) as u32) + DataId { + idx: (value_pairs.len() - 1) as u32, + kind, + } } } } // If the stored data is Datum::Word, return the inner value. pub(crate) fn get_data_word(&self, data_id: &DataId) -> Option { - self.value_pairs.get(data_id.0 as usize).and_then(|entry| { + let value_pairs = match data_id.kind { + DataIdEntryKind::NonConfigurable => &self.non_configurables, + DataIdEntryKind::Configurable => &self.configurables, + }; + value_pairs.get(data_id.idx as usize).and_then(|entry| { if let Datum::Word(w) = entry.value { Some(w) } else { @@ -322,11 +406,12 @@ impl fmt::Display for DataSection { use std::fmt::Write; let mut data_buf = String::new(); - for (ix, entry) in self.value_pairs.iter().enumerate() { + for (ix, entry) in self.iter_all_entries().enumerate() { writeln!( data_buf, - "{} {}", - DataId(ix as u32), + "data_{}_{} {}", + entry.name, + ix, display_entry(&entry.value) )?; } diff --git a/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs b/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs index 0e56e87d33f..5c98c09411e 100644 --- a/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs +++ b/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs @@ -1,4 +1,5 @@ use super::{ + data_section::EntryName, globals_section::GlobalsSection, programs::{AbstractEntry, AbstractProgram}, }; @@ -98,7 +99,12 @@ impl<'ir, 'eng> AsmBuilder for FuelAsmBuilder<'ir, 'eng> { fn compile_configurable(&mut self, config: &ConfigContent) { match config { ConfigContent::V0 { name, constant, .. } => { - let entry = Entry::from_constant(self.context, constant, Some(name.clone()), None); + let entry = Entry::from_constant( + self.context, + constant, + EntryName::Configurable(name.clone()), + None, + ); let dataid = self.data_section.insert_data_value(entry); self.configurable_v0_data_id.insert(name.clone(), dataid); } @@ -117,7 +123,7 @@ impl<'ir, 'eng> AsmBuilder for FuelAsmBuilder<'ir, 'eng> { let (decode_fn_label, _) = self.func_label_map.get(&decode_fn.get()).unwrap(); let dataid = self.data_section.insert_data_value(Entry::new_byte_array( encoded_bytes.clone(), - Some(name.clone()), + EntryName::Configurable(name.clone()), None, )); @@ -2057,6 +2063,11 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> { _otherwise => { // Get the constant into the namespace. + let config_name = if let Some(name) = config_name { + EntryName::Configurable(name) + } else { + EntryName::NonConfigurable + }; let entry = Entry::from_constant(self.context, constant, config_name, None); let data_id = self.data_section.insert_data_value(entry); @@ -2177,9 +2188,11 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> { } } else { let comment = comment.into(); - let data_id = self - .data_section - .insert_data_value(Entry::new_word(imm, None, None)); + let data_id = self.data_section.insert_data_value(Entry::new_word( + imm, + EntryName::NonConfigurable, + None, + )); self.cur_bytecode.push(Op { opcode: Either::Left(VirtualOp::LoadDataId(reg.clone(), data_id)), owning_span: span.clone(), diff --git a/sway-core/src/asm_generation/fuel/functions.rs b/sway-core/src/asm_generation/fuel/functions.rs index 42577c543d6..f217a4e8396 100644 --- a/sway-core/src/asm_generation/fuel/functions.rs +++ b/sway-core/src/asm_generation/fuel/functions.rs @@ -26,7 +26,7 @@ use sway_error::{ }; use sway_types::{Ident, Span}; -use super::compiler_constants::NUM_ARG_REGISTERS; +use super::{compiler_constants::NUM_ARG_REGISTERS, data_section::EntryName}; /// A summary of the adopted calling convention: /// @@ -830,9 +830,13 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> { ); } _ => { - let data_id = self.data_section.insert_data_value( - Entry::from_constant(self.context, constant, None, None), - ); + let data_id = + self.data_section.insert_data_value(Entry::from_constant( + self.context, + constant, + EntryName::NonConfigurable, + None, + )); self.ptr_map.insert(*ptr, Storage::Data(data_id)); } } @@ -858,9 +862,13 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> { }); } _ => { - let data_id = self.data_section.insert_data_value( - Entry::from_constant(self.context, constant, None, None), - ); + let data_id = + self.data_section.insert_data_value(Entry::from_constant( + self.context, + constant, + EntryName::NonConfigurable, + None, + )); init_mut_vars.push(InitMutVars { stack_base_words, diff --git a/sway-core/src/asm_generation/fuel/programs/abstract.rs b/sway-core/src/asm_generation/fuel/programs/abstract.rs index b5a8a12e302..3256da242bb 100644 --- a/sway-core/src/asm_generation/fuel/programs/abstract.rs +++ b/sway-core/src/asm_generation/fuel/programs/abstract.rs @@ -5,7 +5,7 @@ use crate::{ abstract_instruction_set::AbstractInstructionSet, allocated_abstract_instruction_set::AllocatedAbstractInstructionSet, compiler_constants, - data_section::{DataSection, Entry}, + data_section::{DataSection, Entry, EntryName}, globals_section::GlobalsSection, register_sequencer::RegisterSequencer, }, @@ -75,7 +75,7 @@ impl AbstractProgram { pub(crate) fn is_empty(&self) -> bool { self.non_entries.is_empty() && self.entries.is_empty() - && self.data_section.value_pairs.is_empty() + && self.data_section.iter_all_entries().next().is_none() } /// Adds prologue, globals allocation, before entries, contract method switch, and allocates virtual register. @@ -164,14 +164,28 @@ impl AbstractProgram { /// Right now, it looks like this: /// /// WORD OP - /// [1] MOV $scratch $pc - /// [-] JMPF $zero i2 - /// [2] DATA_START (0-32) (in bytes, offset from $is) - /// [-] DATA_START (32-64) - /// [3] LW $ds $scratch 1 - /// [-] ADD $ds $ds $scratch - /// [4] .program_start: + /// 1 MOV $scratch $pc + /// - JMPF $zero i10 + /// 2 DATA_START (0-32) (in bytes, offset from $is) + /// - DATA_START (32-64) + /// 3 CONFIGURABLES_OFFSET (0-32) + /// - CONFIGURABLES_OFFSET (32-64) + /// 4 LW $ds $scratch 1 + /// - ADD $ds $ds $scratch + /// 5 .program_start: fn build_prologue(&mut self) -> AllocatedAbstractInstructionSet { + const _: () = assert!( + crate::PRELUDE_CONFIGURABLES_OFFSET_IN_BYTES == 16, + "Inconsistency in the assumption of prelude organisation" + ); + const _: () = assert!( + crate::PRELUDE_CONFIGURABLES_SIZE_IN_BYTES == 8, + "Inconsistency in the assumption of prelude organisation" + ); + const _: () = assert!( + crate::PRELUDE_SIZE_IN_BYTES == 32, + "Inconsistency in the assumption of prelude organisation" + ); let label = self.reg_seqr.get_label(); AllocatedAbstractInstructionSet { ops: [ @@ -195,12 +209,18 @@ impl AbstractProgram { comment: "data section offset".into(), owning_span: None, }, + // word 3 -- full word u64 placeholder + AllocatedAbstractOp { + opcode: Either::Right(ControlFlowOp::ConfigurablesOffsetPlaceholder), + comment: "configurables offset".into(), + owning_span: None, + }, AllocatedAbstractOp { opcode: Either::Right(ControlFlowOp::Label(label)), - comment: "end of metadata".into(), + comment: "end of configurables offset".into(), owning_span: None, }, - // word 3 -- load the data offset into $ds + // word 4 -- load the data offset into $ds AllocatedAbstractOp { opcode: Either::Left(AllocatedOpcode::LW( AllocatedRegister::Constant(ConstantRegister::DataSectionStart), @@ -210,7 +230,7 @@ impl AbstractProgram { comment: "".into(), owning_span: None, }, - // word 3.5 -- add $ds $ds $is + // word 4.5 -- add $ds $ds $is AllocatedAbstractOp { opcode: Either::Left(AllocatedOpcode::ADD( AllocatedRegister::Constant(ConstantRegister::DataSectionStart), @@ -281,7 +301,7 @@ impl AbstractProgram { // Put the selector in the data section. let data_label = self.data_section.insert_data_value(Entry::new_word( u32::from_be_bytes(selector) as u64, - None, + EntryName::NonConfigurable, None, )); diff --git a/sway-core/src/asm_lang/allocated_ops.rs b/sway-core/src/asm_lang/allocated_ops.rs index b78ba37b2db..31220a0900d 100644 --- a/sway-core/src/asm_lang/allocated_ops.rs +++ b/sway-core/src/asm_lang/allocated_ops.rs @@ -17,7 +17,6 @@ use crate::{ }, fuel_prelude::fuel_asm::{self, op}, }; -use either::Either; use fuel_vm::fuel_asm::{op::ADDI, Imm12}; use std::fmt::{self, Write}; use sway_types::span::Span; @@ -273,6 +272,7 @@ pub(crate) enum AllocatedOpcode { /* Non-VM Instructions */ BLOB(VirtualImmediate24), + ConfigurablesOffsetPlaceholder, DataSectionOffsetPlaceholder, LoadDataId(AllocatedRegister, DataId), AddrDataId(AllocatedRegister, DataId), @@ -397,6 +397,7 @@ impl AllocatedOpcode { /* Non-VM Instructions */ BLOB(_imm) => vec![], + ConfigurablesOffsetPlaceholder => vec![], DataSectionOffsetPlaceholder => vec![], LoadDataId(r1, _i) => vec![r1], AddrDataId(r1, _i) => vec![r1], @@ -525,6 +526,10 @@ impl fmt::Display for AllocatedOpcode { /* Non-VM Instructions */ BLOB(a) => write!(fmtr, "blob {a}"), + ConfigurablesOffsetPlaceholder => write!( + fmtr, + "CONFIGURABLES_OFFSET[0..32]\nCONFIGURABLES_OFFSET[32..64]" + ), DataSectionOffsetPlaceholder => { write!( fmtr, @@ -562,17 +567,21 @@ impl fmt::Display for AllocatedOp { } } -type DoubleWideData = [u8; 8]; +pub(crate) enum FuelAsmData { + ConfigurablesOffset([u8; 8]), + DatasectionOffset([u8; 8]), + Instructions(Vec), +} impl AllocatedOp { pub(crate) fn to_fuel_asm( &self, offset_to_data_section: u64, offset_from_instr_start: u64, - data_section: &mut DataSection, - ) -> Either, DoubleWideData> { + data_section: &DataSection, + ) -> FuelAsmData { use AllocatedOpcode::*; - Either::Left(vec![match &self.opcode { + FuelAsmData::Instructions(vec![match &self.opcode { /* Arithmetic/Logic (ALU) Instructions */ ADD(a, b, c) => op::ADD::new(a.to_reg_id(), b.to_reg_id(), c.to_reg_id()).into(), ADDI(a, b, c) => op::ADDI::new(a.to_reg_id(), b.to_reg_id(), c.value.into()).into(), @@ -641,9 +650,9 @@ impl AllocatedOp { /* Memory Instructions */ ALOC(a) => op::ALOC::new(a.to_reg_id()).into(), - CFEI(a) if a.value == 0 => return Either::Left(vec![]), + CFEI(a) if a.value == 0 => return FuelAsmData::Instructions(vec![]), CFEI(a) => op::CFEI::new(a.value.into()).into(), - CFSI(a) if a.value == 0 => return Either::Left(vec![]), + CFSI(a) if a.value == 0 => return FuelAsmData::Instructions(vec![]), CFSI(a) => op::CFSI::new(a.value.into()).into(), CFE(a) => op::CFE::new(a.to_reg_id()).into(), CFS(a) => op::CFS::new(a.to_reg_id()).into(), @@ -727,17 +736,20 @@ impl AllocatedOp { /* Non-VM Instructions */ BLOB(a) => { - return Either::Left( + return FuelAsmData::Instructions( std::iter::repeat(op::NOOP::new().into()) .take(a.value as usize) .collect(), ) } + ConfigurablesOffsetPlaceholder => { + return FuelAsmData::ConfigurablesOffset([0, 0, 0, 0, 0, 0, 0, 0]) + } DataSectionOffsetPlaceholder => { - return Either::Right(offset_to_data_section.to_be_bytes()) + return FuelAsmData::DatasectionOffset(offset_to_data_section.to_be_bytes()) } LoadDataId(a, b) => { - return Either::Left(realize_load( + return FuelAsmData::Instructions(realize_load( a, b, data_section, @@ -745,7 +757,7 @@ impl AllocatedOp { offset_from_instr_start, )) } - AddrDataId(a, b) => return Either::Left(addr_of(a, b, data_section)), + AddrDataId(a, b) => return FuelAsmData::Instructions(addr_of(a, b, data_section)), Undefined => unreachable!("Sway cannot generate undefined ASM opcodes"), }]) } @@ -755,7 +767,7 @@ impl AllocatedOp { fn addr_of( dest: &AllocatedRegister, data_id: &DataId, - data_section: &mut DataSection, + data_section: &DataSection, ) -> Vec { let offset_bytes = data_section.data_id_to_offset(data_id) as u64; vec![fuel_asm::Instruction::ADDI(ADDI::new( @@ -772,7 +784,7 @@ fn addr_of( fn realize_load( dest: &AllocatedRegister, data_id: &DataId, - data_section: &mut DataSection, + data_section: &DataSection, offset_to_data_section: u64, offset_from_instr_start: u64, ) -> Vec { @@ -815,7 +827,9 @@ fn realize_load( offset_to_data_section - offset_from_instr_start + offset_bytes - 4; // insert the pointer as bytes as a new data section entry at the end of the data - let data_id_for_pointer = data_section.append_pointer(pointer_offset_from_current_instr); + let data_id_for_pointer = data_section + .data_id_of_pointer(pointer_offset_from_current_instr) + .expect("Pointer offset must be in data_section"); // now load the pointer we just created into the `dest`ination let mut buf = Vec::with_capacity(2); diff --git a/sway-core/src/asm_lang/mod.rs b/sway-core/src/asm_lang/mod.rs index 5e1bcaded52..71e09cc2290 100644 --- a/sway-core/src/asm_lang/mod.rs +++ b/sway-core/src/asm_lang/mod.rs @@ -1248,6 +1248,7 @@ impl fmt::Display for VirtualOp { /* Non-VM Instructions */ BLOB(a) => write!(fmtr, "blob {a}"), DataSectionOffsetPlaceholder => write!(fmtr, "data section offset placeholder"), + ConfigurablesOffsetPlaceholder => write!(fmtr, "configurables offset placeholder"), LoadDataId(a, b) => write!(fmtr, "load {a} {b}"), AddrDataId(a, b) => write!(fmtr, "addr {a} {b}"), Undefined => write!(fmtr, "undefined op"), @@ -1277,6 +1278,8 @@ pub(crate) enum ControlFlowOp { Call(Label), // Save a return label address in a register. SaveRetAddr(Reg, Label), + // Placeholder for the offset into the configurables section. + ConfigurablesOffsetPlaceholder, // placeholder for the DataSection offset DataSectionOffsetPlaceholder, // Placeholder for loading an address from the data section. @@ -1304,6 +1307,8 @@ impl fmt::Display for ControlFlowOp { SaveRetAddr(r1, lab) => format!("mova {r1} {lab}"), DataSectionOffsetPlaceholder => "DATA SECTION OFFSET[0..32]\nDATA SECTION OFFSET[32..64]".into(), + ConfigurablesOffsetPlaceholder => + "CONFIGURABLES_OFFSET[0..32]\nCONFIGURABLES_OFFSET[32..64]".into(), LoadLabel(r1, lab) => format!("lwlab {r1} {lab}"), PushAll(lab) => format!("pusha {lab}"), PopAll(lab) => format!("popa {lab}"), @@ -1321,6 +1326,7 @@ impl ControlFlowOp { | Jump(_) | Call(_) | DataSectionOffsetPlaceholder + | ConfigurablesOffsetPlaceholder | PushAll(_) | PopAll(_) => vec![], @@ -1339,6 +1345,7 @@ impl ControlFlowOp { | Call(_) | SaveRetAddr(..) | DataSectionOffsetPlaceholder + | ConfigurablesOffsetPlaceholder | LoadLabel(..) | PushAll(_) | PopAll(_) => vec![], @@ -1360,6 +1367,7 @@ impl ControlFlowOp { | JumpIfNotZero(..) | Call(_) | DataSectionOffsetPlaceholder + | ConfigurablesOffsetPlaceholder | PushAll(_) | PopAll(_) => vec![], }) @@ -1381,6 +1389,7 @@ impl ControlFlowOp { | Jump(_) | Call(_) | DataSectionOffsetPlaceholder + | ConfigurablesOffsetPlaceholder | PushAll(_) | PopAll(_) => self.clone(), @@ -1410,6 +1419,7 @@ impl ControlFlowOp { | Call(_) | SaveRetAddr(..) | DataSectionOffsetPlaceholder + | ConfigurablesOffsetPlaceholder | LoadLabel(..) | PushAll(_) | PopAll(_) => (), @@ -1466,6 +1476,7 @@ impl ControlFlowOp { Jump(label) => Jump(*label), Call(label) => Call(*label), DataSectionOffsetPlaceholder => DataSectionOffsetPlaceholder, + ConfigurablesOffsetPlaceholder => ConfigurablesOffsetPlaceholder, PushAll(label) => PushAll(*label), PopAll(label) => PopAll(*label), diff --git a/sway-core/src/asm_lang/virtual_ops.rs b/sway-core/src/asm_lang/virtual_ops.rs index ffe3509b7cd..3d041713a4f 100644 --- a/sway-core/src/asm_lang/virtual_ops.rs +++ b/sway-core/src/asm_lang/virtual_ops.rs @@ -226,6 +226,7 @@ pub(crate) enum VirtualOp { /* Non-VM Instructions */ BLOB(VirtualImmediate24), + ConfigurablesOffsetPlaceholder, DataSectionOffsetPlaceholder, // LoadDataId takes a virtual register and a DataId, which points to a labeled piece // of data in the data section. Note that the ASM op corresponding to a LW is @@ -347,6 +348,7 @@ impl VirtualOp { /* Non-VM Instructions */ BLOB(_imm) => vec![], DataSectionOffsetPlaceholder => vec![], + ConfigurablesOffsetPlaceholder => vec![], LoadDataId(r1, _i) => vec![r1], AddrDataId(r1, _) => vec![r1], @@ -465,6 +467,7 @@ impl VirtualOp { // Virtual OPs | BLOB(_) | DataSectionOffsetPlaceholder + | ConfigurablesOffsetPlaceholder | Undefined => true } } @@ -571,6 +574,7 @@ impl VirtualOp { | GTF(_, _, _) | BLOB(_) | DataSectionOffsetPlaceholder + | ConfigurablesOffsetPlaceholder | LoadDataId(_, _) | AddrDataId(_, _) | Undefined => vec![], @@ -692,6 +696,7 @@ impl VirtualOp { /* Non-VM Instructions */ BLOB(_imm) => vec![], DataSectionOffsetPlaceholder => vec![], + ConfigurablesOffsetPlaceholder => vec![], LoadDataId(_r1, _i) => vec![], AddrDataId(_r1, _i) => vec![], @@ -815,6 +820,7 @@ impl VirtualOp { LoadDataId(r1, _i) => vec![r1], AddrDataId(r1, _i) => vec![r1], DataSectionOffsetPlaceholder => vec![], + ConfigurablesOffsetPlaceholder => vec![], Undefined => vec![], }) .into_iter() @@ -1263,6 +1269,7 @@ impl VirtualOp { /* Non-VM Instructions */ BLOB(i) => Self::BLOB(i.clone()), DataSectionOffsetPlaceholder => Self::DataSectionOffsetPlaceholder, + ConfigurablesOffsetPlaceholder => Self::ConfigurablesOffsetPlaceholder, LoadDataId(r1, i) => Self::LoadDataId(update_reg(reg_to_reg_map, r1), i.clone()), AddrDataId(r1, i) => Self::AddrDataId(update_reg(reg_to_reg_map, r1), i.clone()), Undefined => Self::Undefined, @@ -1743,6 +1750,7 @@ impl VirtualOp { /* Non-VM Instructions */ BLOB(imm) => AllocatedOpcode::BLOB(imm.clone()), DataSectionOffsetPlaceholder => AllocatedOpcode::DataSectionOffsetPlaceholder, + ConfigurablesOffsetPlaceholder => AllocatedOpcode::ConfigurablesOffsetPlaceholder, LoadDataId(reg1, label) => { AllocatedOpcode::LoadDataId(map_reg(&mapping, reg1), label.clone()) } diff --git a/sway-core/src/lib.rs b/sway-core/src/lib.rs index d66b8e779eb..ac6b7d54d34 100644 --- a/sway-core/src/lib.rs +++ b/sway-core/src/lib.rs @@ -992,6 +992,28 @@ pub fn compile_to_bytecode( asm_to_bytecode(handler, asm_res, source_map, engines.se(), build_config) } +/// Size of the prelude's CONFIGURABLES_OFFSET section, in bytes. +pub const PRELUDE_CONFIGURABLES_SIZE_IN_BYTES: usize = 8; +/// Offset (in bytes) of the CONFIGURABLES_OFFSET section in the prelude. +pub const PRELUDE_CONFIGURABLES_OFFSET_IN_BYTES: usize = 16; +/// Total size of the prelude in bytes. Instructions start right after. +pub const PRELUDE_SIZE_IN_BYTES: usize = 32; + +/// Given bytecode, overwrite the existing offset to configurables offset in the prelude with the given one. +pub fn set_bytecode_configurables_offset( + compiled_bytecode: &mut CompiledBytecode, + md: &[u8; PRELUDE_CONFIGURABLES_SIZE_IN_BYTES], +) { + assert!( + compiled_bytecode.bytecode.len() + >= PRELUDE_CONFIGURABLES_OFFSET_IN_BYTES + PRELUDE_CONFIGURABLES_SIZE_IN_BYTES + ); + let code = &mut compiled_bytecode.bytecode; + for (index, byte) in md.iter().enumerate() { + code[index + PRELUDE_CONFIGURABLES_OFFSET_IN_BYTES] = *byte; + } +} + /// Given the assembly (opcodes), compile to [CompiledBytecode], containing the asm in bytecode form. pub fn asm_to_bytecode( handler: &Handler, diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle_new_encoding.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle_new_encoding.json index 2daeaffdc6a..4447c387c37 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle_new_encoding.json +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle_new_encoding.json @@ -62,82 +62,82 @@ { "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", "name": "BOOL", - "offset": 6896 + "offset": 7056 }, { "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", "name": "U8", - "offset": 7088 + "offset": 7248 }, { "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", "name": "ANOTHER_U8", - "offset": 6824 + "offset": 6984 }, { "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", "name": "U16", - "offset": 7032 + "offset": 7192 }, { "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", "name": "U32", - "offset": 7072 + "offset": 7232 }, { "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", "name": "U64", - "offset": 7080 + "offset": 7240 }, { "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", "name": "U256", - "offset": 7040 + "offset": 7200 }, { "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", "name": "B256", - "offset": 6864 + "offset": 7024 }, { "concreteTypeId": "81fc10c4681a3271cf2d66b2ec6fbc8ed007a442652930844fcf11818c295bff", "name": "CONFIGURABLE_STRUCT", - "offset": 6984 + "offset": 7144 }, { "concreteTypeId": "a2922861f03be8a650595dd76455b95383a61b46dd418f02607fa2e00dc39d5c", "name": "CONFIGURABLE_ENUM_A", - "offset": 6904 + "offset": 7064 }, { "concreteTypeId": "a2922861f03be8a650595dd76455b95383a61b46dd418f02607fa2e00dc39d5c", "name": "CONFIGURABLE_ENUM_B", - "offset": 6944 + "offset": 7104 }, { "concreteTypeId": "4926d35d1a5157936b0a29bc126b8aace6d911209a5c130e9b716b0c73643ea6", "name": "ARRAY_BOOL", - "offset": 6832 + "offset": 6992 }, { "concreteTypeId": "776fb5a3824169d6736138565fdc20aad684d9111266a5ff6d5c675280b7e199", "name": "ARRAY_U64", - "offset": 6840 + "offset": 7000 }, { "concreteTypeId": "c998ca9a5f221fe7b5c66ae70c8a9562b86d964408b00d17f883c906bc1fe4be", "name": "TUPLE_BOOL_U64", - "offset": 7016 + "offset": 7176 }, { "concreteTypeId": "94f0fa95c830be5e4f711963e83259fe7e8bc723278ab6ec34449e791a99b53a", "name": "STR_4", - "offset": 7008 + "offset": 7168 }, { "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", "name": "NOT_USED", - "offset": 7000 + "offset": 7160 } ], "encodingVersion": "1", diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/stdout.snap index 283bf9e035f..be59f759d26 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/stdout.snap @@ -1,5 +1,6 @@ --- source: test/tests/tests.rs +assertion_line: 99 --- > forc build --path test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode --release --ir final exit status: 0 @@ -358,4 +359,4 @@ script { !127 = fn_call_path_span !0 235 236 !128 = (!126 !127) - Finished release [optimized + fuel] target(s) [736 B] in ??? + Finished release [optimized + fuel] target(s) [744 B] in ??? diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/u256/u256_abi/json_abi_oracle_new_encoding.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/u256/u256_abi/json_abi_oracle_new_encoding.json index 5b834c3566e..33f149499d6 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/u256/u256_abi/json_abi_oracle_new_encoding.json +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/u256/u256_abi/json_abi_oracle_new_encoding.json @@ -9,7 +9,7 @@ { "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", "name": "SOME_U256", - "offset": 808 + "offset": 864 } ], "encodingVersion": "1", 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 575ca323135..3150cc69907 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 = 0xbbda20fb25bdb4b18451501418b06324376c61cb984e75fcbc983fc0a047f85b; // AUTO-CONTRACT-ID ../../test_contracts/array_of_structs_contract --release +const CONTRACT_ID = 0x91c3e72c3b3f4bf7bd5c548d8752c766d5fb8ebf15be3cf92ff34682da9bfb4d; // AUTO-CONTRACT-ID ../../test_contracts/array_of_structs_contract --release fn get_address() -> Option { Some(CONTRACT_ID.into()) 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 e177370b102..685e3d5444b 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 = 0xf2fecff29038dab2ef571397ea5507359265c9154608e7de36ccbea20ed5c8aa; +const FUEL_COIN_CONTRACT_ID = 0x19c0d374734bd8a92b776787e9dffa0f105a90e3c977626f93a1916de54dd714; #[cfg(experimental_new_encoding = false)] const BALANCE_CONTRACT_ID = 0xf6cd545152ac83225e8e7df2efb5c6fa6e37bc9b9e977b5ea8103d28668925df; #[cfg(experimental_new_encoding = true)] -const BALANCE_CONTRACT_ID = 0xebe7a84ed5198e9d7d3e002a571058dc24d56f61f2526ca30328f519528f98eb; // AUTO-CONTRACT-ID ../../test_contracts/balance_test_contract --release +const BALANCE_CONTRACT_ID = 0xc0ae93ca2a6ec1c740a4869a3f5bfe061184e30e4e5c6185891d3ec2dba9a33d; // 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 3afdbe1afc2..448359905b5 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 = 0xebe7a84ed5198e9d7d3e002a571058dc24d56f61f2526ca30328f519528f98eb; // AUTO-CONTRACT-ID ../../test_contracts/balance_test_contract --release +const CONTRACT_ID = 0xc0ae93ca2a6ec1c740a4869a3f5bfe061184e30e4e5c6185891d3ec2dba9a33d; // 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 49d7c83bf80..7778fd9369b 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 = 0x95bff8249257356f042d500e9f7db1a964ab5739a1b156eafaca3c7a4efc8aaa; // AUTO-CONTRACT-ID ../../test_contracts/abi_with_tuples_contract --release +const CONTRACT_ID = 0xeb1d43bccc97620c80599c25722b1be3a22affd0570cfdcc57deac7c729e5389; // 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 1f66a607f42..d519240f19d 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 = 0xfa786fd319eeb24fe328ceb0e033779ba444962f5534ec4ec24dc6686d3fdc1d; // AUTO-CONTRACT-ID ../../test_contracts/basic_storage --release +const CONTRACT_ID = 0x770eb6e1b7de06098474e110cac9ed32c72c455ba7f34bea00ebb47a43986701; // 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 a8ae0aaa993..61ba86c1b2c 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 = 0x741e73148cf8c2f12b620adb9a15275eeabe703a5c058b0e786117e92024fde2; // AUTO-CONTRACT-ID ../../test_contracts/contract_with_type_aliases --release +const CONTRACT_ID = 0xa3ebed6b4c9d17001bf759332daaa22c2e522cb1c61116ac395443f5ab392225; // 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 f518c022f5b..cdc8f7d508a 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 = 0xc906accda9e1e516ee3122770217d913edca1ae6e3b8bad15c2c1a53ebf5e13e; // AUTO-CONTRACT-ID ../../test_contracts/increment_contract --release +const CONTRACT_ID = 0x3a0ad1930a751f3849e10d55aedad4b14be604a1807b3016db959a311dbbd101; // 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 c3e736cb17f..c91268acb0f 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 = 0xaa4e990e0796764624423b63c1bb14fdc02918294fab87682c1ee768de745a7e; // AUTO-CONTRACT-ID ../../test_contracts/storage_enum_contract --release +const CONTRACT_ID = 0x14df60f48d5874d2623ba7f5604987b29f6288a1ae35a130bfae57e64f74aa89; // 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 931e9f010df..ec50cbe43bd 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 = 0x57892f3d8bd8c58137b35d177a8c03121193d51138ad2218e814af505e90a7f2; // AUTO-CONTRACT-ID ../../test_contracts/auth_testing_contract --release +const CONTRACT_ID = 0xa3ee3b5d5469efa870ba468c36c3775ea5287da385d70fbcd4aadbf5acb5a772; // 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 0f6ed8007b6..65bca7c89cd 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 = 0x6c159e40368c6a37b8c479cd63f5462832d5dbdc8d872c4b30edc38e230b7e51; // AUTO-CONTRACT-ID ../../test_contracts/context_testing_contract --release +const CONTRACT_ID = 0x16f15adbe1fbdee5d19349fc245429dad3265f8a0f7a8143ffec39de8c809ff4; // 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 8410b0175e8..505fff93133 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 = 0xc26e4f54f9bca811be460d07aaedfa12d46477378573947ae95653affba962be; // AUTO-CONTRACT-ID ../../test_contracts/nested_struct_args_contract --release +const CONTRACT_ID = 0xd9e836ce255122c0c243cb0bd6d10450d87206f995d127e60e90bf9ab4fc3532; // 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 d8f0d656e18..33f80e65b6b 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 = 0xdc525dd2ea57aa691d4d61acd725ebbefd974eaeb397598ca90c38807dc749bb; // AUTO-CONTRACT-ID ../../test_contracts/storage_access_contract --release +const CONTRACT_ID = 0x9075162ba3ecabb57aae8ddcd785d8a1211d08281de71c34a1772a888e339ba1; // AUTO-CONTRACT-ID ../../test_contracts/storage_access_contract --release fn main() -> bool { let caller = abi(StorageAccess, CONTRACT_ID); diff --git a/test/src/sdk-harness/test_projects/auth/mod.rs b/test/src/sdk-harness/test_projects/auth/mod.rs index 2fefd28f8c8..5c167a1d927 100644 --- a/test/src/sdk-harness/test_projects/auth/mod.rs +++ b/test/src/sdk-harness/test_projects/auth/mod.rs @@ -624,7 +624,7 @@ async fn can_get_predicate_address() { // Setup predicate. let hex_predicate_address: &str = - "0x5dcc82a88eebb07fb628db93d11ec38f085cbf36453a7135fea41b93cc44e118"; + "0x8b300a68337368654e71c65ae93c3d9eb3b9837d0c11d770cbf8740a6a5a8631"; let predicate_address = Address::from_str(hex_predicate_address).expect("failed to create Address from string"); let predicate_bech32_address = Bech32Address::from(predicate_address); @@ -750,7 +750,7 @@ async fn when_incorrect_predicate_address_passed() { async fn can_get_predicate_address_in_message() { // Setup predicate address. let hex_predicate_address: &str = - "0x5dcc82a88eebb07fb628db93d11ec38f085cbf36453a7135fea41b93cc44e118"; + "0x8b300a68337368654e71c65ae93c3d9eb3b9837d0c11d770cbf8740a6a5a8631"; let predicate_address = Address::from_str(hex_predicate_address).expect("failed to create Address from string"); let predicate_bech32_address = Bech32Address::from(predicate_address); From 139b5b62f5f292ed191ddafab7c876c5cc4d1e20 Mon Sep 17 00:00:00 2001 From: Marcos Henrich Date: Wed, 30 Oct 2024 10:44:48 +0000 Subject: [PATCH 090/115] Fixes find_method_for_type bail out with 1st match (#6606) ## Description When find_method_for_type could not match the parameters and return type with the available methods it would return the first match by name. This was not a deterministic and secure behavior so now we strictly match the parameter and return types. Fixes #5086 find_method_for_type now if we have: impl FromBytes for T and: impl FromBytes for DataPoint, we pick the second implementation. Fixes https://github.com/FuelLabs/sway/issues/6572 ## 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 Co-authored-by: Joshua Batty --- .../ast_node/declaration/function.rs | 6 +- .../ast_node/expression/typed_expression.rs | 12 ++ .../semantic_analysis/namespace/trait_map.rs | 18 +- .../semantic_analysis/type_check_context.rs | 172 +++++++++++++++--- .../ast_elements/type_parameter.rs | 14 +- .../src/type_system/unify/unify_check.rs | 55 +++++- sway-error/src/error.rs | 19 +- .../abi_supertrait_method_call/test.toml | 4 +- .../associated_fn_as_method_call/test.toml | 4 +- .../test.toml | 4 +- .../excess_associated_fn_arguments/test.toml | 4 +- .../excess_method_arguments/test.toml | 4 +- .../should_fail/for_bad_iterator/test.toml | 2 +- .../for_mismatch_pattern_type/test.toml | 7 +- .../generic_and_associated_type/test.toml | 8 +- .../should_fail/generic_traits/test.toml | 4 +- .../test.toml | 4 +- .../generics_in_contract/test.toml | 6 +- .../illegal_use_of_generic/test.toml | 4 +- .../impl_with_bad_generic/test.toml | 2 +- .../test.toml | 6 +- .../language/import_star_name_clash/test.toml | 2 +- .../language/reexport/aliases/test.toml | 12 +- .../shadowing_in_reexporting_module/test.toml | 14 +- .../reexport/simple_glob_import/test.toml | 14 +- .../reexport/simple_item_import/test.toml | 2 +- .../references/impl_reference_types/test.toml | 20 +- .../missing_associated_fn_arguments/test.toml | 4 +- .../missing_method_arguments/test.toml | 4 +- .../test.toml | 2 +- .../test.toml | 2 +- .../struct_generic_abi_encode/test.toml | 2 +- .../superabi_contract_call2/test.toml | 2 +- .../trait_method_ambiguous/test.toml | 2 +- .../type_mismatch_error_message/test.toml | 3 +- .../should_fail/type_propagation/test.toml | 4 +- .../test_programs/should_fail/vec/test.toml | 12 +- .../should_fail/where_clause_impls/test.toml | 4 +- .../language/overlapped_trait_impls/Forc.lock | 13 ++ .../language/overlapped_trait_impls/Forc.toml | 9 + .../overlapped_trait_impls/src/main.sw | 49 +++++ .../language/overlapped_trait_impls/test.toml | 5 + .../language/trait_generic_override/Forc.lock | 13 ++ .../language/trait_generic_override/Forc.toml | 8 + .../trait_generic_override/src/main.sw | 60 ++++++ .../language/trait_generic_override/test.toml | 5 + 46 files changed, 493 insertions(+), 133 deletions(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/overlapped_trait_impls/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/overlapped_trait_impls/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/overlapped_trait_impls/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/overlapped_trait_impls/test.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/trait_generic_override/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/trait_generic_override/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/trait_generic_override/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/trait_generic_override/test.toml diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/function.rs b/sway-core/src/semantic_analysis/ast_node/declaration/function.rs index 52ede5c3343..4b5b306cb98 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/function.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/function.rs @@ -216,8 +216,12 @@ impl ty::TyFunctionDecl { } = ty_fn_decl; // Insert the previously type checked type parameters into the current namespace. + // We insert all type parameter before the constraints because some constraints may depend on the parameters. + for p in type_parameters.iter() { + p.insert_into_namespace_self(handler, ctx.by_ref())?; + } for p in type_parameters { - p.insert_into_namespace(handler, ctx.by_ref())?; + p.insert_into_namespace_constraints(handler, ctx.by_ref())?; } // Insert the previously type checked function parameters into the current namespace. diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs index 51672758fba..229f38dd9c2 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs @@ -58,6 +58,12 @@ impl ty::TyExpression { arguments: Vec, span: Span, ) -> Result { + let engines = ctx.engines; + let ctx = ctx.with_type_annotation(engines.te().insert( + engines, + TypeInfo::Boolean, + span.source_id(), + )); Self::core_ops(handler, ctx, OpVariant::Equals, arguments, span) } @@ -67,6 +73,12 @@ impl ty::TyExpression { arguments: Vec, span: Span, ) -> Result { + let engines = ctx.engines; + let ctx = ctx.with_type_annotation(engines.te().insert( + engines, + TypeInfo::Boolean, + span.source_id(), + )); Self::core_ops(handler, ctx, OpVariant::NotEquals, arguments, span) } diff --git a/sway-core/src/semantic_analysis/namespace/trait_map.rs b/sway-core/src/semantic_analysis/namespace/trait_map.rs index 6b966d16b5a..15113704762 100644 --- a/sway-core/src/semantic_analysis/namespace/trait_map.rs +++ b/sway-core/src/semantic_analysis/namespace/trait_map.rs @@ -1020,7 +1020,7 @@ impl TraitMap { type_id: TypeId, ) -> Vec<(ResolvedTraitImplItem, TraitKey)> { let type_engine = engines.te(); - let unify_check = UnifyCheck::non_dynamic_equality(engines); + let unify_check = UnifyCheck::non_dynamic_equality(engines).with_unify_ref_mut(false); let mut items = vec![]; // small performance gain in bad case @@ -1298,16 +1298,18 @@ impl TraitMap { CompileError::MultipleApplicableItemsInScope { item_name: symbol.as_str().to_string(), item_kind: "item".to_string(), - type_name: engines.help_out(type_id).to_string(), as_traits: candidates .keys() .map(|k| { - k.clone() - .split("::") - .collect::>() - .last() - .unwrap() - .to_string() + ( + k.clone() + .split("::") + .collect::>() + .last() + .unwrap() + .to_string(), + engines.help_out(type_id).to_string(), + ) }) .collect::>(), span: symbol.span(), diff --git a/sway-core/src/semantic_analysis/type_check_context.rs b/sway-core/src/semantic_analysis/type_check_context.rs index 4a7e6ccf852..d6c3a7c45f1 100644 --- a/sway-core/src/semantic_analysis/type_check_context.rs +++ b/sway-core/src/semantic_analysis/type_check_context.rs @@ -1,5 +1,5 @@ #![allow(clippy::mutable_key_type)] -use std::collections::{HashMap, VecDeque}; +use std::collections::{HashMap, HashSet, VecDeque}; use crate::{ decl_engine::{DeclEngineGet, DeclRefFunction}, @@ -825,17 +825,40 @@ impl<'a> TypeCheckContext<'a> { // While collecting unification we don't decay numeric and will ignore this error. if self.collecting_unifications { return Err(handler.emit_err(CompileError::MethodNotFound { - method_name: method_name.clone(), + method: method_name.clone().as_str().to_string(), type_name: self.engines.help_out(type_id).to_string(), + matching_method_strings: vec![], span: method_name.span(), })); } type_engine.decay_numeric(handler, self.engines, type_id, &method_name.span())?; } - let matching_item_decl_refs = + let mut matching_item_decl_refs = self.find_items_for_type(handler, type_id, method_prefix, method_name)?; + // This code path tries to get items of specific implementation of the annotation type that is a superset of type id. + // This allows the following associated method to be found: + // let _: Option> = MyStruct::try_from(my_u64); + if !matches!(&*type_engine.get(annotation_type), TypeInfo::Unknown) + && !type_id.is_concrete(self.engines, crate::TreatNumericAs::Concrete) + { + let inner_types = + annotation_type.extract_inner_types(self.engines, crate::IncludeSelf::Yes); + for inner_type_id in inner_types { + if coercion_check.check(inner_type_id, type_id) { + matching_item_decl_refs.extend(self.find_items_for_type( + handler, + inner_type_id, + method_prefix, + method_name, + )?); + } + } + } + + let mut matching_method_strings = HashSet::::new(); + let matching_method_decl_refs = matching_item_decl_refs .into_iter() .flat_map(|item| match item { @@ -853,22 +876,40 @@ impl<'a> TypeCheckContext<'a> { let mut maybe_method_decl_refs: Vec = vec![]; for decl_ref in matching_method_decl_refs.clone().into_iter() { let method = decl_engine.get_function(&decl_ref); - if method.parameters.len() == arguments_types.len() + // Contract call methods don't have self parameter. + let args_len_diff = if method.is_contract_call && !arguments_types.is_empty() { + 1 + } else { + 0 + }; + if method.parameters.len() == arguments_types.len() - args_len_diff && method .parameters .iter() - .zip(arguments_types.iter()) - .all(|(p, a)| coercion_check.check(p.type_argument.type_id, *a)) + .zip(arguments_types.iter().skip(args_len_diff)) + .all(|(p, a)| coercion_check.check(*a, p.type_argument.type_id)) && (matches!(&*type_engine.get(annotation_type), TypeInfo::Unknown) - || coercion_check.check(annotation_type, method.return_type.type_id)) + || matches!( + &*type_engine.get(method.return_type.type_id), + TypeInfo::Never + ) + || coercion_check + .with_ignore_generic_names(true) + .check(annotation_type, method.return_type.type_id)) { maybe_method_decl_refs.push(decl_ref); } } if !maybe_method_decl_refs.is_empty() { - let mut trait_methods = - HashMap::<(CallPath, Vec>), DeclRefFunction>::new(); + let mut trait_methods = HashMap::< + ( + CallPath, + Vec>, + Option>, + ), + DeclRefFunction, + >::new(); let mut impl_self_method = None; for method_ref in maybe_method_decl_refs.clone() { let method = decl_engine.get_function(&method_ref); @@ -929,6 +970,11 @@ impl<'a> TypeCheckContext<'a> { .cloned() .map(|a| self.engines.help_out(a)) .collect::>(), + method.implementing_for_typeid.map(|t| { + self.engines.help_out( + (*self.engines.te().get(t)).clone(), + ) + }), ), method_ref.clone(), ); @@ -938,19 +984,38 @@ impl<'a> TypeCheckContext<'a> { } } + let trait_methods_key = ( + trait_decl.trait_name.clone(), + trait_decl + .trait_type_arguments + .iter() + .cloned() + .map(|a| self.engines.help_out(a)) + .collect::>(), + method.implementing_for_typeid.map(|t| { + self.engines.help_out((*self.engines.te().get(t)).clone()) + }), + ); + + // If we have: impl FromBytes for T + // and: impl FromBytes for DataPoint + // We pick the second implementation. + if let Some(existing_value) = trait_methods.get(&trait_methods_key) { + let existing_method = decl_engine.get_function(existing_value); + if let Some(ty::TyDecl::ImplSelfOrTrait(existing_impl_trait)) = + existing_method.implementing_type.clone() + { + let existing_trait_decl = decl_engine + .get_impl_self_or_trait(&existing_impl_trait.decl_id); + if existing_trait_decl.impl_type_parameters.is_empty() { + // We already have an impl without type parameters so we skip the others. + skip_insert = true; + } + } + } + if !skip_insert { - trait_methods.insert( - ( - trait_decl.trait_name.clone(), - trait_decl - .trait_type_arguments - .iter() - .cloned() - .map(|a| self.engines.help_out(a)) - .collect::>(), - ), - method_ref.clone(), - ); + trait_methods.insert(trait_methods_key, method_ref.clone()); } if trait_decl.trait_decl_ref.is_none() { impl_self_method = Some(method_ref); @@ -983,20 +1048,29 @@ impl<'a> TypeCheckContext<'a> { .collect::>() .join(", ") ) - } + }, ) } let mut trait_strings = trait_methods .keys() - .map(|t| to_string(t.0.clone(), t.1.clone())) - .collect::>(); + .map(|t| { + ( + to_string(t.0.clone(), t.1.clone()), + t.2.clone() + .map(|t| t.to_string()) + .or_else(|| { + Some(self.engines().help_out(type_id).to_string()) + }) + .unwrap(), + ) + }) + .collect::>(); // Sort so the output of the error is always the same. trait_strings.sort(); return Err(handler.emit_err( CompileError::MultipleApplicableItemsInScope { item_name: method_name.as_str().to_string(), item_kind: "function".to_string(), - type_name: self.engines.help_out(type_id).to_string(), as_traits: trait_strings, span: method_name.span(), }, @@ -1009,9 +1083,28 @@ impl<'a> TypeCheckContext<'a> { maybe_method_decl_refs.first().cloned() } } else { - // When we can't match any method with parameter types we still return the first method found - // This was the behavior before introducing the parameter type matching - matching_method_decl_refs.first().cloned() + for decl_ref in matching_method_decl_refs.clone().into_iter() { + let method = decl_engine.get_function(&decl_ref); + matching_method_strings.insert(format!( + "{}({}) -> {}{}", + method.name.as_str(), + method + .parameters + .iter() + .map(|p| self.engines.help_out(p.type_argument.type_id).to_string()) + .collect::>() + .join(", "), + self.engines.help_out(method.return_type.type_id), + if let Some(implementing_for_type_id) = method.implementing_for_typeid { + format!(" in {}", self.engines.help_out(implementing_for_type_id)) + } else { + "".to_string() + } + )); + } + + // When we can't match any method with parameter types we will throw an error. + None } }; @@ -1054,9 +1147,30 @@ impl<'a> TypeCheckContext<'a> { } else { self.engines.help_out(type_id).to_string() }; + Err(handler.emit_err(CompileError::MethodNotFound { - method_name: method_name.clone(), + method: format!( + "{}({}){}", + method_name.clone(), + arguments_types + .iter() + .map(|a| self.engines.help_out(a).to_string()) + .collect::>() + .join(", "), + if matches!( + *self.engines.te().get(self.type_annotation), + TypeInfo::Unknown + ) { + "".to_string() + } else { + format!(" -> {}", self.engines.help_out(self.type_annotation)) + } + ), type_name, + matching_method_strings: matching_method_strings + .iter() + .cloned() + .collect::>(), span: method_name.span(), })) } diff --git a/sway-core/src/type_system/ast_elements/type_parameter.rs b/sway-core/src/type_system/ast_elements/type_parameter.rs index 2b2ca658d23..068f486b79f 100644 --- a/sway-core/src/type_system/ast_elements/type_parameter.rs +++ b/sway-core/src/type_system/ast_elements/type_parameter.rs @@ -380,19 +380,7 @@ impl TypeParameter { Ok(()) } - pub fn insert_into_namespace( - &self, - handler: &Handler, - mut ctx: TypeCheckContext, - ) -> Result<(), ErrorEmitted> { - self.insert_into_namespace_constraints(handler, ctx.by_ref())?; - - self.insert_into_namespace_self(handler, ctx.by_ref())?; - - Ok(()) - } - - fn insert_into_namespace_constraints( + pub(crate) fn insert_into_namespace_constraints( &self, handler: &Handler, mut ctx: TypeCheckContext, diff --git a/sway-core/src/type_system/unify/unify_check.rs b/sway-core/src/type_system/unify/unify_check.rs index b1e1a9db62a..9adb491678c 100644 --- a/sway-core/src/type_system/unify/unify_check.rs +++ b/sway-core/src/type_system/unify/unify_check.rs @@ -4,7 +4,7 @@ use crate::{ type_system::{priv_prelude::*, unify::occurs_check::OccursCheck}, }; -#[derive(Debug)] +#[derive(Debug, Clone)] enum UnifyCheckMode { /// Given two [TypeId]'s `left` and `right`, check to see if `left` can be /// coerced into `right`. @@ -173,6 +173,8 @@ enum UnifyCheckMode { pub(crate) struct UnifyCheck<'a> { engines: &'a Engines, mode: UnifyCheckMode, + unify_ref_mut: bool, + ignore_generic_names: bool, } impl<'a> UnifyCheck<'a> { @@ -180,18 +182,24 @@ impl<'a> UnifyCheck<'a> { Self { engines, mode: UnifyCheckMode::Coercion, + unify_ref_mut: true, + ignore_generic_names: false, } } pub(crate) fn constraint_subset(engines: &'a Engines) -> Self { Self { engines, mode: UnifyCheckMode::ConstraintSubset, + unify_ref_mut: true, + ignore_generic_names: false, } } pub(crate) fn non_generic_constraint_subset(engines: &'a Engines) -> Self { Self { engines, mode: UnifyCheckMode::NonGenericConstraintSubset, + unify_ref_mut: true, + ignore_generic_names: false, } } @@ -199,6 +207,26 @@ impl<'a> UnifyCheck<'a> { Self { engines, mode: UnifyCheckMode::NonDynamicEquality, + unify_ref_mut: true, + ignore_generic_names: false, + } + } + + pub(crate) fn with_unify_ref_mut(&self, unify_ref_mut: bool) -> Self { + Self { + unify_ref_mut, + ignore_generic_names: self.ignore_generic_names, + engines: self.engines, + mode: self.mode.clone(), + } + } + + pub(crate) fn with_ignore_generic_names(&self, ignore_generic_names: bool) -> Self { + Self { + unify_ref_mut: self.unify_ref_mut, + ignore_generic_names, + engines: self.engines, + mode: self.mode.clone(), } } @@ -324,7 +352,7 @@ impl<'a> UnifyCheck<'a> { to_mutable_value: r_to_mut, referenced_type: r_ty, }, - ) => { + ) if self.unify_ref_mut => { // Unification is possible in these situations, assuming that the referenced types // can unify: // l -> r @@ -334,6 +362,19 @@ impl<'a> UnifyCheck<'a> { return (*l_to_mut || !*r_to_mut) && self.check_inner(l_ty.type_id, r_ty.type_id); } + ( + Ref { + to_mutable_value: l_to_mut, + referenced_type: l_ty, + }, + Ref { + to_mutable_value: r_to_mut, + referenced_type: r_ty, + }, + ) => { + return *l_to_mut == *r_to_mut && self.check_inner(l_ty.type_id, r_ty.type_id); + } + (UnknownGeneric { parent: lp, .. }, r) if lp.is_some() && self @@ -389,12 +430,12 @@ impl<'a> UnifyCheck<'a> { parent: _, is_from_type_parameter: _, }, - ) => ln == rn && rtc.eq(ltc, &PartialEqWithEnginesContext::new(self.engines)), - // any type can be coerced into a generic, - // except if the type already contains the generic - (_e, _g @ UnknownGeneric { .. }) => { - !OccursCheck::new(self.engines).check(right, left) + ) => { + (ln == rn || self.ignore_generic_names) + && rtc.eq(ltc, &PartialEqWithEnginesContext::new(self.engines)) } + // any type can be coerced into a generic, + (_e, _g @ UnknownGeneric { .. }) => true, // Never coerces to any other type. (Never, _) => true, diff --git a/sway-error/src/error.rs b/sway-error/src/error.rs index 20fc0e02235..3998426f92e 100644 --- a/sway-error/src/error.rs +++ b/sway-error/src/error.rs @@ -370,10 +370,18 @@ pub enum CompileError { }, #[error("Field \"{field_name}\" has multiple definitions.")] StructFieldDuplicated { field_name: Ident, duplicate: Ident }, - #[error("No method named \"{method_name}\" found for type \"{type_name}\".")] + #[error("No method \"{method}\" found for type \"{type_name}\".{}", + if matching_method_strings.is_empty() { + "".to_string() + } else { + format!(" \nMatching method{}:\n{}", if matching_method_strings.len()> 1 {"s"} else {""}, + matching_method_strings.iter().map(|m| format!(" {m}")).collect::>().join("\n")) + } + )] MethodNotFound { - method_name: Ident, + method: String, type_name: String, + matching_method_strings: Vec, span: Span, }, #[error("Module \"{name}\" could not be found.")] @@ -955,18 +963,17 @@ pub enum CompileError { let mut candidates = "".to_string(); let mut as_traits = as_traits.clone(); // Make order deterministic - as_traits.sort_by_key(|a| a.to_lowercase()); + as_traits.sort_by_key(|a| a.0.to_lowercase()); for (index, as_trait) in as_traits.iter().enumerate() { - candidates = format!("{candidates}\n Disambiguate the associated {item_kind} for candidate #{index}\n <{type_name} as {as_trait}>::{item_name}"); + candidates = format!("{candidates}\n Disambiguate the associated {item_kind} for candidate #{index}\n <{} as {}>::{item_name}", as_trait.1, as_trait.0); } candidates })] MultipleApplicableItemsInScope { span: Span, - type_name: String, item_name: String, item_kind: String, - as_traits: Vec, + as_traits: Vec<(String, String)>, }, #[error("Provided generic type is not of type str.")] NonStrGenericType { span: Span }, diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/abi_supertrait_method_call/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/abi_supertrait_method_call/test.toml index 0163a006bee..ec05d227d6e 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/abi_supertrait_method_call/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/abi_supertrait_method_call/test.toml @@ -1,3 +1,5 @@ category = "fail" -# check: $()Cannot call ABI supertrait's method as a contract method: "foo" +# check: $()No method "foo(ContractCaller)" found for type "ContractCaller". +# nextln: $()Matching method: +# nextln: $()foo() -> () in ContractCaller diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/associated_fn_as_method_call/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/associated_fn_as_method_call/test.toml index 5b0a6ad2f12..c1b04f88aac 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/associated_fn_as_method_call/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/associated_fn_as_method_call/test.toml @@ -1,6 +1,8 @@ category = "fail" # check: bar.associated() -# nextln: $()Cannot call associated function "associated" as a method. Use associated function syntax instead. +# nextln: $()No method "associated(Bar)" found for type "Bar". +# nextln: $()Matching method: +# nextln: $()associated() -> () in Bar expected_warnings = 1 \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/associated_fn_params_as_method_call/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/associated_fn_params_as_method_call/test.toml index 5b0a6ad2f12..c1b04f88aac 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/associated_fn_params_as_method_call/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/associated_fn_params_as_method_call/test.toml @@ -1,6 +1,8 @@ category = "fail" # check: bar.associated() -# nextln: $()Cannot call associated function "associated" as a method. Use associated function syntax instead. +# nextln: $()No method "associated(Bar)" found for type "Bar". +# nextln: $()Matching method: +# nextln: $()associated() -> () in Bar expected_warnings = 1 \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/excess_associated_fn_arguments/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/excess_associated_fn_arguments/test.toml index 47b5caf9068..d95ef4d7d41 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/excess_associated_fn_arguments/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/excess_associated_fn_arguments/test.toml @@ -1,3 +1,5 @@ category = "fail" -# check: $()Function "add_values" expects 2 arguments but you provided 3. +# check: $()No method "add_values(Data, Data, Data) -> u64" found for type "Data". +# nextln: $()Matching method: +# nextln: $()add_values(Data, Data) -> u64 in Data diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/excess_method_arguments/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/excess_method_arguments/test.toml index 151067c8a3c..d95ef4d7d41 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/excess_method_arguments/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/excess_method_arguments/test.toml @@ -1,3 +1,5 @@ category = "fail" -# check: $()Method "add_values" expects 1 argument but you provided 2. +# check: $()No method "add_values(Data, Data, Data) -> u64" found for type "Data". +# nextln: $()Matching method: +# nextln: $()add_values(Data, Data) -> u64 in Data diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/for_bad_iterator/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/for_bad_iterator/test.toml index b406de3973a..957600daf8d 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/for_bad_iterator/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/for_bad_iterator/test.toml @@ -1,4 +1,4 @@ category = "fail" # check: $()for _n in vector -# nextln: $()No method named "next" found for type "Vec". +# nextln: $()No method "next(Vec)" found for type "Vec". diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/for_mismatch_pattern_type/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/for_mismatch_pattern_type/test.toml index 210f9990ae8..b1175daf9b9 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/for_mismatch_pattern_type/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/for_mismatch_pattern_type/test.toml @@ -1,7 +1,6 @@ category = "fail" # check: $()for (_n,_m) in vector.iter() -# nextln: $()Mismatched types. -# nextln: $()expected: (_, _) -# nextln: $()found: u64. -# nextln: $()help: Function return type does not match up with local type annotation. +# nextln: $()No method "unwrap(Option) -> (_, _)" found for type "Option". +# nextln: $()Matching method: +# nextln: $()unwrap(Option) -> u64 in Option diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/generic_and_associated_type/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/generic_and_associated_type/test.toml index c6d7130f372..6e1bfcc1c5d 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/generic_and_associated_type/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/generic_and_associated_type/test.toml @@ -1,8 +1,6 @@ category = "fail" -# check: $()Self::method() -# nextln: $()Mismatched types. -# nextln: $()expected: T -# nextln: $()found: trait type Self::T -# nextln: $()help: Function return type does not match up with local type annotation. +# check: $()No method "method() -> T" found for type "Self". +# nextln: $()Matching method: +# nextln: $()method() -> trait type Self::T in Self diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/generic_traits/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/generic_traits/test.toml index 0181ab1b57a..7d6aa0ac218 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/generic_traits/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/generic_traits/test.toml @@ -53,4 +53,6 @@ category = "fail" # check: $()help: Function body's return type does not match up with its return type annotation. # check: $()let b = a.set(42); -# check: $()No method named "set" found for type "FooBarData". +# check: $()No method "set(FooBarData, numeric) -> bool" found for type "FooBarData". + +# check: $()Aborting due to 21 errors. diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/generic_traits_bad_type_inference/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/generic_traits_bad_type_inference/test.toml index 30f4a8a1a94..7da98e8a5e3 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/generic_traits_bad_type_inference/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/generic_traits_bad_type_inference/test.toml @@ -1,4 +1,6 @@ category = "fail" # check: $()let _c = a.set_it(false); -# nextln: $()This parameter was declared as type u8, but argument of type bool was provided. +# nextln: $()No method "set_it(FooBarData, bool)" found for type "FooBarData". +# nextln: $()Matching method: +# nextln: $()set_it(FooBarData, u8) -> FooBarData in FooBarData diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/generics_in_contract/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/generics_in_contract/test.toml index 4ba4bed68ea..86e23d2f128 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/generics_in_contract/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/generics_in_contract/test.toml @@ -1,9 +1,11 @@ category = "fail" # check: $()error -# nextln: generics_in_contract/src/main.sw:19:22 +# nextln: generics_in_contract/src/main.sw:19:17 # check: $()vec.push(item); -# check: $()This parameter was declared as type V, but argument of type K was provided. +# check: $()No method "push(Vec, K)" found for type "Vec". +# nextln: $()Matching method: +# nextln: $()push(Vec, V) -> () in Vec # check: $()error # nextln: generics_in_contract/src/main.sw:39:9 diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/illegal_use_of_generic/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/illegal_use_of_generic/test.toml index 3a9c6fb4f6a..991678c82f4 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/illegal_use_of_generic/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/illegal_use_of_generic/test.toml @@ -1,7 +1,7 @@ category = "fail" # check: $()fn test_function(value: T) { -# check: $()No method named "new" found for type "T" +# check: $()No method "new()" found for type "T". # check: $()fn test_function(self) { -# check: $()No method named "new" found for type "T". +# check: $()No method "new()" found for type "T". diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/impl_with_bad_generic/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/impl_with_bad_generic/test.toml index 1b2e841ba1c..64ae06e9ec3 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/impl_with_bad_generic/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/impl_with_bad_generic/test.toml @@ -2,4 +2,4 @@ category = "fail" # check: $()The generic type parameter "T" is unconstrained. -# check: $()No method named "f" found for type "S". +# check: $()No method "f(S, bool)" found for type "S". diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/impl_with_semantic_type_constraints/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/impl_with_semantic_type_constraints/test.toml index ecf12dbe981..ad9e899e487 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/impl_with_semantic_type_constraints/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/impl_with_semantic_type_constraints/test.toml @@ -1,10 +1,10 @@ category = "fail" # check: let _i = b.add(); -# nextln: $()No method named "add" found for type "DoubleIdentity". +# nextln: $()No method "add(DoubleIdentity)" found for type "DoubleIdentity". # check: let _j = c.get_first(); -# nextln: $()No method named "get_first" found for type "DoubleIdentity". +# nextln: $()No method "get_first(DoubleIdentity)" found for type "DoubleIdentity". # check: let _l = c.add(); -# nextln: $()No method named "add" found for type "DoubleIdentity". +# nextln: $()No method "add(DoubleIdentity)" found for type "DoubleIdentity". diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/language/import_star_name_clash/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/language/import_star_name_clash/test.toml index 0224e899b37..6f28c9e7248 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/language/import_star_name_clash/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/language/import_star_name_clash/test.toml @@ -49,7 +49,7 @@ category = "fail" # check: $()Unknown type name "MyEnum". # check: $()error -# check: $()No method named "B" found for type "MyEnum". +# check: $()No method "B(numeric)" found for type "MyEnum". # check: $()error # check: $()Mismatched types. diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/aliases/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/aliases/test.toml index 8d07f8ae8dc..f546cf5a332 100755 --- a/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/aliases/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/aliases/test.toml @@ -107,7 +107,7 @@ category = "fail" #check: $()error #check: $()assert(items_2_struct_res == 123); -#nextln: $()No method named "eq" found for type "{unknown}". +#nextln: $()No method "eq({unknown}, numeric) -> bool" found for type "{unknown}". #check: $()error #check: $()let items_2_enum = Items2_Enum::C(432); @@ -123,7 +123,7 @@ category = "fail" #check: $()error #check: $()assert(items_2_enum_res == 432); -#nextln: $()No method named "eq" found for type "{unknown}". +#nextln: $()No method "eq({unknown}, numeric) -> bool" found for type "{unknown}". #check: $()error #check: $()let items_2_variants = Z(680); @@ -135,7 +135,7 @@ category = "fail" #check: $()error #check: $()let items_2_trait_teststruct_1_res = teststruct_1.items_2_trait_function(teststruct_2); -#nextln: $()No method named "items_2_trait_function" found for type "TestStruct1". +#nextln: $()No method "items_2_trait_function(TestStruct1, TestStruct2) -> bool" found for type "TestStruct1". #check: $()error #check: $()let items_3_struct = Items3_Struct { c: 123 }; @@ -151,7 +151,7 @@ category = "fail" #check: $()error #check: $()assert(items_3_struct_res == 123); -#nextln: $()No method named "eq" found for type "{unknown}". +#nextln: $()No method "eq({unknown}, numeric) -> bool" found for type "{unknown}". #check: $()error #check: $()let items_3_enum = Items3_Enum::E(432); @@ -167,7 +167,7 @@ category = "fail" #check: $()error #check: $()assert(items_3_enum_res == 432); -#nextln: $()No method named "eq" found for type "{unknown}". +#nextln: $()No method "eq({unknown}, numeric) -> bool" found for type "{unknown}". #check: $()error #check: $()let items_3_variants = U(680); @@ -179,7 +179,7 @@ category = "fail" #check: $()error #check: $()let items_3_trait_teststruct_1_res = teststruct_1.items_3_trait_function(teststruct_2); -#nextln: $()No method named "items_3_trait_function" found for type "TestStruct1". +#nextln: $()No method "items_3_trait_function(TestStruct1, TestStruct2) -> bool" found for type "TestStruct1". #check: $()error #check: $()let items_5_trait_teststruct_1_res = teststruct_1.items_5_trait_function(teststruct_2); 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 700594e5116..4be40b4867c 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 @@ -92,7 +92,7 @@ category = "fail" #check: $()error #check: $()Items1_Enum::B(val) => val + 1000, -#nextln: $()No method named "add" found for type "bool". +#nextln: $()No method "add(bool, numeric) -> u64" found for type "bool". #check: $()error #check: $()items_1_function() @@ -131,7 +131,7 @@ category = "fail" #check: $()error #check: $()Items2_Enum::D(val) => val + 1000, -#nextln: $()No method named "add" found for type "bool". +#nextln: $()No method "add(bool, numeric) -> u64" found for type "bool". #check: $()error #check: $()items_2_function() @@ -164,7 +164,9 @@ category = "fail" #check: $()error #check: $()let items_1_trait_teststruct_1_res = teststruct_1.items_1_trait_function(teststruct_2); -#nextln: $()Cannot call associated function "items_1_trait_function" as a method. Use associated function syntax instead. +#nextln: $()No method "items_1_trait_function(TestStruct1, TestStruct2)" found for type "TestStruct1". +#nextln: $()Matching method: +#nextln: $()items_1_trait_function() -> u64 #check: $()error #check: $()let items_2_struct = Items2_Struct { b: 879 }; @@ -180,7 +182,9 @@ category = "fail" #check: $()error #check: $()let items_2_trait_teststruct_1_res = teststruct_1.items_2_trait_function(teststruct_2); -#nextln: $()Cannot call associated function "items_2_trait_function" as a method. Use associated function syntax instead. +#nextln: $()No method "items_2_trait_function(TestStruct1, TestStruct2)" found for type "TestStruct1". +#nextln: $()Matching method: +#nextln: $()items_2_trait_function() -> u64 #check: $()error #check: $()This path must return a value of type "u64" from function "items_1_trait_function", but it does not. @@ -188,4 +192,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 42 errors. +#check: $()Aborting due to 44 errors. diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/simple_glob_import/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/simple_glob_import/test.toml index a17f001163a..c8cc24eebf1 100755 --- a/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/simple_glob_import/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/simple_glob_import/test.toml @@ -64,7 +64,7 @@ category = "fail" #check: $()Could not find symbol "project_items_1_struct" in this scope. #check: $()error -#check: $()No method named "eq" found for type "{unknown}". +#check: $()No method "eq({unknown}, numeric) -> bool" found for type "{unknown}". #check: $()error #check: $()Could not find symbol "Items1_Enum" in this scope. @@ -76,7 +76,7 @@ category = "fail" #check: $()Could not find symbol "project_items_1_enum" in this scope. #check: $()error -#check: $()No method named "eq" found for type "{unknown}". +#check: $()No method "eq({unknown}, numeric) -> bool" found for type "{unknown}". #check: $()error #check: $()Could not find symbol "X" in this scope. @@ -85,7 +85,7 @@ category = "fail" #check: $()Variable "ITEMS_1_FUNCTION_RES" does not exist in this scope. #check: $()error -#check: $()No method named "items_1_trait_function" found for type "TestStruct1". +#check: $()No method "items_1_trait_function(TestStruct1, TestStruct2) -> bool" found for type "TestStruct1". #check: $()error #check: $()Could not find symbol "Items2_Struct" in this scope. @@ -97,7 +97,7 @@ category = "fail" #check: $()Could not find symbol "project_items_2_struct" in this scope. #check: $()error -#check: $()No method named "eq" found for type "{unknown}". +#check: $()No method "eq({unknown}, numeric) -> bool" found for type "{unknown}". #check: $()error #check: $()Could not find symbol "Items2_Enum" in this scope. @@ -109,7 +109,7 @@ category = "fail" #check: $()Could not find symbol "project_items_2_enum" in this scope. #check: $()error -#check: $()No method named "eq" found for type "{unknown}". +#check: $()No method "eq({unknown}, numeric) -> bool" found for type "{unknown}". #check: $()error #check: $()Could not find symbol "O" in this scope. @@ -118,12 +118,12 @@ category = "fail" #check: $()Could not find symbol "project_items_2_variants" in this scope. #check: $()error -#check: $()No method named "eq" found for type "{unknown}". +#check: $()No method "eq({unknown}, numeric) -> bool" found for type "{unknown}". #check: $()error #check: $()Variable "ITEMS_2_FUNCTION_RES" does not exist in this scope. #check: $()error -#check: $()No method named "items_2_trait_function" found for type "TestStruct1". +#check: $()No method "items_2_trait_function(TestStruct1, TestStruct2) -> bool" found for type "TestStruct1". #check: $()Aborting due to 42 errors. diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/simple_item_import/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/simple_item_import/test.toml index 3e1058ab30e..286919c366a 100755 --- a/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/simple_item_import/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/simple_item_import/test.toml @@ -86,6 +86,6 @@ category = "fail" #check: $()error #check: $()assert(items_3_variants_res == 513); -#nextln: $()No method named "eq" found for type "{unknown}". +#nextln: $()No method "eq({unknown}, numeric) -> bool" found for type "{unknown}". #check: $()Aborting due to 22 errors. diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/language/references/impl_reference_types/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/language/references/impl_reference_types/test.toml index fbf8cf5ea7b..02153a0fcbc 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/language/references/impl_reference_types/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/language/references/impl_reference_types/test.toml @@ -3,52 +3,52 @@ category = "fail" #check: $()error #check: $()concrete_types.sw #check: $()r_x.ref_mut_u64_method(); -#nextln: $()No method named "ref_mut_u64_method" found for type "&u64". +#nextln: $()No method "ref_mut_u64_method(&u64)" found for type "&u64". #check: $()error #check: $()concrete_types.sw #check: $()r_r_x.ref_mut_ref_mut_u64_method(); -#nextln: $()No method named "ref_mut_ref_mut_u64_method" found for type "&&u64". +#nextln: $()No method "ref_mut_ref_mut_u64_method(&&u64)" found for type "&&u64". #check: $()error #check: $()ref_and_ref_mut.sw #check: $()r.ref_mut_u64(); -#nextln: $()No method named "ref_mut_u64" found for type "&u64". +#nextln: $()No method "ref_mut_u64(&u64)" found for type "&u64". #check: $()error #check: $()ref_and_ref_mut.sw #check: $()r.ref_mut_ref_mut_u64(); -#nextln: $()No method named "ref_mut_ref_mut_u64" found for type "&&u64". +#nextln: $()No method "ref_mut_ref_mut_u64(&&u64)" found for type "&&u64". #check: $()error #check: $()ref_and_ref_mut.sw #check: $()r.ref_ref_mut_u64(); -#nextln: $()No method named "ref_ref_mut_u64" found for type "&&u64". +#nextln: $()No method "ref_ref_mut_u64(&&u64)" found for type "&&u64". #check: $()error #check: $()ref_and_ref_mut.sw #check: $()r.ref_mut_ref_u64(); -#nextln: $()No method named "ref_mut_ref_u64" found for type "&&u64". +#nextln: $()No method "ref_mut_ref_u64(&&u64)" found for type "&&u64". #check: $()error #check: $()ref_and_ref_mut.sw #check: $()r.ref_mut_ref_mut_ref_mut_u64(); -#nextln: $()No method named "ref_mut_ref_mut_ref_mut_u64" found for type "&&&u64". +#nextln: $()No method "ref_mut_ref_mut_ref_mut_u64(&&&u64)" found for type "&&&u64". #check: $()error #check: $()ref_and_ref_mut.sw #check: $()r.ref_ref_mut_ref_mut_u64(); -#nextln: $()No method named "ref_ref_mut_ref_mut_u64" found for type "&&&u64". +#nextln: $()No method "ref_ref_mut_ref_mut_u64(&&&u64)" found for type "&&&u64". #check: $()error #check: $()ref_and_ref_mut.sw #check: $()r.ref_mut_ref_ref_mut_u64(); -#nextln: $()No method named "ref_mut_ref_ref_mut_u64" found for type "&&&u64". +#nextln: $()No method "ref_mut_ref_ref_mut_u64(&&&u64)" found for type "&&&u64". #check: $()error #check: $()ref_and_ref_mut.sw #check: $()r.ref_mut_ref_mut_ref_u64(); -#nextln: $()No method named "ref_mut_ref_mut_ref_u64" found for type "&&&u64". +#nextln: $()No method "ref_mut_ref_mut_ref_u64(&&&u64)" found for type "&&&u64". #check: $()Trait is already implemented for type #check: $()ref_and_ref_mut_trait_impls.sw diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/missing_associated_fn_arguments/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/missing_associated_fn_arguments/test.toml index f36cb035da2..e17f6f50baf 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/missing_associated_fn_arguments/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/missing_associated_fn_arguments/test.toml @@ -1,3 +1,5 @@ category = "fail" -# check: $()Function "add_values" expects 2 arguments but you provided 1. +# check: $()No method "add_values(Data) -> u64" found for type "Data". +# nextln: $()Matching method: +# nextln: $()add_values(Data, Data) -> u64 in Data \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/missing_method_arguments/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/missing_method_arguments/test.toml index 28d9481b512..85d0cc1c2b0 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/missing_method_arguments/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/missing_method_arguments/test.toml @@ -1,3 +1,5 @@ category = "fail" -# check: $()Method "add_values" expects 1 argument but you provided 0. +# check: $()No method "add_values(Data) -> u64" found for type "Data". +# nextln: $()Matching method: +# nextln: $()add_values(Data, Data) -> u64 in Data diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_associated_function/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_associated_function/test.toml index 3144024dde2..31d75f3b60c 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_associated_function/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_associated_over_associated_function/test.toml @@ -4,6 +4,6 @@ category = "fail" #nextln: $()Could not find symbol "S_ASSOC" in this scope. #check: $()const S_ASSOC: u8 = Self::assoc(); -#nextln: $()No method named "assoc" found for type "S". +#nextln: $()No method "assoc() -> u8" found for type "S". #check: $()2 errors. diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_function/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_function/test.toml index 40c88a01149..b7656b31d93 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_function/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_const_module_over_associated_function/test.toml @@ -1,7 +1,7 @@ category = "fail" #check: $()const MOD_CONST: u8 = S::assoc(); -#nextln: $()No method named "assoc" found for type "S". +#nextln: $()No method "assoc() -> u8" found for type "S". #check: $()const MOD_CONST: u8 = S::assoc(); #nextln: $()Could not evaluate initializer to a const declaration. diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/struct_generic_abi_encode/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/struct_generic_abi_encode/test.toml index 40fc5bf0e9a..70cfec78ca8 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/struct_generic_abi_encode/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/struct_generic_abi_encode/test.toml @@ -1,4 +1,4 @@ category = "fail" #check: $()self.ptr.abi_encode2(buffer); -#nextln: $()No method named "abi_encode2" found for type "pointer". +#nextln: $()No method "abi_encode2(pointer, Buffer)" found for type "pointer". diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/superabi_contract_call2/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/superabi_contract_call2/test.toml index 57e8ca1c4bd..cf2198b6b8a 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/superabi_contract_call2/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/superabi_contract_call2/test.toml @@ -1,3 +1,3 @@ category = "fail" -# check: $()No method named "super_abi_method" found for type "contract". \ No newline at end of file +# check: $()No method "super_abi_method() -> ()" found for type "contract". \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/trait_method_ambiguous/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/trait_method_ambiguous/test.toml index 7eab73fe377..57e172a56ea 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/trait_method_ambiguous/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/trait_method_ambiguous/test.toml @@ -4,7 +4,7 @@ category = "fail" # nextln: $()Could not find symbol "asd" in this scope. # check: $()::method(); -# nextln: $()No method named "method" found for type "S as S2". +# nextln: $()No method "method()" found for type "S as S2". # check: $()S::method(); // ambiguous method call here # nextln: $()Multiple applicable items in scope. diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/type_mismatch_error_message/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/type_mismatch_error_message/test.toml index 64a85667ae8..4ba8d851535 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/type_mismatch_error_message/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/type_mismatch_error_message/test.toml @@ -9,4 +9,5 @@ category = "fail" # nextln: $()Implicit return must match up with block's type. # check: $()error -# check: $()No method named "does_not_exist" found for type "MyResult, str[4]>". +# check: $()No method "does_not_exist(MyResult, str[4]>)" found for type "MyResult, str[4]>" + diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/type_propagation/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/type_propagation/test.toml index 5e4e3480d0b..70a975a3606 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/type_propagation/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/type_propagation/test.toml @@ -2,4 +2,6 @@ category = "fail" # check: $()a.push("str"); # check: $()a.push("str"); -# nextln: $()This parameter was declared as type u8, but argument of type str was provided +# nextln: $()No method "push(Vec, str)" found for type "Vec". +# nextln: $()Matching method: +# nextln: $()push(Vec, u8) -> () in Vec \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/vec/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/vec/test.toml index 9916d9f2d76..bf0719c436e 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/vec/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/vec/test.toml @@ -1,10 +1,16 @@ category = "fail" # check: vector.push(false); -# nextln: $()This parameter was declared as type u8, but argument of type bool was provided. +# nextln: $()No method "push(Vec, bool)" found for type "Vec". +# nextln: $()Matching method: +# nextln: $()push(Vec, u8) -> () in Vec # check: vector.push("this should break it 1"); -# nextln: $()This parameter was declared as type u8, but argument of type str was provided. +# nextln: $()No method "push(Vec, str)" found for type "Vec". +# nextln: $()Matching method: +# nextln: $()push(Vec, u8) -> () in Vec # check: vector.push("this should break it 2"); -# nextln: $()This parameter was declared as type u8, but argument of type str was provided. +# nextln: $()No method "push(Vec, str)" found for type "Vec". +# nextln: $()Matching method: +# nextln: $()push(Vec, u8) -> () in Vec diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/where_clause_impls/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/where_clause_impls/test.toml index 20ba9ab1c2c..2fc0f7f4c71 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/where_clause_impls/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/where_clause_impls/test.toml @@ -3,8 +3,8 @@ category = "fail" # check: $()x: a.x.my_add(b.x), # check: $()x: a.x.my_add(b.x), -# nextln: $()No method named "my_add" found for type "T". +# nextln: $()No method "my_add(T, T) -> T" found for type "T". # check: $()y: a.y.my_add(b.y), # check: $()y: a.y.my_add(b.y), -# nextln: $()No method named "my_add" found for type "T". +# nextln: $()No method "my_add(T, T) -> T" found for type "T". diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/overlapped_trait_impls/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/overlapped_trait_impls/Forc.lock new file mode 100644 index 00000000000..d3980d9ac06 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/overlapped_trait_impls/Forc.lock @@ -0,0 +1,13 @@ +[[package]] +name = "core" +source = "path+from-root-BB2447E2F19FD755" + +[[package]] +name = "overlapped_trait_impls" +source = "member" +dependencies = ["std"] + +[[package]] +name = "std" +source = "path+from-root-BB2447E2F19FD755" +dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/overlapped_trait_impls/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/overlapped_trait_impls/Forc.toml new file mode 100644 index 00000000000..aa6b2aaf32e --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/overlapped_trait_impls/Forc.toml @@ -0,0 +1,9 @@ +[project] +authors = ["Fuel Labs "] +license = "Apache-2.0" +name = "overlapped_trait_impls" +entry = "main.sw" +implicit-std = false + +[dependencies] +std = { path = "../../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/overlapped_trait_impls/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/overlapped_trait_impls/src/main.sw new file mode 100644 index 00000000000..cf489749e54 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/overlapped_trait_impls/src/main.sw @@ -0,0 +1,49 @@ +script; + +use std::{ + bytes::Bytes, + vec::Vec, +}; + +pub trait FromBytesConvertible { + fn _from_be_bytes(bytes: Bytes) -> Self; +} + +pub trait FromBytes { + fn from_bytes(bytes: Bytes) -> Self; +} + +impl FromBytes for T +where + T: FromBytesConvertible, +{ + fn from_bytes(bytes: Bytes) -> Self { + Self::_from_be_bytes(bytes) + } +} + +pub struct DataPoint {} +pub struct Payload {} + +impl FromBytes for DataPoint { + fn from_bytes(bytes: Bytes) -> Self { + Self {} + } +} + +impl Payload { + pub fn from_bytes(bytes: Bytes) { + let mut data_points = Vec::new(); + + data_points.push(DataPoint::from_bytes(bytes)); + + let a:DataPoint = DataPoint::from_bytes(bytes); + data_points.push(a); + } +} + +pub fn main() -> bool { + Payload::from_bytes(Bytes::new()); + + true +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/overlapped_trait_impls/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/overlapped_trait_impls/test.toml new file mode 100644 index 00000000000..a4d4f4bade7 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/overlapped_trait_impls/test.toml @@ -0,0 +1,5 @@ +category = "run" +expected_result = { action = "return", value = 1 } +expected_result_new_encoding = { action = "return_data", value = "01" } +validate_abi = false +expected_warnings = 3 diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/trait_generic_override/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/trait_generic_override/Forc.lock new file mode 100644 index 00000000000..b44e7f5f12a --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/trait_generic_override/Forc.lock @@ -0,0 +1,13 @@ +[[package]] +name = "core" +source = "path+from-root-708A1FDFF71F06AE" + +[[package]] +name = "std" +source = "path+from-root-708A1FDFF71F06AE" +dependencies = ["core"] + +[[package]] +name = "trait_generic_override" +source = "member" +dependencies = ["std"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/trait_generic_override/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/trait_generic_override/Forc.toml new file mode 100644 index 00000000000..936a6bda08a --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/trait_generic_override/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "trait_generic_override" + +[dependencies] +std = { path = "../../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/trait_generic_override/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/trait_generic_override/src/main.sw new file mode 100644 index 00000000000..03b7c84ec09 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/trait_generic_override/src/main.sw @@ -0,0 +1,60 @@ +script; + +use std::constants::ZERO_B256; + +struct MyStruct { + val: u64 +} + +trait From { + fn from2(num: T) -> Self; + fn try_from2(num: T) -> Option; + fn into2(self) -> T; +} + +// Implements on MyStruct +impl From for MyStruct { + fn from2(num: b256) -> Self { + MyStruct { val: 0 } + } + + fn try_from2(num: b256) -> Option { + Some(MyStruct { val: 0 }) + } + + fn into2(self) -> b256 { + ZERO_B256 + } +} + +// Implements on MyStruct +impl From for MyStruct { + fn from2(num: u64) -> Self { + MyStruct { val: 0 } + } + + fn try_from2(num: u64) -> Option { + Some(MyStruct { val: 0 }) + } + + fn into2(self) -> u64 { + 0 + } +} + +fn main() -> bool { + let my_struct: MyStruct = MyStruct { val: 1 }; + let my_b256 = ZERO_B256; + let my_u64 = 1_u64; + + let _into_b256: b256 = my_struct.into2(); + let _into_u64: u64 = my_struct.into2(); + + let _from_b256: MyStruct = MyStruct::from2(my_b256); + let _from_u64: MyStruct = MyStruct::from2(my_u64); + + let _try_from_b256: Option> = MyStruct::try_from2(my_b256); + let _try_from_u64: Option> = MyStruct::try_from2(my_u64); + + true +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/trait_generic_override/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/trait_generic_override/test.toml new file mode 100644 index 00000000000..ec2e442121c --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/trait_generic_override/test.toml @@ -0,0 +1,5 @@ +category = "run" +expected_result = { action = "return", value = 1 } +expected_result_new_encoding = { action = "return_data", value = "01" } +validate_abi = false +expected_warnings = 7 From 5b7d720cf97e88eedc3c069b617ee7493bb16637 Mon Sep 17 00:00:00 2001 From: IGI-111 Date: Wed, 30 Oct 2024 13:04:48 +0100 Subject: [PATCH 091/115] Bump to v0.66.3 (#6679) --- Cargo.lock | 70 +++++++++++++++++++++++++++--------------------------- Cargo.toml | 50 +++++++++++++++++++------------------- 2 files changed, 60 insertions(+), 60 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 32887369fb4..0d2d424463b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2675,7 +2675,7 @@ checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" [[package]] name = "forc" -version = "0.66.2" +version = "0.66.3" dependencies = [ "annotate-snippets", "ansi_term", @@ -2686,7 +2686,7 @@ dependencies = [ "completest-pty", "forc-pkg", "forc-test", - "forc-tracing 0.66.2", + "forc-tracing 0.66.3", "forc-util", "fs_extra", "fuel-asm", @@ -2713,7 +2713,7 @@ dependencies = [ [[package]] name = "forc-client" -version = "0.66.2" +version = "0.66.3" dependencies = [ "anyhow", "async-trait", @@ -2725,7 +2725,7 @@ dependencies = [ "dialoguer", "forc", "forc-pkg", - "forc-tracing 0.66.2", + "forc-tracing 0.66.3", "forc-tx", "forc-util", "forc-wallet", @@ -2761,14 +2761,14 @@ dependencies = [ [[package]] name = "forc-crypto" -version = "0.66.2" +version = "0.66.3" dependencies = [ "anyhow", "async-trait", "atty", "clap 4.5.20", "criterion", - "forc-tracing 0.66.2", + "forc-tracing 0.66.3", "forc-util", "fuel-core-types", "fuel-crypto", @@ -2792,7 +2792,7 @@ dependencies = [ [[package]] name = "forc-debug" -version = "0.66.2" +version = "0.66.3" dependencies = [ "anyhow", "clap 4.5.20", @@ -2800,7 +2800,7 @@ dependencies = [ "escargot", "forc-pkg", "forc-test", - "forc-tracing 0.66.2", + "forc-tracing 0.66.3", "fuel-core-client", "fuel-types", "fuel-vm", @@ -2819,7 +2819,7 @@ dependencies = [ [[package]] name = "forc-doc" -version = "0.66.2" +version = "0.66.3" dependencies = [ "anyhow", "clap 4.5.20", @@ -2827,7 +2827,7 @@ dependencies = [ "dir_indexer", "expect-test", "forc-pkg", - "forc-tracing 0.66.2", + "forc-tracing 0.66.3", "forc-util", "horrorshow", "include_dir", @@ -2845,12 +2845,12 @@ dependencies = [ [[package]] name = "forc-fmt" -version = "0.66.2" +version = "0.66.3" dependencies = [ "anyhow", "clap 4.5.20", "forc-pkg", - "forc-tracing 0.66.2", + "forc-tracing 0.66.3", "forc-util", "prettydiff 0.7.0", "sway-core", @@ -2862,7 +2862,7 @@ dependencies = [ [[package]] name = "forc-lsp" -version = "0.66.2" +version = "0.66.3" dependencies = [ "anyhow", "clap 4.5.20", @@ -2873,13 +2873,13 @@ dependencies = [ [[package]] name = "forc-pkg" -version = "0.66.2" +version = "0.66.3" dependencies = [ "ansi_term", "anyhow", "byte-unit", "cid", - "forc-tracing 0.66.2", + "forc-tracing 0.66.3", "forc-util", "fuel-abi-types", "futures", @@ -2911,7 +2911,7 @@ dependencies = [ [[package]] name = "forc-test" -version = "0.66.2" +version = "0.66.3" dependencies = [ "anyhow", "forc-pkg", @@ -2939,7 +2939,7 @@ dependencies = [ [[package]] name = "forc-tracing" -version = "0.66.2" +version = "0.66.3" dependencies = [ "ansi_term", "tracing", @@ -2949,7 +2949,7 @@ dependencies = [ [[package]] name = "forc-tx" -version = "0.66.2" +version = "0.66.3" dependencies = [ "anyhow", "clap 4.5.20", @@ -2964,7 +2964,7 @@ dependencies = [ [[package]] name = "forc-util" -version = "0.66.2" +version = "0.66.3" dependencies = [ "annotate-snippets", "ansi_term", @@ -2972,7 +2972,7 @@ dependencies = [ "clap 4.5.20", "dirs 5.0.1", "fd-lock", - "forc-tracing 0.66.2", + "forc-tracing 0.66.3", "fuel-tx", "hex", "paste", @@ -7585,7 +7585,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sway-ast" -version = "0.66.2" +version = "0.66.3" dependencies = [ "extension-trait", "num-bigint", @@ -7597,7 +7597,7 @@ dependencies = [ [[package]] name = "sway-core" -version = "0.66.2" +version = "0.66.3" dependencies = [ "clap 4.5.20", "derivative", @@ -7642,7 +7642,7 @@ dependencies = [ [[package]] name = "sway-error" -version = "0.66.2" +version = "0.66.3" dependencies = [ "either", "in_definite", @@ -7656,7 +7656,7 @@ dependencies = [ [[package]] name = "sway-features" -version = "0.66.2" +version = "0.66.3" dependencies = [ "clap 4.5.20", "paste", @@ -7664,7 +7664,7 @@ dependencies = [ [[package]] name = "sway-ir" -version = "0.66.2" +version = "0.66.3" dependencies = [ "anyhow", "downcast-rs", @@ -7684,7 +7684,7 @@ dependencies = [ [[package]] name = "sway-ir-macros" -version = "0.66.2" +version = "0.66.3" dependencies = [ "itertools 0.13.0", "proc-macro2", @@ -7694,7 +7694,7 @@ dependencies = [ [[package]] name = "sway-lsp" -version = "0.66.2" +version = "0.66.3" dependencies = [ "anyhow", "assert-json-diff", @@ -7705,7 +7705,7 @@ dependencies = [ "dirs 4.0.0", "fd-lock", "forc-pkg", - "forc-tracing 0.66.2", + "forc-tracing 0.66.3", "forc-util", "futures", "indexmap 2.6.0", @@ -7745,7 +7745,7 @@ dependencies = [ [[package]] name = "sway-lsp-test-utils" -version = "0.66.2" +version = "0.66.3" dependencies = [ "assert-json-diff", "futures", @@ -7760,7 +7760,7 @@ dependencies = [ [[package]] name = "sway-parse" -version = "0.66.2" +version = "0.66.3" dependencies = [ "assert_matches", "extension-trait", @@ -7778,7 +7778,7 @@ dependencies = [ [[package]] name = "sway-types" -version = "0.66.2" +version = "0.66.3" dependencies = [ "bytecount", "fuel-asm", @@ -7797,7 +7797,7 @@ dependencies = [ [[package]] name = "sway-utils" -version = "0.66.2" +version = "0.66.3" dependencies = [ "serde", "walkdir", @@ -7805,11 +7805,11 @@ dependencies = [ [[package]] name = "swayfmt" -version = "0.66.2" +version = "0.66.3" dependencies = [ "anyhow", "difference", - "forc-tracing 0.66.2", + "forc-tracing 0.66.3", "indoc", "paste", "prettydiff 0.6.4", @@ -8118,7 +8118,7 @@ dependencies = [ "forc-client", "forc-pkg", "forc-test", - "forc-tracing 0.66.2", + "forc-tracing 0.66.3", "fuel-vm", "futures", "gag", diff --git a/Cargo.toml b/Cargo.toml index 21e63609454..d984e3dfeb9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ exclude = ["examples/*", "swayfmt/test_macros", "forc-test/test_data"] [workspace.package] edition = "2021" -version = "0.66.2" +version = "0.66.3" authors = ["Fuel Labs "] homepage = "https://fuel.network/" license = "Apache-2.0" @@ -42,35 +42,35 @@ repository = "https://github.com/FuelLabs/sway" # Internal dependencies in order to propagate `workspace.version` # -forc = { path = "forc/", version = "0.66.2" } -forc-pkg = { path = "forc-pkg/", version = "0.66.2" } -forc-test = { path = "forc-test/", version = "0.66.2" } -forc-tracing = { path = "forc-tracing/", version = "0.66.2" } -forc-util = { path = "forc-util/", version = "0.66.2" } +forc = { path = "forc/", version = "0.66.3" } +forc-pkg = { path = "forc-pkg/", version = "0.66.3" } +forc-test = { path = "forc-test/", version = "0.66.3" } +forc-tracing = { path = "forc-tracing/", version = "0.66.3" } +forc-util = { path = "forc-util/", version = "0.66.3" } # Forc plugins -forc-plugins = { path = "forc-plugins/", version = "0.66.2" } -forc-client = { path = "forc-plugins/forc-client/", version = "0.66.2" } -forc-crypto = { path = "forc-plugins/forc-crypto/", version = "0.66.2" } -forc-debug = { path = "forc-plugins/forc-debug/", version = "0.66.2" } -forc-doc = { path = "forc-plugins/forc-doc/", version = "0.66.2" } -forc-fmt = { path = "forc-plugins/forc-fmt/", version = "0.66.2" } -forc-lsp = { path = "forc-plugins/forc-lsp/", version = "0.66.2" } -forc-tx = { path = "forc-plugins/forc-tx/", version = "0.66.2" } +forc-plugins = { path = "forc-plugins/", version = "0.66.3" } +forc-client = { path = "forc-plugins/forc-client/", version = "0.66.3" } +forc-crypto = { path = "forc-plugins/forc-crypto/", version = "0.66.3" } +forc-debug = { path = "forc-plugins/forc-debug/", version = "0.66.3" } +forc-doc = { path = "forc-plugins/forc-doc/", version = "0.66.3" } +forc-fmt = { path = "forc-plugins/forc-fmt/", version = "0.66.3" } +forc-lsp = { path = "forc-plugins/forc-lsp/", version = "0.66.3" } +forc-tx = { path = "forc-plugins/forc-tx/", version = "0.66.3" } -sway-ast = { path = "sway-ast/", version = "0.66.2" } -sway-core = { path = "sway-core/", version = "0.66.2" } -sway-error = { path = "sway-error/", version = "0.66.2" } -sway-features = { path = "sway-features/", version = "0.66.2" } -sway-lsp = { path = "sway-lsp/", version = "0.66.2" } -sway-parse = { path = "sway-parse/", version = "0.66.2" } -sway-types = { path = "sway-types/", version = "0.66.2" } -sway-utils = { path = "sway-utils/", version = "0.66.2" } -swayfmt = { path = "swayfmt/", version = "0.66.2" } +sway-ast = { path = "sway-ast/", version = "0.66.3" } +sway-core = { path = "sway-core/", version = "0.66.3" } +sway-error = { path = "sway-error/", version = "0.66.3" } +sway-features = { path = "sway-features/", version = "0.66.3" } +sway-lsp = { path = "sway-lsp/", version = "0.66.3" } +sway-parse = { path = "sway-parse/", version = "0.66.3" } +sway-types = { path = "sway-types/", version = "0.66.3" } +sway-utils = { path = "sway-utils/", version = "0.66.3" } +swayfmt = { path = "swayfmt/", version = "0.66.3" } # Sway IR -sway-ir = { path = "sway-ir/", version = "0.66.2" } -sway-ir-macros = { path = "sway-ir/sway-ir-macros", version = "0.66.2" } +sway-ir = { path = "sway-ir/", version = "0.66.3" } +sway-ir-macros = { path = "sway-ir/sway-ir-macros", version = "0.66.3" } # # External Fuel dependencies From b6bbbf8bf5939eaf2c965b4b94732d43ef656500 Mon Sep 17 00:00:00 2001 From: Joshua Batty Date: Thu, 31 Oct 2024 13:57:08 +1100 Subject: [PATCH 092/115] Optimise TokenMap to only hold either a typed or parsed AST token (#6585) ## Description This PR optimizes the `TokenMap` structure by modifying the `Token` type to store either a parsed or typed AST token, but not both simultaneously. Parsed tokens are now only accessible if a typed token does not exist. Previously, both parsed and typed variants were stored which was inefficient in terms of memory usage. Key changes: - Replaced separate `parsed` and `typed` fields in `Token` with a single `ast_node` field using an enum `TokenAstNode` - Added helper methods `as_parsed()` and `as_typed()` to safely access the token variants - Updated all token creation and access code throughout the codebase to use the new structure - Refactored the attributes handling code to properly check both parsed and typed variants Works towards the memory optimization goals in #6226. ## 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. --- .../code_actions/diagnostic/auto_import.rs | 11 +- sway-lsp/src/capabilities/code_actions/mod.rs | 2 +- .../code_actions/struct_decl/struct_new.rs | 4 +- sway-lsp/src/capabilities/hover/mod.rs | 2 +- sway-lsp/src/capabilities/inlay_hints.rs | 2 +- sway-lsp/src/capabilities/rename.rs | 2 +- sway-lsp/src/core/session.rs | 4 +- sway-lsp/src/core/token.rs | 34 +++- sway-lsp/src/core/token_map.rs | 9 +- sway-lsp/src/traverse/dependency.rs | 6 +- sway-lsp/src/traverse/lexed_tree.rs | 6 +- sway-lsp/src/traverse/parsed_tree.rs | 187 ++++++++++------- sway-lsp/src/traverse/typed_tree.rs | 190 +++++++++++------- sway-lsp/src/utils/attributes.rs | 114 ++++++++--- sway-lsp/src/utils/debug.rs | 4 +- 15 files changed, 369 insertions(+), 208 deletions(-) diff --git a/sway-lsp/src/capabilities/code_actions/diagnostic/auto_import.rs b/sway-lsp/src/capabilities/code_actions/diagnostic/auto_import.rs index 22889c6eea6..abdc28d73dd 100644 --- a/sway-lsp/src/capabilities/code_actions/diagnostic/auto_import.rs +++ b/sway-lsp/src/capabilities/code_actions/diagnostic/auto_import.rs @@ -3,7 +3,7 @@ use crate::{ code_actions::{CodeActionContext, CODE_ACTION_IMPORT_TITLE}, diagnostic::DiagnosticData, }, - core::token::{get_range_from_span, AstToken, SymbolKind, TypedAstToken}, + core::token::{get_range_from_span, ParsedAstToken, SymbolKind, TypedAstToken}, }; use lsp_types::{ CodeAction as LspCodeAction, CodeActionKind, CodeActionOrCommand, Position, Range, TextEdit, @@ -41,13 +41,14 @@ pub(crate) fn import_code_action( let mut program_type_keyword = None; ctx.tokens.tokens_for_file(ctx.temp_uri).for_each(|item| { - if let Some(TypedAstToken::TypedUseStatement(use_stmt)) = &item.value().typed { + if let Some(TypedAstToken::TypedUseStatement(use_stmt)) = &item.value().as_typed() { use_statements.push(use_stmt.clone()); - } else if let Some(TypedAstToken::TypedIncludeStatement(include_stmt)) = &item.value().typed + } else if let Some(TypedAstToken::TypedIncludeStatement(include_stmt)) = + &item.value().as_typed() { include_statements.push(include_stmt.clone()); } else if item.value().kind == SymbolKind::ProgramTypeKeyword { - if let AstToken::Keyword(ident) = &item.value().parsed { + if let Some(ParsedAstToken::Keyword(ident)) = &item.value().as_parsed() { program_type_keyword = Some(ident.clone()); } } @@ -96,7 +97,7 @@ pub(crate) fn get_call_paths_for_name<'s>( .tokens_for_name(symbol_name) .filter_map(move |item| { // If the typed token is a declaration, then we can import it. - match item.value().typed.as_ref() { + match item.value().as_typed().as_ref() { Some(TypedAstToken::TypedDeclaration(ty_decl)) => { return match ty_decl { TyDecl::StructDecl(decl) => { diff --git a/sway-lsp/src/capabilities/code_actions/mod.rs b/sway-lsp/src/capabilities/code_actions/mod.rs index 7de6d1e0290..38207fa75d7 100644 --- a/sway-lsp/src/capabilities/code_actions/mod.rs +++ b/sway-lsp/src/capabilities/code_actions/mod.rs @@ -65,7 +65,7 @@ pub fn code_actions( }; let actions_by_type = token - .typed + .as_typed() .as_ref() .map(|typed_token| match typed_token { TypedAstToken::TypedDeclaration(decl) => match decl { diff --git a/sway-lsp/src/capabilities/code_actions/struct_decl/struct_new.rs b/sway-lsp/src/capabilities/code_actions/struct_decl/struct_new.rs index 2ad3674f68f..a13c5d890e6 100644 --- a/sway-lsp/src/capabilities/code_actions/struct_decl/struct_new.rs +++ b/sway-lsp/src/capabilities/code_actions/struct_decl/struct_new.rs @@ -33,9 +33,9 @@ impl<'a> CodeAction<'a, TyStructDecl> for StructNewCodeAction<'a> { .find_map(|item| { if let Some(TypedAstToken::TypedDeclaration(ty::TyDecl::ImplSelfOrTrait( ty::ImplSelfOrTrait { decl_id, .. }, - ))) = item.value().typed + ))) = item.value().as_typed() { - Some((*ctx.engines.de().get_impl_self_or_trait(&decl_id)).clone()) + Some((*ctx.engines.de().get_impl_self_or_trait(decl_id)).clone()) } else { None } diff --git a/sway-lsp/src/capabilities/hover/mod.rs b/sway-lsp/src/capabilities/hover/mod.rs index 97ef886daf7..87c1a1f2f92 100644 --- a/sway-lsp/src/capabilities/hover/mod.rs +++ b/sway-lsp/src/capabilities/hover/mod.rs @@ -143,7 +143,7 @@ fn hover_format( let mut hover_link_contents = HoverLinkContents::new(session, engines); let sway_block = token - .typed + .as_typed() .as_ref() .and_then(|typed_token| match typed_token { TypedAstToken::TypedDeclaration(decl) => match decl { diff --git a/sway-lsp/src/capabilities/inlay_hints.rs b/sway-lsp/src/capabilities/inlay_hints.rs index a832948fc96..765be558ef4 100644 --- a/sway-lsp/src/capabilities/inlay_hints.rs +++ b/sway-lsp/src/capabilities/inlay_hints.rs @@ -52,7 +52,7 @@ pub fn inlay_hints( .tokens_for_file(uri) .filter_map(|item| { let token = item.value(); - token.typed.as_ref().and_then(|t| match t { + token.as_typed().as_ref().and_then(|t| match t { TypedAstToken::TypedDeclaration(TyDecl::VariableDecl(var_decl)) => { let var_range = get_range_from_span(&var_decl.name.span()); if var_range.start >= range.start && var_range.end <= range.end { diff --git a/sway-lsp/src/capabilities/rename.rs b/sway-lsp/src/capabilities/rename.rs index 6070fd992c9..709d78bf4ea 100644 --- a/sway-lsp/src/capabilities/rename.rs +++ b/sway-lsp/src/capabilities/rename.rs @@ -202,7 +202,7 @@ fn find_all_methods_for_decl<'a>( .all_references_of_token(decl_token, engines) .filter_map(|item| { let token = item.value(); - token.typed.as_ref().and_then(|typed| match typed { + token.as_typed().as_ref().and_then(|typed| match typed { TypedAstToken::TypedDeclaration(decl) => match decl { ty::TyDecl::AbiDecl(ty::AbiDecl { decl_id, .. }) => { let abi_decl = engines.de().get_abi(decl_id); diff --git a/sway-lsp/src/core/session.rs b/sway-lsp/src/core/session.rs index fe5d59a8c9f..0129c8fa583 100644 --- a/sway-lsp/src/core/session.rs +++ b/sway-lsp/src/core/session.rs @@ -227,14 +227,14 @@ impl Session { .tokens_at_position(&engines, uri, shifted_position, Some(true)); let fn_token = fn_tokens.first()?.value(); let compiled_program = &*self.compiled_program.read(); - if let Some(TypedAstToken::TypedFunctionDeclaration(fn_decl)) = fn_token.typed.clone() { + if let Some(TypedAstToken::TypedFunctionDeclaration(fn_decl)) = fn_token.as_typed() { let program = compiled_program.typed.clone()?; let engines = self.engines.read(); return Some(capabilities::completion::to_completion_items( program.root.namespace.module(&engines).current_items(), &engines, ident_to_complete, - &fn_decl, + fn_decl, position, )); } diff --git a/sway-lsp/src/core/token.rs b/sway-lsp/src/core/token.rs index 3e657a0cff9..9e67dc01634 100644 --- a/sway-lsp/src/core/token.rs +++ b/sway-lsp/src/core/token.rs @@ -19,12 +19,12 @@ use sway_core::{ }; use sway_types::{Ident, SourceEngine, Span, Spanned}; -/// The `AstToken` holds the types produced by the [sway_core::language::parsed::ParseProgram]. +/// The `ParsedAstToken` holds the types produced by the [sway_core::language::parsed::ParseProgram]. /// These tokens have not been type-checked. /// See this issue https://github.com/FuelLabs/sway/issues/2257 for more information about why they are /// useful to the language server. #[derive(Debug, Clone)] -pub enum AstToken { +pub enum ParsedAstToken { AbiCastExpression(AbiCastExpression), AmbiguousPathExpression(AmbiguousPathExpression), Attribute(Attribute), @@ -148,14 +148,19 @@ pub enum TypeDefinition { Ident(Ident), } +#[derive(Debug, Clone)] +pub enum TokenAstNode { + Parsed(ParsedAstToken), + Typed(TypedAstToken), +} + /// The `Token` type is created during traversal of the parsed and typed AST's of a program. /// It holds the parsed and typed data structures produced by the sway compiler. /// It also holds the type definition & semantic type of the token if they could be inferred /// during traversal of the AST's. #[derive(Debug, Clone)] pub struct Token { - pub parsed: AstToken, - pub typed: Option, + pub ast_node: TokenAstNode, pub type_def: Option, pub kind: SymbolKind, } @@ -164,15 +169,30 @@ impl Token { /// Create a new token with the given [SymbolKind]. /// This function is intended to be used during traversal of the /// [sway_core::language::parsed::ParseProgram] AST. - pub fn from_parsed(token: AstToken, kind: SymbolKind) -> Self { + pub fn from_parsed(token: ParsedAstToken, kind: SymbolKind) -> Self { Self { - parsed: token, - typed: None, + ast_node: TokenAstNode::Parsed(token), type_def: None, kind, } } + /// Get the `AstToken`, if this is a parsed token. + pub fn as_parsed(&self) -> Option<&ParsedAstToken> { + match &self.ast_node { + TokenAstNode::Parsed(token) => Some(token), + _ => None, + } + } + + /// Get the `TypedAstToken`, if this is a typed token. + pub fn as_typed(&self) -> Option<&TypedAstToken> { + match &self.ast_node { + TokenAstNode::Typed(token) => Some(token), + _ => None, + } + } + /// Return the [TokenIdent] of the declaration of the provided token. pub fn declared_token_ident(&self, engines: &Engines) -> Option { self.type_def.as_ref().and_then(|type_def| match type_def { diff --git a/sway-lsp/src/core/token_map.rs b/sway-lsp/src/core/token_map.rs index ce410e8723c..dc76204a116 100644 --- a/sway-lsp/src/core/token_map.rs +++ b/sway-lsp/src/core/token_map.rs @@ -137,7 +137,7 @@ impl<'a> TokenMap { .into_iter() .find_map(|entry| { let (_, token) = entry.pair(); - if let Some(TypedAstToken::TypedDeclaration(_)) = &token.typed { + if let Some(TypedAstToken::TypedDeclaration(_)) = &token.as_typed() { Some(entry) } else { None @@ -175,7 +175,7 @@ impl<'a> TokenMap { self.tokens_for_file(uri) .filter_map(move |entry| { let (ident, token) = entry.pair(); - let token_ident = match &token.typed { + let token_ident = match &token.as_typed() { Some(TypedAstToken::TypedFunctionDeclaration(decl)) if functions_only == Some(true) => { @@ -188,7 +188,8 @@ impl<'a> TokenMap { }; if position >= token_ident.range.start && position <= token_ident.range.end { if functions_only == Some(true) { - if let Some(TypedAstToken::TypedFunctionDeclaration(_)) = &token.typed { + if let Some(TypedAstToken::TypedFunctionDeclaration(_)) = &token.as_typed() + { return Some(entry); } return None; @@ -213,7 +214,7 @@ impl<'a> TokenMap { token::ident_of_type_id(engines, type_id) .and_then(|decl_ident| self.try_get(&decl_ident).try_unwrap()) .map(|item| item.value().clone()) - .and_then(|token| token.typed) + .and_then(|token| token.as_typed().cloned()) .and_then(|typed_token| match typed_token { TypedAstToken::TypedDeclaration(dec) => Some(dec), _ => None, diff --git a/sway-lsp/src/traverse/dependency.rs b/sway-lsp/src/traverse/dependency.rs index d270f04f9ef..07c7388eb4b 100644 --- a/sway-lsp/src/traverse/dependency.rs +++ b/sway-lsp/src/traverse/dependency.rs @@ -1,5 +1,5 @@ use crate::{ - core::token::{AstToken, SymbolKind, Token, TypeDefinition, TypedAstToken}, + core::token::{ParsedAstToken, SymbolKind, Token, TokenAstNode, TypeDefinition, TypedAstToken}, traverse::ParseContext, }; use sway_core::language::{ @@ -11,7 +11,7 @@ use sway_types::Named; /// Insert Declaration tokens into the TokenMap. pub fn collect_parsed_declaration(node: &AstNode, ctx: &ParseContext) { if let AstNodeContent::Declaration(declaration) = &node.content { - let parsed_token = AstToken::Declaration(declaration.clone()); + let parsed_token = ParsedAstToken::Declaration(declaration.clone()); let (ident, symbol_kind) = match declaration { Declaration::VariableDeclaration(decl_id) => { @@ -73,7 +73,7 @@ pub fn collect_typed_declaration(node: &ty::TyAstNode, ctx: &ParseContext) { let token_ident = ctx.ident(&ident); if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&token_ident) { - token.typed = Some(typed_token); + token.ast_node = TokenAstNode::Typed(typed_token); token.type_def = Some(TypeDefinition::Ident(ident)); } } diff --git a/sway-lsp/src/traverse/lexed_tree.rs b/sway-lsp/src/traverse/lexed_tree.rs index a95f0b55881..fdce32d7e9a 100644 --- a/sway-lsp/src/traverse/lexed_tree.rs +++ b/sway-lsp/src/traverse/lexed_tree.rs @@ -1,5 +1,5 @@ use crate::{ - core::token::{AstToken, SymbolKind, Token}, + core::token::{ParsedAstToken, SymbolKind, Token}, traverse::{adaptive_iter, Parse, ParseContext}, }; use rayon::iter::{ParallelBridge, ParallelIterator}; @@ -59,7 +59,7 @@ fn insert_module_kind(ctx: &ParseContext, kind: &ModuleKind) { fn insert_program_type_keyword(ctx: &ParseContext, span: Span) { let ident = Ident::new(span); let token = Token::from_parsed( - AstToken::Keyword(ident.clone()), + ParsedAstToken::Keyword(ident.clone()), SymbolKind::ProgramTypeKeyword, ); ctx.tokens.insert(ctx.ident(&ident), token); @@ -67,7 +67,7 @@ fn insert_program_type_keyword(ctx: &ParseContext, span: Span) { fn insert_keyword(ctx: &ParseContext, span: Span) { let ident = Ident::new(span); - let token = Token::from_parsed(AstToken::Keyword(ident.clone()), SymbolKind::Keyword); + let token = Token::from_parsed(ParsedAstToken::Keyword(ident.clone()), SymbolKind::Keyword); ctx.tokens.insert(ctx.ident(&ident), token); } diff --git a/sway-lsp/src/traverse/parsed_tree.rs b/sway-lsp/src/traverse/parsed_tree.rs index 04e7750fa69..87f30cd8017 100644 --- a/sway-lsp/src/traverse/parsed_tree.rs +++ b/sway-lsp/src/traverse/parsed_tree.rs @@ -3,7 +3,8 @@ use crate::{ core::{ token::{ - desugared_op, type_info_to_symbol_kind, AstToken, SymbolKind, Token, TypeDefinition, + desugared_op, type_info_to_symbol_kind, ParsedAstToken, SymbolKind, Token, + TypeDefinition, }, token_map::TokenMap, }, @@ -64,7 +65,7 @@ impl<'a> ParsedTree<'a> { self.ctx .ident(&Ident::new(parse_module.module_kind_span.clone())), Token::from_parsed( - AstToken::LibrarySpan(parse_module.module_kind_span.clone()), + ParsedAstToken::LibrarySpan(parse_module.module_kind_span.clone()), SymbolKind::Keyword, ), ); @@ -79,7 +80,7 @@ impl<'a> ParsedTree<'a> { { self.ctx.tokens.insert( self.ctx.ident(&Ident::new(mod_name_span.clone())), - Token::from_parsed(AstToken::ModuleName, SymbolKind::Module), + Token::from_parsed(ParsedAstToken::ModuleName, SymbolKind::Module), ); self.collect_parse_module(module); } @@ -95,7 +96,7 @@ impl Parse for AttributesMap { ctx.tokens.insert( ctx.ident(&attribute.name), Token::from_parsed( - AstToken::Attribute(attribute.clone()), + ParsedAstToken::Attribute(attribute.clone()), SymbolKind::DeriveHelper, ), ); @@ -143,26 +144,38 @@ impl Parse for UseStatement { if let Some(alias) = &self.alias { ctx.tokens.insert( ctx.ident(alias), - Token::from_parsed(AstToken::UseStatement(self.clone()), SymbolKind::Unknown), + Token::from_parsed( + ParsedAstToken::UseStatement(self.clone()), + SymbolKind::Unknown, + ), ); } adaptive_iter(&self.call_path, |prefix| { ctx.tokens.insert( ctx.ident(prefix), - Token::from_parsed(AstToken::UseStatement(self.clone()), SymbolKind::Module), + Token::from_parsed( + ParsedAstToken::UseStatement(self.clone()), + SymbolKind::Module, + ), ); }); match &self.import_type { ImportType::Item(item) => { ctx.tokens.insert( ctx.ident(item), - Token::from_parsed(AstToken::UseStatement(self.clone()), SymbolKind::Unknown), + Token::from_parsed( + ParsedAstToken::UseStatement(self.clone()), + SymbolKind::Unknown, + ), ); } ImportType::SelfImport(span) => { ctx.tokens.insert( ctx.ident(&Ident::new(span.clone())), - Token::from_parsed(AstToken::UseStatement(self.clone()), SymbolKind::Unknown), + Token::from_parsed( + ParsedAstToken::UseStatement(self.clone()), + SymbolKind::Unknown, + ), ); } ImportType::Star => {} @@ -175,7 +188,7 @@ impl Parse for IncludeStatement { ctx.tokens.insert( ctx.ident(&self.mod_name), Token::from_parsed( - AstToken::IncludeStatement(self.clone()), + ParsedAstToken::IncludeStatement(self.clone()), SymbolKind::Unknown, ), ); @@ -190,7 +203,7 @@ impl Parse for Expression { ctx.tokens.insert( ctx.ident(&Ident::new(span.clone())), Token::from_parsed( - AstToken::ErrorRecovery(span.clone()), + ParsedAstToken::ErrorRecovery(span.clone()), SymbolKind::Unknown, ), ); @@ -200,7 +213,7 @@ impl Parse for Expression { let symbol_kind = literal_to_symbol_kind(value); ctx.tokens.insert( ctx.ident(&Ident::new(self.span.clone())), - Token::from_parsed(AstToken::Expression(self.clone()), symbol_kind), + Token::from_parsed(ParsedAstToken::Expression(self.clone()), symbol_kind), ); } ExpressionKind::FunctionApplication(function_application_expression) => { @@ -223,7 +236,7 @@ impl Parse for Expression { }; ctx.tokens.insert( ctx.ident(name), - Token::from_parsed(AstToken::Expression(self.clone()), symbol_kind), + Token::from_parsed(ParsedAstToken::Expression(self.clone()), symbol_kind), ); } } @@ -237,7 +250,7 @@ impl Parse for Expression { ctx.tokens.insert( ctx.ident(&Ident::new(index_span.clone())), Token::from_parsed( - AstToken::Expression(self.clone()), + ParsedAstToken::Expression(self.clone()), SymbolKind::NumericLiteral, ), ); @@ -290,13 +303,13 @@ impl Parse for Expression { prefix.parse(ctx); ctx.tokens.insert( ctx.ident(field_to_access), - Token::from_parsed(AstToken::Expression(self.clone()), SymbolKind::Field), + Token::from_parsed(ParsedAstToken::Expression(self.clone()), SymbolKind::Field), ); } ExpressionKind::AmbiguousVariableExpression(ident) => { ctx.tokens.insert( ctx.ident(ident), - Token::from_parsed(AstToken::Ident(ident.clone()), SymbolKind::Unknown), + Token::from_parsed(ParsedAstToken::Ident(ident.clone()), SymbolKind::Unknown), ); } ExpressionKind::AmbiguousPathExpression(path_expr) => { @@ -320,13 +333,13 @@ impl Parse for Expression { let storage_ident = Ident::new(storage_keyword_span.clone()); ctx.tokens.insert( ctx.ident(&storage_ident), - Token::from_parsed(AstToken::Ident(storage_ident), SymbolKind::Unknown), + Token::from_parsed(ParsedAstToken::Ident(storage_ident), SymbolKind::Unknown), ); adaptive_iter(namespace_names, |namespace_name| { ctx.tokens.insert( ctx.ident(namespace_name), Token::from_parsed( - AstToken::Ident(namespace_name.clone()), + ParsedAstToken::Ident(namespace_name.clone()), SymbolKind::Field, ), ); @@ -334,7 +347,10 @@ impl Parse for Expression { adaptive_iter(field_names, |field_name| { ctx.tokens.insert( ctx.ident(field_name), - Token::from_parsed(AstToken::Ident(field_name.clone()), SymbolKind::Field), + Token::from_parsed( + ParsedAstToken::Ident(field_name.clone()), + SymbolKind::Field, + ), ); }); } @@ -381,7 +397,7 @@ impl Parse for IntrinsicFunctionExpression { ctx.tokens.insert( ctx.ident(&self.name), Token::from_parsed( - AstToken::Intrinsic(self.kind_binding.inner.clone()), + ParsedAstToken::Intrinsic(self.kind_binding.inner.clone()), SymbolKind::Intrinsic, ), ); @@ -397,12 +413,15 @@ impl Parse for AbiCastExpression { adaptive_iter(&self.abi_name.prefixes, |ident| { ctx.tokens.insert( ctx.ident(ident), - Token::from_parsed(AstToken::Ident(ident.clone()), SymbolKind::Module), + Token::from_parsed(ParsedAstToken::Ident(ident.clone()), SymbolKind::Module), ); }); ctx.tokens.insert( ctx.ident(&self.abi_name.suffix), - Token::from_parsed(AstToken::AbiCastExpression(self.clone()), SymbolKind::Trait), + Token::from_parsed( + ParsedAstToken::AbiCastExpression(self.clone()), + SymbolKind::Trait, + ), ); self.address.parse(ctx); } @@ -417,13 +436,13 @@ impl Parse for DelineatedPathExpression { adaptive_iter(&call_path_binding.inner.call_path.prefixes, |ident| { ctx.tokens.insert( ctx.ident(ident), - Token::from_parsed(AstToken::Ident(ident.clone()), SymbolKind::Enum), + Token::from_parsed(ParsedAstToken::Ident(ident.clone()), SymbolKind::Enum), ); }); ctx.tokens.insert( ctx.ident(&call_path_binding.inner.call_path.suffix), Token::from_parsed( - AstToken::DelineatedPathExpression(self.clone()), + ParsedAstToken::DelineatedPathExpression(self.clone()), SymbolKind::Variant, ), ); @@ -454,13 +473,13 @@ impl Parse for AmbiguousPathExpression { ) { ctx.tokens.insert( ctx.ident(ident), - Token::from_parsed(AstToken::Ident(ident.clone()), SymbolKind::Enum), + Token::from_parsed(ParsedAstToken::Ident(ident.clone()), SymbolKind::Enum), ); } ctx.tokens.insert( ctx.ident(&call_path_binding.inner.suffix.suffix), Token::from_parsed( - AstToken::AmbiguousPathExpression(self.clone()), + ParsedAstToken::AmbiguousPathExpression(self.clone()), SymbolKind::Variant, ), ); @@ -499,7 +518,7 @@ impl Parse for MethodApplicationExpression { ctx.tokens.insert( ctx.ident(&self.method_name_binding.inner.easy_name()), Token::from_parsed( - AstToken::MethodApplicationExpression(self.clone()), + ParsedAstToken::MethodApplicationExpression(self.clone()), SymbolKind::Struct, ), ); @@ -515,7 +534,7 @@ impl Parse for Scrutinee { Scrutinee::CatchAll { .. } => (), Scrutinee::Literal { ref value, span } => { let token = Token::from_parsed( - AstToken::Scrutinee(self.clone()), + ParsedAstToken::Scrutinee(self.clone()), literal_to_symbol_kind(value), ); ctx.tokens @@ -525,7 +544,10 @@ impl Parse for Scrutinee { ctx.tokens.insert( ctx.ident(name), // it could either be a variable or a constant - Token::from_parsed(AstToken::Scrutinee(self.clone()), SymbolKind::Unknown), + Token::from_parsed( + ParsedAstToken::Scrutinee(self.clone()), + SymbolKind::Unknown, + ), ); } Scrutinee::StructScrutinee { @@ -534,13 +556,15 @@ impl Parse for Scrutinee { .. } => { adaptive_iter(&struct_name.prefixes, |ident| { - let token = - Token::from_parsed(AstToken::Ident(ident.clone()), SymbolKind::Struct); + let token = Token::from_parsed( + ParsedAstToken::Ident(ident.clone()), + SymbolKind::Struct, + ); ctx.tokens.insert(ctx.ident(ident), token); }); ctx.tokens.insert( ctx.ident(&struct_name.suffix), - Token::from_parsed(AstToken::Scrutinee(self.clone()), SymbolKind::Struct), + Token::from_parsed(ParsedAstToken::Scrutinee(self.clone()), SymbolKind::Struct), ); adaptive_iter(fields, |field| field.parse(ctx)); } @@ -550,16 +574,19 @@ impl Parse for Scrutinee { adaptive_iter(&call_path.prefixes, |ident| { ctx.tokens.insert( ctx.ident(ident), - Token::from_parsed(AstToken::Ident(ident.clone()), SymbolKind::Enum), + Token::from_parsed(ParsedAstToken::Ident(ident.clone()), SymbolKind::Enum), ); }); - let token = - Token::from_parsed(AstToken::Scrutinee(self.clone()), SymbolKind::Variant); + let token = Token::from_parsed( + ParsedAstToken::Scrutinee(self.clone()), + SymbolKind::Variant, + ); ctx.tokens.insert(ctx.ident(&call_path.suffix), token); value.parse(ctx); } Scrutinee::AmbiguousSingleIdent(ident) => { - let token = Token::from_parsed(AstToken::Ident(ident.clone()), SymbolKind::Unknown); + let token = + Token::from_parsed(ParsedAstToken::Ident(ident.clone()), SymbolKind::Unknown); ctx.tokens.insert(ctx.ident(ident), token); } Scrutinee::Tuple { elems, .. } | Scrutinee::Or { elems, .. } => { @@ -575,7 +602,7 @@ impl Parse for Scrutinee { impl Parse for StructScrutineeField { fn parse(&self, ctx: &ParseContext) { let token = Token::from_parsed( - AstToken::StructScrutineeField(self.clone()), + ParsedAstToken::StructScrutineeField(self.clone()), SymbolKind::Field, ); if let StructScrutineeField::Field { @@ -595,7 +622,7 @@ impl Parse for StructExpression { adaptive_iter(&self.call_path_binding.inner.prefixes, |ident| { ctx.tokens.insert( ctx.ident(ident), - Token::from_parsed(AstToken::Ident(ident.clone()), SymbolKind::Struct), + Token::from_parsed(ParsedAstToken::Ident(ident.clone()), SymbolKind::Struct), ); }); let name = &self.call_path_binding.inner.suffix; @@ -606,7 +633,7 @@ impl Parse for StructExpression { }; ctx.tokens.insert( ctx.ident(name), - Token::from_parsed(AstToken::StructExpression(self.clone()), symbol_kind), + Token::from_parsed(ParsedAstToken::StructExpression(self.clone()), symbol_kind), ); let type_arguments = &self.call_path_binding.type_arguments.to_vec(); adaptive_iter(type_arguments, |type_arg| type_arg.parse(ctx)); @@ -619,7 +646,7 @@ impl Parse for StructExpressionField { ctx.tokens.insert( ctx.ident(&self.name), Token::from_parsed( - AstToken::StructExpressionField(self.clone()), + ParsedAstToken::StructExpressionField(self.clone()), SymbolKind::Field, ), ); @@ -634,7 +661,10 @@ impl Parse for ArrayExpression { let ident = Ident::new(length_span.clone()); ctx.tokens.insert( ctx.ident(&ident), - Token::from_parsed(AstToken::Ident(ident.clone()), SymbolKind::NumericLiteral), + Token::from_parsed( + ParsedAstToken::Ident(ident.clone()), + SymbolKind::NumericLiteral, + ), ); } } @@ -647,13 +677,13 @@ impl Parse for FunctionApplicationExpression { adaptive_iter(&self.call_path_binding.inner.prefixes, |ident| { ctx.tokens.insert( ctx.ident(ident), - Token::from_parsed(AstToken::Ident(ident.clone()), SymbolKind::Module), + Token::from_parsed(ParsedAstToken::Ident(ident.clone()), SymbolKind::Module), ); }); ctx.tokens.insert( ctx.ident(&self.call_path_binding.inner.suffix), Token::from_parsed( - AstToken::FunctionApplicationExpression(self.clone()), + ParsedAstToken::FunctionApplicationExpression(self.clone()), SymbolKind::Function, ), ); @@ -692,7 +722,7 @@ impl Parse for ParsedDeclId { ctx.tokens.insert( ctx.ident(&ident), Token::from_parsed( - AstToken::Declaration(Declaration::VariableDeclaration(*self)), + ParsedAstToken::Declaration(Declaration::VariableDeclaration(*self)), symbol_kind, ), ); @@ -705,7 +735,7 @@ impl Parse for ParsedDeclId { impl Parse for ParsedDeclId { fn parse(&self, ctx: &ParseContext) { let token = Token::from_parsed( - AstToken::Declaration(Declaration::FunctionDeclaration(*self)), + ParsedAstToken::Declaration(Declaration::FunctionDeclaration(*self)), SymbolKind::Function, ); let fn_decl = ctx.engines.pe().get_function(self); @@ -728,7 +758,7 @@ impl Parse for ParsedDeclId { ctx.tokens.insert( ctx.ident(&trait_decl.name), Token::from_parsed( - AstToken::Declaration(Declaration::TraitDeclaration(*self)), + ParsedAstToken::Declaration(Declaration::TraitDeclaration(*self)), SymbolKind::Trait, ), ); @@ -749,7 +779,7 @@ impl Parse for ParsedDeclId { ctx.tokens.insert( ctx.ident(&struct_decl.name), Token::from_parsed( - AstToken::Declaration(Declaration::StructDeclaration(*self)), + ParsedAstToken::Declaration(Declaration::StructDeclaration(*self)), SymbolKind::Struct, ), ); @@ -767,7 +797,7 @@ impl Parse for ParsedDeclId { ctx.tokens.insert( ctx.ident(&enum_decl.name), Token::from_parsed( - AstToken::Declaration(Declaration::EnumDeclaration(*self)), + ParsedAstToken::Declaration(Declaration::EnumDeclaration(*self)), SymbolKind::Enum, ), ); @@ -785,13 +815,13 @@ impl Parse for ParsedDeclId { adaptive_iter(&impl_self_or_trait.trait_name.prefixes, |ident| { ctx.tokens.insert( ctx.ident(ident), - Token::from_parsed(AstToken::Ident(ident.clone()), SymbolKind::Module), + Token::from_parsed(ParsedAstToken::Ident(ident.clone()), SymbolKind::Module), ); }); ctx.tokens.insert( ctx.ident(&impl_self_or_trait.trait_name.suffix), Token::from_parsed( - AstToken::Declaration(Declaration::ImplSelfOrTrait(*self)), + ParsedAstToken::Declaration(Declaration::ImplSelfOrTrait(*self)), SymbolKind::Trait, ), ); @@ -806,7 +836,7 @@ impl Parse for ParsedDeclId { ctx.tokens.insert( ctx.ident(&qualified_call_path.call_path.suffix), Token::from_parsed( - AstToken::Declaration(Declaration::ImplSelfOrTrait(*self)), + ParsedAstToken::Declaration(Declaration::ImplSelfOrTrait(*self)), SymbolKind::Struct, ), ); @@ -834,7 +864,7 @@ impl Parse for ParsedDeclId { ctx.tokens.insert( ctx.ident(&abi_decl.name), Token::from_parsed( - AstToken::Declaration(Declaration::AbiDeclaration(*self)), + ParsedAstToken::Declaration(Declaration::AbiDeclaration(*self)), SymbolKind::Trait, ), ); @@ -855,7 +885,7 @@ impl Parse for ParsedDeclId { ctx.tokens.insert( ctx.ident(&const_decl.name), Token::from_parsed( - AstToken::Declaration(Declaration::ConstantDeclaration(*self)), + ParsedAstToken::Declaration(Declaration::ConstantDeclaration(*self)), SymbolKind::Const, ), ); @@ -873,7 +903,7 @@ impl Parse for ParsedDeclId { ctx.tokens.insert( ctx.ident(&const_decl.name), Token::from_parsed( - AstToken::Declaration(Declaration::ConfigurableDeclaration(*self)), + ParsedAstToken::Declaration(Declaration::ConfigurableDeclaration(*self)), SymbolKind::Const, ), ); @@ -891,7 +921,7 @@ impl Parse for ParsedDeclId { ctx.tokens.insert( ctx.ident(&trait_type_decl.name), Token::from_parsed( - AstToken::Declaration(Declaration::TraitTypeDeclaration(*self)), + ParsedAstToken::Declaration(Declaration::TraitTypeDeclaration(*self)), SymbolKind::TraitType, ), ); @@ -923,7 +953,10 @@ impl Parse for StorageNamespace { fn parse(&self, ctx: &ParseContext) { ctx.tokens.insert( ctx.ident(&self.name), - Token::from_parsed(AstToken::StorageNamespace(self.clone()), SymbolKind::Field), + Token::from_parsed( + ParsedAstToken::StorageNamespace(self.clone()), + SymbolKind::Field, + ), ); self.entries.iter().for_each(|entry| entry.parse(ctx)); } @@ -933,7 +966,10 @@ impl Parse for StorageField { fn parse(&self, ctx: &ParseContext) { ctx.tokens.insert( ctx.ident(&self.name), - Token::from_parsed(AstToken::StorageField(self.clone()), SymbolKind::Field), + Token::from_parsed( + ParsedAstToken::StorageField(self.clone()), + SymbolKind::Field, + ), ); self.type_argument.parse(ctx); self.initializer.parse(ctx); @@ -945,7 +981,7 @@ impl Parse for Supertrait { fn parse(&self, ctx: &ParseContext) { ctx.tokens.insert( ctx.ident(&self.name.suffix), - Token::from_parsed(AstToken::Supertrait(self.clone()), SymbolKind::Trait), + Token::from_parsed(ParsedAstToken::Supertrait(self.clone()), SymbolKind::Trait), ); } } @@ -955,7 +991,7 @@ impl Parse for ParsedDeclId { let trait_fn = ctx.engines.pe().get_trait_fn(self); ctx.tokens.insert( ctx.ident(&trait_fn.name), - Token::from_parsed(AstToken::TraitFn(*self), SymbolKind::Function), + Token::from_parsed(ParsedAstToken::TraitFn(*self), SymbolKind::Function), ); adaptive_iter(&trait_fn.parameters, |param| param.parse(ctx)); trait_fn.return_type.parse(ctx); @@ -968,13 +1004,13 @@ impl Parse for TraitConstraint { adaptive_iter(&self.trait_name.prefixes, |prefix| { ctx.tokens.insert( ctx.ident(prefix), - Token::from_parsed(AstToken::Ident(prefix.clone()), SymbolKind::Function), + Token::from_parsed(ParsedAstToken::Ident(prefix.clone()), SymbolKind::Function), ); }); ctx.tokens.insert( ctx.ident(&self.trait_name.suffix), Token::from_parsed( - AstToken::TraitConstraint(self.clone()), + ParsedAstToken::TraitConstraint(self.clone()), SymbolKind::Function, ), ); @@ -987,7 +1023,7 @@ impl Parse for FunctionParameter { ctx.tokens.insert( ctx.ident(&self.name), Token::from_parsed( - AstToken::FunctionParameter(self.clone()), + ParsedAstToken::FunctionParameter(self.clone()), SymbolKind::ValueParam, ), ); @@ -999,7 +1035,7 @@ impl Parse for StructField { fn parse(&self, ctx: &ParseContext) { ctx.tokens.insert( ctx.ident(&self.name), - Token::from_parsed(AstToken::StructField(self.clone()), SymbolKind::Field), + Token::from_parsed(ParsedAstToken::StructField(self.clone()), SymbolKind::Field), ); self.type_argument.parse(ctx); self.attributes.parse(ctx); @@ -1010,7 +1046,10 @@ impl Parse for EnumVariant { fn parse(&self, ctx: &ParseContext) { ctx.tokens.insert( ctx.ident(&self.name), - Token::from_parsed(AstToken::EnumVariant(self.clone()), SymbolKind::Variant), + Token::from_parsed( + ParsedAstToken::EnumVariant(self.clone()), + SymbolKind::Variant, + ), ); self.type_argument.parse(ctx); self.attributes.parse(ctx); @@ -1022,7 +1061,7 @@ impl Parse for TypeParameter { ctx.tokens.insert( ctx.ident(&self.name_ident), Token::from_parsed( - AstToken::TypeParameter(self.clone()), + ParsedAstToken::TypeParameter(self.clone()), SymbolKind::TypeParameter, ), ); @@ -1037,7 +1076,10 @@ impl Parse for TypeArgument { let ident = Ident::new(length.span()); ctx.tokens.insert( ctx.ident(&ident), - Token::from_parsed(AstToken::Ident(ident.clone()), SymbolKind::NumericLiteral), + Token::from_parsed( + ParsedAstToken::Ident(ident.clone()), + SymbolKind::NumericLiteral, + ), ); type_arg.parse(ctx); } @@ -1051,7 +1093,7 @@ impl Parse for TypeArgument { let symbol_kind = type_info_to_symbol_kind(ctx.engines.te(), &type_info, None); if let Some(tree) = &self.call_path_tree { let token = - Token::from_parsed(AstToken::TypeArgument(self.clone()), symbol_kind); + Token::from_parsed(ParsedAstToken::TypeArgument(self.clone()), symbol_kind); collect_call_path_tree(ctx, tree, &token, ctx.tokens); } } @@ -1065,7 +1107,7 @@ impl Parse for ParsedDeclId { ctx.tokens.insert( ctx.ident(&type_alias_decl.name), Token::from_parsed( - AstToken::Declaration(Declaration::TypeAliasDeclaration(*self)), + ParsedAstToken::Declaration(Declaration::TypeAliasDeclaration(*self)), SymbolKind::TypeAlias, ), ); @@ -1081,14 +1123,17 @@ fn collect_type_info_token(ctx: &ParseContext, type_info: &TypeInfo, type_span: let ident = Ident::new(length.span()); ctx.tokens.insert( ctx.ident(&ident), - Token::from_parsed(AstToken::Ident(ident.clone()), symbol_kind), + Token::from_parsed(ParsedAstToken::Ident(ident.clone()), symbol_kind), ); } TypeInfo::Array(type_arg, length) => { let ident = Ident::new(length.span()); ctx.tokens.insert( ctx.ident(&ident), - Token::from_parsed(AstToken::Ident(ident.clone()), SymbolKind::NumericLiteral), + Token::from_parsed( + ParsedAstToken::Ident(ident.clone()), + SymbolKind::NumericLiteral, + ), ); type_arg.parse(ctx); } @@ -1101,7 +1146,7 @@ fn collect_type_info_token(ctx: &ParseContext, type_info: &TypeInfo, type_span: } => { collect_qualified_path_root(ctx, qualified_call_path.qualified_path_root.clone()); let ident = qualified_call_path.call_path.suffix.clone(); - let mut token = Token::from_parsed(AstToken::Ident(ident.clone()), symbol_kind); + let mut token = Token::from_parsed(ParsedAstToken::Ident(ident.clone()), symbol_kind); token.type_def = Some(TypeDefinition::Ident(ident.clone())); ctx.tokens.insert(ctx.ident(&ident), token); if let Some(type_arguments) = type_arguments { @@ -1113,7 +1158,7 @@ fn collect_type_info_token(ctx: &ParseContext, type_info: &TypeInfo, type_span: let ident = Ident::new(type_span.clone()); ctx.tokens.insert( ctx.ident(&ident), - Token::from_parsed(AstToken::Ident(ident.clone()), symbol_kind), + Token::from_parsed(ParsedAstToken::Ident(ident.clone()), symbol_kind), ); } } diff --git a/sway-lsp/src/traverse/typed_tree.rs b/sway-lsp/src/traverse/typed_tree.rs index 0c2745c6f21..9d23bae7316 100644 --- a/sway-lsp/src/traverse/typed_tree.rs +++ b/sway-lsp/src/traverse/typed_tree.rs @@ -1,7 +1,8 @@ #![allow(dead_code)] use crate::{ core::token::{ - type_info_to_symbol_kind, SymbolKind, Token, TokenIdent, TypeDefinition, TypedAstToken, + type_info_to_symbol_kind, SymbolKind, Token, TokenAstNode, TokenIdent, TypeDefinition, + TypedAstToken, }, traverse::{adaptive_iter, Parse, ParseContext}, }; @@ -52,7 +53,7 @@ impl<'a> TypedTree<'a> { .tokens .try_get_mut_with_retry(&self.ctx.ident(&Ident::new(mod_name_span.clone()))) { - token.typed = Some(TypedAstToken::TypedModuleName); + token.ast_node = TokenAstNode::Typed(TypedAstToken::TypedModuleName); token.type_def = Some(TypeDefinition::Ident(Ident::new(module.span.clone()))); } self.collect_module(module); @@ -108,7 +109,9 @@ impl Parse for ty::TySideEffect { ) => { for (mod_path, ident) in iter_prefixes(call_path).zip(call_path) { if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(ident)) { - token.typed = Some(TypedAstToken::TypedUseStatement(use_statement.clone())); + token.ast_node = TokenAstNode::Typed(TypedAstToken::TypedUseStatement( + use_statement.clone(), + )); if let Some(span) = ctx .namespace @@ -123,8 +126,9 @@ impl Parse for ty::TySideEffect { ImportType::Item(item) => { if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(item)) { - token.typed = - Some(TypedAstToken::TypedUseStatement(use_statement.clone())); + token.ast_node = TokenAstNode::Typed(TypedAstToken::TypedUseStatement( + use_statement.clone(), + )); let mut symbol_kind = SymbolKind::Unknown; let mut type_def = None; if let Some(decl_ident) = ctx @@ -150,9 +154,9 @@ impl Parse for ty::TySideEffect { if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(alias)) { - token.typed = Some(TypedAstToken::TypedUseStatement( - use_statement.clone(), - )); + token.ast_node = TokenAstNode::Typed( + TypedAstToken::TypedUseStatement(use_statement.clone()), + ); token.kind = symbol_kind; token.type_def = type_def; } @@ -164,8 +168,9 @@ impl Parse for ty::TySideEffect { .tokens .try_get_mut_with_retry(&ctx.ident(&Ident::new(span.clone()))) { - token.typed = - Some(TypedAstToken::TypedUseStatement(use_statement.clone())); + token.ast_node = TokenAstNode::Typed(TypedAstToken::TypedUseStatement( + use_statement.clone(), + )); if let Some(span) = ctx .namespace .submodule(ctx.engines, call_path) @@ -186,7 +191,7 @@ impl Parse for ty::TySideEffect { }, ) => { if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(mod_name)) { - token.typed = Some(TypedAstToken::TypedIncludeStatement( + token.ast_node = TokenAstNode::Typed(TypedAstToken::TypedIncludeStatement( include_statement.clone(), )); if let Some(span) = ctx @@ -210,7 +215,8 @@ impl Parse for ty::TyExpression { .tokens .try_get_mut_with_retry(&ctx.ident(&Ident::new(self.span.clone()))) { - token.typed = Some(TypedAstToken::TypedExpression(self.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TypedExpression(self.clone())); } } ty::TyExpressionVariant::FunctionApplication { @@ -237,7 +243,9 @@ impl Parse for ty::TyExpression { if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(last)) { if let Some(call_path_typeid) = call_path_typeid { - token.typed = Some(TypedAstToken::Ident(impl_type_name.clone())); + token.ast_node = TokenAstNode::Typed(TypedAstToken::Ident( + impl_type_name.clone(), + )); token.type_def = Some(TypeDefinition::TypeId(*call_path_typeid)); } } @@ -253,14 +261,15 @@ impl Parse for ty::TyExpression { .tokens .try_get_mut_with_retry(&ctx.ident(&call_path.suffix)) { - token.typed = Some(TypedAstToken::TypedExpression(self.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TypedExpression(self.clone())); let function_decl = ctx.engines.de().get_function(fn_ref); token.type_def = Some(TypeDefinition::Ident(function_decl.name.clone())); } contract_call_params.values().for_each(|exp| exp.parse(ctx)); adaptive_iter(arguments, |(ident, exp)| { if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(ident)) { - token.typed = Some(TypedAstToken::Ident(ident.clone())); + token.ast_node = TokenAstNode::Typed(TypedAstToken::Ident(ident.clone())); } exp.parse(ctx); }); @@ -306,7 +315,8 @@ impl Parse for ty::TyExpression { .tokens .try_get_mut_with_retry(&ctx.ident(&Ident::new(span.clone()))) { - token.typed = Some(TypedAstToken::TypedExpression(self.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TypedExpression(self.clone())); token.type_def = Some(TypeDefinition::Ident(name.clone())); } } @@ -332,7 +342,8 @@ impl Parse for ty::TyExpression { .tokens .try_get_mut_with_retry(&ctx.ident(&call_path_binding.inner.suffix)) { - token.typed = Some(TypedAstToken::TypedExpression(self.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TypedExpression(self.clone())); token.type_def = Some(TypeDefinition::TypeId(self.return_type)); } adaptive_iter(&call_path_binding.type_arguments.to_vec(), |type_arg| { @@ -343,7 +354,9 @@ impl Parse for ty::TyExpression { if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(&field.name)) { - token.typed = Some(TypedAstToken::TypedExpression(field.value.clone())); + token.ast_node = TokenAstNode::Typed(TypedAstToken::TypedExpression( + field.value.clone(), + )); if let Some(struct_decl) = &ctx .tokens .struct_declaration_of_type_id(ctx.engines, &self.return_type) @@ -401,7 +414,8 @@ impl Parse for ty::TyExpression { if let Some(mut token) = ctx.tokens.try_get_mut_with_retry( &ctx.ident(&Ident::new(field_instantiation_span.clone())), ) { - token.typed = Some(TypedAstToken::TypedExpression(self.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TypedExpression(self.clone())); token.type_def = Some(TypeDefinition::Ident(field_to_access.name.clone())); } } @@ -415,7 +429,8 @@ impl Parse for ty::TyExpression { .tokens .try_get_mut_with_retry(&ctx.ident(&Ident::new(elem_to_access_span.clone()))) { - token.typed = Some(TypedAstToken::TypedExpression(self.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TypedExpression(self.clone())); } } ty::TyExpressionVariant::EnumInstantiation { @@ -430,7 +445,8 @@ impl Parse for ty::TyExpression { .tokens .try_get_mut_with_retry(&ctx.ident(&call_path_binding.inner.suffix)) { - token.typed = Some(TypedAstToken::TypedExpression(self.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TypedExpression(self.clone())); token.type_def = Some(TypeDefinition::Ident(enum_ref.name().clone())); } adaptive_iter(&call_path_binding.type_arguments.to_vec(), |type_arg| { @@ -440,7 +456,8 @@ impl Parse for ty::TyExpression { if let Some(mut token) = ctx.tokens.try_get_mut_with_retry( &ctx.ident(&Ident::new(variant_instantiation_span.clone())), ) { - token.typed = Some(TypedAstToken::TypedExpression(self.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TypedExpression(self.clone())); token.type_def = Some(TypeDefinition::Ident(variant_name.clone())); } if let Some(contents) = contents.as_deref() { @@ -455,7 +472,8 @@ impl Parse for ty::TyExpression { .tokens .try_get_mut_with_retry(&ctx.ident(&abi_name.suffix)) { - token.typed = Some(TypedAstToken::TypedExpression(self.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TypedExpression(self.clone())); if let Some(abi_def_ident) = ctx .namespace .submodule(ctx.engines, &abi_name.prefixes) @@ -472,7 +490,9 @@ impl Parse for ty::TyExpression { if let Some(mut token) = ctx.tokens.try_get_mut_with_retry( &ctx.ident(&Ident::new(storage_access.storage_keyword_span.clone())), ) { - token.typed = Some(TypedAstToken::TypedStorageAccess(storage_access.clone())); + token.ast_node = TokenAstNode::Typed(TypedAstToken::TypedStorageAccess( + storage_access.clone(), + )); if let Some(storage) = ctx .namespace .current_items() @@ -488,9 +508,9 @@ impl Parse for ty::TyExpression { .tokens .try_get_mut_with_retry(&ctx.ident(&head_field.name)) { - token.typed = Some(TypedAstToken::TypedStorageAccessDescriptor( - head_field.clone(), - )); + token.ast_node = TokenAstNode::Typed( + TypedAstToken::TypedStorageAccessDescriptor(head_field.clone()), + ); if let Some(storage_field) = ctx .namespace .current_items() @@ -514,7 +534,8 @@ impl Parse for ty::TyExpression { if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(&field.name)) { - token.typed = Some(TypedAstToken::Ident(field.name.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::Ident(field.name.clone())); match &*ctx.engines.te().get(container_type_id) { TypeInfo::Struct(decl_ref) => { if let Some(field_name) = ctx @@ -557,7 +578,8 @@ impl Parse for ty::TyExpression { if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(&variant.name)) { - token.typed = Some(TypedAstToken::TypedExpression(self.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TypedExpression(self.clone())); } } ty::TyExpressionVariant::WhileLoop { @@ -586,9 +608,9 @@ impl Parse for ty::TyExpression { impl Parse for ty::TyVariableDecl { fn parse(&self, ctx: &ParseContext) { if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(&self.name)) { - token.typed = Some(TypedAstToken::TypedDeclaration(ty::TyDecl::VariableDecl( - Box::new(self.clone()), - ))); + token.ast_node = TokenAstNode::Typed(TypedAstToken::TypedDeclaration( + ty::TyDecl::VariableDecl(Box::new(self.clone())), + )); token.type_def = Some(TypeDefinition::Ident(self.name.clone())); } if let Some(call_path_tree) = &self.type_ascription.call_path_tree { @@ -627,7 +649,7 @@ impl Parse for ty::FunctionDecl { .tokens .try_get_mut_with_retry(&ctx.ident(&func_decl.name)) { - token.typed = Some(typed_token.clone()); + token.ast_node = TokenAstNode::Typed(typed_token.clone()); token.type_def = Some(TypeDefinition::Ident(func_decl.name.clone())); } adaptive_iter(&func_decl.body.contents, |node| node.parse(ctx)); @@ -646,7 +668,7 @@ impl Parse for ty::FunctionDecl { collect_trait_constraint(ctx, constraint); }); if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(ident)) { - token.typed = Some(typed_token.clone()); + token.ast_node = TokenAstNode::Typed(typed_token.clone()); if let Some(param_decl_ident) = func_decl .type_parameters .par_iter() @@ -667,9 +689,9 @@ impl Parse for ty::TraitDecl { .tokens .try_get_mut_with_retry(&ctx.ident(&trait_decl.name)) { - token.typed = Some(TypedAstToken::TypedDeclaration(ty::TyDecl::TraitDecl( - self.clone(), - ))); + token.ast_node = TokenAstNode::Typed(TypedAstToken::TypedDeclaration( + ty::TyDecl::TraitDecl(self.clone()), + )); token.type_def = Some(TypeDefinition::Ident(trait_decl.name.clone())); } adaptive_iter(&trait_decl.interface_surface, |item| match item { @@ -699,9 +721,9 @@ impl Parse for ty::StructDecl { .tokens .try_get_mut_with_retry(&ctx.ident(&struct_decl.call_path.suffix)) { - token.typed = Some(TypedAstToken::TypedDeclaration(ty::TyDecl::StructDecl( - self.clone(), - ))); + token.ast_node = TokenAstNode::Typed(TypedAstToken::TypedDeclaration( + ty::TyDecl::StructDecl(self.clone()), + )); token.type_def = Some(TypeDefinition::Ident(struct_decl.call_path.suffix.clone())); } adaptive_iter(&struct_decl.fields, |field| { @@ -712,7 +734,8 @@ impl Parse for ty::StructDecl { .tokens .try_get_mut_with_retry(&ctx.ident(&type_param.name_ident)) { - token.typed = Some(TypedAstToken::TypedParameter(type_param.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TypedParameter(type_param.clone())); token.type_def = Some(TypeDefinition::TypeId(type_param.type_id)); } }); @@ -741,7 +764,7 @@ impl Parse for ty::ImplSelfOrTrait { }); adaptive_iter(&trait_name.prefixes, |ident| { if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(ident)) { - token.typed = Some(TypedAstToken::Ident(ident.clone())); + token.ast_node = TokenAstNode::Typed(TypedAstToken::Ident(ident.clone())); } }); // Which typed token should be used for collect_type_id @@ -754,7 +777,7 @@ impl Parse for ty::ImplSelfOrTrait { .tokens .try_get_mut_with_retry(&ctx.ident(&trait_name.suffix)) { - token.typed = Some(TypedAstToken::TypedDeclaration( + token.ast_node = TokenAstNode::Typed(TypedAstToken::TypedDeclaration( ty::TyDecl::ImplSelfOrTrait(self.clone()), )); token.type_def = if let Some(decl_ref) = &trait_decl_ref { @@ -770,7 +793,7 @@ impl Parse for ty::ImplSelfOrTrait { } } } else { - typed_token.clone_from(&token.typed); + typed_token.clone_from(&token.as_typed().cloned()); Some(TypeDefinition::TypeId(implementing_for.type_id)) }; } @@ -816,9 +839,9 @@ impl Parse for ty::AbiDecl { .tokens .try_get_mut_with_retry(&ctx.ident(&abi_decl.name)) { - token.typed = Some(TypedAstToken::TypedDeclaration(ty::TyDecl::AbiDecl( - self.clone(), - ))); + token.ast_node = TokenAstNode::Typed(TypedAstToken::TypedDeclaration( + ty::TyDecl::AbiDecl(self.clone()), + )); token.type_def = Some(TypeDefinition::Ident(abi_decl.name.clone())); } adaptive_iter(&abi_decl.interface_surface, |item| match item { @@ -844,7 +867,7 @@ impl Parse for ty::AbiDecl { impl Parse for ty::GenericTypeForFunctionScope { fn parse(&self, ctx: &ParseContext) { if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(&self.name)) { - token.typed = Some(TypedAstToken::TypedDeclaration( + token.ast_node = TokenAstNode::Typed(TypedAstToken::TypedDeclaration( ty::TyDecl::GenericTypeForFunctionScope(self.clone()), )); token.type_def = Some(TypeDefinition::TypeId(self.type_id)); @@ -857,7 +880,8 @@ impl Parse for ty::StorageDecl { let storage_decl = ctx.engines.de().get_storage(&self.decl_id); adaptive_iter(&storage_decl.fields, |field| { if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(&field.name)) { - token.typed = Some(TypedAstToken::TypedStorageField(field.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TypedStorageField(field.clone())); token.type_def = Some(TypeDefinition::Ident(field.name.clone())); } collect_type_argument(ctx, &field.type_argument); @@ -877,7 +901,7 @@ impl Parse for ty::TyFunctionParameter { fn parse(&self, ctx: &ParseContext) { let typed_token = TypedAstToken::TypedFunctionParameter(self.clone()); if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(&self.name)) { - token.typed = Some(typed_token); + token.ast_node = TokenAstNode::Typed(typed_token); token.type_def = Some(TypeDefinition::Ident(self.name.clone())); } collect_type_argument(ctx, &self.type_argument); @@ -887,13 +911,13 @@ impl Parse for ty::TyFunctionParameter { impl Parse for ty::TyTraitFn { fn parse(&self, ctx: &ParseContext) { if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(&self.name)) { - token.typed = Some(TypedAstToken::TypedTraitFn(self.clone())); + token.ast_node = TokenAstNode::Typed(TypedAstToken::TypedTraitFn(self.clone())); token.type_def = Some(TypeDefinition::Ident(self.name.clone())); } adaptive_iter(&self.parameters, |param| param.parse(ctx)); let return_ident = Ident::new(self.return_type.span.clone()); if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(&return_ident)) { - token.typed = Some(TypedAstToken::TypedTraitFn(self.clone())); + token.ast_node = TokenAstNode::Typed(TypedAstToken::TypedTraitFn(self.clone())); token.type_def = Some(TypeDefinition::TypeId(self.return_type.type_id)); } } @@ -902,7 +926,7 @@ impl Parse for ty::TyTraitFn { impl Parse for ty::TyStructField { fn parse(&self, ctx: &ParseContext) { if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(&self.name)) { - token.typed = Some(TypedAstToken::TypedStructField(self.clone())); + token.ast_node = TokenAstNode::Typed(TypedAstToken::TypedStructField(self.clone())); token.type_def = Some(TypeDefinition::Ident(self.name.clone())); } collect_type_argument(ctx, &self.type_argument); @@ -913,7 +937,7 @@ impl Parse for ty::TyEnumVariant { fn parse(&self, ctx: &ParseContext) { let typed_token = TypedAstToken::TypedEnumVariant(self.clone()); if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(&self.name)) { - token.typed = Some(typed_token); + token.ast_node = TokenAstNode::Typed(typed_token); token.type_def = Some(TypeDefinition::TypeId(self.type_argument.type_id)); } collect_type_argument(ctx, &self.type_argument); @@ -924,7 +948,7 @@ impl Parse for ty::TyFunctionDecl { fn parse(&self, ctx: &ParseContext) { let typed_token = TypedAstToken::TypedFunctionDeclaration(self.clone()); if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(&self.name)) { - token.typed = Some(typed_token.clone()); + token.ast_node = TokenAstNode::Typed(typed_token.clone()); token.type_def = Some(TypeDefinition::Ident(self.name.clone())); } adaptive_iter(&self.body.contents, |node| node.parse(ctx)); @@ -943,7 +967,7 @@ impl Parse for ty::TyFunctionDecl { collect_trait_constraint(ctx, constraint); }); if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(ident)) { - token.typed = Some(typed_token.clone()); + token.ast_node = TokenAstNode::Typed(typed_token.clone()); if let Some(param_decl_ident) = self .type_parameters .par_iter() @@ -960,7 +984,8 @@ impl Parse for ty::TyFunctionDecl { impl Parse for ty::TyTypeAliasDecl { fn parse(&self, ctx: &ParseContext) { if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(&self.name)) { - token.typed = Some(TypedAstToken::TypedTypeAliasDeclaration(self.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TypedTypeAliasDeclaration(self.clone())); token.type_def = Some(TypeDefinition::Ident(self.name.clone())); } collect_type_argument(ctx, &self.ty); @@ -987,7 +1012,8 @@ impl Parse for ty::TyScrutinee { CatchAll => {} Constant(name, _, decl) => { if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(name)) { - token.typed = Some(TypedAstToken::TypedScrutinee(self.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TypedScrutinee(self.clone())); token.type_def = Some(TypeDefinition::Ident(decl.call_path.suffix.clone())); } } @@ -996,12 +1022,14 @@ impl Parse for ty::TyScrutinee { .tokens .try_get_mut_with_retry(&ctx.ident(&Ident::new(self.span.clone()))) { - token.typed = Some(TypedAstToken::TypedScrutinee(self.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TypedScrutinee(self.clone())); } } Variable(ident) => { if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(ident)) { - token.typed = Some(TypedAstToken::TypedScrutinee(self.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TypedScrutinee(self.clone())); } } StructScrutinee { @@ -1013,7 +1041,8 @@ impl Parse for ty::TyScrutinee { .tokens .try_get_mut_with_retry(&ctx.ident(&instantiation_call_path.suffix)) { - token.typed = Some(TypedAstToken::TypedScrutinee(self.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TypedScrutinee(self.clone())); token.type_def = Some(TypeDefinition::Ident(struct_ref.name().clone())); } adaptive_iter(fields, |field| field.parse(ctx)); @@ -1030,7 +1059,8 @@ impl Parse for ty::TyScrutinee { { // the last prefix of the call path is not a module but a type if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(last)) { - token.typed = Some(TypedAstToken::TypedScrutinee(self.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TypedScrutinee(self.clone())); token.type_def = Some(TypeDefinition::Ident(enum_ref.name().clone())); } prefixes @@ -1042,7 +1072,8 @@ impl Parse for ty::TyScrutinee { .tokens .try_get_mut_with_retry(&ctx.ident(&instantiation_call_path.suffix)) { - token.typed = Some(TypedAstToken::TypedScrutinee(self.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TypedScrutinee(self.clone())); token.type_def = Some(TypeDefinition::Ident(variant.name.clone())); } value.parse(ctx); @@ -1057,7 +1088,8 @@ impl Parse for ty::TyScrutinee { impl Parse for ty::TyStructScrutineeField { fn parse(&self, ctx: &ParseContext) { if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(&self.field)) { - token.typed = Some(TypedAstToken::TyStructScrutineeField(self.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TyStructScrutineeField(self.clone())); token.type_def = Some(TypeDefinition::Ident(self.field_def_name.clone())); } if let Some(scrutinee) = &self.scrutinee { @@ -1077,13 +1109,15 @@ impl Parse for ty::TyReassignment { indices, } => { if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(base_name)) { - token.typed = Some(TypedAstToken::TypedReassignment(self.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TypedReassignment(self.clone())); } adaptive_iter(indices, |proj_kind| { if let ty::ProjectionKind::StructField { name } = proj_kind { if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(name)) { - token.typed = Some(TypedAstToken::TypedReassignment(self.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TypedReassignment(self.clone())); if let Some(struct_decl) = &ctx .tokens .struct_declaration_of_type_id(ctx.engines, base_type) @@ -1110,7 +1144,7 @@ fn assign_type_to_token( type_id: TypeId, ) { token.kind = symbol_kind; - token.typed = Some(typed_token); + token.ast_node = TokenAstNode::Typed(typed_token); token.type_def = Some(TypeDefinition::TypeId(type_id)); } @@ -1174,7 +1208,8 @@ fn collect_call_path_tree(ctx: &ParseContext, tree: &CallPathTree, type_arg: &Ty .tokens .try_get_mut_with_retry(&ctx.ident(&abi_call_path.call_path.suffix)) { - token.typed = Some(TypedAstToken::TypedArgument(type_arg.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TypedArgument(type_arg.clone())); if let Some(abi_def_ident) = ctx .namespace .submodule(ctx.engines, &abi_call_path.call_path.prefixes) @@ -1198,7 +1233,7 @@ fn collect_call_path_tree(ctx: &ParseContext, tree: &CallPathTree, type_arg: &Ty fn collect_call_path_prefixes(ctx: &ParseContext, prefixes: &[Ident]) { for (mod_path, ident) in iter_prefixes(prefixes).zip(prefixes) { if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&ctx.ident(ident)) { - token.typed = Some(TypedAstToken::Ident(ident.clone())); + token.ast_node = TokenAstNode::Typed(TypedAstToken::Ident(ident.clone())); if let Some(span) = ctx .namespace .submodule(ctx.engines, mod_path) @@ -1215,7 +1250,8 @@ fn collect_const_decl(ctx: &ParseContext, const_decl: &ty::TyConstantDecl, ident let key = ctx.ident(ident.unwrap_or(const_decl.name())); if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&key) { - token.typed = Some(TypedAstToken::TypedConstantDeclaration(const_decl.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TypedConstantDeclaration(const_decl.clone())); token.type_def = Some(TypeDefinition::Ident(const_decl.call_path.suffix.clone())); } if let Some(call_path_tree) = &const_decl.type_ascription.call_path_tree { @@ -1234,7 +1270,8 @@ fn collect_configurable_decl( let key = ctx.ident(ident.unwrap_or(decl.name())); if let Some(mut token) = ctx.tokens.try_get_mut_with_retry(&key) { - token.typed = Some(TypedAstToken::TypedConfigurableDeclaration(decl.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TypedConfigurableDeclaration(decl.clone())); token.type_def = Some(TypeDefinition::Ident(decl.call_path.suffix.clone())); } if let Some(call_path_tree) = &decl.type_ascription.call_path_tree { @@ -1250,7 +1287,8 @@ fn collect_trait_type_decl(ctx: &ParseContext, type_decl: &ty::TyTraitType, span .tokens .try_get_mut_with_retry(&ctx.ident(&Ident::new(span.clone()))) { - token.typed = Some(TypedAstToken::TypedTraitTypeDeclaration(type_decl.clone())); + token.ast_node = + TokenAstNode::Typed(TypedAstToken::TypedTraitTypeDeclaration(type_decl.clone())); token.type_def = Some(TypeDefinition::Ident(type_decl.name.clone())); } if let Some(ty) = &type_decl.ty { @@ -1376,7 +1414,7 @@ fn collect_trait_constraint( .tokens .try_get_mut_with_retry(&ctx.ident(&trait_name.suffix)) { - token.typed = Some(TypedAstToken::TypedTraitConstraint( + token.ast_node = TokenAstNode::Typed(TypedAstToken::TypedTraitConstraint( trait_constraint.clone(), )); if let Some(trait_def_ident) = ctx @@ -1398,7 +1436,7 @@ fn collect_supertrait(ctx: &ParseContext, supertrait: &Supertrait) { .tokens .try_get_mut_with_retry(&ctx.ident(&supertrait.name.suffix)) { - token.typed = Some(TypedAstToken::TypedSupertrait(supertrait.clone())); + token.ast_node = TokenAstNode::Typed(TypedAstToken::TypedSupertrait(supertrait.clone())); token.type_def = if let Some(decl_ref) = &supertrait.decl_ref { let trait_decl = ctx.engines.de().get_trait(decl_ref); Some(TypeDefinition::Ident(trait_decl.name.clone())) @@ -1414,7 +1452,7 @@ fn collect_enum(ctx: &ParseContext, decl_id: &DeclId, declaratio .tokens .try_get_mut_with_retry(&ctx.ident(&enum_decl.call_path.suffix)) { - token.typed = Some(TypedAstToken::TypedDeclaration(declaration.clone())); + token.ast_node = TokenAstNode::Typed(TypedAstToken::TypedDeclaration(declaration.clone())); token.type_def = Some(TypeDefinition::Ident(enum_decl.call_path.suffix.clone())); } adaptive_iter(&enum_decl.type_parameters, |type_param| { @@ -1422,7 +1460,7 @@ fn collect_enum(ctx: &ParseContext, decl_id: &DeclId, declaratio .tokens .try_get_mut_with_retry(&ctx.ident(&type_param.name_ident)) { - token.typed = Some(TypedAstToken::TypedParameter(type_param.clone())); + token.ast_node = TokenAstNode::Typed(TypedAstToken::TypedParameter(type_param.clone())); token.type_def = Some(TypeDefinition::TypeId(type_param.type_id)); } }); diff --git a/sway-lsp/src/utils/attributes.rs b/sway-lsp/src/utils/attributes.rs index 31fd7be5e94..a7f0e312025 100644 --- a/sway-lsp/src/utils/attributes.rs +++ b/sway-lsp/src/utils/attributes.rs @@ -1,47 +1,103 @@ #![allow(dead_code)] -use crate::core::token::{AstToken, Token}; -use sway_core::{language::parsed::Declaration, transform, Engines}; +use crate::core::token::{ParsedAstToken, Token, TokenAstNode, TypedAstToken}; +use sway_core::{ + language::{parsed::Declaration, ty}, + transform, Engines, +}; +/// Gets attributes map from typed token, falling back to parsed AST node if needed. +/// Callback can be used to retrieve doc comment attributes or storage attributes. pub fn attributes_map(engines: &Engines, token: &Token, mut callback: F) where F: FnMut(&transform::AttributesMap), { - match &token.parsed { - AstToken::Declaration(declaration) => match declaration { - Declaration::EnumDeclaration(decl_id) => { - let decl = engines.pe().get_enum(decl_id); - callback(&decl.attributes); + match &token.ast_node { + TokenAstNode::Typed(typed_token) => match typed_token { + TypedAstToken::TypedDeclaration(decl) => match decl { + ty::TyDecl::EnumDecl(ty::EnumDecl { decl_id, .. }) => { + let enum_decl = engines.de().get_enum(decl_id); + callback(&enum_decl.attributes); + } + ty::TyDecl::StructDecl(ty::StructDecl { decl_id, .. }) => { + let struct_decl = engines.de().get_struct(decl_id); + callback(&struct_decl.attributes); + } + ty::TyDecl::StorageDecl(ty::StorageDecl { decl_id, .. }) => { + let storage_decl = engines.de().get_storage(decl_id); + callback(&storage_decl.attributes); + } + ty::TyDecl::AbiDecl(ty::AbiDecl { decl_id, .. }) => { + let abi_decl = engines.de().get_abi(decl_id); + callback(&abi_decl.attributes); + } + _ => {} + }, + TypedAstToken::TypedFunctionDeclaration(fn_decl) => { + callback(&fn_decl.attributes); } - Declaration::FunctionDeclaration(decl_id) => { - let decl = engines.pe().get_function(decl_id); - callback(&decl.attributes); + TypedAstToken::TypedConstantDeclaration(constant) => { + callback(&constant.attributes); } - Declaration::StructDeclaration(decl_id) => { - let decl = engines.pe().get_struct(decl_id); - callback(&decl.attributes); + TypedAstToken::TypedStorageField(field) => { + callback(&field.attributes); } - Declaration::ConstantDeclaration(decl_id) => { - let decl = engines.pe().get_constant(decl_id); - callback(&decl.attributes); + TypedAstToken::TypedStructField(field) => { + callback(&field.attributes); } - Declaration::StorageDeclaration(decl_id) => { - let decl = engines.pe().get_storage(decl_id); - callback(&decl.attributes); + TypedAstToken::TypedTraitFn(trait_fn) => { + callback(&trait_fn.attributes); + } + TypedAstToken::TypedEnumVariant(variant) => { + callback(&variant.attributes); } - Declaration::AbiDeclaration(decl_id) => { - let decl = engines.pe().get_abi(decl_id); + TypedAstToken::TypedConfigurableDeclaration(configurable) => { + callback(&configurable.attributes); + } + TypedAstToken::TypedTraitTypeDeclaration(trait_type) => { + callback(&trait_type.attributes); + } + TypedAstToken::TypedTypeAliasDeclaration(type_alias) => { + callback(&type_alias.attributes); + } + _ => {} + }, + TokenAstNode::Parsed(parsed_token) => match &parsed_token { + ParsedAstToken::Declaration(declaration) => match declaration { + Declaration::EnumDeclaration(decl_id) => { + let decl = engines.pe().get_enum(decl_id); + callback(&decl.attributes); + } + Declaration::FunctionDeclaration(decl_id) => { + let decl = engines.pe().get_function(decl_id); + callback(&decl.attributes); + } + Declaration::StructDeclaration(decl_id) => { + let decl = engines.pe().get_struct(decl_id); + callback(&decl.attributes); + } + Declaration::ConstantDeclaration(decl_id) => { + let decl = engines.pe().get_constant(decl_id); + callback(&decl.attributes); + } + Declaration::StorageDeclaration(decl_id) => { + let decl = engines.pe().get_storage(decl_id); + callback(&decl.attributes); + } + Declaration::AbiDeclaration(decl_id) => { + let decl = engines.pe().get_abi(decl_id); + callback(&decl.attributes); + } + _ => {} + }, + ParsedAstToken::StorageField(field) => callback(&field.attributes), + ParsedAstToken::StructField(field) => callback(&field.attributes), + ParsedAstToken::TraitFn(decl_id) => { + let decl = engines.pe().get_trait_fn(decl_id); callback(&decl.attributes); } + ParsedAstToken::EnumVariant(variant) => callback(&variant.attributes), _ => {} }, - AstToken::StorageField(field) => callback(&field.attributes), - AstToken::StructField(field) => callback(&field.attributes), - AstToken::TraitFn(decl_id) => { - let decl = engines.pe().get_trait_fn(decl_id); - callback(&decl.attributes); - } - AstToken::EnumVariant(variant) => callback(&variant.attributes), - _ => {} } } diff --git a/sway-lsp/src/utils/debug.rs b/sway-lsp/src/utils/debug.rs index e391acb1e35..e98390d6694 100644 --- a/sway-lsp/src/utils/debug.rs +++ b/sway-lsp/src/utils/debug.rs @@ -14,7 +14,7 @@ where tokens .filter_map(|entry| { let (ident, token) = entry.pair(); - if token.typed.is_none() { + if token.as_parsed().is_some() { Some(warning_from_ident(ident)) } else { None @@ -39,7 +39,7 @@ where tokens .filter_map(|entry| { let (ident, token) = entry.pair(); - if token.typed.is_some() { + if token.as_typed().is_some() { Some(warning_from_ident(ident)) } else { None From 3ff63a59c1b497ffa24ea620c7f722191616e17b Mon Sep 17 00:00:00 2001 From: Vaivaswatha N Date: Sat, 2 Nov 2024 16:17:58 +0530 Subject: [PATCH 093/115] `EncodeBufferAppend`: `grow_if_needed` should allocate sufficiently (#6686) --- forc-plugins/forc-client/tests/deploy.rs | 8 ++-- forc/tests/cli_integration.rs | 8 ++-- sway-core/src/ir_generation/function.rs | 10 +++-- sway-lib-core/src/codec.sw | 11 ++++- .../configurable_dedup_decode/stdout.snap | 42 ++++++++++--------- .../json_abi_oracle_new_encoding.json | 2 +- .../array_of_structs_caller/src/main.sw | 2 +- .../asset_ops_test/src/main.sw | 2 +- .../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 +- 18 files changed, 60 insertions(+), 45 deletions(-) diff --git a/forc-plugins/forc-client/tests/deploy.rs b/forc-plugins/forc-client/tests/deploy.rs index 8f428a6aa6e..eddee21d4d9 100644 --- a/forc-plugins/forc-client/tests/deploy.rs +++ b/forc-plugins/forc-client/tests/deploy.rs @@ -373,7 +373,7 @@ async fn test_simple_deploy() { node.kill().unwrap(); let expected = vec![DeployedPackage::Contract(DeployedContract { id: ContractId::from_str( - "adcd0480deb735ffd8f5bd0683b66c55465e0841076efca4c28be25c767ede5b", + "5c51b8904c539700852c646c6700fddab4b80477f66e56fb2515736facd84e69", ) .unwrap(), proxy: None, @@ -416,7 +416,7 @@ async fn test_deploy_submit_only() { node.kill().unwrap(); let expected = vec![DeployedPackage::Contract(DeployedContract { id: ContractId::from_str( - "adcd0480deb735ffd8f5bd0683b66c55465e0841076efca4c28be25c767ede5b", + "5c51b8904c539700852c646c6700fddab4b80477f66e56fb2515736facd84e69", ) .unwrap(), proxy: None, @@ -462,12 +462,12 @@ async fn test_deploy_fresh_proxy() { node.kill().unwrap(); let impl_contract = DeployedPackage::Contract(DeployedContract { id: ContractId::from_str( - "adcd0480deb735ffd8f5bd0683b66c55465e0841076efca4c28be25c767ede5b", + "5c51b8904c539700852c646c6700fddab4b80477f66e56fb2515736facd84e69", ) .unwrap(), proxy: Some( ContractId::from_str( - "5297238a1d867c9d7c8fa83c700e2d0d1c57e1874ec95ff4a67063e222ab1880", + "7a78517c2c3322028db65e54893dc97958fa3d7c846a66f5675859e64f927540", ) .unwrap(), ), diff --git a/forc/tests/cli_integration.rs b/forc/tests/cli_integration.rs index 7aaf4f054de..422e9f18f9c 100644 --- a/forc/tests/cli_integration.rs +++ b/forc/tests/cli_integration.rs @@ -49,10 +49,10 @@ fn test_forc_test_raw_logs() -> Result<(), rexpect::error::Error> { // Assert that the output is correct process.exp_string(" test test_log_4")?; process.exp_string("Raw logs:")?; - process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12660,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; + process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12672,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; process.exp_string(" test test_log_2")?; process.exp_string("Raw logs:")?; - process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12660,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; + process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12672,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; process.process.exit()?; Ok(()) @@ -74,11 +74,11 @@ fn test_forc_test_both_logs() -> Result<(), rexpect::error::Error> { process.exp_string(" test test_log_4")?; process.exp_string("Decoded log value: 4, log rb: 1515152261580153489")?; process.exp_string("Raw logs:")?; - process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12660,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; + process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12672,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; process.exp_string(" test test_log_2")?; process.exp_string("Decoded log value: 2, log rb: 1515152261580153489")?; process.exp_string("Raw logs:")?; - process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12660,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; + process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12672,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; process.process.exit()?; Ok(()) } diff --git a/sway-core/src/ir_generation/function.rs b/sway-core/src/ir_generation/function.rs index 7c333f55185..c97ad7a94ff 100644 --- a/sway-core/src/ir_generation/function.rs +++ b/sway-core/src/ir_generation/function.rs @@ -1783,7 +1783,7 @@ impl<'eng> FnCompiler<'eng> { ); // needs realloc block - // new_cap = cap * 2 + // new_cap = (cap * 2) + needed_size // aloc new_cap // mcp hp old_ptr len // hp: ptr u8 @@ -1793,11 +1793,15 @@ impl<'eng> FnCompiler<'eng> { let two = Constant::new_uint(context, 64, 2); let two = Value::new_constant(context, two); - let new_cap = + let new_cap_part = s.current_block .append(context) .binary_op(BinaryOpKind::Mul, cap, two); - + let new_cap = s.current_block.append(context).binary_op( + BinaryOpKind::Add, + new_cap_part, + needed_size, + ); let new_ptr = s.current_block.append(context).asm_block( vec![ AsmArg { diff --git a/sway-lib-core/src/codec.sw b/sway-lib-core/src/codec.sw index 2e9ed4aae20..913da976a0c 100644 --- a/sway-lib-core/src/codec.sw +++ b/sway-lib-core/src/codec.sw @@ -5156,6 +5156,15 @@ fn to_slice(array: T) -> raw_slice { raw_slice::from_parts::(__addr_of(array), len) } +fn assert_ge(a: T, b: T, revert_code: u64) +where + T: Ord, +{ + if a.lt(b) { + __revert(revert_code) + } +} + fn assert_eq(a: T, b: T, revert_code: u64) where T: Eq, @@ -5205,7 +5214,7 @@ where // Append another item let buffer = value_to_append.abi_encode(buffer); assert_neq(ptr1, buffer.buffer.0, 4); // must have allocated new buffer - assert_eq(buffer.buffer.1, size_of_t * 2, 5); // capacity for two items + assert_ge(buffer.buffer.1, size_of_t * 2, 5); // capacity for at least two items assert_eq(buffer.buffer.2, size_of_t * 2, 6); // buffer has two items // Check that red zones were not overwritten diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/stdout.snap index be59f759d26..b4b15b07969 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/stdout.snap @@ -1,6 +1,6 @@ --- source: test/tests/tests.rs -assertion_line: 99 +assertion_line: 115 --- > forc build --path test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode --release --ir final exit status: 0 @@ -207,24 +207,25 @@ script { encode_10_abi_encode_11_block1(): v81 = const u64 2 v82 = mul v33, v81, !116 - v83 = asm(new_cap: v82, old_ptr: v30, len: v36) -> ptr u8 hp, !117 { + v83 = add v82, v37, !117 + v84 = asm(new_cap: v83, old_ptr: v30, len: v36) -> ptr u8 hp, !118 { aloc new_cap mcp hp old_ptr len } - br encode_10_abi_encode_11_block0(v83, v82), !118 + br encode_10_abi_encode_11_block0(v84, v83), !119 } - entry_orig fn main_8() -> u64, !121 { + entry_orig fn main_8() -> u64, !122 { entry(): - v0 = get_config ptr { u64 }, WRAPPED, !122 + v0 = get_config ptr { u64 }, WRAPPED, !123 v1 = const u64 0 - v2 = get_elem_ptr v0, ptr u64, v1, !123 + v2 = get_elem_ptr v0, ptr u64, v1, !124 v3 = load v2 - v4 = get_config ptr { u64 }, TUPLE, !124 + v4 = get_config ptr { u64 }, TUPLE, !125 v5 = const u64 0 - v6 = get_elem_ptr v4, ptr u64, v5, !125 + v6 = get_elem_ptr v4, ptr u64, v5, !126 v7 = load v6 - v8 = add v3, v7, !128 + v8 = add v3, v7, !129 ret u64 v8 } } @@ -348,15 +349,16 @@ script { !116 = (!49 !50 !66 !67) !117 = (!49 !50 !66 !67) !118 = (!49 !50 !66 !67) -!119 = span !0 202 246 -!120 = fn_name_span !0 205 209 -!121 = (!119 !120) -!122 = span !0 225 232 -!123 = span !0 30 36 -!124 = span !0 237 242 -!125 = span !0 243 244 -!126 = span !0 225 244 -!127 = fn_call_path_span !0 235 236 -!128 = (!126 !127) +!119 = (!49 !50 !66 !67) +!120 = span !0 202 246 +!121 = fn_name_span !0 205 209 +!122 = (!120 !121) +!123 = span !0 225 232 +!124 = span !0 30 36 +!125 = span !0 237 242 +!126 = span !0 243 244 +!127 = span !0 225 244 +!128 = fn_call_path_span !0 235 236 +!129 = (!127 !128) - Finished release [optimized + fuel] target(s) [744 B] in ??? + Finished release [optimized + fuel] target(s) [752 B] in ??? diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/u256/u256_abi/json_abi_oracle_new_encoding.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/u256/u256_abi/json_abi_oracle_new_encoding.json index 33f149499d6..c58838960ad 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/u256/u256_abi/json_abi_oracle_new_encoding.json +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/u256/u256_abi/json_abi_oracle_new_encoding.json @@ -9,7 +9,7 @@ { "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", "name": "SOME_U256", - "offset": 864 + "offset": 872 } ], "encodingVersion": "1", 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 3150cc69907..deee7c52ae5 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 = 0x91c3e72c3b3f4bf7bd5c548d8752c766d5fb8ebf15be3cf92ff34682da9bfb4d; // AUTO-CONTRACT-ID ../../test_contracts/array_of_structs_contract --release +const CONTRACT_ID = 0x6b01f04c84ce955e8dfc6ed3611fd2518424ab757e5a540878f49fbd1bdec571; // AUTO-CONTRACT-ID ../../test_contracts/array_of_structs_contract --release fn get_address() -> Option { Some(CONTRACT_ID.into()) 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 685e3d5444b..1c2a953fc35 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 @@ -14,7 +14,7 @@ const FUEL_COIN_CONTRACT_ID = 0x19c0d374734bd8a92b776787e9dffa0f105a90e3c977626f #[cfg(experimental_new_encoding = false)] const BALANCE_CONTRACT_ID = 0xf6cd545152ac83225e8e7df2efb5c6fa6e37bc9b9e977b5ea8103d28668925df; #[cfg(experimental_new_encoding = true)] -const BALANCE_CONTRACT_ID = 0xc0ae93ca2a6ec1c740a4869a3f5bfe061184e30e4e5c6185891d3ec2dba9a33d; // AUTO-CONTRACT-ID ../../test_contracts/balance_test_contract --release +const BALANCE_CONTRACT_ID = 0xb770fa56f665d6fbdbdceecce21b7b61878f650981ac7f21c052613015937034; // 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 448359905b5..638541084b4 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 = 0xc0ae93ca2a6ec1c740a4869a3f5bfe061184e30e4e5c6185891d3ec2dba9a33d; // AUTO-CONTRACT-ID ../../test_contracts/balance_test_contract --release +const CONTRACT_ID = 0xb770fa56f665d6fbdbdceecce21b7b61878f650981ac7f21c052613015937034; // 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 7778fd9369b..9a078ca2bbc 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 = 0xeb1d43bccc97620c80599c25722b1be3a22affd0570cfdcc57deac7c729e5389; // AUTO-CONTRACT-ID ../../test_contracts/abi_with_tuples_contract --release +const CONTRACT_ID = 0xcc679c89d2950879d4f8fb3b99770f93dfde3335fff574cbf0588691fbcefde3; // 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 d519240f19d..44c854b196b 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 = 0x770eb6e1b7de06098474e110cac9ed32c72c455ba7f34bea00ebb47a43986701; // AUTO-CONTRACT-ID ../../test_contracts/basic_storage --release +const CONTRACT_ID = 0x38ea1d4d087b96c1e0b4b70e031cf1acc02363f000e8059d02ffc07d61885452; // 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 61ba86c1b2c..dae00c1579b 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 = 0xa3ebed6b4c9d17001bf759332daaa22c2e522cb1c61116ac395443f5ab392225; // AUTO-CONTRACT-ID ../../test_contracts/contract_with_type_aliases --release +const CONTRACT_ID = 0x2e8efc627379d037c6ac70249d0bf0726f228ea6bade786e11639b878241f333; // 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 cdc8f7d508a..28218e97054 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 = 0x3a0ad1930a751f3849e10d55aedad4b14be604a1807b3016db959a311dbbd101; // AUTO-CONTRACT-ID ../../test_contracts/increment_contract --release +const CONTRACT_ID = 0xc2694e6a397883ae59ea2e807c0ba3714865d0c4bf16571893d632b3bd7ec6f7; // 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 c91268acb0f..4c605d999cd 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 = 0x14df60f48d5874d2623ba7f5604987b29f6288a1ae35a130bfae57e64f74aa89; // AUTO-CONTRACT-ID ../../test_contracts/storage_enum_contract --release +const CONTRACT_ID = 0xd3da5ae426182db1a2a6c900ad374a9641dabfdebe610b39f0e9c5186cedf39b; // 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 ec50cbe43bd..ea5fb5c74e5 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 = 0xa3ee3b5d5469efa870ba468c36c3775ea5287da385d70fbcd4aadbf5acb5a772; // AUTO-CONTRACT-ID ../../test_contracts/auth_testing_contract --release +const CONTRACT_ID = 0xcdc67c314d13752e5c3e10aa1de6615e1ec6864e0461317b5f26eef3320a9a8e; // 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 65bca7c89cd..64dec655d14 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 = 0x16f15adbe1fbdee5d19349fc245429dad3265f8a0f7a8143ffec39de8c809ff4; // AUTO-CONTRACT-ID ../../test_contracts/context_testing_contract --release +const CONTRACT_ID = 0xecf511a0e2f4022c17413625d69c390d51d0740424d6886cbbe9ca60acd0606b; // 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 505fff93133..1364b7aa4b4 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 = 0xd9e836ce255122c0c243cb0bd6d10450d87206f995d127e60e90bf9ab4fc3532; // AUTO-CONTRACT-ID ../../test_contracts/nested_struct_args_contract --release +const CONTRACT_ID = 0x27e6a749a1773f65f850b36e4e61afdbfe72ba4189cd518c16e06cf0c04a1fa9; // 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 33f80e65b6b..12e4d20fdec 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 = 0x9075162ba3ecabb57aae8ddcd785d8a1211d08281de71c34a1772a888e339ba1; // AUTO-CONTRACT-ID ../../test_contracts/storage_access_contract --release +const CONTRACT_ID = 0xb509b52a765f2a8e97b29e4699d0ec8fa056b2bb649f785c75e36f868c318b98; // AUTO-CONTRACT-ID ../../test_contracts/storage_access_contract --release fn main() -> bool { let caller = abi(StorageAccess, CONTRACT_ID); From d7dd104dac4394aa7af56f05b720c975744db853 Mon Sep 17 00:00:00 2001 From: IGI-111 Date: Sun, 3 Nov 2024 17:12:45 +0100 Subject: [PATCH 094/115] Bump to v0.66.4 (#6688) --- Cargo.lock | 70 +++---- Cargo.toml | 50 ++--- forc-pkg/src/pkg.rs | 23 +-- .../deployed_script-loader-abi.json | 24 +-- forc-plugins/forc-client/tests/deploy.rs | 8 +- forc-test/src/execute.rs | 25 +-- forc/src/cli/commands/parse_bytecode.rs | 8 - forc/tests/cli_integration.rs | 8 +- sway-core/src/asm_generation/finalized_asm.rs | 66 ++---- .../allocated_abstract_instruction_set.rs | 27 +-- .../src/asm_generation/fuel/data_section.rs | 191 +++++------------- .../asm_generation/fuel/fuel_asm_builder.rs | 23 +-- .../src/asm_generation/fuel/functions.rs | 22 +- .../asm_generation/fuel/programs/abstract.rs | 46 ++--- sway-core/src/asm_lang/allocated_ops.rs | 42 ++-- sway-core/src/asm_lang/mod.rs | 11 - sway-core/src/asm_lang/virtual_ops.rs | 8 - sway-core/src/lib.rs | 22 -- .../json_abi_oracle_new_encoding.json | 32 +-- .../configurable_dedup_decode/stdout.snap | 4 +- .../json_abi_oracle_new_encoding.json | 2 +- .../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 +- .../src/sdk-harness/test_projects/auth/mod.rs | 4 +- test/update-contract-ids.sh | 2 +- 35 files changed, 241 insertions(+), 503 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0d2d424463b..7bb96c29e3a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2675,7 +2675,7 @@ checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" [[package]] name = "forc" -version = "0.66.3" +version = "0.66.4" dependencies = [ "annotate-snippets", "ansi_term", @@ -2686,7 +2686,7 @@ dependencies = [ "completest-pty", "forc-pkg", "forc-test", - "forc-tracing 0.66.3", + "forc-tracing 0.66.4", "forc-util", "fs_extra", "fuel-asm", @@ -2713,7 +2713,7 @@ dependencies = [ [[package]] name = "forc-client" -version = "0.66.3" +version = "0.66.4" dependencies = [ "anyhow", "async-trait", @@ -2725,7 +2725,7 @@ dependencies = [ "dialoguer", "forc", "forc-pkg", - "forc-tracing 0.66.3", + "forc-tracing 0.66.4", "forc-tx", "forc-util", "forc-wallet", @@ -2761,14 +2761,14 @@ dependencies = [ [[package]] name = "forc-crypto" -version = "0.66.3" +version = "0.66.4" dependencies = [ "anyhow", "async-trait", "atty", "clap 4.5.20", "criterion", - "forc-tracing 0.66.3", + "forc-tracing 0.66.4", "forc-util", "fuel-core-types", "fuel-crypto", @@ -2792,7 +2792,7 @@ dependencies = [ [[package]] name = "forc-debug" -version = "0.66.3" +version = "0.66.4" dependencies = [ "anyhow", "clap 4.5.20", @@ -2800,7 +2800,7 @@ dependencies = [ "escargot", "forc-pkg", "forc-test", - "forc-tracing 0.66.3", + "forc-tracing 0.66.4", "fuel-core-client", "fuel-types", "fuel-vm", @@ -2819,7 +2819,7 @@ dependencies = [ [[package]] name = "forc-doc" -version = "0.66.3" +version = "0.66.4" dependencies = [ "anyhow", "clap 4.5.20", @@ -2827,7 +2827,7 @@ dependencies = [ "dir_indexer", "expect-test", "forc-pkg", - "forc-tracing 0.66.3", + "forc-tracing 0.66.4", "forc-util", "horrorshow", "include_dir", @@ -2845,12 +2845,12 @@ dependencies = [ [[package]] name = "forc-fmt" -version = "0.66.3" +version = "0.66.4" dependencies = [ "anyhow", "clap 4.5.20", "forc-pkg", - "forc-tracing 0.66.3", + "forc-tracing 0.66.4", "forc-util", "prettydiff 0.7.0", "sway-core", @@ -2862,7 +2862,7 @@ dependencies = [ [[package]] name = "forc-lsp" -version = "0.66.3" +version = "0.66.4" dependencies = [ "anyhow", "clap 4.5.20", @@ -2873,13 +2873,13 @@ dependencies = [ [[package]] name = "forc-pkg" -version = "0.66.3" +version = "0.66.4" dependencies = [ "ansi_term", "anyhow", "byte-unit", "cid", - "forc-tracing 0.66.3", + "forc-tracing 0.66.4", "forc-util", "fuel-abi-types", "futures", @@ -2911,7 +2911,7 @@ dependencies = [ [[package]] name = "forc-test" -version = "0.66.3" +version = "0.66.4" dependencies = [ "anyhow", "forc-pkg", @@ -2939,7 +2939,7 @@ dependencies = [ [[package]] name = "forc-tracing" -version = "0.66.3" +version = "0.66.4" dependencies = [ "ansi_term", "tracing", @@ -2949,7 +2949,7 @@ dependencies = [ [[package]] name = "forc-tx" -version = "0.66.3" +version = "0.66.4" dependencies = [ "anyhow", "clap 4.5.20", @@ -2964,7 +2964,7 @@ dependencies = [ [[package]] name = "forc-util" -version = "0.66.3" +version = "0.66.4" dependencies = [ "annotate-snippets", "ansi_term", @@ -2972,7 +2972,7 @@ dependencies = [ "clap 4.5.20", "dirs 5.0.1", "fd-lock", - "forc-tracing 0.66.3", + "forc-tracing 0.66.4", "fuel-tx", "hex", "paste", @@ -7585,7 +7585,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sway-ast" -version = "0.66.3" +version = "0.66.4" dependencies = [ "extension-trait", "num-bigint", @@ -7597,7 +7597,7 @@ dependencies = [ [[package]] name = "sway-core" -version = "0.66.3" +version = "0.66.4" dependencies = [ "clap 4.5.20", "derivative", @@ -7642,7 +7642,7 @@ dependencies = [ [[package]] name = "sway-error" -version = "0.66.3" +version = "0.66.4" dependencies = [ "either", "in_definite", @@ -7656,7 +7656,7 @@ dependencies = [ [[package]] name = "sway-features" -version = "0.66.3" +version = "0.66.4" dependencies = [ "clap 4.5.20", "paste", @@ -7664,7 +7664,7 @@ dependencies = [ [[package]] name = "sway-ir" -version = "0.66.3" +version = "0.66.4" dependencies = [ "anyhow", "downcast-rs", @@ -7684,7 +7684,7 @@ dependencies = [ [[package]] name = "sway-ir-macros" -version = "0.66.3" +version = "0.66.4" dependencies = [ "itertools 0.13.0", "proc-macro2", @@ -7694,7 +7694,7 @@ dependencies = [ [[package]] name = "sway-lsp" -version = "0.66.3" +version = "0.66.4" dependencies = [ "anyhow", "assert-json-diff", @@ -7705,7 +7705,7 @@ dependencies = [ "dirs 4.0.0", "fd-lock", "forc-pkg", - "forc-tracing 0.66.3", + "forc-tracing 0.66.4", "forc-util", "futures", "indexmap 2.6.0", @@ -7745,7 +7745,7 @@ dependencies = [ [[package]] name = "sway-lsp-test-utils" -version = "0.66.3" +version = "0.66.4" dependencies = [ "assert-json-diff", "futures", @@ -7760,7 +7760,7 @@ dependencies = [ [[package]] name = "sway-parse" -version = "0.66.3" +version = "0.66.4" dependencies = [ "assert_matches", "extension-trait", @@ -7778,7 +7778,7 @@ dependencies = [ [[package]] name = "sway-types" -version = "0.66.3" +version = "0.66.4" dependencies = [ "bytecount", "fuel-asm", @@ -7797,7 +7797,7 @@ dependencies = [ [[package]] name = "sway-utils" -version = "0.66.3" +version = "0.66.4" dependencies = [ "serde", "walkdir", @@ -7805,11 +7805,11 @@ dependencies = [ [[package]] name = "swayfmt" -version = "0.66.3" +version = "0.66.4" dependencies = [ "anyhow", "difference", - "forc-tracing 0.66.3", + "forc-tracing 0.66.4", "indoc", "paste", "prettydiff 0.6.4", @@ -8118,7 +8118,7 @@ dependencies = [ "forc-client", "forc-pkg", "forc-test", - "forc-tracing 0.66.3", + "forc-tracing 0.66.4", "fuel-vm", "futures", "gag", diff --git a/Cargo.toml b/Cargo.toml index d984e3dfeb9..ee350835e17 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ exclude = ["examples/*", "swayfmt/test_macros", "forc-test/test_data"] [workspace.package] edition = "2021" -version = "0.66.3" +version = "0.66.4" authors = ["Fuel Labs "] homepage = "https://fuel.network/" license = "Apache-2.0" @@ -42,35 +42,35 @@ repository = "https://github.com/FuelLabs/sway" # Internal dependencies in order to propagate `workspace.version` # -forc = { path = "forc/", version = "0.66.3" } -forc-pkg = { path = "forc-pkg/", version = "0.66.3" } -forc-test = { path = "forc-test/", version = "0.66.3" } -forc-tracing = { path = "forc-tracing/", version = "0.66.3" } -forc-util = { path = "forc-util/", version = "0.66.3" } +forc = { path = "forc/", version = "0.66.4" } +forc-pkg = { path = "forc-pkg/", version = "0.66.4" } +forc-test = { path = "forc-test/", version = "0.66.4" } +forc-tracing = { path = "forc-tracing/", version = "0.66.4" } +forc-util = { path = "forc-util/", version = "0.66.4" } # Forc plugins -forc-plugins = { path = "forc-plugins/", version = "0.66.3" } -forc-client = { path = "forc-plugins/forc-client/", version = "0.66.3" } -forc-crypto = { path = "forc-plugins/forc-crypto/", version = "0.66.3" } -forc-debug = { path = "forc-plugins/forc-debug/", version = "0.66.3" } -forc-doc = { path = "forc-plugins/forc-doc/", version = "0.66.3" } -forc-fmt = { path = "forc-plugins/forc-fmt/", version = "0.66.3" } -forc-lsp = { path = "forc-plugins/forc-lsp/", version = "0.66.3" } -forc-tx = { path = "forc-plugins/forc-tx/", version = "0.66.3" } +forc-plugins = { path = "forc-plugins/", version = "0.66.4" } +forc-client = { path = "forc-plugins/forc-client/", version = "0.66.4" } +forc-crypto = { path = "forc-plugins/forc-crypto/", version = "0.66.4" } +forc-debug = { path = "forc-plugins/forc-debug/", version = "0.66.4" } +forc-doc = { path = "forc-plugins/forc-doc/", version = "0.66.4" } +forc-fmt = { path = "forc-plugins/forc-fmt/", version = "0.66.4" } +forc-lsp = { path = "forc-plugins/forc-lsp/", version = "0.66.4" } +forc-tx = { path = "forc-plugins/forc-tx/", version = "0.66.4" } -sway-ast = { path = "sway-ast/", version = "0.66.3" } -sway-core = { path = "sway-core/", version = "0.66.3" } -sway-error = { path = "sway-error/", version = "0.66.3" } -sway-features = { path = "sway-features/", version = "0.66.3" } -sway-lsp = { path = "sway-lsp/", version = "0.66.3" } -sway-parse = { path = "sway-parse/", version = "0.66.3" } -sway-types = { path = "sway-types/", version = "0.66.3" } -sway-utils = { path = "sway-utils/", version = "0.66.3" } -swayfmt = { path = "swayfmt/", version = "0.66.3" } +sway-ast = { path = "sway-ast/", version = "0.66.4" } +sway-core = { path = "sway-core/", version = "0.66.4" } +sway-error = { path = "sway-error/", version = "0.66.4" } +sway-features = { path = "sway-features/", version = "0.66.4" } +sway-lsp = { path = "sway-lsp/", version = "0.66.4" } +sway-parse = { path = "sway-parse/", version = "0.66.4" } +sway-types = { path = "sway-types/", version = "0.66.4" } +sway-utils = { path = "sway-utils/", version = "0.66.4" } +swayfmt = { path = "swayfmt/", version = "0.66.4" } # Sway IR -sway-ir = { path = "sway-ir/", version = "0.66.3" } -sway-ir-macros = { path = "sway-ir/sway-ir-macros", version = "0.66.3" } +sway-ir = { path = "sway-ir/", version = "0.66.4" } +sway-ir-macros = { path = "sway-ir/sway-ir-macros", version = "0.66.4" } # # External Fuel dependencies diff --git a/forc-pkg/src/pkg.rs b/forc-pkg/src/pkg.rs index 50d8b24c703..19291e0d0ce 100644 --- a/forc-pkg/src/pkg.rs +++ b/forc-pkg/src/pkg.rs @@ -46,7 +46,7 @@ use sway_core::{ transform::AttributeKind, write_dwarf, BuildTarget, Engines, FinalizedEntry, LspConfig, }; -use sway_core::{set_bytecode_configurables_offset, PrintAsm, PrintIr}; +use sway_core::{PrintAsm, PrintIr}; use sway_error::{error::CompileError, handler::Handler, warning::CompileWarning}; use sway_features::ExperimentalFeatures; use sway_types::constants::{CORE, PRELUDE, STD}; @@ -1914,7 +1914,7 @@ pub fn compile( let errored = handler.has_errors() || (handler.has_warnings() && profile.error_on_warnings); - let mut compiled = match bc_res { + let compiled = match bc_res { Ok(compiled) if !errored => compiled, _ => return fail(handler), }; @@ -1923,12 +1923,9 @@ pub fn compile( print_warnings(engines.se(), terse_mode, &pkg.name, &warnings, &tree_type); - // Metadata to be placed into the binary. - let mut md = [0u8, 0, 0, 0, 0, 0, 0, 0]; // TODO: This should probably be in `fuel_abi_json::generate_json_abi_program`? // If ABI requires knowing config offsets, they should be inputs to ABI gen. if let ProgramABI::Fuel(ref mut program_abi) = program_abi { - let mut configurables_offset = compiled.bytecode.len() as u64; if let Some(ref mut configurables) = program_abi.configurables { // Filter out all dead configurables (i.e. ones without offsets in the bytecode) configurables.retain(|c| { @@ -1937,22 +1934,12 @@ pub fn compile( .contains_key(&c.name) }); // Set the actual offsets in the JSON object - for (config, offset) in &compiled.named_data_section_entries_offsets { - if *offset < configurables_offset { - configurables_offset = *offset; - } - if let Some(idx) = configurables.iter().position(|c| &c.name == config) { - configurables[idx].offset = *offset; + for (config, offset) in compiled.named_data_section_entries_offsets { + if let Some(idx) = configurables.iter().position(|c| c.name == config) { + configurables[idx].offset = offset; } } } - - md = configurables_offset.to_be_bytes(); - } - - // We know to set the metadata only for fuelvm right now. - if let BuildTarget::Fuel = pkg.target { - set_bytecode_configurables_offset(&mut compiled, &md); } metrics.bytecode_size = compiled.bytecode.len(); diff --git a/forc-plugins/forc-client/test/data/deployed_script/deployed_script-loader-abi.json b/forc-plugins/forc-client/test/data/deployed_script/deployed_script-loader-abi.json index c51c80ae2e9..81b65c43cd7 100644 --- a/forc-plugins/forc-client/test/data/deployed_script/deployed_script-loader-abi.json +++ b/forc-plugins/forc-client/test/data/deployed_script/deployed_script-loader-abi.json @@ -251,62 +251,62 @@ { "name": "BOOL", "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", - "offset": 240 + "offset": 136 }, { "name": "U8", "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", - "offset": 352 + "offset": 248 }, { "name": "U16", "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", - "offset": 296 + "offset": 192 }, { "name": "U32", "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", - "offset": 336 + "offset": 232 }, { "name": "U64", "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", - "offset": 344 + "offset": 240 }, { "name": "U256", "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", - "offset": 304 + "offset": 200 }, { "name": "B256", "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", - "offset": 208 + "offset": 104 }, { "name": "STR_4", "concreteTypeId": "94f0fa95c830be5e4f711963e83259fe7e8bc723278ab6ec34449e791a99b53a", - "offset": 280 + "offset": 176 }, { "name": "TUPLE", "concreteTypeId": "e0128f7be9902d1fe16326cafe703b52038064a7997b03ebfc1c9dd607e1536c", - "offset": 288 + "offset": 184 }, { "name": "ARRAY", "concreteTypeId": "d9fac01ab38fe10950758ae9604da330d6406a71fda3ef1ea818121261132d56", - "offset": 192 + "offset": 88 }, { "name": "STRUCT", "concreteTypeId": "563310524b4f4447a10d0e50556310253dfb3b5eb4b29c3773222b737c8b7075", - "offset": 264 + "offset": 160 }, { "name": "ENUM", "concreteTypeId": "37cd1cba311039a851ac8bfa614cc41359b4ad95c8656fcef2e8f504fe7a1272", - "offset": 248 + "offset": 144 } ] } \ No newline at end of file diff --git a/forc-plugins/forc-client/tests/deploy.rs b/forc-plugins/forc-client/tests/deploy.rs index eddee21d4d9..afabb238e82 100644 --- a/forc-plugins/forc-client/tests/deploy.rs +++ b/forc-plugins/forc-client/tests/deploy.rs @@ -373,7 +373,7 @@ async fn test_simple_deploy() { node.kill().unwrap(); let expected = vec![DeployedPackage::Contract(DeployedContract { id: ContractId::from_str( - "5c51b8904c539700852c646c6700fddab4b80477f66e56fb2515736facd84e69", + "5a4d19b92e784817f3e4f7d7c9961c5cba3069e53dcee2a93e8cd723e555c5f3", ) .unwrap(), proxy: None, @@ -416,7 +416,7 @@ async fn test_deploy_submit_only() { node.kill().unwrap(); let expected = vec![DeployedPackage::Contract(DeployedContract { id: ContractId::from_str( - "5c51b8904c539700852c646c6700fddab4b80477f66e56fb2515736facd84e69", + "5a4d19b92e784817f3e4f7d7c9961c5cba3069e53dcee2a93e8cd723e555c5f3", ) .unwrap(), proxy: None, @@ -462,12 +462,12 @@ async fn test_deploy_fresh_proxy() { node.kill().unwrap(); let impl_contract = DeployedPackage::Contract(DeployedContract { id: ContractId::from_str( - "5c51b8904c539700852c646c6700fddab4b80477f66e56fb2515736facd84e69", + "5a4d19b92e784817f3e4f7d7c9961c5cba3069e53dcee2a93e8cd723e555c5f3", ) .unwrap(), proxy: Some( ContractId::from_str( - "7a78517c2c3322028db65e54893dc97958fa3d7c846a66f5675859e64f927540", + "f0641246d72044059de56248becf345bd8553c7892df8c12d7df23f461a7f95b", ) .unwrap(), ), diff --git a/forc-test/src/execute.rs b/forc-test/src/execute.rs index 76e89324903..3436261af94 100644 --- a/forc-test/src/execute.rs +++ b/forc-test/src/execute.rs @@ -9,7 +9,7 @@ use fuel_vm::{ self as vm, checked_transaction::builder::TransactionBuilderExt, interpreter::{Interpreter, NotSupportedEcal}, - prelude::SecretKey, + prelude::{Instruction, SecretKey}, storage::MemoryStorage, }; use rand::{Rng, SeedableRng}; @@ -246,21 +246,18 @@ impl TestExecutor { /// The following is how the beginning of the bytecode is laid out: /// /// ```ignore -/// [ 0] ji i(4 + 2) ; Jumps to the data section setup. -/// [ 1] noop -/// [ 2] DATA_SECTION_OFFSET[0..32] -/// [ 3] DATA_SECTION_OFFSET[32..64] -/// [ 4] CONFIGURABLES_OFFSET[0..32] -/// [ 5] CONFIGURABLES_OFFSET[32..64] -/// [ 6] lw $ds $is 1 ; The data section setup, i.e. where the first ji lands. -/// [ 7] add $$ds $$ds $is -/// [ 8] ; This is where we want to jump from to our test code! +/// [0] ji i4 ; Jumps to the data section setup. +/// [1] noop +/// [2] DATA_SECTION_OFFSET[0..32] +/// [3] DATA_SECTION_OFFSET[32..64] +/// [4] lw $ds $is 1 ; The data section setup, i.e. where the first ji lands. +/// [5] add $$ds $$ds $is +/// [6] ; This is where we want to jump from to our test code! /// ``` fn patch_test_bytecode(bytecode: &[u8], test_offset: u32) -> std::borrow::Cow<[u8]> { - // Each instruction is 4 bytes, - // so we divide the total byte-size by 4 to get the instruction offset. - const PROGRAM_START_INST_OFFSET: u32 = (sway_core::PRELUDE_SIZE_IN_BYTES / 4) as u32; - const PROGRAM_START_BYTE_OFFSET: usize = sway_core::PRELUDE_SIZE_IN_BYTES; + // TODO: Standardize this or add metadata to bytecode. + const PROGRAM_START_INST_OFFSET: u32 = 6; + const PROGRAM_START_BYTE_OFFSET: usize = PROGRAM_START_INST_OFFSET as usize * Instruction::SIZE; // If our desired entry point is the program start, no need to jump. if test_offset == PROGRAM_START_INST_OFFSET { diff --git a/forc/src/cli/commands/parse_bytecode.rs b/forc/src/cli/commands/parse_bytecode.rs index 4d5ecf0bdb6..f4a30c82d6d 100644 --- a/forc/src/cli/commands/parse_bytecode.rs +++ b/forc/src/cli/commands/parse_bytecode.rs @@ -59,14 +59,6 @@ pub(crate) fn exec(command: Command) -> ForcResult<()> { parsed_raw ) } - Err(fuel_asm::InvalidOpcode) if word_ix == 4 || word_ix == 5 => { - let parsed_raw = u32::from_be_bytes([raw[0], raw[1], raw[2], raw[3]]); - format!( - "configurables offset {} ({})", - if word_ix == 4 { "lo" } else { "hi" }, - parsed_raw - ) - } Ok(_) | Err(fuel_asm::InvalidOpcode) => "".into(), }; table.add_row(Row::new(vec![ diff --git a/forc/tests/cli_integration.rs b/forc/tests/cli_integration.rs index 422e9f18f9c..1f1248a2205 100644 --- a/forc/tests/cli_integration.rs +++ b/forc/tests/cli_integration.rs @@ -49,10 +49,10 @@ fn test_forc_test_raw_logs() -> Result<(), rexpect::error::Error> { // Assert that the output is correct process.exp_string(" test test_log_4")?; process.exp_string("Raw logs:")?; - process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12672,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; + process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12664,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; process.exp_string(" test test_log_2")?; process.exp_string("Raw logs:")?; - process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12672,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; + process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12664,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; process.process.exit()?; Ok(()) @@ -74,11 +74,11 @@ fn test_forc_test_both_logs() -> Result<(), rexpect::error::Error> { process.exp_string(" test test_log_4")?; process.exp_string("Decoded log value: 4, log rb: 1515152261580153489")?; process.exp_string("Raw logs:")?; - process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12672,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; + process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12664,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; process.exp_string(" test test_log_2")?; process.exp_string("Decoded log value: 2, log rb: 1515152261580153489")?; process.exp_string("Raw logs:")?; - process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12672,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; + process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12664,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; process.process.exit()?; Ok(()) } diff --git a/sway-core/src/asm_generation/finalized_asm.rs b/sway-core/src/asm_generation/finalized_asm.rs index c132d687855..ce3c81e3a56 100644 --- a/sway-core/src/asm_generation/finalized_asm.rs +++ b/sway-core/src/asm_generation/finalized_asm.rs @@ -3,8 +3,8 @@ use super::{ fuel::{checks, data_section::DataSection}, ProgramABI, ProgramKind, }; -use crate::asm_generation::fuel::data_section::{Datum, Entry, EntryName}; -use crate::asm_lang::allocated_ops::{AllocatedOp, AllocatedOpcode, FuelAsmData}; +use crate::asm_generation::fuel::data_section::{DataId, Datum, Entry}; +use crate::asm_lang::allocated_ops::{AllocatedOp, AllocatedOpcode}; use crate::decl_engine::DeclRefFunction; use crate::source_map::SourceMap; use crate::BuildConfig; @@ -16,6 +16,7 @@ use sway_error::handler::{ErrorEmitted, Handler}; use sway_types::span::Span; use sway_types::SourceEngine; +use either::Either; use std::{collections::BTreeMap, fmt}; /// Represents an ASM set which has had register allocation, jump elimination, and optimization @@ -111,7 +112,6 @@ fn to_bytecode_mut( { 8 } - AllocatedOpcode::ConfigurablesOffsetPlaceholder => 8, AllocatedOpcode::DataSectionOffsetPlaceholder => 8, AllocatedOpcode::BLOB(count) => count.value as u64 * 4, AllocatedOpcode::CFEI(i) | AllocatedOpcode::CFSI(i) if i.value == 0 => 0, @@ -141,29 +141,6 @@ fn to_bytecode_mut( &ops_padded }; - let mut offset_from_instr_start = 0; - for op in ops.iter() { - match &op.opcode { - AllocatedOpcode::LoadDataId(_reg, data_label) - if !data_section - .has_copy_type(data_label) - .expect("data label references non existent data -- internal error") => - { - // For non-copy type loads, pre-insert pointers into the data_section so that - // from this point on, the data_section remains immutable. This is necessary - // so that when we take addresses of configurables, that address doesn't change - // later on if a non-configurable is added to the data-section. - let offset_bytes = data_section.data_id_to_offset(data_label) as u64; - // The -4 is because $pc is added in the *next* instruction. - let pointer_offset_from_current_instr = - offset_to_data_section_in_bytes - offset_from_instr_start + offset_bytes - 4; - data_section.append_pointer(pointer_offset_from_current_instr); - } - _ => (), - } - offset_from_instr_start += op_size_in_bytes(data_section, op); - } - let mut bytecode = Vec::with_capacity(offset_to_data_section_in_bytes as usize); if build_config.print_bytecode { @@ -189,7 +166,7 @@ fn to_bytecode_mut( offset_from_instr_start += op_size_in_bytes(data_section, op); match fuel_op { - FuelAsmData::DatasectionOffset(data) => { + Either::Right(data) => { if build_config.print_bytecode { print!("{}{:#010x} ", " ".repeat(indentation), bytecode.len()); println!( @@ -205,23 +182,7 @@ fn to_bytecode_mut( bytecode.extend(data.iter().cloned()); half_word_ix += 2; } - FuelAsmData::ConfigurablesOffset(data) => { - if build_config.print_bytecode { - print!("{}{:#010x} ", " ".repeat(indentation), bytecode.len()); - println!( - " ;; {:?}", - data - ); - } - - // Static assert to ensure that we're only dealing with ConfigurablesOffsetPlaceholder, - // a 1-word (8 bytes) data within the code. No other uses are known. - let _: [u8; 8] = data; - - bytecode.extend(data.iter().cloned()); - half_word_ix += 2; - } - FuelAsmData::Instructions(instructions) => { + Either::Left(instructions) => { for instruction in instructions { // Print original source span only once if build_config.print_bytecode_spans { @@ -334,9 +295,9 @@ fn to_bytecode_mut( }; } - for (i, entry) in data_section.iter_all_entries().enumerate() { - let entry_offset = data_section.absolute_idx_to_offset(i); - print_entry(indentation, offset + entry_offset, &entry); + for (i, entry) in data_section.value_pairs.iter().enumerate() { + let entry_offset = data_section.data_id_to_offset(&DataId(i as u32)); + print_entry(indentation, offset + entry_offset, entry); } println!(";; --- END OF TARGET BYTECODE ---\n"); @@ -345,19 +306,16 @@ fn to_bytecode_mut( assert_eq!(half_word_ix * 4, offset_to_data_section_in_bytes as usize); assert_eq!(bytecode.len(), offset_to_data_section_in_bytes as usize); - let num_nonconfigurables = data_section.non_configurables.len(); let named_data_section_entries_offsets = data_section - .configurables + .value_pairs .iter() .enumerate() + .filter(|entry| entry.1.name.is_some()) .map(|(id, entry)| { - let EntryName::Configurable(name) = &entry.name else { - panic!("Non-configurable in configurables part of datasection"); - }; ( - name.clone(), + entry.name.as_ref().unwrap().clone(), offset_to_data_section_in_bytes - + data_section.absolute_idx_to_offset(id + num_nonconfigurables) as u64, + + data_section.raw_data_id_to_offset(id as u32) as u64, ) }) .collect::>(); diff --git a/sway-core/src/asm_generation/fuel/allocated_abstract_instruction_set.rs b/sway-core/src/asm_generation/fuel/allocated_abstract_instruction_set.rs index a0e53c98cce..0865687f5c8 100644 --- a/sway-core/src/asm_generation/fuel/allocated_abstract_instruction_set.rs +++ b/sway-core/src/asm_generation/fuel/allocated_abstract_instruction_set.rs @@ -1,10 +1,7 @@ -use crate::{ - asm_generation::fuel::data_section::EntryName, - asm_lang::{ - allocated_ops::{AllocatedOpcode, AllocatedRegister}, - AllocatedAbstractOp, ConstantRegister, ControlFlowOp, Label, RealizedOp, - VirtualImmediate12, VirtualImmediate18, VirtualImmediate24, - }, +use crate::asm_lang::{ + allocated_ops::{AllocatedOpcode, AllocatedRegister}, + AllocatedAbstractOp, ConstantRegister, ControlFlowOp, Label, RealizedOp, VirtualImmediate12, + VirtualImmediate18, VirtualImmediate24, }; use super::{ @@ -351,13 +348,6 @@ impl AllocatedAbstractInstructionSet { comment: String::new(), }); } - ControlFlowOp::ConfigurablesOffsetPlaceholder => { - realized_ops.push(RealizedOp { - opcode: AllocatedOpcode::ConfigurablesOffsetPlaceholder, - owning_span: None, - comment: String::new(), - }); - } ControlFlowOp::LoadLabel(r1, ref lab) => { // LoadLabel ops are inserted by `rewrite_far_jumps`. // So the next instruction must be a relative jump. @@ -373,11 +363,8 @@ impl AllocatedAbstractInstructionSet { // We compute the relative offset w.r.t the actual jump. // Sub 1 because the relative jumps add a 1. let offset = rel_offset(curr_offset + 1, lab) - 1; - let data_id = data_section.insert_data_value(Entry::new_word( - offset, - EntryName::NonConfigurable, - None, - )); + let data_id = + data_section.insert_data_value(Entry::new_word(offset, None, None)); realized_ops.push(RealizedOp { opcode: AllocatedOpcode::LoadDataId(r1, data_id), owning_span, @@ -486,8 +473,6 @@ impl AllocatedAbstractInstructionSet { 2 } - Either::Right(ConfigurablesOffsetPlaceholder) => 2, - Either::Right(PushAll(_)) | Either::Right(PopAll(_)) => unreachable!( "fix me, pushall and popall don't really belong in control flow ops \ since they're not about control flow" diff --git a/sway-core/src/asm_generation/fuel/data_section.rs b/sway-core/src/asm_generation/fuel/data_section.rs index e442dcf5ac1..3db12443f4f 100644 --- a/sway-core/src/asm_generation/fuel/data_section.rs +++ b/sway-core/src/asm_generation/fuel/data_section.rs @@ -1,30 +1,16 @@ -use rustc_hash::FxHashMap; use sway_ir::{size_bytes_round_up_to_word_alignment, Constant, ConstantValue, Context, Padding}; use std::{fmt, iter::repeat}; -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum EntryName { - NonConfigurable, - Configurable(String), -} - -impl fmt::Display for EntryName { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - EntryName::NonConfigurable => write!(f, "NonConfigurable"), - EntryName::Configurable(name) => write!(f, "", name), - } - } -} - // An entry in the data section. It's important for the size to be correct, especially for unions // where the size could be larger than the represented value. #[derive(Clone, Debug)] pub struct Entry { pub value: Datum, pub padding: Padding, - pub name: EntryName, + // It is assumed, for now, that only configuration-time constants have a name. Otherwise, this + // is `None`. + pub name: Option, } #[derive(Clone, Debug)] @@ -37,7 +23,7 @@ pub enum Datum { } impl Entry { - pub(crate) fn new_byte(value: u8, name: EntryName, padding: Option) -> Entry { + pub(crate) fn new_byte(value: u8, name: Option, padding: Option) -> Entry { Entry { value: Datum::Byte(value), padding: padding.unwrap_or(Padding::default_for_u8(value)), @@ -45,7 +31,7 @@ impl Entry { } } - pub(crate) fn new_word(value: u64, name: EntryName, padding: Option) -> Entry { + pub(crate) fn new_word(value: u64, name: Option, padding: Option) -> Entry { Entry { value: Datum::Word(value), padding: padding.unwrap_or(Padding::default_for_u64(value)), @@ -55,7 +41,7 @@ impl Entry { pub(crate) fn new_byte_array( bytes: Vec, - name: EntryName, + name: Option, padding: Option, ) -> Entry { Entry { @@ -65,7 +51,11 @@ impl Entry { } } - pub(crate) fn new_slice(bytes: Vec, name: EntryName, padding: Option) -> Entry { + pub(crate) fn new_slice( + bytes: Vec, + name: Option, + padding: Option, + ) -> Entry { Entry { padding: padding.unwrap_or(Padding::default_for_byte_array(&bytes)), value: Datum::Slice(bytes), @@ -75,7 +65,7 @@ impl Entry { pub(crate) fn new_collection( elements: Vec, - name: EntryName, + name: Option, padding: Option, ) -> Entry { Entry { @@ -90,7 +80,7 @@ impl Entry { pub(crate) fn from_constant( context: &Context, constant: &Constant, - name: EntryName, + name: Option, padding: Option, ) -> Entry { // We need a special handling in case of enums. @@ -99,9 +89,8 @@ impl Entry { .enum_tag_and_value_with_paddings(context) .expect("Constant is an enum."); - let tag_entry = Entry::from_constant(context, tag.0, EntryName::NonConfigurable, tag.1); - let value_entry = - Entry::from_constant(context, value.0, EntryName::NonConfigurable, value.1); + let tag_entry = Entry::from_constant(context, tag.0, None, tag.1); + let value_entry = Entry::from_constant(context, value.0, None, value.1); return Entry::new_collection(vec![tag_entry, value_entry], name, padding); } @@ -129,9 +118,7 @@ impl Entry { .array_elements_with_padding(context) .expect("Constant is an array.") .into_iter() - .map(|(elem, padding)| { - Entry::from_constant(context, elem, EntryName::NonConfigurable, padding) - }) + .map(|(elem, padding)| Entry::from_constant(context, elem, None, padding)) .collect(), name, padding, @@ -141,9 +128,7 @@ impl Entry { .struct_fields_with_padding(context) .expect("Constant is a struct.") .into_iter() - .map(|(elem, padding)| { - Entry::from_constant(context, elem, EntryName::NonConfigurable, padding) - }) + .map(|(elem, padding)| Entry::from_constant(context, elem, None, padding)) .collect(), name, padding, @@ -213,92 +198,45 @@ impl Entry { } } -#[derive(Clone, Debug)] -pub enum DataIdEntryKind { - NonConfigurable, - Configurable, -} - -impl fmt::Display for DataIdEntryKind { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - DataIdEntryKind::NonConfigurable => write!(f, "NonConfigurable"), - DataIdEntryKind::Configurable => write!(f, "Configurable"), - } - } -} - /// An address which refers to a value in the data section of the asm. #[derive(Clone, Debug)] -pub(crate) struct DataId { - pub(crate) idx: u32, - pub(crate) kind: DataIdEntryKind, -} +pub(crate) struct DataId(pub(crate) u32); impl fmt::Display for DataId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "data_{}_{}", self.kind, self.idx) + write!(f, "data_{}", self.0) } } -/// The data to be put in the data section of the asm #[derive(Default, Clone, Debug)] pub struct DataSection { - pub non_configurables: Vec, - pub configurables: Vec, - pub(crate) pointer_id: FxHashMap, + /// the data to be put in the data section of the asm + pub value_pairs: Vec, } impl DataSection { - /// Get the number of entries - pub(crate) fn num_entries(&self) -> usize { - self.non_configurables.len() + self.configurables.len() - } - - /// Iterate over all entries, non-configurables followed by configurables - pub(crate) fn iter_all_entries(&self) -> impl Iterator + '_ { - self.non_configurables - .iter() - .chain(self.configurables.iter()) - .cloned() - } - - /// Get the absolute index of an id - fn absolute_idx(&self, id: &DataId) -> usize { - match id.kind { - DataIdEntryKind::NonConfigurable => id.idx as usize, - DataIdEntryKind::Configurable => id.idx as usize + self.non_configurables.len(), - } - } - - /// Get entry at id - fn get(&self, id: &DataId) -> Option<&Entry> { - match id.kind { - DataIdEntryKind::NonConfigurable => self.non_configurables.get(id.idx as usize), - DataIdEntryKind::Configurable => self.configurables.get(id.idx as usize), - } - } - /// Given a [DataId], calculate the offset _from the beginning of the data section_ to the data /// in bytes. pub(crate) fn data_id_to_offset(&self, id: &DataId) -> usize { - let idx = self.absolute_idx(id); - self.absolute_idx_to_offset(idx) + self.raw_data_id_to_offset(id.0) } - /// Given an absolute index, calculate the offset _from the beginning of the data section_ to the data + /// Given a [DataId], calculate the offset _from the beginning of the data section_ to the data /// in bytes. - pub(crate) fn absolute_idx_to_offset(&self, idx: usize) -> usize { - self.iter_all_entries().take(idx).fold(0, |offset, entry| { - //entries must be word aligned - size_bytes_round_up_to_word_alignment!(offset + entry.to_bytes().len()) - }) + pub(crate) fn raw_data_id_to_offset(&self, id: u32) -> usize { + self.value_pairs + .iter() + .take(id as usize) + .fold(0, |offset, entry| { + //entries must be word aligned + size_bytes_round_up_to_word_alignment!(offset + entry.to_bytes().len()) + }) } pub(crate) fn serialize_to_bytes(&self) -> Vec { // not the exact right capacity but serves as a lower bound - let mut buf = Vec::with_capacity(self.num_entries()); - for entry in self.iter_all_entries() { + let mut buf = Vec::with_capacity(self.value_pairs.len()); + for entry in &self.value_pairs { buf.append(&mut entry.to_bytes()); //entries must be word aligned @@ -310,12 +248,16 @@ impl DataSection { /// Returns whether a specific [DataId] value has a copy type (fits in a register). pub(crate) fn has_copy_type(&self, id: &DataId) -> Option { - self.get(id).map(|entry| entry.has_copy_type()) + self.value_pairs + .get(id.0 as usize) + .map(|entry| entry.has_copy_type()) } /// Returns whether a specific [DataId] value is a byte entry. pub(crate) fn is_byte(&self, id: &DataId) -> Option { - self.get(id).map(|entry| entry.is_byte()) + self.value_pairs + .get(id.0 as usize) + .map(|entry| entry.is_byte()) } /// When generating code, sometimes a hard-coded data pointer is needed to reference @@ -326,57 +268,31 @@ impl DataSection { /// relative to the current (load) instruction. pub(crate) fn append_pointer(&mut self, pointer_value: u64) -> DataId { // The 'pointer' is just a literal 64 bit address. - let data_id = self.insert_data_value(Entry::new_word( - pointer_value, - EntryName::NonConfigurable, - None, - )); - self.pointer_id.insert(pointer_value, data_id.clone()); - data_id - } - - /// Get the [DataId] for a pointer, if it exists. - /// The pointer must've been inserted with append_pointer. - pub(crate) fn data_id_of_pointer(&self, pointer_value: u64) -> Option { - self.pointer_id.get(&pointer_value).cloned() + self.insert_data_value(Entry::new_word(pointer_value, None, None)) } /// Given any data in the form of a [Literal] (using this type mainly because it includes type - /// information and debug spans), insert it into the data section and return its handle as + /// information and debug spans), insert it into the data section and return its offset as a /// [DataId]. pub(crate) fn insert_data_value(&mut self, new_entry: Entry) -> DataId { // if there is an identical data value, use the same id - - let (value_pairs, kind) = match new_entry.name { - EntryName::NonConfigurable => ( - &mut self.non_configurables, - DataIdEntryKind::NonConfigurable, - ), - EntryName::Configurable(_) => (&mut self.configurables, DataIdEntryKind::Configurable), - }; - match value_pairs.iter().position(|entry| entry.equiv(&new_entry)) { - Some(num) => DataId { - idx: num as u32, - kind, - }, + match self + .value_pairs + .iter() + .position(|entry| entry.equiv(&new_entry)) + { + Some(num) => DataId(num as u32), None => { - value_pairs.push(new_entry); + self.value_pairs.push(new_entry); // the index of the data section where the value is stored - DataId { - idx: (value_pairs.len() - 1) as u32, - kind, - } + DataId((self.value_pairs.len() - 1) as u32) } } } // If the stored data is Datum::Word, return the inner value. pub(crate) fn get_data_word(&self, data_id: &DataId) -> Option { - let value_pairs = match data_id.kind { - DataIdEntryKind::NonConfigurable => &self.non_configurables, - DataIdEntryKind::Configurable => &self.configurables, - }; - value_pairs.get(data_id.idx as usize).and_then(|entry| { + self.value_pairs.get(data_id.0 as usize).and_then(|entry| { if let Datum::Word(w) = entry.value { Some(w) } else { @@ -406,12 +322,11 @@ impl fmt::Display for DataSection { use std::fmt::Write; let mut data_buf = String::new(); - for (ix, entry) in self.iter_all_entries().enumerate() { + for (ix, entry) in self.value_pairs.iter().enumerate() { writeln!( data_buf, - "data_{}_{} {}", - entry.name, - ix, + "{} {}", + DataId(ix as u32), display_entry(&entry.value) )?; } diff --git a/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs b/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs index 5c98c09411e..0e56e87d33f 100644 --- a/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs +++ b/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs @@ -1,5 +1,4 @@ use super::{ - data_section::EntryName, globals_section::GlobalsSection, programs::{AbstractEntry, AbstractProgram}, }; @@ -99,12 +98,7 @@ impl<'ir, 'eng> AsmBuilder for FuelAsmBuilder<'ir, 'eng> { fn compile_configurable(&mut self, config: &ConfigContent) { match config { ConfigContent::V0 { name, constant, .. } => { - let entry = Entry::from_constant( - self.context, - constant, - EntryName::Configurable(name.clone()), - None, - ); + let entry = Entry::from_constant(self.context, constant, Some(name.clone()), None); let dataid = self.data_section.insert_data_value(entry); self.configurable_v0_data_id.insert(name.clone(), dataid); } @@ -123,7 +117,7 @@ impl<'ir, 'eng> AsmBuilder for FuelAsmBuilder<'ir, 'eng> { let (decode_fn_label, _) = self.func_label_map.get(&decode_fn.get()).unwrap(); let dataid = self.data_section.insert_data_value(Entry::new_byte_array( encoded_bytes.clone(), - EntryName::Configurable(name.clone()), + Some(name.clone()), None, )); @@ -2063,11 +2057,6 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> { _otherwise => { // Get the constant into the namespace. - let config_name = if let Some(name) = config_name { - EntryName::Configurable(name) - } else { - EntryName::NonConfigurable - }; let entry = Entry::from_constant(self.context, constant, config_name, None); let data_id = self.data_section.insert_data_value(entry); @@ -2188,11 +2177,9 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> { } } else { let comment = comment.into(); - let data_id = self.data_section.insert_data_value(Entry::new_word( - imm, - EntryName::NonConfigurable, - None, - )); + let data_id = self + .data_section + .insert_data_value(Entry::new_word(imm, None, None)); self.cur_bytecode.push(Op { opcode: Either::Left(VirtualOp::LoadDataId(reg.clone(), data_id)), owning_span: span.clone(), diff --git a/sway-core/src/asm_generation/fuel/functions.rs b/sway-core/src/asm_generation/fuel/functions.rs index f217a4e8396..42577c543d6 100644 --- a/sway-core/src/asm_generation/fuel/functions.rs +++ b/sway-core/src/asm_generation/fuel/functions.rs @@ -26,7 +26,7 @@ use sway_error::{ }; use sway_types::{Ident, Span}; -use super::{compiler_constants::NUM_ARG_REGISTERS, data_section::EntryName}; +use super::compiler_constants::NUM_ARG_REGISTERS; /// A summary of the adopted calling convention: /// @@ -830,13 +830,9 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> { ); } _ => { - let data_id = - self.data_section.insert_data_value(Entry::from_constant( - self.context, - constant, - EntryName::NonConfigurable, - None, - )); + let data_id = self.data_section.insert_data_value( + Entry::from_constant(self.context, constant, None, None), + ); self.ptr_map.insert(*ptr, Storage::Data(data_id)); } } @@ -862,13 +858,9 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> { }); } _ => { - let data_id = - self.data_section.insert_data_value(Entry::from_constant( - self.context, - constant, - EntryName::NonConfigurable, - None, - )); + let data_id = self.data_section.insert_data_value( + Entry::from_constant(self.context, constant, None, None), + ); init_mut_vars.push(InitMutVars { stack_base_words, diff --git a/sway-core/src/asm_generation/fuel/programs/abstract.rs b/sway-core/src/asm_generation/fuel/programs/abstract.rs index 3256da242bb..b5a8a12e302 100644 --- a/sway-core/src/asm_generation/fuel/programs/abstract.rs +++ b/sway-core/src/asm_generation/fuel/programs/abstract.rs @@ -5,7 +5,7 @@ use crate::{ abstract_instruction_set::AbstractInstructionSet, allocated_abstract_instruction_set::AllocatedAbstractInstructionSet, compiler_constants, - data_section::{DataSection, Entry, EntryName}, + data_section::{DataSection, Entry}, globals_section::GlobalsSection, register_sequencer::RegisterSequencer, }, @@ -75,7 +75,7 @@ impl AbstractProgram { pub(crate) fn is_empty(&self) -> bool { self.non_entries.is_empty() && self.entries.is_empty() - && self.data_section.iter_all_entries().next().is_none() + && self.data_section.value_pairs.is_empty() } /// Adds prologue, globals allocation, before entries, contract method switch, and allocates virtual register. @@ -164,28 +164,14 @@ impl AbstractProgram { /// Right now, it looks like this: /// /// WORD OP - /// 1 MOV $scratch $pc - /// - JMPF $zero i10 - /// 2 DATA_START (0-32) (in bytes, offset from $is) - /// - DATA_START (32-64) - /// 3 CONFIGURABLES_OFFSET (0-32) - /// - CONFIGURABLES_OFFSET (32-64) - /// 4 LW $ds $scratch 1 - /// - ADD $ds $ds $scratch - /// 5 .program_start: + /// [1] MOV $scratch $pc + /// [-] JMPF $zero i2 + /// [2] DATA_START (0-32) (in bytes, offset from $is) + /// [-] DATA_START (32-64) + /// [3] LW $ds $scratch 1 + /// [-] ADD $ds $ds $scratch + /// [4] .program_start: fn build_prologue(&mut self) -> AllocatedAbstractInstructionSet { - const _: () = assert!( - crate::PRELUDE_CONFIGURABLES_OFFSET_IN_BYTES == 16, - "Inconsistency in the assumption of prelude organisation" - ); - const _: () = assert!( - crate::PRELUDE_CONFIGURABLES_SIZE_IN_BYTES == 8, - "Inconsistency in the assumption of prelude organisation" - ); - const _: () = assert!( - crate::PRELUDE_SIZE_IN_BYTES == 32, - "Inconsistency in the assumption of prelude organisation" - ); let label = self.reg_seqr.get_label(); AllocatedAbstractInstructionSet { ops: [ @@ -209,18 +195,12 @@ impl AbstractProgram { comment: "data section offset".into(), owning_span: None, }, - // word 3 -- full word u64 placeholder - AllocatedAbstractOp { - opcode: Either::Right(ControlFlowOp::ConfigurablesOffsetPlaceholder), - comment: "configurables offset".into(), - owning_span: None, - }, AllocatedAbstractOp { opcode: Either::Right(ControlFlowOp::Label(label)), - comment: "end of configurables offset".into(), + comment: "end of metadata".into(), owning_span: None, }, - // word 4 -- load the data offset into $ds + // word 3 -- load the data offset into $ds AllocatedAbstractOp { opcode: Either::Left(AllocatedOpcode::LW( AllocatedRegister::Constant(ConstantRegister::DataSectionStart), @@ -230,7 +210,7 @@ impl AbstractProgram { comment: "".into(), owning_span: None, }, - // word 4.5 -- add $ds $ds $is + // word 3.5 -- add $ds $ds $is AllocatedAbstractOp { opcode: Either::Left(AllocatedOpcode::ADD( AllocatedRegister::Constant(ConstantRegister::DataSectionStart), @@ -301,7 +281,7 @@ impl AbstractProgram { // Put the selector in the data section. let data_label = self.data_section.insert_data_value(Entry::new_word( u32::from_be_bytes(selector) as u64, - EntryName::NonConfigurable, + None, None, )); diff --git a/sway-core/src/asm_lang/allocated_ops.rs b/sway-core/src/asm_lang/allocated_ops.rs index 31220a0900d..b78ba37b2db 100644 --- a/sway-core/src/asm_lang/allocated_ops.rs +++ b/sway-core/src/asm_lang/allocated_ops.rs @@ -17,6 +17,7 @@ use crate::{ }, fuel_prelude::fuel_asm::{self, op}, }; +use either::Either; use fuel_vm::fuel_asm::{op::ADDI, Imm12}; use std::fmt::{self, Write}; use sway_types::span::Span; @@ -272,7 +273,6 @@ pub(crate) enum AllocatedOpcode { /* Non-VM Instructions */ BLOB(VirtualImmediate24), - ConfigurablesOffsetPlaceholder, DataSectionOffsetPlaceholder, LoadDataId(AllocatedRegister, DataId), AddrDataId(AllocatedRegister, DataId), @@ -397,7 +397,6 @@ impl AllocatedOpcode { /* Non-VM Instructions */ BLOB(_imm) => vec![], - ConfigurablesOffsetPlaceholder => vec![], DataSectionOffsetPlaceholder => vec![], LoadDataId(r1, _i) => vec![r1], AddrDataId(r1, _i) => vec![r1], @@ -526,10 +525,6 @@ impl fmt::Display for AllocatedOpcode { /* Non-VM Instructions */ BLOB(a) => write!(fmtr, "blob {a}"), - ConfigurablesOffsetPlaceholder => write!( - fmtr, - "CONFIGURABLES_OFFSET[0..32]\nCONFIGURABLES_OFFSET[32..64]" - ), DataSectionOffsetPlaceholder => { write!( fmtr, @@ -567,21 +562,17 @@ impl fmt::Display for AllocatedOp { } } -pub(crate) enum FuelAsmData { - ConfigurablesOffset([u8; 8]), - DatasectionOffset([u8; 8]), - Instructions(Vec), -} +type DoubleWideData = [u8; 8]; impl AllocatedOp { pub(crate) fn to_fuel_asm( &self, offset_to_data_section: u64, offset_from_instr_start: u64, - data_section: &DataSection, - ) -> FuelAsmData { + data_section: &mut DataSection, + ) -> Either, DoubleWideData> { use AllocatedOpcode::*; - FuelAsmData::Instructions(vec![match &self.opcode { + Either::Left(vec![match &self.opcode { /* Arithmetic/Logic (ALU) Instructions */ ADD(a, b, c) => op::ADD::new(a.to_reg_id(), b.to_reg_id(), c.to_reg_id()).into(), ADDI(a, b, c) => op::ADDI::new(a.to_reg_id(), b.to_reg_id(), c.value.into()).into(), @@ -650,9 +641,9 @@ impl AllocatedOp { /* Memory Instructions */ ALOC(a) => op::ALOC::new(a.to_reg_id()).into(), - CFEI(a) if a.value == 0 => return FuelAsmData::Instructions(vec![]), + CFEI(a) if a.value == 0 => return Either::Left(vec![]), CFEI(a) => op::CFEI::new(a.value.into()).into(), - CFSI(a) if a.value == 0 => return FuelAsmData::Instructions(vec![]), + CFSI(a) if a.value == 0 => return Either::Left(vec![]), CFSI(a) => op::CFSI::new(a.value.into()).into(), CFE(a) => op::CFE::new(a.to_reg_id()).into(), CFS(a) => op::CFS::new(a.to_reg_id()).into(), @@ -736,20 +727,17 @@ impl AllocatedOp { /* Non-VM Instructions */ BLOB(a) => { - return FuelAsmData::Instructions( + return Either::Left( std::iter::repeat(op::NOOP::new().into()) .take(a.value as usize) .collect(), ) } - ConfigurablesOffsetPlaceholder => { - return FuelAsmData::ConfigurablesOffset([0, 0, 0, 0, 0, 0, 0, 0]) - } DataSectionOffsetPlaceholder => { - return FuelAsmData::DatasectionOffset(offset_to_data_section.to_be_bytes()) + return Either::Right(offset_to_data_section.to_be_bytes()) } LoadDataId(a, b) => { - return FuelAsmData::Instructions(realize_load( + return Either::Left(realize_load( a, b, data_section, @@ -757,7 +745,7 @@ impl AllocatedOp { offset_from_instr_start, )) } - AddrDataId(a, b) => return FuelAsmData::Instructions(addr_of(a, b, data_section)), + AddrDataId(a, b) => return Either::Left(addr_of(a, b, data_section)), Undefined => unreachable!("Sway cannot generate undefined ASM opcodes"), }]) } @@ -767,7 +755,7 @@ impl AllocatedOp { fn addr_of( dest: &AllocatedRegister, data_id: &DataId, - data_section: &DataSection, + data_section: &mut DataSection, ) -> Vec { let offset_bytes = data_section.data_id_to_offset(data_id) as u64; vec![fuel_asm::Instruction::ADDI(ADDI::new( @@ -784,7 +772,7 @@ fn addr_of( fn realize_load( dest: &AllocatedRegister, data_id: &DataId, - data_section: &DataSection, + data_section: &mut DataSection, offset_to_data_section: u64, offset_from_instr_start: u64, ) -> Vec { @@ -827,9 +815,7 @@ fn realize_load( offset_to_data_section - offset_from_instr_start + offset_bytes - 4; // insert the pointer as bytes as a new data section entry at the end of the data - let data_id_for_pointer = data_section - .data_id_of_pointer(pointer_offset_from_current_instr) - .expect("Pointer offset must be in data_section"); + let data_id_for_pointer = data_section.append_pointer(pointer_offset_from_current_instr); // now load the pointer we just created into the `dest`ination let mut buf = Vec::with_capacity(2); diff --git a/sway-core/src/asm_lang/mod.rs b/sway-core/src/asm_lang/mod.rs index 71e09cc2290..5e1bcaded52 100644 --- a/sway-core/src/asm_lang/mod.rs +++ b/sway-core/src/asm_lang/mod.rs @@ -1248,7 +1248,6 @@ impl fmt::Display for VirtualOp { /* Non-VM Instructions */ BLOB(a) => write!(fmtr, "blob {a}"), DataSectionOffsetPlaceholder => write!(fmtr, "data section offset placeholder"), - ConfigurablesOffsetPlaceholder => write!(fmtr, "configurables offset placeholder"), LoadDataId(a, b) => write!(fmtr, "load {a} {b}"), AddrDataId(a, b) => write!(fmtr, "addr {a} {b}"), Undefined => write!(fmtr, "undefined op"), @@ -1278,8 +1277,6 @@ pub(crate) enum ControlFlowOp { Call(Label), // Save a return label address in a register. SaveRetAddr(Reg, Label), - // Placeholder for the offset into the configurables section. - ConfigurablesOffsetPlaceholder, // placeholder for the DataSection offset DataSectionOffsetPlaceholder, // Placeholder for loading an address from the data section. @@ -1307,8 +1304,6 @@ impl fmt::Display for ControlFlowOp { SaveRetAddr(r1, lab) => format!("mova {r1} {lab}"), DataSectionOffsetPlaceholder => "DATA SECTION OFFSET[0..32]\nDATA SECTION OFFSET[32..64]".into(), - ConfigurablesOffsetPlaceholder => - "CONFIGURABLES_OFFSET[0..32]\nCONFIGURABLES_OFFSET[32..64]".into(), LoadLabel(r1, lab) => format!("lwlab {r1} {lab}"), PushAll(lab) => format!("pusha {lab}"), PopAll(lab) => format!("popa {lab}"), @@ -1326,7 +1321,6 @@ impl ControlFlowOp { | Jump(_) | Call(_) | DataSectionOffsetPlaceholder - | ConfigurablesOffsetPlaceholder | PushAll(_) | PopAll(_) => vec![], @@ -1345,7 +1339,6 @@ impl ControlFlowOp { | Call(_) | SaveRetAddr(..) | DataSectionOffsetPlaceholder - | ConfigurablesOffsetPlaceholder | LoadLabel(..) | PushAll(_) | PopAll(_) => vec![], @@ -1367,7 +1360,6 @@ impl ControlFlowOp { | JumpIfNotZero(..) | Call(_) | DataSectionOffsetPlaceholder - | ConfigurablesOffsetPlaceholder | PushAll(_) | PopAll(_) => vec![], }) @@ -1389,7 +1381,6 @@ impl ControlFlowOp { | Jump(_) | Call(_) | DataSectionOffsetPlaceholder - | ConfigurablesOffsetPlaceholder | PushAll(_) | PopAll(_) => self.clone(), @@ -1419,7 +1410,6 @@ impl ControlFlowOp { | Call(_) | SaveRetAddr(..) | DataSectionOffsetPlaceholder - | ConfigurablesOffsetPlaceholder | LoadLabel(..) | PushAll(_) | PopAll(_) => (), @@ -1476,7 +1466,6 @@ impl ControlFlowOp { Jump(label) => Jump(*label), Call(label) => Call(*label), DataSectionOffsetPlaceholder => DataSectionOffsetPlaceholder, - ConfigurablesOffsetPlaceholder => ConfigurablesOffsetPlaceholder, PushAll(label) => PushAll(*label), PopAll(label) => PopAll(*label), diff --git a/sway-core/src/asm_lang/virtual_ops.rs b/sway-core/src/asm_lang/virtual_ops.rs index 3d041713a4f..ffe3509b7cd 100644 --- a/sway-core/src/asm_lang/virtual_ops.rs +++ b/sway-core/src/asm_lang/virtual_ops.rs @@ -226,7 +226,6 @@ pub(crate) enum VirtualOp { /* Non-VM Instructions */ BLOB(VirtualImmediate24), - ConfigurablesOffsetPlaceholder, DataSectionOffsetPlaceholder, // LoadDataId takes a virtual register and a DataId, which points to a labeled piece // of data in the data section. Note that the ASM op corresponding to a LW is @@ -348,7 +347,6 @@ impl VirtualOp { /* Non-VM Instructions */ BLOB(_imm) => vec![], DataSectionOffsetPlaceholder => vec![], - ConfigurablesOffsetPlaceholder => vec![], LoadDataId(r1, _i) => vec![r1], AddrDataId(r1, _) => vec![r1], @@ -467,7 +465,6 @@ impl VirtualOp { // Virtual OPs | BLOB(_) | DataSectionOffsetPlaceholder - | ConfigurablesOffsetPlaceholder | Undefined => true } } @@ -574,7 +571,6 @@ impl VirtualOp { | GTF(_, _, _) | BLOB(_) | DataSectionOffsetPlaceholder - | ConfigurablesOffsetPlaceholder | LoadDataId(_, _) | AddrDataId(_, _) | Undefined => vec![], @@ -696,7 +692,6 @@ impl VirtualOp { /* Non-VM Instructions */ BLOB(_imm) => vec![], DataSectionOffsetPlaceholder => vec![], - ConfigurablesOffsetPlaceholder => vec![], LoadDataId(_r1, _i) => vec![], AddrDataId(_r1, _i) => vec![], @@ -820,7 +815,6 @@ impl VirtualOp { LoadDataId(r1, _i) => vec![r1], AddrDataId(r1, _i) => vec![r1], DataSectionOffsetPlaceholder => vec![], - ConfigurablesOffsetPlaceholder => vec![], Undefined => vec![], }) .into_iter() @@ -1269,7 +1263,6 @@ impl VirtualOp { /* Non-VM Instructions */ BLOB(i) => Self::BLOB(i.clone()), DataSectionOffsetPlaceholder => Self::DataSectionOffsetPlaceholder, - ConfigurablesOffsetPlaceholder => Self::ConfigurablesOffsetPlaceholder, LoadDataId(r1, i) => Self::LoadDataId(update_reg(reg_to_reg_map, r1), i.clone()), AddrDataId(r1, i) => Self::AddrDataId(update_reg(reg_to_reg_map, r1), i.clone()), Undefined => Self::Undefined, @@ -1750,7 +1743,6 @@ impl VirtualOp { /* Non-VM Instructions */ BLOB(imm) => AllocatedOpcode::BLOB(imm.clone()), DataSectionOffsetPlaceholder => AllocatedOpcode::DataSectionOffsetPlaceholder, - ConfigurablesOffsetPlaceholder => AllocatedOpcode::ConfigurablesOffsetPlaceholder, LoadDataId(reg1, label) => { AllocatedOpcode::LoadDataId(map_reg(&mapping, reg1), label.clone()) } diff --git a/sway-core/src/lib.rs b/sway-core/src/lib.rs index ac6b7d54d34..d66b8e779eb 100644 --- a/sway-core/src/lib.rs +++ b/sway-core/src/lib.rs @@ -992,28 +992,6 @@ pub fn compile_to_bytecode( asm_to_bytecode(handler, asm_res, source_map, engines.se(), build_config) } -/// Size of the prelude's CONFIGURABLES_OFFSET section, in bytes. -pub const PRELUDE_CONFIGURABLES_SIZE_IN_BYTES: usize = 8; -/// Offset (in bytes) of the CONFIGURABLES_OFFSET section in the prelude. -pub const PRELUDE_CONFIGURABLES_OFFSET_IN_BYTES: usize = 16; -/// Total size of the prelude in bytes. Instructions start right after. -pub const PRELUDE_SIZE_IN_BYTES: usize = 32; - -/// Given bytecode, overwrite the existing offset to configurables offset in the prelude with the given one. -pub fn set_bytecode_configurables_offset( - compiled_bytecode: &mut CompiledBytecode, - md: &[u8; PRELUDE_CONFIGURABLES_SIZE_IN_BYTES], -) { - assert!( - compiled_bytecode.bytecode.len() - >= PRELUDE_CONFIGURABLES_OFFSET_IN_BYTES + PRELUDE_CONFIGURABLES_SIZE_IN_BYTES - ); - let code = &mut compiled_bytecode.bytecode; - for (index, byte) in md.iter().enumerate() { - code[index + PRELUDE_CONFIGURABLES_OFFSET_IN_BYTES] = *byte; - } -} - /// Given the assembly (opcodes), compile to [CompiledBytecode], containing the asm in bytecode form. pub fn asm_to_bytecode( handler: &Handler, diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle_new_encoding.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle_new_encoding.json index 4447c387c37..2daeaffdc6a 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle_new_encoding.json +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle_new_encoding.json @@ -62,82 +62,82 @@ { "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", "name": "BOOL", - "offset": 7056 + "offset": 6896 }, { "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", "name": "U8", - "offset": 7248 + "offset": 7088 }, { "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", "name": "ANOTHER_U8", - "offset": 6984 + "offset": 6824 }, { "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", "name": "U16", - "offset": 7192 + "offset": 7032 }, { "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", "name": "U32", - "offset": 7232 + "offset": 7072 }, { "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", "name": "U64", - "offset": 7240 + "offset": 7080 }, { "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", "name": "U256", - "offset": 7200 + "offset": 7040 }, { "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", "name": "B256", - "offset": 7024 + "offset": 6864 }, { "concreteTypeId": "81fc10c4681a3271cf2d66b2ec6fbc8ed007a442652930844fcf11818c295bff", "name": "CONFIGURABLE_STRUCT", - "offset": 7144 + "offset": 6984 }, { "concreteTypeId": "a2922861f03be8a650595dd76455b95383a61b46dd418f02607fa2e00dc39d5c", "name": "CONFIGURABLE_ENUM_A", - "offset": 7064 + "offset": 6904 }, { "concreteTypeId": "a2922861f03be8a650595dd76455b95383a61b46dd418f02607fa2e00dc39d5c", "name": "CONFIGURABLE_ENUM_B", - "offset": 7104 + "offset": 6944 }, { "concreteTypeId": "4926d35d1a5157936b0a29bc126b8aace6d911209a5c130e9b716b0c73643ea6", "name": "ARRAY_BOOL", - "offset": 6992 + "offset": 6832 }, { "concreteTypeId": "776fb5a3824169d6736138565fdc20aad684d9111266a5ff6d5c675280b7e199", "name": "ARRAY_U64", - "offset": 7000 + "offset": 6840 }, { "concreteTypeId": "c998ca9a5f221fe7b5c66ae70c8a9562b86d964408b00d17f883c906bc1fe4be", "name": "TUPLE_BOOL_U64", - "offset": 7176 + "offset": 7016 }, { "concreteTypeId": "94f0fa95c830be5e4f711963e83259fe7e8bc723278ab6ec34449e791a99b53a", "name": "STR_4", - "offset": 7168 + "offset": 7008 }, { "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", "name": "NOT_USED", - "offset": 7160 + "offset": 7000 } ], "encodingVersion": "1", diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/stdout.snap index b4b15b07969..8e825421dd7 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/stdout.snap @@ -1,6 +1,6 @@ --- source: test/tests/tests.rs -assertion_line: 115 +snapshot_kind: text --- > forc build --path test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode --release --ir final exit status: 0 @@ -361,4 +361,4 @@ script { !128 = fn_call_path_span !0 235 236 !129 = (!127 !128) - Finished release [optimized + fuel] target(s) [752 B] in ??? + Finished release [optimized + fuel] target(s) [744 B] in ??? diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/u256/u256_abi/json_abi_oracle_new_encoding.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/u256/u256_abi/json_abi_oracle_new_encoding.json index c58838960ad..49a75d8d5c1 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/u256/u256_abi/json_abi_oracle_new_encoding.json +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/u256/u256_abi/json_abi_oracle_new_encoding.json @@ -9,7 +9,7 @@ { "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", "name": "SOME_U256", - "offset": 872 + "offset": 816 } ], "encodingVersion": "1", 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 deee7c52ae5..ffc9dcbe016 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 = 0x6b01f04c84ce955e8dfc6ed3611fd2518424ab757e5a540878f49fbd1bdec571; // AUTO-CONTRACT-ID ../../test_contracts/array_of_structs_contract --release +const CONTRACT_ID = 0xdf53a7533a12c5ee3df459fc424f51807fc9740f13080a725f5f66408ede1186; // AUTO-CONTRACT-ID ../../test_contracts/array_of_structs_contract --release fn get_address() -> Option { Some(CONTRACT_ID.into()) 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 1c2a953fc35..5459da78f0c 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 = 0x19c0d374734bd8a92b776787e9dffa0f105a90e3c977626f93a1916de54dd714; +const FUEL_COIN_CONTRACT_ID = 0xf2fecff29038dab2ef571397ea5507359265c9154608e7de36ccbea20ed5c8aa; #[cfg(experimental_new_encoding = false)] const BALANCE_CONTRACT_ID = 0xf6cd545152ac83225e8e7df2efb5c6fa6e37bc9b9e977b5ea8103d28668925df; #[cfg(experimental_new_encoding = true)] -const BALANCE_CONTRACT_ID = 0xb770fa56f665d6fbdbdceecce21b7b61878f650981ac7f21c052613015937034; // AUTO-CONTRACT-ID ../../test_contracts/balance_test_contract --release +const BALANCE_CONTRACT_ID = 0xaa4e3d9c953790384f76dcad07e21d6973ae8df79432e48bbed76ccb6437a9a7; // 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 638541084b4..365a489a3dd 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 = 0xb770fa56f665d6fbdbdceecce21b7b61878f650981ac7f21c052613015937034; // AUTO-CONTRACT-ID ../../test_contracts/balance_test_contract --release +const CONTRACT_ID = 0xaa4e3d9c953790384f76dcad07e21d6973ae8df79432e48bbed76ccb6437a9a7; // 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 9a078ca2bbc..b0a18868637 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 = 0xcc679c89d2950879d4f8fb3b99770f93dfde3335fff574cbf0588691fbcefde3; // AUTO-CONTRACT-ID ../../test_contracts/abi_with_tuples_contract --release +const CONTRACT_ID = 0xe21bdb5e019c073978f5bd6eee1339a0e68ab38b913d8a00ff1286e9e5eb894d; // 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 44c854b196b..1ed97f22e9d 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 = 0x38ea1d4d087b96c1e0b4b70e031cf1acc02363f000e8059d02ffc07d61885452; // AUTO-CONTRACT-ID ../../test_contracts/basic_storage --release +const CONTRACT_ID = 0xb48002b23e2861d62237348199ff111e310f5dd10298a01562e3a4d41cb6aae6; // 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 dae00c1579b..eab00cc7b7c 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 = 0x2e8efc627379d037c6ac70249d0bf0726f228ea6bade786e11639b878241f333; // AUTO-CONTRACT-ID ../../test_contracts/contract_with_type_aliases --release +const CONTRACT_ID = 0x8b400005d6178d7ceaccac502a021abad28a899ab8692099c0bfa5e70853d573; // 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 28218e97054..28089f44fa3 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 = 0xc2694e6a397883ae59ea2e807c0ba3714865d0c4bf16571893d632b3bd7ec6f7; // AUTO-CONTRACT-ID ../../test_contracts/increment_contract --release +const CONTRACT_ID = 0xe1dbd25c5d2ccb547ce1f592d04a407dec80cc715255c358dfb32ccf9ca0f926; // 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 4c605d999cd..af5bdc4cd47 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 = 0xd3da5ae426182db1a2a6c900ad374a9641dabfdebe610b39f0e9c5186cedf39b; // AUTO-CONTRACT-ID ../../test_contracts/storage_enum_contract --release +const CONTRACT_ID = 0x434f5f10c3270134e51a1963f610286466e448c1c6109e4f20502939c7a3d429; // 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 ea5fb5c74e5..ae8dc25bd57 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 = 0xcdc67c314d13752e5c3e10aa1de6615e1ec6864e0461317b5f26eef3320a9a8e; // AUTO-CONTRACT-ID ../../test_contracts/auth_testing_contract --release +const CONTRACT_ID = 0x507e5e609fdb2a085da8d681519b6bb6b738f2beb0321600c1e3497db3114a37; // 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 64dec655d14..4a0c2e86a63 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 = 0xecf511a0e2f4022c17413625d69c390d51d0740424d6886cbbe9ca60acd0606b; // AUTO-CONTRACT-ID ../../test_contracts/context_testing_contract --release +const CONTRACT_ID = 0xb80ada1b7018cd6cb45dac7e0dfc1b17fc2931439facc55bd784523410e31449; // 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 1364b7aa4b4..69da3b33161 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 = 0x27e6a749a1773f65f850b36e4e61afdbfe72ba4189cd518c16e06cf0c04a1fa9; // AUTO-CONTRACT-ID ../../test_contracts/nested_struct_args_contract --release +const CONTRACT_ID = 0xc4f40cab476f1e705db3cdb22367eb20ebb180213801918db9b2030db56a0542; // 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 12e4d20fdec..7850cbec2ad 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 = 0xb509b52a765f2a8e97b29e4699d0ec8fa056b2bb649f785c75e36f868c318b98; // AUTO-CONTRACT-ID ../../test_contracts/storage_access_contract --release +const CONTRACT_ID = 0xa8eb4bf19964abcc5fdeac8daa1e5816326f728e9883f0287cf4c404527291a8; // AUTO-CONTRACT-ID ../../test_contracts/storage_access_contract --release fn main() -> bool { let caller = abi(StorageAccess, CONTRACT_ID); diff --git a/test/src/sdk-harness/test_projects/auth/mod.rs b/test/src/sdk-harness/test_projects/auth/mod.rs index 5c167a1d927..2fefd28f8c8 100644 --- a/test/src/sdk-harness/test_projects/auth/mod.rs +++ b/test/src/sdk-harness/test_projects/auth/mod.rs @@ -624,7 +624,7 @@ async fn can_get_predicate_address() { // Setup predicate. let hex_predicate_address: &str = - "0x8b300a68337368654e71c65ae93c3d9eb3b9837d0c11d770cbf8740a6a5a8631"; + "0x5dcc82a88eebb07fb628db93d11ec38f085cbf36453a7135fea41b93cc44e118"; let predicate_address = Address::from_str(hex_predicate_address).expect("failed to create Address from string"); let predicate_bech32_address = Bech32Address::from(predicate_address); @@ -750,7 +750,7 @@ async fn when_incorrect_predicate_address_passed() { async fn can_get_predicate_address_in_message() { // Setup predicate address. let hex_predicate_address: &str = - "0x8b300a68337368654e71c65ae93c3d9eb3b9837d0c11d770cbf8740a6a5a8631"; + "0x5dcc82a88eebb07fb628db93d11ec38f085cbf36453a7135fea41b93cc44e118"; let predicate_address = Address::from_str(hex_predicate_address).expect("failed to create Address from string"); let predicate_bech32_address = Bech32Address::from(predicate_address); diff --git a/test/update-contract-ids.sh b/test/update-contract-ids.sh index 591a2a7052d..f0bcc22ad62 100755 --- a/test/update-contract-ids.sh +++ b/test/update-contract-ids.sh @@ -1,4 +1,4 @@ -#! /bin/bash +#!/usr/bin/env bash print_help() { echo " From 0f82e5ce2bbe1200d683260da090dd7e35c3f5ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaya=20G=C3=B6kalp?= Date: Sun, 3 Nov 2024 22:20:09 -0800 Subject: [PATCH 095/115] chore: add a script to bump all fuel maintained dependencies (#6684) ## Description Adds a bash script which iterates over all fuel owned/maintained crates we depend on and only runs cargo update for them. This is especially useful for incorporating minor bumps which happens much more often. Co-authored-by: Joshua Batty --- update_fuel_dependencies.sh | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100755 update_fuel_dependencies.sh diff --git a/update_fuel_dependencies.sh b/update_fuel_dependencies.sh new file mode 100755 index 00000000000..5f278493541 --- /dev/null +++ b/update_fuel_dependencies.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Run this script to only bump fuel maintained dependencies. +# +# We currently pin dependencies using "X.Y" in the root Cargo.toml file. +# Since `cargo build` does not check for minor version bumps at each invocation +# it is hard to move between new versions, especially for minor bumps which +# happens much often. Use this script to keep every fuel owned dependency up to +# date. + +# Define the list of fuel maintained crates +crates=( + "fuel-abi-types" + "fuel-core-client" + "fuel-core-types" + "fuels" + "fuels-core" + "fuels-accounts" + "fuel-asm" + "fuel-crypto" + "fuel-types" + "fuel-tx" + "fuel-vm" + "forc-wallet" +) + +# Run `cargo update -p ` for each fuel owned crate. +for crate in "${crates[@]}"; do + echo "Updating package: $crate" + cargo update -p "$crate" +done From 8073fab0b63f41b9b5ba5a8887330f6afed28820 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaya=20G=C3=B6kalp?= Date: Sun, 3 Nov 2024 23:39:54 -0800 Subject: [PATCH 096/115] docs: remove dead links to sway-libs/fixed-point (#6689) ## Description closes #6636. closes #6631. As of https://github.com/FuelLabs/sway-libs/pull/278 sway-libs/fixed-point library is deprecated and removed completely from sway-libs repo. We should not link it from our book as well. --- docs/book/src/reference/sway_libs.md | 1 - docs/book/src/sway-program-types/libraries.md | 1 - 2 files changed, 2 deletions(-) diff --git a/docs/book/src/reference/sway_libs.md b/docs/book/src/reference/sway_libs.md index 8e5d237fe07..15be990c56d 100644 --- a/docs/book/src/reference/sway_libs.md +++ b/docs/book/src/reference/sway_libs.md @@ -32,7 +32,6 @@ Cryptography Libraries are any libraries that provided cryptographic functionali Math Libraries are libraries which provide mathematic functions or number types that are outside of the std-lib's scope. -- [Fixed Point Number Library](https://fuellabs.github.io/sway-libs/book/fixed_point/index.html); an interface to implement fixed-point numbers. - [Signed Integers Library](https://fuellabs.github.io/sway-libs/book/signed_integers/index.html); an interface to implement signed integers. ## Data Structures Libraries diff --git a/docs/book/src/sway-program-types/libraries.md b/docs/book/src/sway-program-types/libraries.md index 60d820a7b01..4247c9873ca 100644 --- a/docs/book/src/sway-program-types/libraries.md +++ b/docs/book/src/sway-program-types/libraries.md @@ -192,7 +192,6 @@ Some Sway Libraries to try out: - [Binary Merkle Proof](https://github.com/FuelLabs/sway-libs/tree/master/libs/src/merkle) - [Signed Integers](https://github.com/FuelLabs/sway-libs/tree/master/libs/src/signed_integers) -- [Unsigned Fixed Point Number](https://github.com/FuelLabs/sway-libs/tree/master/libs/src/fixed_point) - [Ownership](https://github.com/FuelLabs/sway-libs/tree/master/libs/src/ownership) ### Example From 431eab101250e713b38db9cb8185b6b8a92d2fdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaya=20G=C3=B6kalp?= Date: Mon, 4 Nov 2024 03:47:46 -0800 Subject: [PATCH 097/115] chore: remove unmaintained `atty` crate (#6691) ## Description closes #6599. atty [is no longer maintained](https://github.com/softprops/atty/commit/5bfdbe9e48c6ca6a4909e8d5b04f5e843a257e93), and equivalent functionality is available in the std-lib as of rust 1.79. This PR switches to that functionality and removes `atty` dependency. --- Cargo.lock | 1 - Cargo.toml | 1 - forc-plugins/forc-crypto/Cargo.toml | 1 - forc-plugins/forc-crypto/src/main.rs | 5 ++--- 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7bb96c29e3a..1ab07481f7a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2765,7 +2765,6 @@ version = "0.66.4" dependencies = [ "anyhow", "async-trait", - "atty", "clap 4.5.20", "criterion", "forc-tracing 0.66.4", diff --git a/Cargo.toml b/Cargo.toml index ee350835e17..340bc9d0581 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -112,7 +112,6 @@ ansi_term = "0.12" anyhow = "1.0" assert-json-diff = "2.0" async-trait = "0.1" -atty = "0.2" aws-config = "1.5" aws-sdk-kms = "1.44" byte-unit = "5.1" diff --git a/forc-plugins/forc-crypto/Cargo.toml b/forc-plugins/forc-crypto/Cargo.toml index bea4711b7d5..e0e631e937d 100644 --- a/forc-plugins/forc-crypto/Cargo.toml +++ b/forc-plugins/forc-crypto/Cargo.toml @@ -11,7 +11,6 @@ repository.workspace = true [dependencies] anyhow.workspace = true async-trait.workspace = true -atty.workspace = true clap = { workspace = true, features = ["derive", "env"] } forc-tracing.workspace = true forc-util.workspace = true diff --git a/forc-plugins/forc-crypto/src/main.rs b/forc-plugins/forc-crypto/src/main.rs index c9ae55b23f0..575b3e9d1ec 100644 --- a/forc-plugins/forc-crypto/src/main.rs +++ b/forc-plugins/forc-crypto/src/main.rs @@ -1,13 +1,12 @@ //! A `forc` plugin for converting a given string or path to their hash. use anyhow::Result; -use atty::Stream; use clap::Parser; use forc_crypto::{address, keccak256, keys, sha256, Command}; use forc_tracing::{init_tracing_subscriber, println_error}; use std::{ default::Default, - io::{stdin, stdout, Read, Write}, + io::{stdin, stdout, IsTerminal, Read, Write}, }; use termion::screen::IntoAlternateScreen; @@ -53,7 +52,7 @@ pub fn display_output(message: T) -> anyhow::Result<()> where T: serde::Serialize, { - if atty::is(Stream::Stdout) { + if stdout().is_terminal() { let text = serde_yaml::to_string(&message).expect("valid string"); if has_sensible_info(&message) { let mut screen = stdout().into_alternate_screen()?; From 16318d302e69ef3a486ecbcad8bf7aa484d009c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaya=20G=C3=B6kalp?= Date: Mon, 4 Nov 2024 20:13:35 -0800 Subject: [PATCH 098/115] chore: remove unmaintained `difference` in favor of `similar` (#6694) ## Description closes #5421. Removes unmaintained `difference` create used in swayfmt and uses `similar` instead. Security wise this is not an important problem as the dependency is only used as a dev-dependency. But the pr is a part of an effort cleaning `RUSTSEC` issues mainly for housekeeping reasons of our ever growing repo. --- Cargo.lock | 8 +------- swayfmt/Cargo.toml | 2 +- swayfmt/test_macros/src/lib.rs | 23 ++++++++++++++--------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1ab07481f7a..95a6bab5a68 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2071,12 +2071,6 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" -[[package]] -name = "difference" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" - [[package]] name = "digest" version = "0.9.0" @@ -7807,7 +7801,6 @@ name = "swayfmt" version = "0.66.4" dependencies = [ "anyhow", - "difference", "forc-tracing 0.66.4", "indoc", "paste", @@ -7815,6 +7808,7 @@ dependencies = [ "ropey", "serde", "serde_ignored", + "similar", "sway-ast", "sway-core", "sway-error", diff --git a/swayfmt/Cargo.toml b/swayfmt/Cargo.toml index 584bc0320ec..475cbe5d1b2 100644 --- a/swayfmt/Cargo.toml +++ b/swayfmt/Cargo.toml @@ -25,7 +25,7 @@ thiserror.workspace = true toml = { workspace = true, features = ["parse"] } [dev-dependencies] -difference = "2.0.0" paste = "1.0" prettydiff = "0.6" +similar = "2.0" test-macros = { path = "test_macros" } diff --git a/swayfmt/test_macros/src/lib.rs b/swayfmt/test_macros/src/lib.rs index faa93230e8e..8ec3decc2fd 100644 --- a/swayfmt/test_macros/src/lib.rs +++ b/swayfmt/test_macros/src/lib.rs @@ -119,18 +119,23 @@ macro_rules! fmt_test_inner { #[macro_export] macro_rules! assert_eq_pretty { ($got:expr, $expected:expr) => { - let got = &$got; - let expected = &$expected; + let got = &$got[..]; + let expected = &$expected[..]; + if got != expected { - use difference::{Changeset, Difference}; - let changeset = Changeset::new(expected, got, "\n"); - for diff in changeset.diffs { - match diff { - Difference::Same(s) => println!("{}", s), - Difference::Add(s) => println!("\x1b[32m+{}\x1b[0m", s), // Green color for additions - Difference::Rem(s) => println!("\x1b[31m-{}\x1b[0m", s), // Red color for removals + use similar::TextDiff; + + let diff = TextDiff::from_lines(expected, got); + for op in diff.ops() { + for change in diff.iter_changes(op) { + match change.tag() { + similar::ChangeTag::Equal => print!("{}", change), + similar::ChangeTag::Insert => print!("\x1b[32m+{}\x1b[0m", change), // Green for additions + similar::ChangeTag::Delete => print!("\x1b[31m-{}\x1b[0m", change), // Red for deletions + } } } + println!(); panic!("printed outputs differ!"); } }; From 73e1a7a80301d341864ea75de4124bf98d52a3ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ron=C4=8Devi=C4=87?= Date: Wed, 6 Nov 2024 10:03:21 +0100 Subject: [PATCH 099/115] Rewrite `TypeEngine` for performance, robustness, and simplicity (#6613) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description This PR implements a major rewrite of the `TypeEngine`. The rewrite: - significantly improves overall compilation performance. The compilation time of the real-world [Spark Orderbook workspace](https://github.com/compolabs/orderbook-contract) got **reduced from 8.99 to 5.94 seconds**, and the memory consumption from **3.32 to 1.78 GB**. - provides robust API for inserting types, related to the usage of the `source_id` (see: #5991). The new API forbids not providing `source_id`s or providing semantically questionable or non-optimal ones. - introduces simpler, much less verbose, API for inserting types. The PR also removes the obsolete and unused `TypeInfo::Storage`. The PR **does not address** the following: - The `TypeEngine`'s "garbage-collection-(un)friendlines" (see: #6603). - The handling of the `TypeInfo::Custom` and `TypeInfo::TraitType` types within the `TypeEngine` (see: #6601). - The number of interactions with the `TypeEngine`. E.g., removing unnecessary insertions after `resolve()`ing or `monomorphyze()`ing types will be done as a part of `DeclEngine` optimization. Closes #5991. ## Shareable types The PR formalizes the notion of a _shareable type_ within the `TypeEngine` (strictly speaking, a shareable `TypeInfo`). A shareable type is a type that is both: - _unchangeable_: it, or any of its parts, cannot be replaced during the unification or monomorphization. - and _undistinguishable by annotations_: it doesn't carry any additional information (annotations) that could differ it from another instance of `TypeInfo` that would, purely from the type perspective, be a same type. E.g., `u64` or `MyStruct` are unchangeable while `Numeric`, `Unknown` or `MyStruct` are changeable. E.g., in this example, `a` and `b` have the same type, `[u64; 2]` but those two types differ in spans assigned to the "u64"s and the "2"s, and are treated as different within the `TypeEngine`, and thus as non-shareable. ``` let a: [u64; 2] = [1, 1]; let b: [u64; 2] = [2, 2]; ``` Shareability of a type is crucial for reusing the `TypeSourceInfo` instances within the type engine. Shareable types can be given different `TypeId`s without the need to newly allocate a `TypeSourceInfo`. ## Performance improvements The cummulative effect of the performance improvements on the compilataion of the real-world [Spark Orderbook workspace](https://github.com/compolabs/orderbook-contract) is given below. The compilation means the frontend compilation, up to the IR generation (`forc check`). **Compilation time** ``` Before: Time (mean ± σ): 8.995 s ± 0.297 s [User: 7.126 s, System: 1.289 s] Range (min … max): 8.675 s … 9.262 s 3 runs After: Time (mean ± σ): 5.945 s ± 0.517 s [User: 4.749 s, System: 0.768 s] Range (min … max): 5.349 s … 6.280 s 3 runs ``` **Memory consumption** ``` --------------------------------------------------------- total(B) useful-heap(B) extra-heap(B) --------------------------------------------------------- Before: 3,316,786,808 3,237,317,383 79,469,425 After: 1,784,467,376 1,743,772,406 40,694,970 ``` ### Applied optimizations: - **Replacement of expensive `insert` calls with compile time constants for built-in types.** Built-in types like `!`, `bool`, `()`, `u8`, etc. are inserted into the engine at its creation at predefined slots within the `slab`. The `id_of_` methods just return those predefined `TypeId`s, effectively being compiled down to constants. The calls like `type_engine.insert(engines, TypeInfo::Boolean, None)` are replaced with maximally optimized and non-verbose `type_engine.id_of_bool()`. - **Elimination of extensive creation of `TypeSourceInfo`s for `TypeInfo::Unknown/Numeric`s.** `Unknown` and `Numeric` are inserted into the engine ~50.000 times. Each insert used to create a new instance of `TypeSourceInfo` with the `source_id` set to `None`. The optimization replaces those ~50.000 instances with two predefined singleton instances, one for `Unknown` + `None` and one for `Numeric` + `None`. (Note that when implementing #6603, we will want to bind also `Unknown`s and `Numeric`s to `source_id`s different then `None`, but we will still want to reuse the `TypeInfo` instances.) - **Elimination of extensive temporary heap-allocations during hash calculation.** The custom hasher obtained by `make_hasher` required a `TypeSourceInfo` to calculate the hash and it was called every time the `insert` was called, ~530.000 times. Getting the `TypeSourceInfo` originally required cloning the `TypeInfo`, which depending on the concrete `TypeInfo` instance could cause heap allocations, and also heap-allocating that copy within an `Arc`. Hash was calculated regardless of the possibility for the type to be stored in the hash map of reusable types. The optimization removed the hashing step if the type is not shareable, removed the cloning of the `TypeInfo` and introduced a custom `compute_hash_without_heap_allocation` method that produced the same hash as the `make_hasher` but without unnecessary temporary heap-allocations of `TypeSourceInfo`s. - **Replacement of `TypeSourceInfo`s within the hash map with `Arc`s.** The hash map unnecessarily required making copies of reused `TypeSourceInfo`s. - **Introducing the concept of a _shareable type_ and rolling it out for all types.** Previously, the engine checked only for changeability of types by using the `TypeInfo::is_changeable` method. The implementation of that method was extremely simplified, e.g. treating all structs and enums with generic arguments as changeable even if they were fully monomorphized. This resulted in over-bloating the engine with type instances that were actually unchangeable, but considered to be changeable. Also, strictly seen, the unchangeability (during unification and monomorphization) is not the only necessary criteria for reuse (or sharing) a type within the engine. Another important aspect is, as explained above, the _differentiability by annotations_. The PR introduces the notion of a _shareable type_ which is both unchangeable and not differentiable by annotations. The optimization takes advantage of such types by storing them only once per `source_id`. - **Elimination of extensive unnecessary inserts of new types during `replace()` calls.** When `replace()`ing types during unifications, a new `TypeSourceInfo` instance was created for every replacement, ~46.000 times. This meant a heap-allocation of the `TypeSourceInfo` (16 bytes) and the `Arc`-contained `TypeInfo` (232 bytes), even if the replaced type was shareable and already available in the type engine. The optimization now reuses an already existing shareable type if available. ## Robustness related to `source_id`s The issues we had with properly providing the `source_id` in the `insert` method are explained in #5991. This PR removes the `source_id` from the new public API and calculates it internally within the engine, based on the type being inserted. This makes inserting of types both more robust and less verbose and eliminates the possibility of providing a semantically wrong `source_id`. Note that the calculation of an optimal `source_id` done within the engine fully corresponds to the "calculations" we currently have at call sites. E.g., when inserting enums, previously we always had to write `type_engine.insert(engines, TypeInfo::Enum(decl_id), enum_decl.span.source_id())`. Fetching the `source_id` from the enum declaration is now done within the `insert_enum` method: `type_engine.insert_enum(engines, decl_id)`. Note that for certain types we will want to change the current behavior and either provide a `source_id` or pick a more suitable one. E.g, even when inserting `Unknown`s, we will want to have `source_id`s, if possible. This will be done in #6603, but again, together with providing a robust API that will be difficult to misuse. ## Simplicity As already mentioned in some of the examples above, the new `id_of_()` and `insert_` methods provide much simpler and less verbose API to use. Introducing those methods remove a lot of boilerplate code from the callers. Also, the individual `insert_` methods are additionally optimized for inserting the particular type. The common `insert` method is intended to be used only in cases where the inserted `TypeInfo` is not known at the call site. Here are some examples of the new API versus the existing one: |Before|After| |------|-----| | `type_engine.insert(engines, TypeInfo::Tuple(vec![]), None)` | `type_engine.id_of_unit()` | | `type_engine.insert(engines, TypeInfo::Unknown, None)` | `type_engine.new_unknown()` | | `type_engine.insert(engines, TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), None)` | `type_engine.id_of_u64()` | For more complex types, like, e.g., `TypeInfo::Tuple`, the difference in inserting is even more prominent, as can be seen from the diffs of numerous code lines deleted in this PR. ## 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. --------- Co-authored-by: Joshua Batty Co-authored-by: João Matos --- Cargo.lock | 1 + Cargo.toml | 2 +- sway-core/Cargo.toml | 1 + sway-core/src/abi_generation/abi_str.rs | 1 - sway-core/src/abi_generation/evm_abi.rs | 1 - sway-core/src/concurrent_slab.rs | 7 + sway-core/src/engine_threading.rs | 11 +- sway-core/src/ir_generation/const_eval.rs | 2 +- sway-core/src/ir_generation/convert.rs | 1 - .../language/parsed/declaration/impl_trait.rs | 2 +- sway-core/src/language/ty/declaration/abi.rs | 9 +- .../language/ty/declaration/declaration.rs | 26 +- .../src/language/ty/declaration/storage.rs | 23 +- .../src/language/ty/declaration/type_alias.rs | 12 +- .../src/language/ty/expression/expression.rs | 2 +- .../semantic_analysis/ast_node/code_block.rs | 16 +- .../ast_node/declaration/abi.rs | 2 + .../ast_node/declaration/auto_impl.rs | 11 +- .../ast_node/declaration/configurable.rs | 23 +- .../ast_node/declaration/constant.rs | 4 +- .../ast_node/declaration/declaration.rs | 14 +- .../ast_node/declaration/enum.rs | 3 +- .../ast_node/declaration/function.rs | 27 +- .../function/function_parameter.rs | 6 +- .../ast_node/declaration/impl_trait.rs | 63 +- .../ast_node/declaration/struct.rs | 4 +- .../ast_node/declaration/trait.rs | 4 +- .../ast_node/declaration/trait_fn.rs | 5 +- .../ast_node/declaration/trait_type.rs | 13 +- .../ast_node/declaration/variable.rs | 2 +- .../ast_node/expression/intrinsic_function.rs | 345 +-- .../match_expression/typed/instantiate.rs | 18 +- .../match_expression/typed/matcher.rs | 16 +- .../typed/typed_match_branch.rs | 18 +- .../typed/typed_match_expression.rs | 46 +- .../match_expression/typed/typed_scrutinee.rs | 65 +- .../ast_node/expression/typed_expression.rs | 220 +- .../typed_expression/enum_instantiation.rs | 12 +- .../typed_expression/if_expression.rs | 9 +- .../typed_expression/method_application.rs | 68 +- .../typed_expression/struct_instantiation.rs | 26 +- .../src/semantic_analysis/ast_node/mod.rs | 6 +- .../semantic_analysis/namespace/trait_map.rs | 35 +- .../semantic_analysis/node_dependencies.rs | 1 - .../semantic_analysis/type_check_context.rs | 10 +- .../src/semantic_analysis/type_resolve.rs | 51 +- .../to_parsed_lang/convert_parse_tree.rs | 135 +- .../src/type_system/ast_elements/binding.rs | 20 +- .../src/type_system/ast_elements/length.rs | 34 +- .../ast_elements/trait_constraint.rs | 6 +- .../type_system/ast_elements/type_argument.rs | 47 +- .../ast_elements/type_parameter.rs | 176 +- sway-core/src/type_system/engine.rs | 1916 ++++++++++++++++- sway-core/src/type_system/id.rs | 33 +- sway-core/src/type_system/info.rs | 149 +- sway-core/src/type_system/mod.rs | 72 +- sway-core/src/type_system/monomorphization.rs | 35 +- sway-core/src/type_system/priv_prelude.rs | 2 +- .../src/type_system/substitute/subst_map.rs | 126 +- sway-core/src/type_system/unify/unifier.rs | 20 +- .../src/type_system/unify/unify_check.rs | 1 - sway-lsp/README.md | 10 + .../code_actions/common/generate_impl.rs | 2 +- sway-lsp/src/server_state.rs | 17 +- sway-lsp/src/traverse/parsed_tree.rs | 2 +- sway-lsp/src/traverse/typed_tree.rs | 27 +- sway-lsp/tests/lib.rs | 239 +- sway-lsp/tests/utils/src/lib.rs | 12 + sway-types/src/lib.rs | 31 +- sway-types/src/source_engine.rs | 2 +- .../abi_cast_nested_method/src/main.sw | 4 +- .../language/match_expressions_or/test.toml | 2 +- 72 files changed, 2768 insertions(+), 1596 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 95a6bab5a68..07c201f8f60 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7611,6 +7611,7 @@ dependencies = [ "lazy_static", "object", "parking_lot 0.12.3", + "paste", "pest", "pest_derive", "petgraph", diff --git a/Cargo.toml b/Cargo.toml index 340bc9d0581..cc4f22bd5c7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -165,7 +165,7 @@ libtest-mimic = "0.7" lsp-types = "0.94" mdbook = { version = "0.4", default-features = false } minifier = "0.3" -normalize-path = "0.2.1" +normalize-path = "0.2" notify = "6.1" notify-debouncer-mini = "0.4" num-bigint = "0.4" diff --git a/sway-core/Cargo.toml b/sway-core/Cargo.toml index 3a351390cbb..5e2e5d54536 100644 --- a/sway-core/Cargo.toml +++ b/sway-core/Cargo.toml @@ -28,6 +28,7 @@ itertools.workspace = true lazy_static.workspace = true object = { workspace = true, features = ["write"] } parking_lot.workspace = true +paste.workspace = true pest.workspace = true pest_derive.workspace = true petgraph.workspace = true diff --git a/sway-core/src/abi_generation/abi_str.rs b/sway-core/src/abi_generation/abi_str.rs index 254b8a805ad..5794906d7c9 100644 --- a/sway-core/src/abi_generation/abi_str.rs +++ b/sway-core/src/abi_generation/abi_str.rs @@ -179,7 +179,6 @@ impl TypeInfo { length.val() ) } - Storage { .. } => "contract storage".into(), RawUntypedPtr => "raw untyped ptr".into(), RawUntypedSlice => "raw untyped slice".into(), Ptr(ty) => { diff --git a/sway-core/src/abi_generation/evm_abi.rs b/sway-core/src/abi_generation/evm_abi.rs index f723f36d14a..147fa387a6f 100644 --- a/sway-core/src/abi_generation/evm_abi.rs +++ b/sway-core/src/abi_generation/evm_abi.rs @@ -115,7 +115,6 @@ pub fn abi_str(type_info: &TypeInfo, engines: &Engines) -> String { Array(elem_ty, length) => { format!("{}[{}]", abi_str_type_arg(elem_ty, engines), length.val()) } - Storage { .. } => "contract storage".into(), RawUntypedPtr => "raw untyped ptr".into(), RawUntypedSlice => "raw untyped slice".into(), Ptr(ty) => { diff --git a/sway-core/src/concurrent_slab.rs b/sway-core/src/concurrent_slab.rs index 77aef759e9d..8c3d1eacf2c 100644 --- a/sway-core/src/concurrent_slab.rs +++ b/sway-core/src/concurrent_slab.rs @@ -100,6 +100,13 @@ where Arc::into_inner(old) } + pub fn replace_arc(&self, index: usize, new_value: Arc) -> Option { + let mut inner = self.inner.write(); + let item = inner.items.get_mut(index)?; + let old = item.replace(new_value)?; + Arc::into_inner(old) + } + pub fn get(&self, index: usize) -> Arc { let inner = self.inner.read(); inner.items[index] diff --git a/sway-core/src/engine_threading.rs b/sway-core/src/engine_threading.rs index 2af209c807f..c5e48557e72 100644 --- a/sway-core/src/engine_threading.rs +++ b/sway-core/src/engine_threading.rs @@ -7,6 +7,7 @@ use std::{ cmp::Ordering, fmt, hash::{BuildHasher, Hash, Hasher}, + sync::Arc, }; use sway_types::{SourceEngine, Span}; @@ -40,7 +41,7 @@ impl Engines { &self.source_engine } - /// Removes all data associated with `program_id` from the declaration and type engines. + /// Removes all data associated with `program_id` from the engines. /// It is intended to be used during garbage collection to remove any data that is no longer needed. pub fn clear_program(&mut self, program_id: &sway_types::ProgramId) { self.type_engine.clear_program(program_id); @@ -49,7 +50,7 @@ impl Engines { self.query_engine.clear_program(program_id); } - /// Removes all data associated with `source_id` from the declaration and type engines. + /// Removes all data associated with `source_id` from the engines. /// It is intended to be used during garbage collection to remove any data that is no longer needed. pub fn clear_module(&mut self, source_id: &sway_types::SourceId) { self.type_engine.clear_module(source_id); @@ -258,6 +259,12 @@ impl HashWithEngines for Box { } } +impl HashWithEngines for Arc { + fn hash(&self, state: &mut H, engines: &Engines) { + (**self).hash(state, engines) + } +} + pub trait EqWithEngines: PartialEqWithEngines {} pub struct PartialEqWithEnginesContext<'a> { diff --git a/sway-core/src/ir_generation/const_eval.rs b/sway-core/src/ir_generation/const_eval.rs index ad2d5a307ff..258d63cb6d2 100644 --- a/sway-core/src/ir_generation/const_eval.rs +++ b/sway-core/src/ir_generation/const_eval.rs @@ -221,7 +221,7 @@ pub(crate) fn compile_constant_expression_to_constant( // definition, rather than the actual call site. ty::TyExpressionVariant::FunctionApplication { call_path, .. } => { let span = call_path.span(); - let span = if span == Span::dummy() { + let span = if span.is_dummy() { const_expr.span.clone() } else { span diff --git a/sway-core/src/ir_generation/convert.rs b/sway-core/src/ir_generation/convert.rs index 4d0ee1d20c7..f95217fb2b4 100644 --- a/sway-core/src/ir_generation/convert.rs +++ b/sway-core/src/ir_generation/convert.rs @@ -184,7 +184,6 @@ fn convert_resolved_type_info( TypeInfo::Placeholder(_) => reject_type!("Placeholder"), TypeInfo::TypeParam(_) => reject_type!("TypeParam"), TypeInfo::ErrorRecovery(_) => reject_type!("Error recovery"), - TypeInfo::Storage { .. } => reject_type!("Storage"), TypeInfo::TraitType { .. } => reject_type!("TraitType"), }) } diff --git a/sway-core/src/language/parsed/declaration/impl_trait.rs b/sway-core/src/language/parsed/declaration/impl_trait.rs index 48ba779155e..ed0ee15bf35 100644 --- a/sway-core/src/language/parsed/declaration/impl_trait.rs +++ b/sway-core/src/language/parsed/declaration/impl_trait.rs @@ -72,7 +72,7 @@ pub struct ImplSelfOrTrait { pub trait_decl_ref: Option, pub implementing_for: TypeArgument, pub items: Vec, - // the span of the whole impl trait and block + /// The [Span] of the whole impl trait and block. pub(crate) block_span: Span, } diff --git a/sway-core/src/language/ty/declaration/abi.rs b/sway-core/src/language/ty/declaration/abi.rs index 5ad5ea2c3dc..7dae1ef3271 100644 --- a/sway-core/src/language/ty/declaration/abi.rs +++ b/sway-core/src/language/ty/declaration/abi.rs @@ -76,12 +76,9 @@ impl HashWithEngines for TyAbiDecl { impl CreateTypeId for TyAbiDecl { fn create_type_id(&self, engines: &Engines) -> TypeId { - let type_engine = engines.te(); - let ty = TypeInfo::ContractCaller { - abi_name: AbiName::Known(self.name.clone().into()), - address: None, - }; - type_engine.insert(engines, ty, self.name.span().source_id()) + engines + .te() + .new_contract_caller(engines, AbiName::Known(self.name.clone().into()), None) } } diff --git a/sway-core/src/language/ty/declaration/declaration.rs b/sway-core/src/language/ty/declaration/declaration.rs index 9bd68ec0046..3c5b6481d09 100644 --- a/sway-core/src/language/ty/declaration/declaration.rs +++ b/sway-core/src/language/ty/declaration/declaration.rs @@ -740,31 +740,9 @@ impl TyDecl { decl.return_type.type_id } TyDecl::StructDecl(StructDecl { decl_id }) => { - let decl = decl_engine.get_struct(decl_id); - type_engine.insert( - engines, - TypeInfo::Struct(*decl_id), - decl.name().span().source_id(), - ) - } - TyDecl::EnumDecl(EnumDecl { decl_id }) => { - let decl = decl_engine.get_enum(decl_id); - type_engine.insert( - engines, - TypeInfo::Enum(*decl_id), - decl.name().span().source_id(), - ) - } - TyDecl::StorageDecl(StorageDecl { decl_id, .. }) => { - let storage_decl = decl_engine.get_storage(decl_id); - type_engine.insert( - engines, - TypeInfo::Storage { - fields: storage_decl.fields_as_typed_struct_fields(), - }, - storage_decl.span().source_id(), - ) + type_engine.insert_struct(engines, *decl_id) } + TyDecl::EnumDecl(EnumDecl { decl_id }) => type_engine.insert_enum(engines, *decl_id), TyDecl::TypeAliasDecl(TypeAliasDecl { decl_id, .. }) => { let decl = decl_engine.get_type_alias(decl_id); decl.create_type_id(engines) diff --git a/sway-core/src/language/ty/declaration/storage.rs b/sway-core/src/language/ty/declaration/storage.rs index 767d5728ee7..23e4b7a09ba 100644 --- a/sway-core/src/language/ty/declaration/storage.rs +++ b/sway-core/src/language/ty/declaration/storage.rs @@ -8,7 +8,7 @@ use sway_types::{Ident, Named, Span, Spanned}; use crate::{ engine_threading::*, - language::{parsed::StorageDeclaration, ty::*, Visibility}, + language::{parsed::StorageDeclaration, ty::*}, transform::{self}, type_system::*, Namespace, @@ -233,27 +233,6 @@ impl TyStorageDecl { return_type, )) } - - pub(crate) fn fields_as_typed_struct_fields(&self) -> Vec { - self.fields - .iter() - .map( - |TyStorageField { - ref name, - ref type_argument, - ref span, - ref attributes, - .. - }| TyStructField { - visibility: Visibility::Public, - name: name.clone(), - span: span.clone(), - type_argument: type_argument.clone(), - attributes: attributes.clone(), - }, - ) - .collect() - } } impl Spanned for TyStorageField { diff --git a/sway-core/src/language/ty/declaration/type_alias.rs b/sway-core/src/language/ty/declaration/type_alias.rs index e2e5844de3f..cb33c0d27bd 100644 --- a/sway-core/src/language/ty/declaration/type_alias.rs +++ b/sway-core/src/language/ty/declaration/type_alias.rs @@ -64,15 +64,9 @@ impl SubstTypes for TyTypeAliasDecl { impl CreateTypeId for TyTypeAliasDecl { fn create_type_id(&self, engines: &Engines) -> TypeId { - let type_engine = engines.te(); - type_engine.insert( - engines, - TypeInfo::Alias { - name: self.name.clone(), - ty: self.ty.clone(), - }, - self.name.span().source_id(), - ) + engines + .te() + .new_alias(engines, self.name.clone(), self.ty.clone()) } } diff --git a/sway-core/src/language/ty/expression/expression.rs b/sway-core/src/language/ty/expression/expression.rs index 15f57369007..a0c70559b1d 100644 --- a/sway-core/src/language/ty/expression/expression.rs +++ b/sway-core/src/language/ty/expression/expression.rs @@ -369,7 +369,7 @@ impl TyExpression { let type_engine = engines.te(); TyExpression { expression: TyExpressionVariant::Tuple { fields: vec![] }, - return_type: type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None), + return_type: type_engine.id_of_error_recovery(err), span, } } diff --git a/sway-core/src/semantic_analysis/ast_node/code_block.rs b/sway-core/src/semantic_analysis/ast_node/code_block.rs index 330b8e4e4e9..c82523f9395 100644 --- a/sway-core/src/semantic_analysis/ast_node/code_block.rs +++ b/sway-core/src/semantic_analysis/ast_node/code_block.rs @@ -91,8 +91,6 @@ impl ty::TyCodeBlock { ctx: &TypeCheckContext, code_block: &TyCodeBlock, ) -> (TypeId, Span) { - let engines = ctx.engines(); - let implicit_return_span = code_block .contents .iter() @@ -122,12 +120,8 @@ impl ty::TyCodeBlock { .. }), .. - } => Some( - ctx.engines - .te() - .insert(engines, TypeInfo::Never, span.source_id()), - ), - // find the implicit return, if any, and use it as the code block's return type. + } => Some(ctx.engines.te().id_of_never()), + // Find the implicit return, if any, and use it as the code block's return type. // The fact that there is at most one implicit return is an invariant held by the parser. ty::TyAstNode { content: @@ -153,11 +147,7 @@ impl ty::TyCodeBlock { _ => None, } }) - .unwrap_or_else(|| { - ctx.engines - .te() - .insert(engines, TypeInfo::Tuple(Vec::new()), span.source_id()) - }); + .unwrap_or_else(|| ctx.engines.te().id_of_unit()); (block_type, span) } diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/abi.rs b/sway-core/src/semantic_analysis/ast_node/declaration/abi.rs index bb0bc9e2fb8..0274195845b 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/abi.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/abi.rs @@ -79,6 +79,8 @@ impl ty::TyAbiDecl { // so we don't support the case of calling a contract's own interface // from itself. This is by design. + // The span of the `abi_decl` `name` points to the file (use site) in which + // the ABI is getting declared, so we can use it as the `use_site_span`. let self_type_param = TypeParameter::new_self_type(ctx.engines, name.span()); let self_type_id = self_type_param.type_id; diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/auto_impl.rs b/sway-core/src/semantic_analysis/ast_node/declaration/auto_impl.rs index 55ef6a25e79..98def2c187f 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/auto_impl.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/auto_impl.rs @@ -75,11 +75,8 @@ where } else { format!( "<{}>", - itertools::intersperse( - type_parameters.iter().map(|x| { x.name_ident.as_str() }), - ", " - ) - .collect::() + itertools::intersperse(type_parameters.iter().map(|x| { x.name.as_str() }), ", ") + .collect::() ) } } @@ -94,7 +91,7 @@ where for t in type_parameters.iter() { code.push_str(&format!( "{}: {},\n", - t.name_ident.as_str(), + t.name.as_str(), itertools::intersperse( [extra_constraint].into_iter().chain( t.trait_constraints @@ -502,7 +499,7 @@ where fn generate_type(engines: &Engines, type_id: TypeId) -> Option { let name = match &*engines.te().get(type_id) { TypeInfo::UnknownGeneric { name, .. } => name.to_string(), - TypeInfo::Placeholder(type_param) => type_param.name_ident.to_string(), + TypeInfo::Placeholder(type_param) => type_param.name.to_string(), TypeInfo::StringSlice => "str".into(), TypeInfo::StringArray(x) => format!("str[{}]", x.val()), TypeInfo::UnsignedInteger(x) => match x { diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/configurable.rs b/sway-core/src/semantic_analysis/ast_node/declaration/configurable.rs index 6c9f5e7f404..7fefd0c1636 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/configurable.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/configurable.rs @@ -19,7 +19,6 @@ use crate::{ }, semantic_analysis::*, EnforceTypeArguments, Engines, SubstTypes, TypeArgument, TypeBinding, TypeCheckTypeBinding, - TypeInfo, }; impl ty::TyConfigurableDecl { @@ -68,7 +67,7 @@ impl ty::TyConfigurableDecl { EnforceTypeArguments::No, None, ) - .unwrap_or_else(|err| type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None)); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); // this subst is required to replace associated types, namely TypeInfo::TraitType. type_ascription.type_id.subst(&ctx.subst_ctx()); @@ -84,7 +83,7 @@ impl ty::TyConfigurableDecl { let (value, decode_fn) = if ctx.experimental.new_encoding { let mut ctx = ctx .by_ref() - .with_type_annotation(type_engine.insert(engines, TypeInfo::RawUntypedSlice, None)) + .with_type_annotation(type_engine.id_of_raw_slice()) .with_help_text("Configurables must evaluate to slices."); let value = value.map(|value| { @@ -93,21 +92,9 @@ impl ty::TyConfigurableDecl { }); let mut arguments = VecDeque::default(); - arguments.push_back( - engines - .te() - .insert(engines, TypeInfo::RawUntypedSlice, None), - ); - arguments.push_back(engines.te().insert( - engines, - TypeInfo::UnsignedInteger(sway_types::integer_bits::IntegerBits::SixtyFour), - None, - )); - arguments.push_back( - engines - .te() - .insert(engines, TypeInfo::RawUntypedSlice, None), - ); + arguments.push_back(engines.te().id_of_raw_slice()); + arguments.push_back(engines.te().id_of_u64()); + arguments.push_back(engines.te().id_of_raw_slice()); let value_span = value .as_ref() diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/constant.rs b/sway-core/src/semantic_analysis/ast_node/declaration/constant.rs index e5cca67ecde..6a0c788d2a8 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/constant.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/constant.rs @@ -61,7 +61,7 @@ impl ty::TyConstantDecl { EnforceTypeArguments::No, None, ) - .unwrap_or_else(|err| type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None)); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); // this subst is required to replace associated types, namely TypeInfo::TraitType. type_ascription.type_id.subst(&ctx.subst_ctx()); @@ -129,7 +129,7 @@ impl ty::TyConstantDecl { call_path, span, attributes: Default::default(), - return_type: type_engine.insert(engines, TypeInfo::Unknown, None), + return_type: type_engine.new_unknown(), type_ascription, value: None, visibility, diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/declaration.rs b/sway-core/src/semantic_analysis/ast_node/declaration/declaration.rs index 663891261bd..0f965bd0d4e 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/declaration.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/declaration.rs @@ -157,8 +157,7 @@ impl TyDecl { let fn_decl = engines.pe().get_function(&decl_id); let span = fn_decl.span.clone(); - let mut ctx = - ctx.with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + let mut ctx = ctx.with_type_annotation(type_engine.new_unknown()); let fn_decl = match ty::TyFunctionDecl::type_check( handler, ctx.by_ref(), @@ -444,11 +443,8 @@ impl TyDecl { let mut key_ty_expression = None; if let Some(key_expression) = key_expression { - let mut key_ctx = ctx.with_type_annotation(engines.te().insert( - engines, - TypeInfo::B256, - None, - )); + let mut key_ctx = + ctx.with_type_annotation(engines.te().id_of_b256()); key_ty_expression = Some(ty::TyExpression::type_check( handler, @@ -522,9 +518,7 @@ impl TyDecl { // Resolve the type that the type alias replaces let new_ty = ctx .resolve_type(handler, ty.type_id, &span, EnforceTypeArguments::Yes, None) - .unwrap_or_else(|err| { - type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None) - }); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); // create the type alias decl using the resolved type above let decl = ty::TyTypeAliasDecl { diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs b/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs index 0434857f18f..5e4839c0172 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs @@ -87,7 +87,6 @@ impl ty::TyEnumVariant { variant: EnumVariant, ) -> Result { let type_engine = ctx.engines.te(); - let engines = ctx.engines(); let mut type_argument = variant.type_argument; type_argument.type_id = ctx .resolve_type( @@ -97,7 +96,7 @@ impl ty::TyEnumVariant { EnforceTypeArguments::Yes, None, ) - .unwrap_or_else(|err| type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None)); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); Ok(ty::TyEnumVariant { name: variant.name.clone(), type_argument, diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/function.rs b/sway-core/src/semantic_analysis/ast_node/declaration/function.rs index 4b5b306cb98..69603909545 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/function.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/function.rs @@ -85,7 +85,6 @@ impl ty::TyFunctionDecl { let mut return_type = fn_decl.return_type.clone(); let type_engine = ctx.engines.te(); - let engines = ctx.engines(); // If functions aren't allowed in this location, return an error. if ctx.functions_disallowed() { @@ -146,9 +145,7 @@ impl ty::TyFunctionDecl { EnforceTypeArguments::Yes, None, ) - .unwrap_or_else(|err| { - type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None) - }); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); let (visibility, is_contract_call) = if is_method { if is_in_impl_self { @@ -329,7 +326,7 @@ impl TypeCheckFinalization for ty::TyFunctionDecl { fn test_function_selector_behavior() { use crate::language::Visibility; use crate::Engines; - use sway_types::{integer_bits::IntegerBits, Ident, Span}; + use sway_types::{Ident, Span}; let engines = Engines::default(); let handler = Handler::default(); @@ -373,11 +370,7 @@ fn test_function_selector_behavior() { mutability_span: Span::dummy(), type_argument: engines .te() - .insert( - &engines, - TypeInfo::StringArray(Length::new(5, Span::dummy())), - None, - ) + .insert_string_array_without_annotations(&engines, 5) .into(), }, ty::TyFunctionParameter { @@ -386,16 +379,10 @@ fn test_function_selector_behavior() { is_mutable: false, mutability_span: Span::dummy(), type_argument: TypeArgument { - type_id: engines.te().insert( - &engines, - TypeInfo::UnsignedInteger(IntegerBits::ThirtyTwo), - None, - ), - initial_type_id: engines.te().insert( - &engines, - TypeInfo::StringArray(Length::new(5, Span::dummy())), - None, - ), + type_id: engines.te().id_of_u32(), + initial_type_id: engines + .te() + .insert_string_array_without_annotations(&engines, 5), span: Span::dummy(), call_path_tree: None, }, diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/function/function_parameter.rs b/sway-core/src/semantic_analysis/ast_node/declaration/function/function_parameter.rs index 324a2d14404..be929464af6 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/function/function_parameter.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/function/function_parameter.rs @@ -17,7 +17,6 @@ impl ty::TyFunctionParameter { parameter: FunctionParameter, ) -> Result { let type_engine = ctx.engines.te(); - let engines = ctx.engines(); let FunctionParameter { name, @@ -35,7 +34,7 @@ impl ty::TyFunctionParameter { EnforceTypeArguments::Yes, None, ) - .unwrap_or_else(|err| type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None)); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); type_argument.type_id.check_type_parameter_bounds( handler, @@ -71,7 +70,6 @@ impl ty::TyFunctionParameter { parameter: &FunctionParameter, ) -> Result { let type_engine = ctx.engines.te(); - let engines = ctx.engines(); let FunctionParameter { name, @@ -90,7 +88,7 @@ impl ty::TyFunctionParameter { EnforceTypeArguments::Yes, None, ) - .unwrap_or_else(|err| type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None)); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); let typed_parameter = ty::TyFunctionParameter { name: name.clone(), diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs b/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs index 8d88a8989d8..72320202ba2 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs @@ -83,8 +83,13 @@ impl TyImplSelfOrTrait { let decl_engine = ctx.engines.de(); let engines = ctx.engines(); - // Create a new type parameter for the Self type - let self_type_param = TypeParameter::new_self_type(engines, implementing_for.span()); + // Create a new type parameter for the Self type. + // For the `use_site_span` of the self type parameter we take the `block_span`. + // This is the span of the whole impl trait and block and thus, points to + // the code in the source file in which the self type is used in the implementation. + let self_type_use_site_span = block_span.clone(); + let self_type_param = + TypeParameter::new_self_type(engines, self_type_use_site_span.clone()); let self_type_id = self_type_param.type_id; // create a namespace for the impl @@ -157,7 +162,7 @@ impl TyImplSelfOrTrait { // Update the context let mut ctx = ctx .with_help_text("") - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)) + .with_type_annotation(type_engine.new_unknown()) .with_self_type(Some(implementing_for.type_id)); let impl_trait = match ctx @@ -248,7 +253,7 @@ impl TyImplSelfOrTrait { } let self_type_param = - TypeParameter::new_self_type(engines, abi.span.clone()); + TypeParameter::new_self_type(engines, self_type_use_site_span); // Unify the "self" type param from the abi declaration with // the type that we are implementing for. handler.scope(|h| { @@ -340,9 +345,11 @@ impl TyImplSelfOrTrait { ctx.with_const_shadowing_mode(ConstShadowingMode::ItemStyle) .allow_functions() .scoped(handler, Some(block_span.clone()), |mut ctx| { - // Create a new type parameter for the "self type". + // Create a new type parameter for the self type. let self_type_param = - TypeParameter::new_self_type(engines, implementing_for.span()); + // Same as with impl trait or ABI, we take the `block_span` as the `use_site_span` + // of the self type. + TypeParameter::new_self_type(engines, block_span.clone()); let self_type_id = self_type_param.type_id; // create the trait name @@ -413,7 +420,7 @@ impl TyImplSelfOrTrait { let mut ctx = ctx .with_help_text("") - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + .with_type_annotation(type_engine.new_unknown()); // type check the items inside of the impl block let mut new_items = vec![]; @@ -854,41 +861,29 @@ fn type_check_trait_implementation( let decl_ref = decl_engine.insert(type_decl.clone(), Some(decl_id)); impld_item_refs.insert((name, implementing_for), TyTraitItem::Type(decl_ref)); - let old_type_decl_info1 = TypeInfo::TraitType { - name: type_decl.name.clone(), - trait_type_id: implementing_for, - }; - let old_type_decl_info2 = TypeInfo::TraitType { - name: type_decl.name.clone(), - trait_type_id: type_engine.insert( - engines, - TypeInfo::UnknownGeneric { - // Using Span::dummy just to match the type substitution, type is not used anywhere else. - name: Ident::new_with_override("Self".into(), Span::dummy()), - trait_constraints: VecSet(vec![]), - parent: None, - is_from_type_parameter: false, - }, - None, - ), - }; + // We want the `Self` type to have the span that points to an arbitrary location within + // the source file in which the trait is implemented for a type. The `trait_name` points + // to the name in the `impl for ...` and is thus a good candidate. + let self_type_id = type_engine + .new_unknown_generic_self(trait_name.span(), false) + .0; if let Some(type_arg) = type_decl.ty.clone() { trait_type_mapping.extend( &TypeSubstMap::from_type_parameters_and_type_arguments( - vec![type_engine.insert( + vec![type_engine.insert_trait_type( engines, - old_type_decl_info1, - type_decl.name.span().source_id(), + type_decl.name.clone(), + implementing_for, )], vec![type_arg.type_id], ), ); trait_type_mapping.extend( &TypeSubstMap::from_type_parameters_and_type_arguments( - vec![type_engine.insert( + vec![type_engine.insert_trait_type( engines, - old_type_decl_info2, - type_decl.name.span().source_id(), + type_decl.name.clone(), + self_type_id, )], vec![type_arg.type_id], ), @@ -1106,7 +1101,7 @@ fn type_check_impl_method( let mut ctx = ctx .by_ref() .with_help_text("") - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + .with_type_annotation(type_engine.new_unknown()); let interface_name = || -> InterfaceName { if is_contract { @@ -1335,7 +1330,7 @@ fn type_check_const_decl( let mut ctx = ctx .by_ref() .with_help_text("") - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + .with_type_annotation(type_engine.new_unknown()); let interface_name = || -> InterfaceName { if is_contract { @@ -1416,7 +1411,7 @@ fn type_check_type_decl( let mut ctx = ctx .by_ref() .with_help_text("") - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + .with_type_annotation(type_engine.new_unknown()); let interface_name = || -> InterfaceName { if is_contract { diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs b/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs index 0d3a7a25d34..4ad0a268284 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs @@ -93,9 +93,7 @@ impl ty::TyStructField { EnforceTypeArguments::Yes, None, ) - .unwrap_or_else(|err| { - type_engine.insert(ctx.engines(), TypeInfo::ErrorRecovery(err), None) - }); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); let field = ty::TyStructField { visibility: field.visibility, name: field.name, diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs b/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs index 9a0ed2942eb..2f4504c1b90 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs @@ -100,7 +100,9 @@ impl TyTraitDecl { let decl_engine = ctx.engines.de(); let engines = ctx.engines(); - // Create a new type parameter for the "self type". + // Create a new type parameter for the self type. + // The span of the `trait_decl` `name` points to the file (use site) in which + // the trait is getting declared, so we can use it as the `use_site_span`. let self_type_param = TypeParameter::new_self_type(engines, name.span()); let self_type = self_type_param.type_id; diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/trait_fn.rs b/sway-core/src/semantic_analysis/ast_node/declaration/trait_fn.rs index 07bd2feee81..fc2b0fc6c3f 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/trait_fn.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/trait_fn.rs @@ -49,7 +49,6 @@ impl ty::TyTraitFn { } = trait_fn; let type_engine = ctx.engines.te(); - let engines = ctx.engines(); // Create a namespace for the trait function. ctx.by_ref().scoped(handler, Some(span.clone()), |mut ctx| { @@ -80,9 +79,7 @@ impl ty::TyTraitFn { EnforceTypeArguments::Yes, None, ) - .unwrap_or_else(|err| { - type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None) - }); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); let trait_fn = ty::TyTraitFn { name: name.clone(), diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/trait_type.rs b/sway-core/src/semantic_analysis/ast_node/declaration/trait_type.rs index 262c2a5ef36..27338cede56 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/trait_type.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/trait_type.rs @@ -14,8 +14,7 @@ use crate::{ symbol_collection_context::SymbolCollectionContext, TypeCheckAnalysis, TypeCheckAnalysisContext, TypeCheckContext, }, - type_system::*, - Engines, + EnforceTypeArguments, Engines, }; impl ty::TyTraitType { @@ -58,9 +57,7 @@ impl ty::TyTraitType { EnforceTypeArguments::No, None, ) - .unwrap_or_else(|err| { - type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None) - }); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); Some(ty) } else { None @@ -92,11 +89,7 @@ impl ty::TyTraitType { name, attributes, ty: ty_opt, - implementing_type: engines.te().insert( - engines, - TypeInfo::new_self_type(Span::dummy()), - None, - ), + implementing_type: engines.te().new_self_type(engines, Span::dummy()), span, } } diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/variable.rs b/sway-core/src/semantic_analysis/ast_node/declaration/variable.rs index cd9bff70750..ea66d6e6194 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/variable.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/variable.rs @@ -48,7 +48,7 @@ impl ty::TyVariableDecl { EnforceTypeArguments::Yes, None, ) - .unwrap_or_else(|err| type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None)); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); let mut ctx = ctx .with_type_annotation(type_ascription.type_id) .with_help_text( 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 0219bec7d15..3ed6c9de234 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 @@ -132,7 +132,7 @@ fn type_check_elem_at( // check first argument let first_argument_span = arguments[0].span.clone(); - let first_argument_type = type_engine.insert(engines, TypeInfo::Unknown, None); + let first_argument_type = type_engine.new_unknown(); let first_argument_typed_expr = { let ctx = ctx .by_ref() @@ -163,32 +163,16 @@ fn type_check_elem_at( }; // index argument - let index_type = type_engine.insert( - engines, - TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), - None, - ); let index_typed_expr = { let ctx = ctx .by_ref() .with_help_text("") - .with_type_annotation(index_type); + .with_type_annotation(type_engine.id_of_u64()); ty::TyExpression::type_check(handler, ctx, &arguments[1])? }; - let return_type = type_engine.insert( - engines, - TypeInfo::Ref { - to_mutable_value, - referenced_type: TypeArgument { - type_id: elem_type_type_id, - initial_type_id: elem_type_type_id, - span: Span::dummy(), - call_path_tree: None, - }, - }, - None, - ); + let return_type = + type_engine.insert_ref_without_annotations(engines, to_mutable_value, elem_type_type_id); Ok(( TyIntrinsicFunctionKind { @@ -221,36 +205,26 @@ fn type_check_slice( let engines = ctx.engines(); // start index argument - let start_type = type_engine.insert( - engines, - TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), - None, - ); let start_ty_expr = { let ctx = ctx .by_ref() .with_help_text("") - .with_type_annotation(start_type); + .with_type_annotation(type_engine.id_of_u64()); ty::TyExpression::type_check(handler, ctx, &arguments[1])? }; // end index argument - let end_type = type_engine.insert( - engines, - TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), - None, - ); let end_ty_expr = { let ctx = ctx .by_ref() .with_help_text("") - .with_type_annotation(end_type); + .with_type_annotation(type_engine.id_of_u64()); ty::TyExpression::type_check(handler, ctx, &arguments[2])? }; // check first argument let first_argument_span = arguments[0].span.clone(); - let first_argument_type = type_engine.insert(engines, TypeInfo::Unknown, None); + let first_argument_type = type_engine.new_unknown(); let first_argument_ty_expr = { let ctx = ctx .by_ref() @@ -288,18 +262,8 @@ fn type_check_slice( elem_type_arg: TypeArgument, ) -> TypeId { let type_engine = engines.te(); - let slice_type_id = - type_engine.insert(engines, TypeInfo::Slice(elem_type_arg.clone()), None); - let ref_to_slice_type = TypeInfo::Ref { - to_mutable_value, - referenced_type: TypeArgument { - type_id: slice_type_id, - initial_type_id: slice_type_id, - span: Span::dummy(), - call_path_tree: None, - }, - }; - type_engine.insert(engines, ref_to_slice_type, None) + let slice_type_id = type_engine.insert_slice(engines, elem_type_arg); + type_engine.insert_ref_without_annotations(engines, to_mutable_value, slice_type_id) } // first argument can be ref to array or ref to slice @@ -375,45 +339,22 @@ fn type_check_encode_as_raw_slice( span: Span, ) -> Result<(ty::TyIntrinsicFunctionKind, TypeId), ErrorEmitted> { let type_engine = ctx.engines.te(); - let engines = ctx.engines(); let buffer_expr = { let ctx = ctx .by_ref() .with_help_text("") - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + .with_type_annotation(type_engine.new_unknown()); ty::TyExpression::type_check(handler, ctx, &arguments[0].clone())? }; - let return_type = type_engine.insert(engines, TypeInfo::RawUntypedSlice, None); - let kind = ty::TyIntrinsicFunctionKind { kind, arguments: vec![buffer_expr], type_arguments: vec![], span, }; - Ok((kind, return_type)) -} - -// TODO: Rename to `new_tuple` and move to `TypeInfo` once https://github.com/FuelLabs/sway/issues/5991 is implemented. -fn new_encoding_buffer_tuple( - engines: &Engines, - items: impl IntoIterator, - span: Span, -) -> TypeInfo { - let te = engines.te(); - let items = items - .into_iter() - .map(|x| te.insert(engines, x, None)) - .map(|type_id| TypeArgument { - initial_type_id: type_id, - type_id, - span: span.clone(), - call_path_tree: None, - }) - .collect(); - TypeInfo::Tuple(items) + Ok((kind, type_engine.id_of_raw_slice())) } fn type_check_encode_buffer_empty( @@ -432,56 +373,29 @@ fn type_check_encode_buffer_empty( })); } - let type_engine = ctx.engines.te(); - let engines = ctx.engines(); - - let return_type = new_encoding_buffer_tuple( - engines, - [ - TypeInfo::RawUntypedPtr, - TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), - TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), - ], - span.clone(), - ); - let return_type = type_engine.insert(engines, return_type, None); - let kind = ty::TyIntrinsicFunctionKind { kind, arguments: vec![], type_arguments: vec![], span, }; - Ok((kind, return_type)) + + Ok((kind, get_encoding_buffer_type(ctx.engines()))) } -fn encode_buffer_type(engines: &Engines) -> TypeInfo { - let raw_ptr = engines.te().insert(engines, TypeInfo::RawUntypedPtr, None); - let uint64 = engines.te().insert( +/// Returns the [TypeId] of the buffer type used in encoding: `(raw_ptr, u64, u64)`. +/// The buffer type is a shareable [TypeInfo::Tuple], so it will be inserted into +/// the [TypeEngine] only once, when this method is called for the first time. +fn get_encoding_buffer_type(engines: &Engines) -> TypeId { + let type_engine = engines.te(); + type_engine.insert_tuple_without_annotations( engines, - TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), - None, - ); - TypeInfo::Tuple(vec![ - TypeArgument { - type_id: raw_ptr, - initial_type_id: raw_ptr, - span: Span::dummy(), - call_path_tree: None, - }, - TypeArgument { - type_id: uint64, - initial_type_id: uint64, - span: Span::dummy(), - call_path_tree: None, - }, - TypeArgument { - type_id: uint64, - initial_type_id: uint64, - span: Span::dummy(), - call_path_tree: None, - }, - ]) + vec![ + type_engine.id_of_raw_ptr(), + type_engine.id_of_u64(), + type_engine.id_of_u64(), + ], + ) } fn type_check_encode_append( @@ -503,7 +417,7 @@ fn type_check_encode_append( let type_engine = ctx.engines.te(); let engines = ctx.engines(); - let buffer_type = type_engine.insert(engines, encode_buffer_type(engines), None); + let buffer_type = get_encoding_buffer_type(engines); let buffer_expr = { let ctx = ctx .by_ref() @@ -513,7 +427,7 @@ fn type_check_encode_append( }; let item_span = arguments[1].span.clone(); - let item_type = type_engine.insert(engines, TypeInfo::Unknown, None); + let item_type = type_engine.new_unknown(); let item_expr = { let ctx = ctx .by_ref() @@ -574,7 +488,7 @@ fn type_check_not( })); } - let return_type = type_engine.insert(engines, TypeInfo::Unknown, None); + let return_type = type_engine.new_unknown(); let mut ctx = ctx.with_help_text("").with_type_annotation(return_type); @@ -616,7 +530,6 @@ fn type_check_size_of_val( span: Span, ) -> Result<(ty::TyIntrinsicFunctionKind, TypeId), ErrorEmitted> { let type_engine = ctx.engines.te(); - let engines = ctx.engines(); if arguments.len() != 1 { return Err(handler.emit_err(CompileError::IntrinsicIncorrectNumArgs { @@ -627,7 +540,7 @@ fn type_check_size_of_val( } let ctx = ctx .with_help_text("") - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + .with_type_annotation(type_engine.new_unknown()); let exp = ty::TyExpression::type_check(handler, ctx, &arguments[0])?; let intrinsic_function = ty::TyIntrinsicFunctionKind { kind, @@ -635,12 +548,7 @@ fn type_check_size_of_val( type_arguments: vec![], span: span.clone(), }; - let return_type = type_engine.insert( - engines, - TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), - span.source_id(), - ); - Ok((intrinsic_function, return_type)) + Ok((intrinsic_function, type_engine.id_of_u64())) } /// Signature: `__size_of() -> u64` @@ -685,7 +593,7 @@ fn type_check_size_of_type( EnforceTypeArguments::Yes, None, ) - .unwrap_or_else(|err| type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None)); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); let intrinsic_function = ty::TyIntrinsicFunctionKind { kind, arguments: vec![], @@ -697,12 +605,7 @@ fn type_check_size_of_type( }], span, }; - let return_type = type_engine.insert( - engines, - TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), - None, - ); - Ok((intrinsic_function, return_type)) + Ok((intrinsic_function, type_engine.id_of_u64())) } /// Signature: `__is_reference_type() -> bool` @@ -740,7 +643,7 @@ fn type_check_is_reference_type( EnforceTypeArguments::Yes, None, ) - .unwrap_or_else(|err| type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None)); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); let intrinsic_function = ty::TyIntrinsicFunctionKind { kind, arguments: vec![], @@ -752,10 +655,7 @@ fn type_check_is_reference_type( }], span, }; - Ok(( - intrinsic_function, - type_engine.insert(engines, TypeInfo::Boolean, None), - )) + Ok((intrinsic_function, type_engine.id_of_bool())) } /// Signature: `__assert_is_str_array()` @@ -793,7 +693,7 @@ fn type_check_assert_is_str_array( EnforceTypeArguments::Yes, None, ) - .unwrap_or_else(|err| type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None)); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); let intrinsic_function = ty::TyIntrinsicFunctionKind { kind, arguments: vec![], @@ -805,10 +705,7 @@ fn type_check_assert_is_str_array( }], span, }; - Ok(( - intrinsic_function, - type_engine.insert(engines, TypeInfo::Tuple(vec![]), None), - )) + Ok((intrinsic_function, type_engine.id_of_unit())) } fn type_check_to_str_array( @@ -832,17 +729,9 @@ fn type_check_to_str_array( match &arg.kind { ExpressionKind::Literal(Literal::String(s)) => { - let literal_length = s.as_str().len(); - let l = Length::new(literal_length, s.clone()); - let t = TypeInfo::StringArray(l); - let span = arg.span.clone(); - let mut ctx = ctx.by_ref().with_type_annotation(type_engine.insert( - engines, - TypeInfo::Unknown, - None, - )); + let mut ctx = ctx.by_ref().with_type_annotation(type_engine.new_unknown()); let new_type = ty::TyExpression::type_check(handler, ctx.by_ref(), arg)?; Ok(( @@ -852,7 +741,7 @@ fn type_check_to_str_array( type_arguments: vec![], span, }, - type_engine.insert(engines, t, None), + type_engine.insert_string_array_without_annotations(engines, s.as_str().len()), )) } _ => Err(handler.emit_err(CompileError::ExpectedStringLiteral { @@ -880,7 +769,6 @@ fn type_check_cmp( 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 { @@ -889,9 +777,7 @@ fn type_check_cmp( span, })); } - let mut ctx = - ctx.by_ref() - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + let mut ctx = ctx.by_ref().with_type_annotation(type_engine.new_unknown()); let lhs = &arguments[0]; let lhs = ty::TyExpression::type_check(handler, ctx.by_ref(), lhs)?; @@ -926,7 +812,7 @@ fn type_check_cmp( type_arguments: vec![], span, }, - type_engine.insert(engines, TypeInfo::Boolean, None), + type_engine.id_of_bool(), )) } @@ -964,19 +850,11 @@ fn type_check_gtf( } // Type check the first argument which is the index - let mut ctx = ctx.by_ref().with_type_annotation(type_engine.insert( - engines, - TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), - None, - )); + let mut ctx = ctx.by_ref().with_type_annotation(type_engine.id_of_u64()); let index = ty::TyExpression::type_check(handler, ctx.by_ref(), &arguments[0])?; // Type check the second argument which is the tx field ID - let mut ctx = ctx.by_ref().with_type_annotation(type_engine.insert( - engines, - TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), - None, - )); + let mut ctx = ctx.by_ref().with_type_annotation(type_engine.id_of_u64()); let tx_field_id = ty::TyExpression::type_check(handler, ctx.by_ref(), &arguments[1])?; let targ = type_arguments[0].clone(); @@ -993,7 +871,7 @@ fn type_check_gtf( EnforceTypeArguments::Yes, None, ) - .unwrap_or_else(|err| type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None)); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); Ok(( ty::TyIntrinsicFunctionKind { @@ -1022,7 +900,6 @@ fn type_check_addr_of( span: Span, ) -> Result<(ty::TyIntrinsicFunctionKind, TypeId), ErrorEmitted> { let type_engine = ctx.engines.te(); - let engines = ctx.engines(); if arguments.len() != 1 { return Err(handler.emit_err(CompileError::IntrinsicIncorrectNumArgs { @@ -1033,7 +910,7 @@ fn type_check_addr_of( } let ctx = ctx .with_help_text("") - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + .with_type_annotation(type_engine.new_unknown()); let exp = ty::TyExpression::type_check(handler, ctx, &arguments[0])?; let copy_type_info = type_engine .to_typeinfo(exp.return_type, &span) @@ -1053,8 +930,7 @@ fn type_check_addr_of( type_arguments: vec![], span, }; - let return_type = type_engine.insert(engines, TypeInfo::RawUntypedPtr, None); - Ok((intrinsic_function, return_type)) + Ok((intrinsic_function, type_engine.id_of_raw_ptr())) } /// Signature: `__state_load_clear(key: b256, slots: u64) -> bool` @@ -1069,7 +945,6 @@ fn type_check_state_clear( 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 { @@ -1082,7 +957,7 @@ fn type_check_state_clear( // `key` argument let mut ctx = ctx .with_help_text("") - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + .with_type_annotation(type_engine.new_unknown()); let key_exp = ty::TyExpression::type_check(handler, ctx.by_ref(), &arguments[0])?; let key_ty = type_engine .to_typeinfo(key_exp.return_type, &span) @@ -1100,11 +975,7 @@ fn type_check_state_clear( } // `slots` argument - let mut ctx = ctx.with_type_annotation(type_engine.insert( - engines, - TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), - None, - )); + let mut ctx = ctx.with_type_annotation(type_engine.id_of_u64()); let number_of_slots_exp = ty::TyExpression::type_check(handler, ctx.by_ref(), &arguments[1])?; // Typed intrinsic @@ -1114,8 +985,7 @@ fn type_check_state_clear( type_arguments: vec![], span, }; - let return_type = type_engine.insert(engines, TypeInfo::Boolean, None); - Ok((intrinsic_function, return_type)) + Ok((intrinsic_function, type_engine.id_of_bool())) } /// Signature: `__state_load_word(key: b256) -> u64` @@ -1140,7 +1010,7 @@ fn type_check_state_load_word( } let ctx = ctx .with_help_text("") - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + .with_type_annotation(type_engine.new_unknown()); let exp = ty::TyExpression::type_check(handler, ctx, &arguments[0])?; let key_ty = type_engine .to_typeinfo(exp.return_type, &span) @@ -1159,12 +1029,7 @@ fn type_check_state_load_word( type_arguments: vec![], span, }; - let return_type = type_engine.insert( - engines, - TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), - None, - ); - Ok((intrinsic_function, return_type)) + Ok((intrinsic_function, type_engine.id_of_u64())) } /// Signature: `__state_store_word(key: b256, val: u64) -> bool` @@ -1198,7 +1063,7 @@ fn type_check_state_store_word( } let mut ctx = ctx .with_help_text("") - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + .with_type_annotation(type_engine.new_unknown()); let key_exp = ty::TyExpression::type_check(handler, ctx.by_ref(), &arguments[0])?; let key_ty = type_engine .to_typeinfo(key_exp.return_type, &span) @@ -1214,15 +1079,11 @@ fn type_check_state_store_word( hint: "Argument type must be B256, a key into the state storage".to_string(), })); } - let mut ctx = ctx.with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + let mut ctx = ctx.with_type_annotation(type_engine.new_unknown()); let val_exp = ty::TyExpression::type_check(handler, ctx.by_ref(), &arguments[1])?; - let ctx = ctx.with_type_annotation(type_engine.insert( - engines, - TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), - None, - )); + let ctx = ctx.with_type_annotation(type_engine.id_of_u64()); let type_argument = type_arguments.first().map(|targ| { - let ctx = ctx.with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + let ctx = ctx.with_type_annotation(type_engine.new_unknown()); let initial_type_info = type_engine .to_typeinfo(targ.type_id, &targ.span) .map_err(|e| handler.emit_err(e.into())) @@ -1236,7 +1097,7 @@ fn type_check_state_store_word( EnforceTypeArguments::Yes, None, ) - .unwrap_or_else(|err| type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None)); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); TypeArgument { type_id, initial_type_id, @@ -1250,8 +1111,7 @@ fn type_check_state_store_word( type_arguments: type_argument.map_or(vec![], |ta| vec![ta]), span, }; - let return_type = type_engine.insert(engines, TypeInfo::Boolean, None); - Ok((intrinsic_function, return_type)) + Ok((intrinsic_function, type_engine.id_of_bool())) } /// Signature: `__state_load_quad(key: b256, ptr: raw_ptr, slots: u64)` @@ -1292,7 +1152,7 @@ fn type_check_state_quad( } let mut ctx = ctx .with_help_text("") - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + .with_type_annotation(type_engine.new_unknown()); let key_exp = ty::TyExpression::type_check(handler, ctx.by_ref(), &arguments[0])?; let key_ty = type_engine .to_typeinfo(key_exp.return_type, &span) @@ -1308,16 +1168,12 @@ fn type_check_state_quad( hint: "Argument type must be B256, a key into the state storage".to_string(), })); } - let mut ctx = ctx.with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + let mut ctx = ctx.with_type_annotation(type_engine.new_unknown()); let val_exp = ty::TyExpression::type_check(handler, ctx.by_ref(), &arguments[1])?; - let mut ctx = ctx.with_type_annotation(type_engine.insert( - engines, - TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), - None, - )); + let mut ctx = ctx.with_type_annotation(type_engine.id_of_u64()); let number_of_slots_exp = ty::TyExpression::type_check(handler, ctx.by_ref(), &arguments[2])?; let type_argument = type_arguments.first().map(|targ| { - let ctx = ctx.with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + let ctx = ctx.with_type_annotation(type_engine.new_unknown()); let initial_type_info = type_engine .to_typeinfo(targ.type_id, &targ.span) .map_err(|e| handler.emit_err(e.into())) @@ -1331,7 +1187,7 @@ fn type_check_state_quad( EnforceTypeArguments::Yes, None, ) - .unwrap_or_else(|err| type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None)); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); TypeArgument { type_id, initial_type_id, @@ -1345,8 +1201,7 @@ fn type_check_state_quad( type_arguments: type_argument.map_or(vec![], |ta| vec![ta]), span, }; - let return_type = type_engine.insert(engines, TypeInfo::Boolean, None); - Ok((intrinsic_function, return_type)) + Ok((intrinsic_function, type_engine.id_of_bool())) } /// Signature: `__log(val: T)` @@ -1360,7 +1215,6 @@ fn type_check_log( span: Span, ) -> Result<(ty::TyIntrinsicFunctionKind, TypeId), ErrorEmitted> { let type_engine = ctx.engines.te(); - let engines = ctx.engines(); if arguments.len() != 1 { return Err(handler.emit_err(CompileError::IntrinsicIncorrectNumArgs { @@ -1372,7 +1226,7 @@ fn type_check_log( let ctx = ctx .by_ref() .with_help_text("") - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + .with_type_annotation(type_engine.new_unknown()); let exp = ty::TyExpression::type_check(handler, ctx, &arguments[0])?; let intrinsic_function = ty::TyIntrinsicFunctionKind { kind, @@ -1380,8 +1234,7 @@ fn type_check_log( type_arguments: vec![], span, }; - let return_type = type_engine.insert(engines, TypeInfo::Tuple(vec![]), None); - Ok((intrinsic_function, return_type)) + Ok((intrinsic_function, type_engine.id_of_unit())) } /// Signature: `__add(lhs: T, rhs: T) -> T` @@ -1420,7 +1273,6 @@ fn type_check_arith_binary_op( 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 { @@ -1437,7 +1289,7 @@ fn type_check_arith_binary_op( })); } - let return_type = type_engine.insert(engines, TypeInfo::Numeric, None); + let return_type = type_engine.new_numeric(); let mut ctx = ctx .by_ref() .with_type_annotation(return_type) @@ -1485,7 +1337,7 @@ fn type_check_bitwise_binary_op( })); } - let return_type = type_engine.insert(engines, TypeInfo::Unknown, None); + let return_type = type_engine.new_unknown(); let mut ctx = ctx .by_ref() .with_type_annotation(return_type) @@ -1551,7 +1403,7 @@ fn type_check_shift_binary_op( })); } - let return_type = engines.te().insert(engines, TypeInfo::Unknown, None); + let return_type = engines.te().new_unknown(); let lhs = &arguments[0]; let lhs = ty::TyExpression::type_check( handler, @@ -1566,7 +1418,7 @@ fn type_check_shift_binary_op( handler, ctx.by_ref() .with_help_text("Incorrect argument type") - .with_type_annotation(engines.te().insert(engines, TypeInfo::Numeric, None)), + .with_type_annotation(engines.te().new_numeric()), rhs, )?; @@ -1605,7 +1457,6 @@ fn type_check_revert( span: Span, ) -> Result<(ty::TyIntrinsicFunctionKind, TypeId), ErrorEmitted> { let type_engine = ctx.engines.te(); - let engines = ctx.engines(); if arguments.len() != 1 { return Err(handler.emit_err(CompileError::IntrinsicIncorrectNumArgs { @@ -1624,11 +1475,7 @@ fn type_check_revert( } // Type check the argument which is the revert code - let mut ctx = ctx.by_ref().with_type_annotation(type_engine.insert( - engines, - TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), - None, - )); + let mut ctx = ctx.by_ref().with_type_annotation(type_engine.id_of_u64()); let revert_code = ty::TyExpression::type_check(handler, ctx.by_ref(), &arguments[0])?; Ok(( @@ -1638,7 +1485,7 @@ fn type_check_revert( type_arguments: vec![], span, }, - type_engine.insert(engines, TypeInfo::Never, None), + type_engine.id_of_never(), )) } @@ -1653,7 +1500,6 @@ fn type_check_jmp_mem( span: Span, ) -> Result<(ty::TyIntrinsicFunctionKind, TypeId), ErrorEmitted> { let type_engine = ctx.engines.te(); - let engines = ctx.engines(); if !arguments.is_empty() { return Err(handler.emit_err(CompileError::IntrinsicIncorrectNumArgs { @@ -1678,7 +1524,7 @@ fn type_check_jmp_mem( type_arguments: vec![], span, }, - type_engine.insert(engines, TypeInfo::Never, None), + type_engine.id_of_never(), )) } @@ -1728,11 +1574,9 @@ fn type_check_ptr_ops( EnforceTypeArguments::No, None, ) - .unwrap_or_else(|err| type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None)); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); - let mut ctx = - ctx.by_ref() - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + let mut ctx = ctx.by_ref().with_type_annotation(type_engine.new_unknown()); let lhs = &arguments[0]; let lhs = ty::TyExpression::type_check(handler, ctx.by_ref(), lhs)?; @@ -1754,11 +1598,7 @@ fn type_check_ptr_ops( let ctx = ctx .by_ref() .with_help_text("Incorrect argument type") - .with_type_annotation(type_engine.insert( - engines, - TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), - None, - )); + .with_type_annotation(type_engine.id_of_u64()); let rhs = ty::TyExpression::type_check(handler, ctx, rhs)?; Ok(( @@ -1813,7 +1653,7 @@ fn type_check_smo( let ctx = ctx .by_ref() .with_help_text("") - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + .with_type_annotation(type_engine.new_unknown()); let initial_type_info = type_engine .to_typeinfo(targ.type_id, &targ.span) .map_err(|e| handler.emit_err(e.into())) @@ -1827,7 +1667,7 @@ fn type_check_smo( EnforceTypeArguments::Yes, None, ) - .unwrap_or_else(|err| type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None)); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); TypeArgument { type_id, initial_type_id, @@ -1837,9 +1677,7 @@ fn type_check_smo( }); // Type check the first argument which is the recipient address, so it has to be a `b256`. - let mut ctx = - ctx.by_ref() - .with_type_annotation(type_engine.insert(engines, TypeInfo::B256, None)); + let mut ctx = ctx.by_ref().with_type_annotation(type_engine.id_of_b256()); let recipient = ty::TyExpression::type_check(handler, ctx.by_ref(), &arguments[0])?; // Type check the second argument which is the data, which can be anything. If a type @@ -1847,18 +1685,12 @@ fn type_check_smo( let mut ctx = ctx.by_ref().with_type_annotation( type_argument .clone() - .map_or(type_engine.insert(engines, TypeInfo::Unknown, None), |ta| { - ta.type_id - }), + .map_or(type_engine.new_unknown(), |ta| ta.type_id), ); let data = ty::TyExpression::type_check(handler, ctx.by_ref(), &arguments[1])?; // 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), - None, - )); + let mut ctx = ctx.by_ref().with_type_annotation(type_engine.id_of_u64()); let coins = ty::TyExpression::type_check(handler, ctx.by_ref(), &arguments[2])?; Ok(( @@ -1868,7 +1700,7 @@ fn type_check_smo( type_arguments: type_argument.map_or(vec![], |ta| vec![ta]), span, }, - type_engine.insert(engines, TypeInfo::Tuple(vec![]), None), + type_engine.id_of_unit(), )) } @@ -1885,7 +1717,6 @@ fn type_check_contract_ret( 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 { @@ -1909,13 +1740,11 @@ fn type_check_contract_ret( let ctx = ctx .by_ref() .with_help_text("") - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + .with_type_annotation(type_engine.new_unknown()); ty::TyExpression::type_check(handler, ctx, x) }) .collect::, _>>()?; - let t = ctx.engines.te().insert(ctx.engines, TypeInfo::Never, None); - Ok(( ty::TyIntrinsicFunctionKind { kind: Intrinsic::ContractRet, @@ -1923,7 +1752,7 @@ fn type_check_contract_ret( type_arguments: vec![], span, }, - t, + ctx.engines.te().id_of_never(), )) } @@ -1939,17 +1768,11 @@ fn type_check_contract_call( span: Span, ) -> Result<(ty::TyIntrinsicFunctionKind, TypeId), ErrorEmitted> { let type_engine = ctx.engines.te(); - let engines = ctx.engines(); if !type_arguments.is_empty() { return Err(handler.emit_err(CompileError::TypeArgumentsNotAllowed { span })); } - let return_type_id = ctx - .engines - .te() - .insert(ctx.engines, TypeInfo::Tuple(vec![]), None); - // Arguments let arguments: Vec = arguments .iter() @@ -1957,7 +1780,7 @@ fn type_check_contract_call( let ctx = ctx .by_ref() .with_help_text("") - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + .with_type_annotation(type_engine.new_unknown()); ty::TyExpression::type_check(handler, ctx, x) }) .collect::, _>>()?; @@ -1969,5 +1792,5 @@ fn type_check_contract_call( span, }; - Ok((intrinsic_function, return_type_id)) + Ok((intrinsic_function, type_engine.id_of_unit())) } diff --git a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/instantiate.rs b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/instantiate.rs index 31306c2f247..792de9d779b 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/instantiate.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/instantiate.rs @@ -1,5 +1,5 @@ use sway_error::handler::{ErrorEmitted, Handler}; -use sway_types::{integer_bits::IntegerBits, Ident, Span}; +use sway_types::{Ident, Span}; use crate::{ language::{ty, LazyOp, Literal}, @@ -7,7 +7,7 @@ use crate::{ typed_expression::{instantiate_lazy_operator, instantiate_tuple_index_access}, TypeCheckContext, }, - Engines, TypeId, TypeInfo, + Engines, TypeId, }; /// Simplifies instantiation of desugared code in the match expression and match arms. @@ -23,19 +23,11 @@ pub(super) struct Instantiate { impl Instantiate { pub(super) fn new(engines: &Engines, span: Span) -> Self { let type_engine = engines.te(); - let u64_type = type_engine.insert( - engines, - TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), - None, - ); - let boolean_type = type_engine.insert(engines, TypeInfo::Boolean, None); - let revert_type = type_engine.insert(engines, TypeInfo::Never, None); - Self { span, - u64_type, - boolean_type, - revert_type, + u64_type: type_engine.id_of_u64(), + boolean_type: type_engine.id_of_bool(), + revert_type: type_engine.id_of_never(), } } diff --git a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/matcher.rs b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/matcher.rs index 39cd872146d..3f7856f4854 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/matcher.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/matcher.rs @@ -12,7 +12,7 @@ use crate::{ }, TypeCheckContext, }, - Ident, TypeId, TypeInfo, UnifyCheck, + Ident, TypeId, UnifyCheck, }; use sway_error::{ @@ -20,7 +20,7 @@ use sway_error::{ handler::{ErrorEmitted, Handler}, }; -use sway_types::{integer_bits::IntegerBits, span::Span, Named, Spanned}; +use sway_types::{span::Span, Named, Spanned}; /// A single requirement in the form ` == ` that has to be /// fulfilled for the match arm to match. @@ -492,20 +492,12 @@ fn match_enum( expression: ty::TyExpressionVariant::EnumTag { exp: Box::new(exp.clone()), }, - return_type: type_engine.insert( - ctx.engines, - TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), - None, - ), + return_type: type_engine.id_of_u64(), span: exp.span.clone(), }, ty::TyExpression { expression: ty::TyExpressionVariant::Literal(Literal::U64(variant.tag as u64)), - return_type: type_engine.insert( - ctx.engines, - TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), - None, - ), + return_type: type_engine.id_of_u64(), span: exp.span.clone(), }, ); diff --git a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_match_branch.rs b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_match_branch.rs index 7e110b86e49..e00b968c4ce 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_match_branch.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_match_branch.rs @@ -17,7 +17,7 @@ use crate::{ ty::{self, MatchBranchCondition, MatchedOrVariantIndexVars, TyExpression}, }, semantic_analysis::*, - Engines, TypeArgument, TypeInfo, UnifyCheck, + Engines, TypeInfo, UnifyCheck, }; use super::{instantiate::Instantiate, matcher::matcher, ReqDeclTree}; @@ -619,7 +619,7 @@ fn instantiate_branch_condition_result_var_declarations_and_matched_or_variant_i ) -> Result<(VarDecl, Vec), ErrorEmitted> { let type_engine = ctx.engines.te(); // At this point we have the guarantee that we have: - // - exactly the same variables in each OR variant + // - exactly the same variables in each of the OR variants // - that variables of the same name are of the same type // - that we do not have duplicates in variable names inside of alternatives @@ -645,18 +645,10 @@ fn instantiate_branch_condition_result_var_declarations_and_matched_or_variant_i // All variants have same variable types and names, thus we pick them from the first alternative. let tuple_field_types = carry_over_vars[0] .iter() - .map(|(_, var_body)| TypeArgument { - type_id: var_body.return_type, - initial_type_id: var_body.return_type, - span: var_body.span.clone(), // Although not needed, this span can be mapped to var declaration. - call_path_tree: None, - }) + .map(|(_, var_body)| var_body.return_type) .collect(); - let tuple_type = type_engine.insert( - ctx.engines, - TypeInfo::Tuple(tuple_field_types), - instantiate.dummy_span().source_id(), - ); + let tuple_type = + type_engine.insert_tuple_without_annotations(ctx.engines, tuple_field_types); let variable_names = carry_over_vars[0] .iter() .map(|(ident, _)| ident.clone()) diff --git a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_match_expression.rs b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_match_expression.rs index bd271a7f638..98168776ac2 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_match_expression.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_match_expression.rs @@ -12,7 +12,7 @@ use crate::{ ast_node::expression::typed_expression::instantiate_if_expression, expression::match_expression::typed::instantiate::Instantiate, TypeCheckContext, }, - CompileError, TypeId, TypeInfo, + CompileError, TypeEngine, TypeId, TypeInfo, }; use std::{collections::BTreeMap, ops::ControlFlow}; use sway_error::handler::{ErrorEmitted, Handler}; @@ -32,19 +32,19 @@ struct Trie { nodes: Vec, } -fn revert(never_type_id: TypeId, u64_type_id: TypeId) -> TyExpression { +fn revert(type_engine: &TypeEngine) -> TyExpression { TyExpression { expression: TyExpressionVariant::IntrinsicFunction(TyIntrinsicFunctionKind { kind: sway_ast::Intrinsic::Revert, arguments: vec![TyExpression { expression: TyExpressionVariant::Literal(crate::language::Literal::U64(17)), - return_type: u64_type_id, + return_type: type_engine.id_of_u64(), span: Span::dummy(), }], type_arguments: vec![], span: Span::dummy(), }), - return_type: never_type_id, + return_type: type_engine.id_of_never(), span: Span::dummy(), } } @@ -124,18 +124,7 @@ impl ty::TyMatchExpression { &self, mut ctx: TypeCheckContext<'_>, ) -> Result { - let never_type_id = ctx.engines.te().insert(ctx.engines, TypeInfo::Never, None); - - let u64_type_id = ctx.engines.te().insert( - ctx.engines, - TypeInfo::UnsignedInteger(sway_types::integer_bits::IntegerBits::SixtyFour), - None, - ); - - let bool_type_id = ctx - .engines - .te() - .insert(ctx.engines, TypeInfo::Boolean, None); + let type_engine = ctx.engines.te(); let branch_return_type_id = self .branches @@ -163,7 +152,7 @@ impl ty::TyMatchExpression { .filter(|x| x.condition.is_none()) .map(|x| x.result.clone()) .next() - .unwrap_or_else(|| revert(never_type_id, u64_type_id)); + .unwrap_or_else(|| revert(type_engine)); // All the match string slices, ignoring the wildcard let match_arms_string_slices = self @@ -246,7 +235,7 @@ impl ty::TyMatchExpression { expression: TyExpressionVariant::Literal( crate::language::Literal::U64(k as u64), ), - return_type: u64_type_id, + return_type: type_engine.id_of_u64(), span: Span::dummy(), }), }, @@ -285,7 +274,6 @@ impl ty::TyMatchExpression { .generate_radix_tree_checks( ctx.by_ref(), matched_value, - u64_type_id, branch_return_type_id, wildcard_return_expr.clone(), trie, @@ -297,7 +285,7 @@ impl ty::TyMatchExpression { expression: TyExpressionVariant::IfExp { condition: Box::new(TyExpression { expression, - return_type: bool_type_id, + return_type: type_engine.id_of_bool(), span: self.span.clone(), }), then: Box::new(then_node), @@ -373,28 +361,18 @@ impl ty::TyMatchExpression { &self, ctx: TypeCheckContext<'_>, matched_value: &TyExpression, - u64_type_id: TypeId, branch_return_type_id: TypeId, wildcard_return_expr: TyExpression, trie: Trie, packed_strings: &str, ) -> Result { - //generate code - let bool_type_id = ctx - .engines - .te() - .insert(ctx.engines, TypeInfo::Boolean, None); - - let string_slice_type_id = - ctx.engines - .te() - .insert(ctx.engines, TypeInfo::StringSlice, None); + let type_engine = ctx.engines.te(); let packed_strings_expr = TyExpression { expression: TyExpressionVariant::Literal(crate::language::Literal::String( Span::from_string(packed_strings.to_string()), )), - return_type: string_slice_type_id, + return_type: type_engine.id_of_string_slice(), span: Span::dummy(), }; @@ -405,8 +383,8 @@ impl ty::TyMatchExpression { &trie.nodes, 0, 0, - bool_type_id, - u64_type_id, + type_engine.id_of_bool(), + type_engine.id_of_u64(), branch_return_type_id, 1, wildcard_return_expr, diff --git a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_scrutinee.rs b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_scrutinee.rs index fddb0ee7b21..f81916fa337 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_scrutinee.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_scrutinee.rs @@ -3,7 +3,7 @@ use sway_error::{ error::{CompileError, StructFieldUsageContext}, handler::{ErrorEmitted, Handler}, }; -use sway_types::{BaseIdent, Ident, Span, Spanned}; +use sway_types::{Ident, Span, Spanned}; use crate::{ decl_engine::{DeclEngineGetParsedDeclId, DeclEngineInsert}, @@ -26,8 +26,6 @@ impl TyScrutinee { let engines = ctx.engines(); match scrutinee { Scrutinee::Or { elems, span } => { - let type_id = type_engine.insert(engines, TypeInfo::Unknown, None); - let mut typed_elems = Vec::with_capacity(elems.len()); for scrutinee in elems { typed_elems.push(ty::TyScrutinee::type_check( @@ -38,28 +36,22 @@ impl TyScrutinee { } let typed_scrutinee = ty::TyScrutinee { variant: ty::TyScrutineeVariant::Or(typed_elems), - type_id, + type_id: type_engine.new_unknown(), span, }; Ok(typed_scrutinee) } Scrutinee::CatchAll { span } => { - let type_id = type_engine.insert(engines, TypeInfo::Unknown, None); - let dummy_type_param = TypeParameter { - type_id, - initial_type_id: type_id, - name_ident: BaseIdent::new_with_override("_".into(), span.clone()), - trait_constraints: vec![], - trait_constraints_span: Span::dummy(), - is_from_parent: false, - }; let typed_scrutinee = ty::TyScrutinee { variant: ty::TyScrutineeVariant::CatchAll, - type_id: type_engine.insert( - engines, - TypeInfo::Placeholder(dummy_type_param), - span.source_id(), - ), + // The `span` will mostly point to a "_" in code. However, match expressions + // are heavily used in code generation, e.g., to generate code for contract + // function selection in the `__entry` and sometimes the span does not point + // to a "_". But it is always in the code in which the match expression is. + type_id: type_engine.new_placeholder(TypeParameter::new_placeholder( + type_engine.new_unknown(), + span.clone(), + )), span, }; Ok(typed_scrutinee) @@ -207,7 +199,7 @@ fn type_check_variable( // appropriate helpful errors, depending on the exact usage of that configurable. _ => ty::TyScrutinee { variant: ty::TyScrutineeVariant::Variable(name), - type_id: type_engine.insert(ctx.engines(), TypeInfo::Unknown, None), + type_id: type_engine.new_unknown(), span, }, }; @@ -425,11 +417,7 @@ fn type_check_struct( decl_engine.get_parsed_decl_id(&struct_id).as_ref(), ); let typed_scrutinee = ty::TyScrutinee { - type_id: type_engine.insert( - ctx.engines(), - TypeInfo::Struct(*struct_ref.id()), - struct_ref.span().source_id(), - ), + type_id: type_engine.insert_struct(engines, *struct_ref.id()), span, variant: ty::TyScrutineeVariant::StructScrutinee { struct_ref, @@ -552,11 +540,7 @@ fn type_check_enum( value: Box::new(typed_value), instantiation_call_path: call_path, }, - type_id: type_engine.insert( - engines, - TypeInfo::Enum(*enum_ref.id()), - enum_ref.span().source_id(), - ), + type_id: type_engine.insert_enum(engines, *enum_ref.id()), span, }; @@ -581,20 +565,17 @@ fn type_check_tuple( }, ); } - let type_id = type_engine.insert( + let type_id = type_engine.insert_tuple( engines, - TypeInfo::Tuple( - typed_elems - .iter() - .map(|x| TypeArgument { - type_id: x.type_id, - initial_type_id: x.type_id, - span: span.clone(), - call_path_tree: None, - }) - .collect(), - ), - span.source_id(), + typed_elems + .iter() + .map(|elem| TypeArgument { + type_id: elem.type_id, + initial_type_id: elem.type_id, + span: elem.span.clone(), + call_path_tree: None, + }) + .collect(), ); let typed_scrutinee = ty::TyScrutinee { variant: ty::TyScrutineeVariant::Tuple(typed_elems), diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs index 229f38dd9c2..3d6204c46ce 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs @@ -355,11 +355,7 @@ impl ty::TyExpression { ) } ExpressionKind::LazyOperator(LazyOperatorExpression { op, lhs, rhs }) => { - let ctx = ctx.by_ref().with_type_annotation(type_engine.insert( - engines, - TypeInfo::Boolean, - None, - )); + let ctx = ctx.by_ref().with_type_annotation(type_engine.id_of_bool()); Self::type_check_lazy_operator(handler, ctx, op.clone(), lhs, rhs, span) } ExpressionKind::CodeBlock(contents) => { @@ -477,7 +473,7 @@ impl ty::TyExpression { ExpressionKind::ArrayIndex(ArrayIndexExpression { prefix, index }) => { let ctx = ctx .by_ref() - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)) + .with_type_annotation(type_engine.new_unknown()) .with_help_text(""); Self::type_check_array_index(handler, ctx, prefix, index, span) } @@ -488,7 +484,7 @@ impl ty::TyExpression { }) => { let ctx = ctx .by_ref() - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)) + .with_type_annotation(type_engine.new_unknown()) .with_help_text(""); Self::type_check_storage_access( handler, @@ -519,7 +515,7 @@ impl ty::TyExpression { ExpressionKind::Break => { let expr = ty::TyExpression { expression: ty::TyExpressionVariant::Break, - return_type: type_engine.insert(engines, TypeInfo::Never, None), + return_type: type_engine.id_of_never(), span, }; Ok(expr) @@ -527,7 +523,7 @@ impl ty::TyExpression { ExpressionKind::Continue => { let expr = ty::TyExpression { expression: ty::TyExpressionVariant::Continue, - return_type: type_engine.insert(engines, TypeInfo::Never, None), + return_type: type_engine.id_of_never(), span, }; Ok(expr) @@ -563,7 +559,7 @@ impl ty::TyExpression { .unwrap_or_else(|err| ty::TyExpression::error(err, expr_span, engines)); let typed_expr = ty::TyExpression { expression: ty::TyExpressionVariant::Return(Box::new(expr)), - return_type: type_engine.insert(engines, TypeInfo::Never, None), + return_type: type_engine.id_of_never(), span, }; Ok(typed_expr) @@ -593,7 +589,7 @@ impl ty::TyExpression { EnforceTypeArguments::No, None, ) - .unwrap_or_else(|err| type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None)); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); // Literals of type Numeric can now be resolved if typed_expression.return_type is // an UnsignedInteger or a Numeric @@ -620,20 +616,19 @@ impl ty::TyExpression { fn type_check_literal(engines: &Engines, lit: Literal, span: Span) -> ty::TyExpression { let type_engine = engines.te(); let return_type = match &lit { - Literal::String(_) => TypeInfo::StringSlice, - Literal::Numeric(_) => TypeInfo::Numeric, - Literal::U8(_) => TypeInfo::UnsignedInteger(IntegerBits::Eight), - Literal::U16(_) => TypeInfo::UnsignedInteger(IntegerBits::Sixteen), - Literal::U32(_) => TypeInfo::UnsignedInteger(IntegerBits::ThirtyTwo), - Literal::U64(_) => TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), - Literal::U256(_) => TypeInfo::UnsignedInteger(IntegerBits::V256), - Literal::Boolean(_) => TypeInfo::Boolean, - Literal::B256(_) => TypeInfo::B256, + Literal::String(_) => type_engine.id_of_string_slice(), + Literal::Numeric(_) => type_engine.new_numeric(), + Literal::U8(_) => type_engine.id_of_u8(), + Literal::U16(_) => type_engine.id_of_u16(), + Literal::U32(_) => type_engine.id_of_u32(), + Literal::U64(_) => type_engine.id_of_u64(), + Literal::U256(_) => type_engine.id_of_u256(), + Literal::Boolean(_) => type_engine.id_of_bool(), + Literal::B256(_) => type_engine.id_of_b256(), }; - let id = type_engine.insert(engines, return_type, span.source_id()); ty::TyExpression { expression: ty::TyExpressionVariant::Literal(lit), - return_type: id, + return_type, span, } } @@ -782,7 +777,6 @@ impl ty::TyExpression { span: Span, ) -> Result { let type_engine = ctx.engines.te(); - let engines = ctx.engines(); let (typed_block, block_return_type) = match ty::TyCodeBlock::type_check(handler, ctx.by_ref(), contents, false) { @@ -790,10 +784,7 @@ impl ty::TyExpression { let (block_type, _span) = TyCodeBlock::compute_return_type_and_span(&ctx, &res); (res, block_type) } - Err(_err) => ( - ty::TyCodeBlock::default(), - type_engine.insert(engines, TypeInfo::Tuple(Vec::new()), None), - ), + Err(_err) => (ty::TyCodeBlock::default(), type_engine.id_of_unit()), }; let exp = ty::TyExpression { @@ -820,7 +811,7 @@ impl ty::TyExpression { let ctx = ctx .by_ref() .with_help_text("The condition of an if expression must be a boolean expression.") - .with_type_annotation(type_engine.insert(engines, TypeInfo::Boolean, None)); + .with_type_annotation(type_engine.id_of_bool()); ty::TyExpression::type_check(handler, ctx, &condition) .unwrap_or_else(|err| ty::TyExpression::error(err, condition.span(), engines)) }; @@ -883,7 +874,7 @@ impl ty::TyExpression { let ctx = ctx .by_ref() .with_help_text("") - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + .with_type_annotation(type_engine.new_unknown()); ty::TyExpression::type_check(handler, ctx, value) .unwrap_or_else(|err| ty::TyExpression::error(err, value.span().clone(), engines)) }; @@ -1071,20 +1062,27 @@ impl ty::TyExpression { // 2. Check that initialized registers are not reassigned in the `asm` block. check_asm_block_validity(handler, &asm, &ctx)?; - let asm_span = asm + // Take the span of the returns register, or as a fallback, the span of the + // whole ASM block. + let asm_returns_span = asm .returns .clone() .map(|x| x.1) .unwrap_or_else(|| asm.whole_block_span.clone()); + let return_type = ctx .resolve_type( handler, - type_engine.insert(engines, asm.return_type.clone(), asm_span.source_id()), - &asm_span, + type_engine.insert( + engines, + asm.return_type.clone(), + asm_returns_span.source_id(), + ), + &asm_returns_span, EnforceTypeArguments::No, None, ) - .unwrap_or_else(|err| type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None)); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); // type check the initializers let typed_registers = asm @@ -1095,9 +1093,10 @@ impl ty::TyExpression { |AsmRegisterDeclaration { name, initializer }| ty::TyAsmRegisterDeclaration { name, initializer: initializer.map(|initializer| { - let ctx = ctx.by_ref().with_help_text("").with_type_annotation( - type_engine.insert(engines, TypeInfo::Unknown, None), - ); + let ctx = ctx + .by_ref() + .with_help_text("") + .with_type_annotation(type_engine.new_unknown()); ty::TyExpression::type_check(handler, ctx, &initializer).unwrap_or_else( |err| ty::TyExpression::error(err, initializer.span(), engines), @@ -1132,7 +1131,7 @@ impl ty::TyExpression { let mut ctx = ctx .with_help_text("") - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + .with_type_annotation(type_engine.new_unknown()); let parent = ty::TyExpression::type_check(handler, ctx.by_ref(), prefix)?; let exp = instantiate_struct_field_access( handler, @@ -1168,7 +1167,7 @@ impl ty::TyExpression { .as_ref() .map(|field_type_ids| field_type_ids[i].clone()) .unwrap_or_else(|| { - let initial_type_id = type_engine.insert(engines, TypeInfo::Unknown, None); + let initial_type_id = type_engine.new_unknown(); TypeArgument { type_id: initial_type_id, initial_type_id, @@ -1195,11 +1194,7 @@ impl ty::TyExpression { expression: ty::TyExpressionVariant::Tuple { fields: typed_fields, }, - return_type: ctx.engines.te().insert( - engines, - TypeInfo::Tuple(typed_field_types), - span.source_id(), - ), + return_type: ctx.engines.te().insert_tuple(engines, typed_field_types), span, }; Ok(exp) @@ -1297,11 +1292,7 @@ impl ty::TyExpression { .get_parsed_decl_id(&storage_key_struct_decl_id) .as_ref(), ); - access_type = type_engine.insert( - engines, - TypeInfo::Struct(*storage_key_struct_decl_ref.id()), - storage_key_struct_decl_ref.span().source_id(), - ); + access_type = type_engine.insert_struct(engines, *storage_key_struct_decl_ref.id()); Ok(ty::TyExpression { expression: ty::TyExpressionVariant::StorageAccess(storage_access), @@ -1323,7 +1314,7 @@ impl ty::TyExpression { let ctx = ctx .with_help_text("") - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + .with_type_annotation(type_engine.new_unknown()); let parent = ty::TyExpression::type_check(handler, ctx, &prefix)?; let exp = instantiate_tuple_index_access(handler, engines, parent, index, index_span, span)?; @@ -1793,7 +1784,7 @@ impl ty::TyExpression { let ctx = ctx .by_ref() .with_help_text("An address that is being ABI cast must be of type b256") - .with_type_annotation(type_engine.insert(engines, TypeInfo::B256, None)); + .with_type_annotation(type_engine.id_of_b256()); ty::TyExpression::type_check(handler, ctx, address) .unwrap_or_else(|err| ty::TyExpression::error(err, err_span, engines)) }; @@ -1835,13 +1826,10 @@ impl ty::TyExpression { } AbiName::Deferred => { return Ok(ty::TyExpression { - return_type: type_engine.insert( + return_type: type_engine.new_contract_caller( engines, - TypeInfo::ContractCaller { - abi_name: AbiName::Deferred, - address: None, - }, - span.source_id(), + AbiName::Deferred, + None, ), expression: ty::TyExpressionVariant::Tuple { fields: vec![] }, span, @@ -1865,13 +1853,10 @@ impl ty::TyExpression { .. } = &*abi_decl; - let return_type = type_engine.insert( + let return_type = type_engine.new_contract_caller( engines, - TypeInfo::ContractCaller { - abi_name: AbiName::Known(abi_name.clone()), - address: Some(Box::new(address_expr.clone())), - }, - abi_name.span().source_id(), + AbiName::Known(abi_name.clone()), + Some(Box::new(address_expr.clone())), ); // Retrieve the interface surface for this abi. @@ -1961,25 +1946,13 @@ impl ty::TyExpression { let engines = ctx.engines(); if contents.is_empty() { - let elem_type = type_engine.insert(engines, TypeInfo::Unknown, None); + let elem_type = type_engine.new_unknown(); return Ok(ty::TyExpression { expression: ty::TyExpressionVariant::Array { elem_type, contents: Vec::new(), }, - return_type: type_engine.insert( - engines, - TypeInfo::Array( - TypeArgument { - type_id: elem_type, - span: Span::dummy(), - call_path_tree: None, - initial_type_id: elem_type, - }, - Length::new(0, Span::dummy()), - ), - None, - ), + return_type: type_engine.insert_array_without_annotations(engines, elem_type, 0), span, }); }; @@ -2036,25 +2009,13 @@ impl ty::TyExpression { }; let elem_type = type_engine.insert(engines, initial_type.clone(), None); - let array_count = typed_contents.len(); + let length = typed_contents.len(); let expr = ty::TyExpression { expression: ty::TyExpressionVariant::Array { elem_type, contents: typed_contents, }, - return_type: type_engine.insert( - engines, - TypeInfo::Array( - TypeArgument { - type_id: elem_type, - span: Span::dummy(), - call_path_tree: None, - initial_type_id: elem_type, - }, - Length::new(array_count, Span::dummy()), - ), - None, - ), + return_type: type_engine.insert_array_without_annotations(engines, elem_type, length), span, }; @@ -2079,7 +2040,7 @@ impl ty::TyExpression { let ctx = ctx .by_ref() .with_help_text("") - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + .with_type_annotation(type_engine.new_unknown()); ty::TyExpression::type_check(handler, ctx, prefix)? }); @@ -2126,10 +2087,9 @@ impl ty::TyExpression { }; let index_te = { - let type_info_u64 = TypeInfo::UnsignedInteger(IntegerBits::SixtyFour); let ctx = ctx .with_help_text("Array index must be of type \"u64\".") - .with_type_annotation(type_engine.insert(engines, type_info_u64, None)); + .with_type_annotation(type_engine.id_of_u64()); ty::TyExpression::type_check(handler, ctx, index)? }; @@ -2174,17 +2134,16 @@ impl ty::TyExpression { span: Span, ) -> Result { let type_engine = ctx.engines.te(); - let engines = ctx.engines(); let typed_condition = { let ctx = ctx .by_ref() - .with_type_annotation(type_engine.insert(engines, TypeInfo::Boolean, None)) + .with_type_annotation(type_engine.id_of_bool()) .with_help_text("A while loop's loop condition must be a boolean expression."); ty::TyExpression::type_check(handler, ctx, condition)? }; - let unit_ty = type_engine.insert(engines, TypeInfo::Tuple(Vec::new()), None); + let unit_ty = type_engine.id_of_unit(); let mut ctx = ctx.with_type_annotation(unit_ty).with_help_text( "A while loop's loop body cannot implicitly return a value. Try \ assigning it to a mutable variable declared outside of the loop \ @@ -2222,7 +2181,7 @@ impl ty::TyExpression { let engines = ctx.engines(); let mut ctx = ctx - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)) + .with_type_annotation(type_engine.new_unknown()) .with_help_text(""); let (lhs, expected_rhs_type) = match lhs { @@ -2407,15 +2366,10 @@ impl ty::TyExpression { expr = prefix; } ExpressionKind::ArrayIndex(ArrayIndexExpression { prefix, index }) => { - let type_info_u64 = TypeInfo::UnsignedInteger(IntegerBits::SixtyFour); let ctx = ctx .by_ref() .with_help_text("Array index must be of type \"u64\".") - .with_type_annotation(type_engine.insert( - engines, - type_info_u64, - None, - )); + .with_type_annotation(type_engine.id_of_u64()); let typed_index = ty::TyExpression::type_check(handler, ctx, index.as_ref()) .unwrap_or_else(|err| { @@ -2470,7 +2424,7 @@ impl ty::TyExpression { lhs, rhs, })), - return_type: type_engine.insert(engines, TypeInfo::Tuple(Vec::new()), None), + return_type: type_engine.id_of_unit(), span, }) } @@ -2496,7 +2450,7 @@ impl ty::TyExpression { TypeInfo::Ref { referenced_type, .. } => referenced_type.type_id, - _ => type_engine.insert(engines, TypeInfo::Unknown, None), + _ => type_engine.new_unknown(), }; let ctx = ctx @@ -2518,16 +2472,13 @@ impl ty::TyExpression { } }; - let expr_type_argument: TypeArgument = expr.return_type.into(); + let expr_return_type = expr.return_type; let typed_expr = ty::TyExpression { expression: ty::TyExpressionVariant::Ref(Box::new(expr)), - return_type: type_engine.insert( + return_type: type_engine.insert_ref_without_annotations( engines, - TypeInfo::Ref { - to_mutable_value, - referenced_type: expr_type_argument, - }, - None, + to_mutable_value, + expr_return_type, ), span, }; @@ -2601,15 +2552,8 @@ impl ty::TyExpression { // Since `&mut T` coerces into `&T` we always go with a lesser expectation, `&T`. // Thus, `to_mutable_vale` is set to false. let type_annotation = match &*type_engine.get(ctx.type_annotation()) { - TypeInfo::Unknown => type_engine.insert(engines, TypeInfo::Unknown, None), - _ => type_engine.insert( - engines, - TypeInfo::Ref { - to_mutable_value: false, - referenced_type: ctx.type_annotation().into(), - }, - None, - ), + TypeInfo::Unknown => type_engine.new_unknown(), + _ => type_engine.insert_ref_without_annotations(engines, false, ctx.type_annotation()), }; let deref_ctx = ctx @@ -2710,7 +2654,7 @@ impl ty::TyExpression { num.to_string().parse().map(Literal::Numeric).map_err(|e| { Literal::handle_parse_int_error(engines, e, TypeInfo::Numeric, span.clone()) }), - type_engine.insert(engines, TypeInfo::Numeric, None), + type_engine.new_numeric(), ), _ => unreachable!("Unexpected type for integer literals"), }, @@ -2949,19 +2893,9 @@ mod tests { handler, &engines, expr, - engines.te().insert( - &engines, - TypeInfo::Array( - TypeArgument { - type_id: engines.te().insert(&engines, TypeInfo::Boolean, None), - span: Span::dummy(), - call_path_tree: None, - initial_type_id: engines.te().insert(&engines, TypeInfo::Boolean, None), - }, - Length::new(2, Span::dummy()), - ), - None, - ), + engines + .te() + .insert_array_without_annotations(&engines, engines.te().id_of_bool(), 2), ExperimentalFeatures::default(), )?; expr.type_check_analyze(handler, &mut TypeCheckAnalysisContext::new(&engines))?; @@ -3089,19 +3023,9 @@ mod tests { &handler, &engines, &expr, - engines.te().insert( - &engines, - TypeInfo::Array( - TypeArgument { - type_id: engines.te().insert(&engines, TypeInfo::Boolean, None), - span: Span::dummy(), - call_path_tree: None, - initial_type_id: engines.te().insert(&engines, TypeInfo::Boolean, None), - }, - Length::new(0, Span::dummy()), - ), - None, - ), + engines + .te() + .insert_array_without_annotations(&engines, engines.te().id_of_bool(), 0), ExperimentalFeatures::default(), ); let (errors, warnings) = handler.consume(); diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/enum_instantiation.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/enum_instantiation.rs index 35ddcb183ca..4da63001bb4 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/enum_instantiation.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/enum_instantiation.rs @@ -56,11 +56,7 @@ pub(crate) fn instantiate_enum( match (&args, &*type_engine.get(enum_variant.type_argument.type_id)) { ([], ty) if ty.is_unit() => Ok(ty::TyExpression { - return_type: type_engine.insert( - engines, - TypeInfo::Enum(*enum_ref.id()), - enum_ref.span().source_id(), - ), + return_type: type_engine.insert_enum(engines, *enum_ref.id()), expression: ty::TyExpressionVariant::EnumInstantiation { tag: enum_variant.tag, contents: None, @@ -149,11 +145,7 @@ pub(crate) fn instantiate_enum( // Create the resulting enum type based on the enum we have instantiated. // Note that we clone the `enum_ref` but the unification we do below will // affect the types behind that new enum decl reference. - let type_id = type_engine.insert( - engines, - TypeInfo::Enum(*enum_ref.id()), - enum_ref.span().source_id(), - ); + let type_id = type_engine.insert_enum(engines, *enum_ref.id()); // The above type check will unify the type behind the `enum_variant_type_id` // and the resulting expression type. diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/if_expression.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/if_expression.rs index bdd3679c869..9b1a5e4ebc8 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/if_expression.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/if_expression.rs @@ -22,7 +22,7 @@ pub(crate) fn instantiate_if_expression( let ty_to_check = if r#else.is_some() { ctx.type_annotation() } else { - type_engine.insert(engines, TypeInfo::Tuple(vec![]), then.span.source_id()) + type_engine.id_of_unit() }; // We check then_type_is_never and else_type_is_never before unifying to make sure we don't @@ -62,9 +62,10 @@ pub(crate) fn instantiate_if_expression( Box::new(r#else) }); - let r#else_ret_ty = r#else.as_ref().map(|x| x.return_type).unwrap_or_else(|| { - type_engine.insert(engines, TypeInfo::Tuple(Vec::new()), span.source_id()) - }); + let r#else_ret_ty = r#else + .as_ref() + .map(|x| x.return_type) + .unwrap_or_else(|| type_engine.id_of_unit()); // delay emitting the errors until we decide if this is a missing else branch or some other set of errors let h = Handler::default(); diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs index 3c118c43536..d7d724caea1 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs @@ -20,7 +20,7 @@ use sway_error::{ error::CompileError, handler::{ErrorEmitted, Handler}, }; -use sway_types::{constants, integer_bits::IntegerBits, BaseIdent, IdentUnique}; +use sway_types::{constants, BaseIdent, IdentUnique}; use sway_types::{constants::CONTRACT_CALL_COINS_PARAMETER_NAME, Spanned}; use sway_types::{Ident, Span}; @@ -45,7 +45,7 @@ pub(crate) fn type_check_method_application( let ctx = ctx .by_ref() .with_help_text("") - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); + .with_type_annotation(type_engine.new_unknown()); // Ignore errors in method parameters // On the second pass we will throw the errors if they persist. @@ -82,7 +82,7 @@ pub(crate) fn type_check_method_application( .iter() .map(|(arg, _has_errors)| match arg { Some(arg) => arg.return_type, - None => type_engine.insert(engines, TypeInfo::Unknown, None), + None => type_engine.new_unknown(), }) .collect(), )?; @@ -130,7 +130,7 @@ pub(crate) fn type_check_method_application( } else { ctx.by_ref() .with_help_text("") - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)) + .with_type_annotation(type_engine.new_unknown()) }; args_buf.push_back( @@ -183,17 +183,13 @@ pub(crate) fn type_check_method_application( | constants::CONTRACT_CALL_ASSET_ID_PARAMETER_NAME => { untyped_contract_call_params_map .insert(param.name.to_string(), param.value.clone()); - let type_annotation = type_engine.insert( - engines, - if param.name.span().as_str() - != constants::CONTRACT_CALL_ASSET_ID_PARAMETER_NAME - { - TypeInfo::UnsignedInteger(IntegerBits::SixtyFour) - } else { - TypeInfo::B256 - }, - param.name.span().source_id(), - ); + let type_annotation = if param.name.span().as_str() + != constants::CONTRACT_CALL_ASSET_ID_PARAMETER_NAME + { + type_engine.id_of_u64() + } else { + type_engine.id_of_b256() + }; let ctx = ctx .by_ref() .with_help_text("") @@ -443,21 +439,10 @@ pub(crate) fn type_check_method_application( asset_id_expr: Expression, gas_expr: Expression, ) -> Expression { - let tuple_args_type_id = ctx.engines.te().insert( - ctx.engines, - TypeInfo::Tuple( - typed_arguments - .iter() - .map(|&type_id| TypeArgument { - type_id, - initial_type_id: type_id, - span: Span::dummy(), - call_path_tree: None, - }) - .collect(), - ), - None, - ); + let tuple_args_type_id = ctx + .engines + .te() + .insert_tuple_without_annotations(ctx.engines, typed_arguments); Expression { kind: ExpressionKind::FunctionApplication(Box::new( FunctionApplicationExpression { @@ -608,7 +593,7 @@ pub(crate) fn type_check_method_application( for p in method.type_parameters.clone() { if p.is_from_parent { if let Some(impl_type_param) = - names_index.get(&p.name_ident).and_then(|type_param_index| { + names_index.get(&p.name).and_then(|type_param_index| { implementing_type_parameters.get(*type_param_index) }) { @@ -672,7 +657,7 @@ pub(crate) fn type_check_method_application( // This handles the case of substituting the generic blanket type by call_path_typeid. for p in method.type_parameters.clone() { - if p.name_ident.as_str() == qualified_call_path.call_path.suffix.as_str() { + if p.name.as_str() == qualified_call_path.call_path.suffix.as_str() { subst_type_parameters.push(t.initial_type_id); subst_type_arguments.push(call_path_typeid); break; @@ -682,13 +667,10 @@ pub(crate) fn type_check_method_application( // This will subst inner method_application placeholders with the already resolved // current method application type parameter for p in method.type_parameters.clone() { - if names_type_ids.contains_key(&p.name_ident) { - subst_type_parameters.push(engines.te().insert( - engines, - TypeInfo::Placeholder(p.clone()), - p.span().source_id(), - )); - subst_type_arguments.push(p.type_id); + if names_type_ids.contains_key(&p.name) { + let type_parameter_type_id = p.type_id; + subst_type_parameters.push(engines.te().new_placeholder(p)); + subst_type_arguments.push(type_parameter_type_id); } } @@ -818,9 +800,7 @@ pub(crate) fn resolve_method_name( // type check the call path let type_id = call_path_binding .type_check_with_type_info(handler, &mut ctx) - .unwrap_or_else(|err| { - type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None) - }); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); // find the module that the symbol is in let type_info_prefix = ctx @@ -867,7 +847,7 @@ pub(crate) fn resolve_method_name( let type_id = arguments_types .front() .cloned() - .unwrap_or_else(|| type_engine.insert(engines, TypeInfo::Unknown, None)); + .unwrap_or_else(|| type_engine.new_unknown()); // find the method let decl_ref = ctx.find_method_for_type( @@ -891,7 +871,7 @@ pub(crate) fn resolve_method_name( let type_id = arguments_types .front() .cloned() - .unwrap_or_else(|| type_engine.insert(engines, TypeInfo::Unknown, None)); + .unwrap_or_else(|| type_engine.new_unknown()); // find the method let decl_ref = ctx.find_method_for_type( diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_instantiation.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_instantiation.rs index 1d84a623fbd..47c190a0c2b 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_instantiation.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_instantiation.rs @@ -59,21 +59,16 @@ pub(crate) fn struct_instantiation( let type_arguments = type_arguments.to_vec(); - let type_info = match (suffix.as_str(), type_arguments.is_empty()) { - ("Self", true) => TypeInfo::new_self_type(suffix.span()), + // We first create a custom type and then resolve it to the struct type. + let custom_type_id = match (suffix.as_str(), type_arguments.is_empty()) { + ("Self", true) => type_engine.new_self_type(engines, suffix.span()), ("Self", false) => { return Err(handler.emit_err(CompileError::TypeArgumentsNotAllowed { span: suffix.span(), })); } - (_, true) => TypeInfo::Custom { - qualified_call_path: suffix.clone().into(), - type_arguments: None, - }, - (_, false) => TypeInfo::Custom { - qualified_call_path: suffix.clone().into(), - type_arguments: Some(type_arguments), - }, + (_, true) => type_engine.new_custom_from_name(engines, suffix.clone()), + (_, false) => type_engine.new_custom(engines, suffix.clone().into(), Some(type_arguments)), }; // find the module that the struct decl is in @@ -85,12 +80,12 @@ pub(crate) fn struct_instantiation( let type_id = ctx .resolve_type( handler, - type_engine.insert(engines, type_info, suffix.span().source_id()), + custom_type_id, inner_span, EnforceTypeArguments::No, Some(&type_info_prefix), ) - .unwrap_or_else(|err| type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None)); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); // extract the struct name and fields from the type info let type_info = type_engine.get(type_id); @@ -389,7 +384,6 @@ fn type_check_field_arguments( ) -> Result, ErrorEmitted> { handler.scope(|handler| { let type_engine = ctx.engines.te(); - let engines = ctx.engines(); let mut typed_fields = vec![]; let mut missing_fields = vec![]; @@ -434,11 +428,7 @@ fn type_check_field_arguments( name: struct_field.name.clone(), value: ty::TyExpression { expression: ty::TyExpressionVariant::Tuple { fields: vec![] }, - return_type: type_engine.insert( - engines, - TypeInfo::ErrorRecovery(err), - None, - ), + return_type: type_engine.id_of_error_recovery(err), span: span.clone(), }, }); diff --git a/sway-core/src/semantic_analysis/ast_node/mod.rs b/sway-core/src/semantic_analysis/ast_node/mod.rs index 3a6ea5f2153..5dee758e227 100644 --- a/sway-core/src/semantic_analysis/ast_node/mod.rs +++ b/sway-core/src/semantic_analysis/ast_node/mod.rs @@ -91,11 +91,7 @@ impl ty::TyAstNode { _ => { ctx = ctx .with_help_text("") - .with_type_annotation(type_engine.insert( - engines, - TypeInfo::Unknown, - None, - )); + .with_type_annotation(type_engine.new_unknown()); } } let inner = ty::TyExpression::type_check(handler, ctx, &expr) diff --git a/sway-core/src/semantic_analysis/namespace/trait_map.rs b/sway-core/src/semantic_analysis/namespace/trait_map.rs index 15113704762..e37c30dfd61 100644 --- a/sway-core/src/semantic_analysis/namespace/trait_map.rs +++ b/sway-core/src/semantic_analysis/namespace/trait_map.rs @@ -177,7 +177,6 @@ enum TypeRootFilter { Struct(ParsedDeclId), ContractCaller(String), Array(usize), - Storage, RawUntypedPtr, RawUntypedSlice, Ptr, @@ -882,7 +881,8 @@ impl TraitMap { }, } in impls.iter() { - if !type_info.can_change(engines) && *type_id == *map_type_id { + if !type_engine.is_type_changeable(engines, &type_info) && *type_id == *map_type_id + { trait_map.insert_inner( map_trait_name.clone(), impl_span.clone(), @@ -1397,17 +1397,14 @@ impl TraitMap { let key = &e.key; let suffix = &key.name.suffix; if unify_check.check(type_id, key.type_id) { - let map_trait_type_id = type_engine.insert( + let map_trait_type_id = type_engine.new_custom( engines, - TypeInfo::Custom { - qualified_call_path: suffix.name.clone().into(), - type_arguments: if suffix.args.is_empty() { - None - } else { - Some(suffix.args.to_vec()) - }, + suffix.name.clone().into(), + if suffix.args.is_empty() { + None + } else { + Some(suffix.args.to_vec()) }, - suffix.name.span().source_id(), ); Some((suffix.name.clone(), map_trait_type_id)) } else { @@ -1423,17 +1420,14 @@ impl TraitMap { trait_name: constraint_trait_name, type_arguments: constraint_type_arguments, } = c; - let constraint_type_id = type_engine.insert( + let constraint_type_id = type_engine.new_custom( engines, - TypeInfo::Custom { - qualified_call_path: constraint_trait_name.suffix.clone().into(), - type_arguments: if constraint_type_arguments.is_empty() { - None - } else { - Some(constraint_type_arguments.clone()) - }, + constraint_trait_name.suffix.clone().into(), + if constraint_type_arguments.is_empty() { + None + } else { + Some(constraint_type_arguments.clone()) }, - constraint_trait_name.span().source_id(), ); (c.trait_name.suffix.clone(), constraint_type_id) }) @@ -1604,7 +1598,6 @@ impl TraitMap { } ContractCaller { abi_name, .. } => TypeRootFilter::ContractCaller(abi_name.to_string()), Array(_, length) => TypeRootFilter::Array(length.val()), - Storage { .. } => TypeRootFilter::Storage, RawUntypedPtr => TypeRootFilter::RawUntypedPtr, RawUntypedSlice => TypeRootFilter::RawUntypedSlice, Ptr(_) => TypeRootFilter::Ptr, diff --git a/sway-core/src/semantic_analysis/node_dependencies.rs b/sway-core/src/semantic_analysis/node_dependencies.rs index e0a5b5b3f0b..2ca2ee6ad38 100644 --- a/sway-core/src/semantic_analysis/node_dependencies.rs +++ b/sway-core/src/semantic_analysis/node_dependencies.rs @@ -1029,7 +1029,6 @@ fn type_info_name(type_info: &TypeInfo) -> String { TypeInfo::Struct { .. } => "struct", TypeInfo::Enum { .. } => "enum", TypeInfo::Array(..) => "array", - TypeInfo::Storage { .. } => "contract storage", TypeInfo::RawUntypedPtr => "raw untyped ptr", TypeInfo::RawUntypedSlice => "raw untyped slice", TypeInfo::Ptr(..) => "__ptr", diff --git a/sway-core/src/semantic_analysis/type_check_context.rs b/sway-core/src/semantic_analysis/type_check_context.rs index d6c3a7c45f1..2a6b71b5687 100644 --- a/sway-core/src/semantic_analysis/type_check_context.rs +++ b/sway-core/src/semantic_analysis/type_check_context.rs @@ -124,8 +124,8 @@ impl<'a> TypeCheckContext<'a> { namespace, engines, collection_ctx, - type_annotation: engines.te().insert(engines, TypeInfo::Unknown, None), - function_type_annotation: engines.te().insert(engines, TypeInfo::Unknown, None), + type_annotation: engines.te().new_unknown(), + function_type_annotation: engines.te().new_unknown(), unify_generic: false, self_type: None, type_subst: TypeSubstMap::new(), @@ -168,8 +168,8 @@ impl<'a> TypeCheckContext<'a> { collection_ctx, namespace, engines, - type_annotation: engines.te().insert(engines, TypeInfo::Unknown, None), - function_type_annotation: engines.te().insert(engines, TypeInfo::Unknown, None), + type_annotation: engines.te().new_unknown(), + function_type_annotation: engines.te().new_unknown(), unify_generic: false, self_type: None, type_subst: TypeSubstMap::new(), @@ -750,7 +750,7 @@ impl<'a> TypeCheckContext<'a> { self.self_type(), &self.subst_ctx(), ) - .unwrap_or_else(|err| type_engine.insert(self.engines, TypeInfo::ErrorRecovery(err), None)); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); // grab the module where the type itself is declared let type_module = self.namespace().lookup_submodule_from_absolute_path( diff --git a/sway-core/src/semantic_analysis/type_resolve.rs b/sway-core/src/semantic_analysis/type_resolve.rs index e4c676fda1e..387d3f48b2d 100644 --- a/sway-core/src/semantic_analysis/type_resolve.rs +++ b/sway-core/src/semantic_analysis/type_resolve.rs @@ -63,7 +63,7 @@ pub fn resolve_type( subst_ctx, )? } - TypeInfo::Array(mut elem_ty, n) => { + TypeInfo::Array(mut elem_ty, length) => { elem_ty.type_id = resolve_type( handler, engines, @@ -76,17 +76,9 @@ pub fn resolve_type( self_type, subst_ctx, ) - .unwrap_or_else(|err| { - engines - .te() - .insert(engines, TypeInfo::ErrorRecovery(err), None) - }); + .unwrap_or_else(|err| engines.te().id_of_error_recovery(err)); - engines.te().insert( - engines, - TypeInfo::Array(elem_ty.clone(), n.clone()), - elem_ty.span.source_id(), - ) + engines.te().insert_array(engines, elem_ty, length) } TypeInfo::Slice(mut elem_ty) => { elem_ty.type_id = resolve_type( @@ -101,17 +93,9 @@ pub fn resolve_type( self_type, subst_ctx, ) - .unwrap_or_else(|err| { - engines - .te() - .insert(engines, TypeInfo::ErrorRecovery(err), None) - }); + .unwrap_or_else(|err| engines.te().id_of_error_recovery(err)); - engines.te().insert( - engines, - TypeInfo::Slice(elem_ty.clone()), - elem_ty.span.source_id(), - ) + engines.te().insert_slice(engines, elem_ty) } TypeInfo::Tuple(mut type_arguments) => { for type_argument in type_arguments.iter_mut() { @@ -127,16 +111,10 @@ pub fn resolve_type( self_type, subst_ctx, ) - .unwrap_or_else(|err| { - engines - .te() - .insert(engines, TypeInfo::ErrorRecovery(err), None) - }); + .unwrap_or_else(|err| engines.te().id_of_error_recovery(err)); } - engines - .te() - .insert(engines, TypeInfo::Tuple(type_arguments), span.source_id()) + engines.te().insert_tuple(engines, type_arguments) } TypeInfo::TraitType { name, @@ -179,20 +157,9 @@ pub fn resolve_type( self_type, subst_ctx, ) - .unwrap_or_else(|err| { - engines - .te() - .insert(engines, TypeInfo::ErrorRecovery(err), None) - }); + .unwrap_or_else(|err| engines.te().id_of_error_recovery(err)); - engines.te().insert( - engines, - TypeInfo::Ref { - to_mutable_value, - referenced_type: ty.clone(), - }, - None, - ) + engines.te().insert_ref(engines, to_mutable_value, ty) } _ => type_id, }; diff --git a/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs b/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs index e40c9148fda..0cbf326b070 100644 --- a/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs +++ b/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs @@ -542,11 +542,7 @@ pub fn item_fn_to_function_declaration( let return_type = match item_fn.fn_signature.return_type_opt { Some((_right_arrow, ty)) => ty_to_type_argument(context, handler, engines, ty)?, None => { - let type_id = engines.te().insert( - engines, - TypeInfo::Tuple(Vec::new()), - item_fn.fn_signature.span().source_id(), - ); + let type_id = engines.te().id_of_unit(); TypeArgument { type_id, initial_type_id: type_id, @@ -992,7 +988,7 @@ pub(crate) fn item_const_to_constant_declaration( return Err(errors); } } - engines.te().insert(engines, TypeInfo::Unknown, None).into() + engines.te().new_unknown().into() } }; @@ -1255,18 +1251,11 @@ fn generic_params_opt_to_type_parameters_with_parent( .into_inner() .into_iter() .map(|ident| { - let custom_type = type_engine.insert( - engines, - TypeInfo::Custom { - qualified_call_path: ident.clone().into(), - type_arguments: None, - }, - ident.span().source_id(), - ); + let custom_type = type_engine.new_custom_from_name(engines, ident.clone()); TypeParameter { type_id: custom_type, initial_type_id: custom_type, - name_ident: ident, + name: ident, trait_constraints: Vec::new(), trait_constraints_span: Span::dummy(), is_from_parent, @@ -1286,12 +1275,12 @@ fn generic_params_opt_to_type_parameters_with_parent( { let param_to_edit = if let Some(o) = params .iter_mut() - .find(|TypeParameter { name_ident, .. }| name_ident.as_str() == ty_name.as_str()) + .find(|TypeParameter { name, .. }| name.as_str() == ty_name.as_str()) { o } else if let Some(o2) = parent_params .iter() - .find(|TypeParameter { name_ident, .. }| name_ident.as_str() == ty_name.as_str()) + .find(|TypeParameter { name, .. }| name.as_str() == ty_name.as_str()) { params.push(o2.clone()); params.last_mut().unwrap() @@ -1405,11 +1394,7 @@ fn fn_args_to_function_parameters( (Some(reference), None) => reference.span(), (Some(reference), Some(mutable)) => Span::join(reference.span(), &mutable.span()), }; - let type_id = engines.te().insert( - engines, - TypeInfo::new_self_type(self_token.span()), - self_token.span().source_id(), - ); + let type_id = engines.te().new_self_type(engines, self_token.span()); let mut function_parameters = vec![FunctionParameter { name: Ident::new(self_token.span()), is_reference: ref_self.is_some(), @@ -1613,11 +1598,7 @@ fn fn_signature_to_trait_fn( let return_type = match &fn_signature.return_type_opt { Some((_right_arrow, ty)) => ty_to_type_argument(context, handler, engines, ty.clone())?, None => { - let type_id = engines.te().insert( - engines, - TypeInfo::Tuple(Vec::new()), - fn_signature.span().source_id(), - ); + let type_id = engines.te().id_of_unit(); TypeArgument { type_id, initial_type_id: type_id, @@ -2754,7 +2735,10 @@ fn expr_to_length( expr: Expr, ) -> Result { let span = expr.span(); - Ok(Length::new(expr_to_usize(context, handler, expr)?, span)) + Ok(Length::from_numeric_literal( + expr_to_usize(context, handler, expr)?, + span, + )) } fn expr_to_usize( @@ -3047,7 +3031,7 @@ fn match_expr_to_expression( let var_decl = engines.pe().insert(VariableDeclaration { type_ascription: { - let type_id = engines.te().insert(engines, TypeInfo::Unknown, None); + let type_id = engines.te().new_unknown(); TypeArgument { type_id, initial_type_id: type_id, @@ -3131,7 +3115,7 @@ fn for_expr_to_expression( // Declare iterable with iterator return let iterable_decl = engines.pe().insert(VariableDeclaration { type_ascription: { - let type_id = engines.te().insert(engines, TypeInfo::Unknown, None); + let type_id = engines.te().new_unknown(); TypeArgument { type_id, initial_type_id: type_id, @@ -3164,7 +3148,7 @@ fn for_expr_to_expression( // Declare value_opt = iterable.next() let value_opt_to_next_decl = engines.pe().insert(VariableDeclaration { type_ascription: { - let type_id = engines.te().insert(engines, TypeInfo::Unknown, None); + let type_id = engines.te().new_unknown(); TypeArgument { type_id, initial_type_id: type_id, @@ -3820,7 +3804,7 @@ fn statement_let_to_ast_nodes_unfold( let type_ascription = match ty_opt { Some(ty) => ty_to_type_argument(context, handler, engines, ty)?, None => { - let type_id = engines.te().insert(engines, TypeInfo::Unknown, None); + let type_id = engines.te().new_unknown(); TypeArgument { type_id, initial_type_id: type_id, @@ -3870,7 +3854,7 @@ fn statement_let_to_ast_nodes_unfold( let type_ascription = match &ty_opt { Some(ty) => ty_to_type_argument(context, handler, engines, ty.clone())?, None => { - let type_id = engines.te().insert(engines, TypeInfo::Unknown, None); + let type_id = engines.te().new_unknown(); TypeArgument { type_id, initial_type_id: type_id, @@ -3954,52 +3938,38 @@ fn statement_let_to_ast_nodes_unfold( let tuple_name = generate_tuple_var_name(context.next_destructured_tuple_unique_suffix()); - let tuple_name = Ident::new_with_override(tuple_name, pat_tuple.span().clone()); + let tuple_name = Ident::new_with_override(tuple_name, pat_tuple.span()); - // Acript a second declaration to a tuple of placeholders to check that the tuple - // is properly sized to the pattern + // Ascribe a second declaration to a tuple of placeholders to check that the tuple + // is properly sized to the pattern. let placeholders_type_ascription = { - let type_id = engines.te().insert( + let type_id = engines.te().insert_tuple_without_annotations( engines, - TypeInfo::Tuple( - pat_tuple - .clone() - .into_inner() - .into_iter() - .map(|pat| { - let initial_type_id = - engines.te().insert(engines, TypeInfo::Unknown, None); - let dummy_type_param = TypeParameter { - type_id: initial_type_id, - initial_type_id, - name_ident: Ident::new_with_override( - "_".into(), - pat.span().clone(), - ), - trait_constraints: vec![], - trait_constraints_span: Span::dummy(), - is_from_parent: false, - }; - let initial_type_id = engines.te().insert( - engines, - TypeInfo::Placeholder(dummy_type_param), - None, - ); - TypeArgument { - type_id: initial_type_id, - initial_type_id, - call_path_tree: None, - span: Span::dummy(), - } - }) - .collect(), - ), - tuple_name.span().source_id(), + pat_tuple + .clone() + .into_inner() + .into_iter() + .map(|pat| { + // Since these placeholders are generated specifically for checks, the `pat.span()` must not + // necessarily point to a "_" string in code. E.g., in this example: + // let (a, _) = (0, 0); + // The first `pat.span()` will point to "a", while the second one will indeed point to "_". + // However, their `pat.span()`s will always be in the source file in which the placeholder + // is logically situated. + engines.te().new_placeholder(TypeParameter::new_placeholder( + engines.te().new_unknown(), + pat.span(), + )) + }) + .collect(), ); + + // The type argument is a tuple of place holders of unknowns pointing to + // the tuple pattern. TypeArgument { type_id, initial_type_id: type_id, - span: tuple_name.span(), + span: pat_tuple.span(), call_path_tree: None, } }; @@ -4313,14 +4283,14 @@ fn ty_to_type_parameter( ) -> Result { let type_engine = engines.te(); - let name_ident = match ty { + let name = match ty { Ty::Path(path_type) => path_type_to_ident(context, handler, path_type)?, Ty::Infer { underscore_token } => { - let unknown_type = type_engine.insert(engines, TypeInfo::Unknown, None); + let unknown_type = type_engine.new_unknown(); return Ok(TypeParameter { type_id: unknown_type, initial_type_id: unknown_type, - name_ident: underscore_token.into(), + name: underscore_token.into(), trait_constraints: Vec::default(), trait_constraints_span: Span::dummy(), is_from_parent: false, @@ -4328,25 +4298,18 @@ fn ty_to_type_parameter( } Ty::Tuple(..) => panic!("tuple types are not allowed in this position"), Ty::Array(..) => panic!("array types are not allowed in this position"), - Ty::StringSlice(..) => panic!("str types are not allowed in this position"), - Ty::StringArray { .. } => panic!("str types are not allowed in this position"), + Ty::StringSlice(..) => panic!("str slice types are not allowed in this position"), + Ty::StringArray { .. } => panic!("str array types are not allowed in this position"), Ty::Ptr { .. } => panic!("__ptr types are not allowed in this position"), Ty::Slice { .. } => panic!("__slice types are not allowed in this position"), Ty::Ref { .. } => panic!("ref types are not allowed in this position"), Ty::Never { .. } => panic!("never types are not allowed in this position"), }; - let custom_type = type_engine.insert( - engines, - TypeInfo::Custom { - qualified_call_path: name_ident.clone().into(), - type_arguments: None, - }, - name_ident.span().source_id(), - ); + let custom_type = type_engine.new_custom_from_name(engines, name.clone()); Ok(TypeParameter { type_id: custom_type, initial_type_id: custom_type, - name_ident, + name, trait_constraints: Vec::new(), trait_constraints_span: Span::dummy(), is_from_parent: false, diff --git a/sway-core/src/type_system/ast_elements/binding.rs b/sway-core/src/type_system/ast_elements/binding.rs index 9a4c7c1dd43..3ea45397a51 100644 --- a/sway-core/src/type_system/ast_elements/binding.rs +++ b/sway-core/src/type_system/ast_elements/binding.rs @@ -238,7 +238,7 @@ impl TypeBinding> { EnforceTypeArguments::No, Some(&type_info_prefix), ) - .unwrap_or_else(|err| type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None)); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); Ok(type_id) } @@ -309,7 +309,7 @@ impl TypeCheckTypeBinding for TypeBinding { > { let type_engine = ctx.engines.te(); let decl_engine = ctx.engines.de(); - let engines = ctx.engines(); + // Grab the declaration. let unknown_decl = ctx .resolve_call_path_with_visibility_check(handler, &self.inner)? @@ -339,9 +339,7 @@ impl TypeCheckTypeBinding for TypeBinding { EnforceTypeArguments::Yes, None, ) - .unwrap_or_else(|err| { - type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None) - }); + .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); } } } @@ -411,11 +409,7 @@ impl TypeCheckTypeBinding for TypeBinding { new_copy, decl_engine.get_parsed_decl_id(&struct_id).as_ref(), ); - let type_id = type_engine.insert( - engines, - TypeInfo::Struct(*new_struct_ref.id()), - new_struct_ref.span().source_id(), - ); + let type_id = type_engine.insert_struct(engines, *new_struct_ref.id()); Ok((new_struct_ref, Some(type_id), None)) } } @@ -464,11 +458,7 @@ impl TypeCheckTypeBinding for TypeBinding { // Insert the new copy into the declaration engine. let new_enum_ref = decl_engine.insert(new_copy, decl_engine.get_parsed_decl_id(&enum_id).as_ref()); - let type_id = type_engine.insert( - engines, - TypeInfo::Enum(*new_enum_ref.id()), - new_enum_ref.span().source_id(), - ); + let type_id = type_engine.insert_enum(engines, *new_enum_ref.id()); Ok((new_enum_ref, Some(type_id), Some(unknown_decl))) } } diff --git a/sway-core/src/type_system/ast_elements/length.rs b/sway-core/src/type_system/ast_elements/length.rs index 3decee557fd..913e9ce38c6 100644 --- a/sway-core/src/type_system/ast_elements/length.rs +++ b/sway-core/src/type_system/ast_elements/length.rs @@ -1,6 +1,17 @@ use sway_types::{span::Span, Spanned}; -/// Describes a fixed length for types that needs it such as arrays and strings +/// Describes a fixed length for types that need it, e.g., [crate::TypeInfo::Array]. +/// +/// Optionally, if the length is coming from a literal in code, the [Length] +/// also keeps the [Span] of that literal. In that case, we say that the length +/// is annotated. +/// +/// E.g., in this example, the two lengths coming from the literal `3` will +/// have two different spans pointing to the two different strings "3": +/// +/// ```ignore +/// fn copy(a: [u64;3], b: [u64;3]) +/// ``` #[derive(Debug, Clone, Hash)] pub struct Length { val: usize, @@ -8,13 +19,30 @@ pub struct Length { } impl Length { - pub fn new(val: usize, span: Span) -> Self { - Length { val, span } + /// Creates a new [Length] without span annotation. + pub fn new(val: usize) -> Self { + Length { + val, + span: Span::dummy(), + } + } + + /// Creates a new [Length] from a numeric literal. + /// The `span` will be set to the span of the numeric literal. + pub fn from_numeric_literal(val: usize, numeric_literal_span: Span) -> Self { + Length { + val, + span: numeric_literal_span, + } } pub fn val(&self) -> usize { self.val } + + pub fn is_annotated(&self) -> bool { + !self.span.is_dummy() + } } impl Spanned for Length { diff --git a/sway-core/src/type_system/ast_elements/trait_constraint.rs b/sway-core/src/type_system/ast_elements/trait_constraint.rs index e91411595bb..cfe0b41bcb1 100644 --- a/sway-core/src/type_system/ast_elements/trait_constraint.rs +++ b/sway-core/src/type_system/ast_elements/trait_constraint.rs @@ -170,11 +170,7 @@ impl TraitConstraint { EnforceTypeArguments::Yes, None, ) - .unwrap_or_else(|err| { - ctx.engines - .te() - .insert(ctx.engines(), TypeInfo::ErrorRecovery(err), None) - }); + .unwrap_or_else(|err| ctx.engines.te().id_of_error_recovery(err)); } Ok(()) diff --git a/sway-core/src/type_system/ast_elements/type_argument.rs b/sway-core/src/type_system/ast_elements/type_argument.rs index 1476fe6627b..bdddde93ad4 100644 --- a/sway-core/src/type_system/ast_elements/type_argument.rs +++ b/sway-core/src/type_system/ast_elements/type_argument.rs @@ -2,15 +2,60 @@ use crate::{engine_threading::*, language::CallPathTree, type_system::priv_prelu use std::{cmp::Ordering, fmt, hash::Hasher}; use sway_types::{Span, Spanned}; +/// [TypeArgument] can be seen as an "annotated reference" to a [TypeInfo]. +/// It holds the [TypeArgument::type_id] which is the actual "reference" +/// to the type, as well as an additional information about that type, +/// called the annotation. +/// +/// If a [TypeArgument] only references a [TypeInfo] and is considered as +/// not being annotated, its `initial_type_id` must be the same as `type_id`, +/// its `span` must be [Span::dummy] and its `call_path_tree` must be `None`. +/// +/// The annotations are ignored when calculating the [TypeArgument]'s hash +/// (with engines) and equality (with engines). #[derive(Debug, Clone)] pub struct TypeArgument { + /// The [TypeId] of the "referenced" [TypeInfo]. pub type_id: TypeId, + /// Denotes the initial type that was referenced before the type + /// unification, monomorphization, or replacement of [TypeInfo::Custom]s. pub initial_type_id: TypeId, + /// The [Span] related in code to the [TypeInfo] represented by this + /// [TypeArgument]. This information is mostly used by the LSP and it + /// differs from use case to use case. + /// + /// E.g., in the following example: + /// + /// ```ignore + /// let a: [u64;2] = [0, 0]; + /// let b: [u64;2] = [1, 1]; + /// ``` + /// + /// the type arguments of the [TypeInfo::Array]s of `a` and `b` will + /// have two different spans pointing to two different strings "u64". + /// On the other hand, the two [TypeInfo::Array]s describing the + /// two instances `[0, 0]`, and `[1, 1]` will have neither the array + /// type span set, nor the length span, which means they will not be + /// annotated. pub span: Span, pub call_path_tree: Option, } +impl TypeArgument { + /// Returns true if `self` is annotated by having either + /// its [Self::initial_type_id] different from [Self::type_id], + /// or [Self::span] different from [Span::dummy] + /// or [Self::call_path_tree] different from `None`. + pub fn is_annotated(&self) -> bool { + self.type_id != self.initial_type_id + || self.call_path_tree.is_some() + || !self.span.is_dummy() + } +} + impl From for TypeArgument { + /// Creates *a non-annotated* [TypeArgument] that points + /// to the [TypeInfo] represented by the `type_id`. fn from(type_id: TypeId) -> Self { TypeArgument { type_id, @@ -102,7 +147,7 @@ impl From<&TypeParameter> for TypeArgument { TypeArgument { type_id: type_param.type_id, initial_type_id: type_param.initial_type_id, - span: type_param.name_ident.span(), + span: type_param.name.span(), call_path_tree: None, } } diff --git a/sway-core/src/type_system/ast_elements/type_parameter.rs b/sway-core/src/type_system/ast_elements/type_parameter.rs index 068f486b79f..cdd656aaef0 100644 --- a/sway-core/src/type_system/ast_elements/type_parameter.rs +++ b/sway-core/src/type_system/ast_elements/type_parameter.rs @@ -12,7 +12,7 @@ use sway_error::{ error::CompileError, handler::{ErrorEmitted, Handler}, }; -use sway_types::{ident::Ident, span::Span, Spanned}; +use sway_types::{ident::Ident, span::Span, BaseIdent, Spanned}; use std::{ cmp::Ordering, @@ -21,21 +21,47 @@ use std::{ hash::{Hash, Hasher}, }; -#[derive(Clone)] +/// [TypeParameter] describes a generic type parameter, including its +/// monomorphized version. It holds the `name` of the parameter, its +/// `type_id`, and the `initial_type_id`, as well as an additional +/// information about that type parameter, called the annotation. +/// +/// If a [TypeParameter] is considered as not being annotated, +/// its `initial_type_id` must be same as `type_id`, its +/// `trait_constraints_span` must be [Span::dummy] +/// and its `is_from_parent` must be false. +/// +/// The annotations are ignored when calculating the [TypeParameter]'s hash +/// (with engines) and equality (with engines). +#[derive(Debug, Clone)] pub struct TypeParameter { pub type_id: TypeId, + /// Denotes the initial type represented by the [TypeParameter], before + /// unification, monomorphization, or replacement of [TypeInfo::Custom]s. pub(crate) initial_type_id: TypeId, - pub name_ident: Ident, + pub name: Ident, pub(crate) trait_constraints: Vec, pub(crate) trait_constraints_span: Span, pub(crate) is_from_parent: bool, } +impl TypeParameter { + /// Returns true if `self` is annotated by heaving either + /// its [Self::initial_type_id] different from [Self::type_id], + /// or [Self::trait_constraints_span] different from [Span::dummy] + /// or [Self::is_from_parent] different from false. + pub fn is_annotated(&self) -> bool { + self.type_id != self.initial_type_id + || self.is_from_parent + || !self.trait_constraints_span.is_dummy() + } +} + impl HashWithEngines for TypeParameter { fn hash(&self, state: &mut H, engines: &Engines) { let TypeParameter { type_id, - name_ident, + name, trait_constraints, // these fields are not hashed because they aren't relevant/a // reliable source of obj v. obj distinction @@ -45,7 +71,7 @@ impl HashWithEngines for TypeParameter { } = self; let type_engine = engines.te(); type_engine.get(*type_id).hash(state, engines); - name_ident.hash(state); + name.hash(state); trait_constraints.hash(state, engines); } } @@ -57,7 +83,7 @@ impl PartialEqWithEngines for TypeParameter { type_engine .get(self.type_id) .eq(&type_engine.get(other.type_id), ctx) - && self.name_ident == other.name_ident + && self.name == other.name && self.trait_constraints.eq(&other.trait_constraints, ctx) } } @@ -66,7 +92,7 @@ impl OrdWithEngines for TypeParameter { fn cmp(&self, other: &Self, ctx: &OrdWithEnginesContext) -> Ordering { let TypeParameter { type_id: lti, - name_ident: ln, + name: ln, trait_constraints: ltc, // these fields are not compared because they aren't relevant/a // reliable source of obj v. obj distinction @@ -76,7 +102,7 @@ impl OrdWithEngines for TypeParameter { } = self; let TypeParameter { type_id: rti, - name_ident: rn, + name: rn, trait_constraints: rtc, // these fields are not compared because they aren't relevant/a // reliable source of obj v. obj distinction @@ -106,7 +132,7 @@ impl SubstTypes for TypeParameter { impl Spanned for TypeParameter { fn span(&self) -> Span { - self.name_ident.span() + self.name.span() } } @@ -118,7 +144,7 @@ impl IsConcrete for TypeParameter { impl DebugWithEngines for TypeParameter { fn fmt(&self, f: &mut fmt::Formatter<'_>, engines: &Engines) -> fmt::Result { - write!(f, "{}", self.name_ident)?; + write!(f, "{}", self.name)?; if !self.trait_constraints.is_empty() { write!( f, @@ -134,37 +160,56 @@ impl DebugWithEngines for TypeParameter { } } -impl fmt::Debug for TypeParameter { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let _ = write!(f, "{}: {:?}", self.name_ident, self.type_id); - for c in &self.trait_constraints { - let _ = write!(f, "+ {:?}", c.trait_name); - } - write!(f, "") - } -} - impl TypeParameter { - pub(crate) fn new_self_type(engines: &Engines, span: Span) -> TypeParameter { + /// Creates a new [TypeParameter] that represents a `Self` type. + /// The returned type parameter will have its [TypeParameter::name] + /// set to "Self" with the provided `use_site_span`. + /// + /// `Self` type is a [TypeInfo::UnknownGeneric] and therefore [TypeParameter::type_id]s + /// will be set to newly created unknown generic type. + /// + /// Note that the span in general does not point to a reserved word "Self" in + /// the source code, nor is related to it. The `Self` type represents the type + /// in `impl`s and does not necessarily relate to the "Self" keyword in code. + /// + /// Therefore, *the span must always point to a location in the source file in which + /// the particular `Self` type is, e.g., being declared or implemented*. + pub(crate) fn new_self_type(engines: &Engines, use_site_span: Span) -> TypeParameter { let type_engine = engines.te(); - let name = Ident::new_with_override("Self".into(), span.clone()); - let type_id = type_engine.insert( - engines, - TypeInfo::UnknownGeneric { - name: name.clone(), - trait_constraints: VecSet(vec![]), - parent: None, - is_from_type_parameter: true, - }, - span.source_id(), - ); + let (type_id, name) = type_engine.new_unknown_generic_self(use_site_span, true); TypeParameter { type_id, initial_type_id: type_id, - name_ident: name, + name, trait_constraints: vec![], - trait_constraints_span: span, + trait_constraints_span: Span::dummy(), + is_from_parent: false, + } + } + + /// Creates a new [TypeParameter] specifically to be used as the type parameter + /// for a [TypeInfo::Placeholder]. The returned type parameter will have its + /// [TypeParameter::name] set to "_" with the provided `placeholder_or_use_site_span` + /// and its [TypeParameter::type_id]s set to the `type_id`. + /// + /// Note that in the user written code, the span will always point to the place in + /// the source code where "_" is located. In the compiler generated code that is not always the case + /// be the case. For cases when the span does not point to "_" see the comments + /// in the usages of this method. + /// + /// However, *the span must always point to a location in the source file in which + /// the particular placeholder is considered to be used*. + pub(crate) fn new_placeholder( + type_id: TypeId, + placeholder_or_use_site_span: Span, + ) -> TypeParameter { + TypeParameter { + type_id, + initial_type_id: type_id, + name: BaseIdent::new_with_override("_".into(), placeholder_or_use_site_span), + trait_constraints: vec![], + trait_constraints_span: Span::dummy(), is_from_parent: false, } } @@ -176,11 +221,11 @@ impl TypeParameter { ) { let type_parameter_decl = ty::TyDecl::GenericTypeForFunctionScope(ty::GenericTypeForFunctionScope { - name: self.name_ident.clone(), + name: self.name.clone(), type_id: self.type_id, }); - let name_a = Ident::new_with_override("self".into(), self.name_ident.span()); - let name_b = Ident::new_with_override("Self".into(), self.name_ident.span()); + let name_a = Ident::new_with_override("self".into(), self.name.span()); + let name_b = Ident::new_with_override("Self".into(), self.name.span()); let _ = ctx.insert_symbol(handler, name_a, type_parameter_decl.clone()); let _ = ctx.insert_symbol(handler, name_b, type_parameter_decl); } @@ -266,11 +311,10 @@ impl TypeParameter { type_parameter: TypeParameter, ) -> Result { let type_engine = ctx.engines.te(); - let engines = ctx.engines(); let TypeParameter { initial_type_id, - name_ident, + name, trait_constraints, trait_constraints_span, is_from_parent, @@ -296,19 +340,15 @@ impl TypeParameter { // Create type id and type parameter before type checking trait constraints. // This order is required because a trait constraint may depend on its own type parameter. - let type_id = type_engine.insert( - engines, - TypeInfo::UnknownGeneric { - name: name_ident.clone(), - trait_constraints: VecSet(trait_constraints_with_supertraits.clone()), - parent, - is_from_type_parameter: true, - }, - name_ident.span().source_id(), + let type_id = type_engine.new_unknown_generic( + name.clone(), + VecSet(trait_constraints_with_supertraits.clone()), + parent, + true, ); let type_parameter = TypeParameter { - name_ident: name_ident.clone(), + name, type_id, initial_type_id, trait_constraints, @@ -360,15 +400,11 @@ impl TypeParameter { type_engine.replace( ctx.engines(), type_parameter.type_id, - TypeSourceInfo { - type_info: TypeInfo::UnknownGeneric { - name: type_parameter.name_ident.clone(), - trait_constraints: VecSet(trait_constraints_with_supertraits.clone()), - parent, - is_from_type_parameter: true, - } - .into(), - source_id: type_parameter.name_ident.span().source_id().copied(), + TypeInfo::UnknownGeneric { + name: type_parameter.name.clone(), + trait_constraints: VecSet(trait_constraints_with_supertraits.clone()), + parent, + is_from_type_parameter: true, }, ); @@ -405,7 +441,7 @@ impl TypeParameter { ) -> Result<(), ErrorEmitted> { let Self { is_from_parent, - name_ident, + name, type_id, .. } = self; @@ -418,7 +454,7 @@ impl TypeParameter { .module(ctx.engines()) .current_items() .symbols - .get(name_ident) + .get(name) .unwrap(); match sy.expect_typed_ref() { @@ -440,15 +476,11 @@ impl TypeParameter { ctx.engines.te().replace( ctx.engines(), *type_id, - TypeSourceInfo { - type_info: TypeInfo::UnknownGeneric { - name: name.clone(), - trait_constraints: trait_constraints.clone(), - parent: Some(*parent_type_id), - is_from_type_parameter: *is_from_type_parameter, - } - .into(), - source_id: name.span().source_id().copied(), + TypeInfo::UnknownGeneric { + name: name.clone(), + trait_constraints: trait_constraints.clone(), + parent: Some(*parent_type_id), + is_from_type_parameter: *is_from_type_parameter, }, ); } @@ -456,7 +488,7 @@ impl TypeParameter { _ => { handler.emit_err(CompileError::Internal( "Unexpected TyDeclaration for TypeParameter.", - self.name_ident.span(), + self.name.span(), )); } } @@ -466,10 +498,10 @@ impl TypeParameter { // declaration. let type_parameter_decl = ty::TyDecl::GenericTypeForFunctionScope(ty::GenericTypeForFunctionScope { - name: name_ident.clone(), + name: name.clone(), type_id: *type_id, }); - ctx.insert_symbol(handler, name_ident.clone(), type_parameter_decl) + ctx.insert_symbol(handler, name.clone(), type_parameter_decl) .ok(); Ok(()) diff --git a/sway-core/src/type_system/engine.rs b/sway-core/src/type_system/engine.rs index 7dea1cbb281..8c97dd475af 100644 --- a/sway-core/src/type_system/engine.rs +++ b/sway-core/src/type_system/engine.rs @@ -2,25 +2,140 @@ use crate::{ concurrent_slab::{ConcurrentSlab, ListDisplay}, decl_engine::*, engine_threading::*, + language::{ + parsed::{EnumDeclaration, StructDeclaration}, + ty::{TyEnumDecl, TyExpression, TyStructDecl}, + QualifiedCallPath, + }, type_system::priv_prelude::*, }; use core::fmt::Write; use hashbrown::{hash_map::RawEntryMut, HashMap}; use parking_lot::RwLock; -use std::{sync::Arc, time::Instant}; +use std::{ + hash::{BuildHasher, Hash, Hasher}, + sync::Arc, + time::Instant, +}; use sway_error::{ error::CompileError, handler::{ErrorEmitted, Handler}, type_error::TypeError, }; -use sway_types::{integer_bits::IntegerBits, span::Span, ProgramId, SourceId}; +use sway_types::{integer_bits::IntegerBits, span::Span, Ident, ProgramId, SourceId, Spanned}; use super::unify::unifier::UnifyKind; +/// To be able to garbage-collect [TypeInfo]s from the [TypeEngine] +/// we need to track which types need to be GCed when a particular +/// module, represented by its source id, is GCed. [TypeSourceInfo] +/// encapsulates this information. +/// +/// For types that should never be GCed the `source_id` must be `None`. +/// +/// The concrete logic of assigning `source_id`s to `type_info`s is +/// given in the [TypeEngine::get_type_fallback_source_id]. +// TODO: This logic will be further improved when https://github.com/FuelLabs/sway/issues/6603 +// is implemented (Optimize `TypeEngine` for garbage collection). +#[derive(Debug, Default, Clone)] +struct TypeSourceInfo { + type_info: Arc, + source_id: Option, +} + +impl TypeSourceInfo { + /// Returns true if the `self` would be equal to another [TypeSourceInfo] + /// created from `type_info` and `source_id`. + /// + /// This method allows us to test equality "upfront", without the need to + /// create a new [TypeSourceInfo] which would require a heap allocation + /// of a new [TypeInfo]. + pub(crate) fn equals( + &self, + type_info: &TypeInfo, + source_id: &Option, + ctx: &PartialEqWithEnginesContext, + ) -> bool { + &self.source_id == source_id && self.type_info.eq(type_info, ctx) + } +} + +impl HashWithEngines for TypeSourceInfo { + fn hash(&self, state: &mut H, engines: &Engines) { + self.type_info.hash(state, engines); + self.source_id.hash(state); + } +} + +impl EqWithEngines for TypeSourceInfo {} +impl PartialEqWithEngines for TypeSourceInfo { + fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool { + self.equals(&other.type_info, &other.source_id, ctx) + } +} + +/// Holds the singleton instances of [TypeSourceInfo]s of *replaceable types* that, +/// although being inserted anew into the [TypeEngine], all share the single definition. +/// This means that, e.g., all the different [TypeEngine::slab] entries representing +/// the, e.g., [TypeInfo::Unknown] will point to the same singleton instance +/// of the corresponding [TypeSourceInfo]. +#[derive(Debug, Clone)] +struct SingletonTypeSourceInfos { + /// The single instance of the [TypeSourceInfo] + /// representing the [TypeInfo::Unknown] replaceable type. + unknown: Arc, + /// The single instance of the [TypeSourceInfo] + /// representing the [TypeInfo::Numeric] replaceable type. + numeric: Arc, +} + +/// Holds the instances of [TypeInfo]s and allows exchanging them for [TypeId]s. +/// Supports LSP garbage collection of unused [TypeInfo]s assigned to a particular [SourceId]. +/// +/// ## Intended Usage +/// Inserting [TypeInfo]s into the type engine returns a [TypeId] that can later be used +/// to get the same [TypeInfo] by using the [TypeEngine::get] method. +/// +/// Properly using the various inserting methods is crucial for the optimal work of the type engine. +/// +/// These methods are grouped by the following convention and are intended to be used in the +/// order of precedence given below: +/// - `id_of_`: methods that always return the same [TypeId] for a type. +/// These methods, when inlined, compile to constant [TypeId]s. +/// - `new_`: methods that always return a new [TypeId] for a type. +/// - `insert_[_]`: methods that might insert a new type into the engine, +/// and return a new [TypeId], but also reuse an existing [TypeInfo] and return an existing [TypeId]. +/// - `insert`: the fallback method that should be used only in cases when the type is not known +/// at the call site. +/// +/// ## Internal Implementation +/// [TypeInfo]s are stored in a private [TypeSourceInfo] structure that binds them with a [SourceId] +/// of the module in which they are used. Those [TypeSourceInfo]s are referenced from the `slab`. +/// The actual [TypeId] of a [TypeInfo] is just an index in the `slab`. +/// +/// The engine attempts to maximize the reuse of [TypeSourceInfo]s by holding _shareable types_ +/// (see: [Self::is_type_shareable]) in the `shareable_types` hash map. +/// +/// TODO: Note that the reuse currently happens on the level of [TypeSourceInfo]s, and not [TypeInfo]s. +/// This is not optimal and will be improved in https://github.com/FuelLabs/sway/issues/6603. +/// Also note that because of that, having [TypeInfo] stored in `Arc` within the [TypeSourceInfo] +/// does not bring any real benefits. +/// +/// The implementation of the type engine is primarily directed with the goal of maximizing the +/// reuse of the [TypeSourceInfo]s while at the same time having the [TypeInfo]s bound to [SourceId]s +/// of their use site, so that they can be garbage collected. +/// +/// TODO: Note that the assignment of [SourceId]s to [TypeInfo]s is currently not as optimal as it +/// can be. This will be improved in https://github.com/FuelLabs/sway/issues/6603. #[derive(Debug)] pub struct TypeEngine { slab: ConcurrentSlab, - id_map: RwLock>, + /// Holds [TypeId]s of [TypeSourceInfo]s of shareable types (see: [Self::is_type_shareable]). + /// [TypeSourceInfo]s of shareable types can be reused if the type is used more + /// then once. In that case, for every usage, instead of inserting a new [TypeSourceInfo] instance + /// into the [Self::slab], the [TypeId] of an existing instance is returned. + shareable_types: RwLock, TypeId>>, + singleton_types: RwLock, unifications: ConcurrentSlab, last_replace: RwLock, } @@ -40,12 +155,28 @@ pub(crate) struct Unification { impl Default for TypeEngine { fn default() -> Self { - TypeEngine { + let singleton_types = SingletonTypeSourceInfos { + unknown: TypeSourceInfo { + type_info: TypeInfo::Unknown.into(), + source_id: None, + } + .into(), + numeric: TypeSourceInfo { + type_info: TypeInfo::Numeric.into(), + source_id: None, + } + .into(), + }; + + let mut te = TypeEngine { slab: Default::default(), - id_map: Default::default(), + shareable_types: Default::default(), + singleton_types: RwLock::new(singleton_types), unifications: Default::default(), last_replace: RwLock::new(Instant::now()), - } + }; + te.insert_shareable_built_in_types(); + te } } @@ -53,14 +184,614 @@ impl Clone for TypeEngine { fn clone(&self) -> Self { TypeEngine { slab: self.slab.clone(), - id_map: RwLock::new(self.id_map.read().clone()), + shareable_types: RwLock::new(self.shareable_types.read().clone()), + singleton_types: RwLock::new(self.singleton_types.read().clone()), unifications: self.unifications.clone(), last_replace: RwLock::new(*self.last_replace.read()), } } } +/// Generates: +/// - `id_of_` methods for every provided shareable built-in type. +/// - `insert_shareable_built_in_types` method for initial creation of built-in types within the [TypeEngine]. +/// - `get_shareable_built_in_type_id` method for potential retrieval of built-in types in the [TypeEngine::insert] method. +/// +/// Note that, when invoking the macro, the `unit` and the [TypeInfo::ErrorRecovery] types *must not be provided in the list*. +/// The shareable `unit` type requires a special treatment within the macro, because it is modeled +/// as [TypeInfo::Tuple] with zero elements and not as a separate [TypeInfo] variant. +/// The [TypeInfo::ErrorRecovery], although being an enum variant with the parameter (the [ErrorEmitted] proof), is +/// actually a single type because all the [ErrorEmitted] proofs are the same. +/// This special case is also handled within the macro. +/// +/// Unfortunately, due to limitations of Rust's macro-by-example, the [TypeInfo] must be +/// provided twice during the macro invocation, once as an expression `expr` and once as a pattern `pat`. +/// +/// The macro recursively creates the `id_of_` methods in order to get the proper `usize` value +/// generated, which corresponds to the index of those types within the slab. +macro_rules! type_engine_shareable_built_in_types { + // The base recursive case. + (@step $_idx:expr,) => {}; + + // The actual recursion step that generates the `id_of_` functions. + (@step $idx:expr, ($ty_name:ident, $ti:expr, $ti_pat:pat), $(($tail_ty_name:ident, $tail_ti:expr, $tail_ti_pat:pat),)*) => { + paste::paste! { + pub(crate) const fn [](&self) -> TypeId { + TypeId::new($idx) + } + } + + type_engine_shareable_built_in_types!(@step $idx + 1, $(($tail_ty_name, $tail_ti, $tail_ti_pat),)*); + }; + + // The entry point. Invoking the macro matches this arm. + ($(($ty_name:ident, $ti:expr, $ti_pat:pat),)*) => { + // The `unit` type is a special case. It will be inserted in the slab as the first type. + pub(crate) const fn id_of_unit(&self) -> TypeId { + TypeId::new(0) + } + + // The error recovery type is a special case. It will be inserted in the slab as the second type. + // To preserve the semantics of the `TypeInfo::ErrorRecovery(ErrorEmitted)`, we still insist on + // providing the proof of the error being emitted, although that proof is actually + // not needed to obtain the type id, nor is used within this method at all. + #[allow(unused_variables)] + pub(crate) const fn id_of_error_recovery(&self, error_emitted: ErrorEmitted) -> TypeId { + TypeId::new(1) + } + + // Generate the remaining `id_of_` methods. We start counting the indices from 2. + type_engine_shareable_built_in_types!(@step 2, $(($ty_name, $ti, $ti_pat),)*); + + // Generate the method that initially inserts the built-in shareable types into the `slab` in the right order. + // + // Note that we are inserting the types **only into the `slab`, but not into the `shareable_types`**, + // although they should, by definition, be in the `shareable_types` as well. + // + // What is the reason for not inserting them into the `shareable_types`? + // + // To insert them into the `shareable_types` we need `Engines` to be able to calculate + // the hash and equality with engines, and method is supposed be called internally during the creation + // of the `TypeEngine`. At that moment, we are creating a single, isolated engine, and do not + // have all the engines available. The only way to have it called with all the engines, is + // to do it when `Engines` are created. But this would mean that we cannot have a semantically + // valid `TypeEngine` created in isolation, without the `Engines`, which would be a problematic + // design that breaks cohesion and creates unexpected dependency. + // + // Note that having the built-in shareable types initially inserted only in the `slab` does + // not cause any issues with type insertion and retrieval. The `id_of_` methods return + // indices that are compile-time constants and there is no need for `shareable_types` access. + // Also, calling `insert` with built-in shareable types has an optimized path which will redirect + // to `id_of_` methods, again bypassing the `shareable_types`. + // + // The only negligible small "penalty" comes during replacements of replaceable types, + // where a potential replacement with a built-in shareable type will create a separate instance + // of that built-in type and add it to `shareable_types`. + fn insert_shareable_built_in_types(&mut self) { + use TypeInfo::*; + + let tsi = TypeSourceInfo { + type_info: Tuple(vec![]).into(), + source_id: None, + }; + self.slab.insert(tsi); + + // For the `ErrorRecovery`, we need an `ErrorEmitted` instance. + // All of its instances are the same, so we will use, or perhaps misuse, + // the `Handler::cancel` method here to obtain an instance. + let tsi = TypeSourceInfo { + type_info: ErrorRecovery(crate::Handler::default().cancel()).into(), + source_id: None, + }; + self.slab.insert(tsi); + + $( + let tsi = TypeSourceInfo { + type_info: $ti.into(), + source_id: None, + }; + self.slab.insert(tsi); + )* + } + + /// Returns the [TypeId] of the `type_info` only if the type info is + /// a shareable built-in type, otherwise `None`. + /// + /// For a particular shareable built-in type, the method guarantees to always + /// return the same, existing [TypeId]. + fn get_shareable_built_in_type_id(&self, type_info: &TypeInfo) -> Option { + paste::paste! { + use TypeInfo::*; + match type_info { + Tuple(v) if v.is_empty() => Some(self.id_of_unit()), + // Here we also "pass" the dummy value obtained from `Handler::cancel` which will be + // optimized away. + ErrorRecovery(_) => Some(self.id_of_error_recovery(crate::Handler::default().cancel())), + $( + $ti_pat => Some(self.[]()), + )* + _ => None + } + } + } + + /// Returns true if the type represented by the `type_info` + /// is a shareable built-in type. + fn is_shareable_built_in_type(&self, type_info: &TypeInfo) -> bool { + use TypeInfo::*; + match type_info { + Tuple(v) if v.is_empty() => true, + // Here we also "pass" the dummy value obtained from `Handler::cancel` which will be + // optimized away. + ErrorRecovery(_) => true, + $( + $ti_pat => true, + )* + _ => false + } + } + } +} + impl TypeEngine { + type_engine_shareable_built_in_types!( + (never, Never, Never), + (string_slice, StringSlice, StringSlice), + ( + u8, + UnsignedInteger(IntegerBits::Eight), + UnsignedInteger(IntegerBits::Eight) + ), + ( + u16, + UnsignedInteger(IntegerBits::Sixteen), + UnsignedInteger(IntegerBits::Sixteen) + ), + ( + u32, + UnsignedInteger(IntegerBits::ThirtyTwo), + UnsignedInteger(IntegerBits::ThirtyTwo) + ), + ( + u64, + UnsignedInteger(IntegerBits::SixtyFour), + UnsignedInteger(IntegerBits::SixtyFour) + ), + ( + u256, + UnsignedInteger(IntegerBits::V256), + UnsignedInteger(IntegerBits::V256) + ), + (bool, Boolean, Boolean), + (b256, B256, B256), + (contract, Contract, Contract), + (raw_ptr, RawUntypedPtr, RawUntypedPtr), + (raw_slice, RawUntypedSlice, RawUntypedSlice), + ); + + /// Inserts a new [TypeInfo::Unknown] into the [TypeEngine] and returns its [TypeId]. + /// + /// [TypeInfo::Unknown] is an always replaceable type and the method + /// guarantees that a new (or unused) [TypeId] will be returned on every + /// call. + pub(crate) fn new_unknown(&self) -> TypeId { + TypeId::new( + self.slab + .insert_arc(self.singleton_types.read().unknown.clone()), + ) + } + + /// Inserts a new [TypeInfo::Numeric] into the [TypeEngine] and returns its [TypeId]. + /// + /// [TypeInfo::Numeric] is an always replaceable type and the method + /// guarantees that a new (or unused) [TypeId] will be returned on every + /// call. + pub(crate) fn new_numeric(&self) -> TypeId { + TypeId::new( + self.slab + .insert_arc(self.singleton_types.read().numeric.clone()), + ) + } + + /// Inserts a new [TypeInfo::Placeholder] into the [TypeEngine] and returns its [TypeId]. + /// + /// [TypeInfo::Placeholder] is an always replaceable type and the method + /// guarantees that a new (or unused) [TypeId] will be returned on every + /// call. + pub(crate) fn new_placeholder(&self, type_parameter: TypeParameter) -> TypeId { + self.new_placeholder_impl(TypeInfo::Placeholder(type_parameter)) + } + + fn new_placeholder_impl(&self, placeholder: TypeInfo) -> TypeId { + let source_id = self.get_placeholder_fallback_source_id(&placeholder); + let tsi = TypeSourceInfo { + type_info: placeholder.into(), + source_id, + }; + TypeId::new(self.slab.insert(tsi)) + } + + /// Inserts a new [TypeInfo::UnknownGeneric] into the [TypeEngine] and returns its [TypeId]. + /// + /// [TypeInfo::UnknownGeneric] is an always replaceable type and the method + /// guarantees that a new (or unused) [TypeId] will be returned on every + /// call. + pub(crate) fn new_unknown_generic( + &self, + name: Ident, + trait_constraints: VecSet, + parent: Option, + is_from_type_parameter: bool, + ) -> TypeId { + self.new_unknown_generic_impl(TypeInfo::UnknownGeneric { + name, + trait_constraints, + parent, + is_from_type_parameter, + }) + } + + fn new_unknown_generic_impl(&self, unknown_generic: TypeInfo) -> TypeId { + let source_id = Self::get_unknown_generic_fallback_source_id(&unknown_generic); + let tsi = TypeSourceInfo { + type_info: unknown_generic.into(), + source_id, + }; + TypeId::new(self.slab.insert(tsi)) + } + + /// Inserts a new [TypeInfo::UnknownGeneric] into the [TypeEngine] + /// that represents a `Self` type and returns its [TypeId]. + /// The unknown generic `name` [Ident] will be set to "Self" with the provided `use_site_span`. + /// + /// Note that the span in general does not point to a reserved word "Self" in + /// the source code, nor is related to it. The `Self` type represents the type + /// in `impl`s and does not necessarily relate to the "Self" keyword in code. + /// + /// Therefore, *the span must always point to a location in the source file in which + /// the particular `Self` type is, e.g., being declared or implemented*. + /// + /// Returns the [TypeId] and the [Ident] set to "Self" and the provided `use_site_span`. + pub(crate) fn new_unknown_generic_self( + &self, + use_site_span: Span, + is_from_type_parameter: bool, + ) -> (TypeId, Ident) { + let name = Ident::new_with_override("Self".into(), use_site_span); + let type_id = + self.new_unknown_generic(name.clone(), VecSet(vec![]), None, is_from_type_parameter); + (type_id, name) + } + + /// Inserts a new [TypeInfo::Enum] into the [TypeEngine] and returns + /// its [TypeId], or returns a [TypeId] of an existing shareable enum type + /// that corresponds to the enum given by the `decl_id`. + pub(crate) fn insert_enum(&self, engines: &Engines, decl_id: DeclId) -> TypeId { + let decl = engines.de().get_enum(&decl_id); + let source_id = Self::get_enum_fallback_source_id(&decl); + let is_shareable_type = self.is_shareable_enum(engines, &decl); + let type_info = TypeInfo::Enum(decl_id); + self.insert_or_replace_type_source_info( + engines, + type_info, + source_id, + is_shareable_type, + None, + ) + } + + /// Inserts a new [TypeInfo::Struct] into the [TypeEngine] and returns + /// its [TypeId], or returns a [TypeId] of an existing shareable struct type + /// that corresponds to the struct given by the `decl_id`. + pub(crate) fn insert_struct(&self, engines: &Engines, decl_id: DeclId) -> TypeId { + let decl = engines.de().get_struct(&decl_id); + let source_id = Self::get_struct_fallback_source_id(&decl); + let is_shareable_type = self.is_shareable_struct(engines, &decl); + let type_info = TypeInfo::Struct(decl_id); + self.insert_or_replace_type_source_info( + engines, + type_info, + source_id, + is_shareable_type, + None, + ) + } + + /// Inserts a new [TypeInfo::Tuple] into the [TypeEngine] and returns + /// its [TypeId], or returns a [TypeId] of an existing shareable tuple type + /// that corresponds to the tuple given by the `elements`. + pub(crate) fn insert_tuple(&self, engines: &Engines, elements: Vec) -> TypeId { + let source_id = self.get_tuple_fallback_source_id(&elements); + let is_shareable_type = self.is_shareable_tuple(engines, &elements); + let type_info = TypeInfo::Tuple(elements); + self.insert_or_replace_type_source_info( + engines, + type_info, + source_id, + is_shareable_type, + None, + ) + } + + /// Same as [Self::insert_tuple], but intended to be used mostly in the code generation, + /// where the tuple elements are non-annotated [TypeArgument]s that contain + /// only the [TypeId]s provided in the `elements`. + pub(crate) fn insert_tuple_without_annotations( + &self, + engines: &Engines, + elements: Vec, + ) -> TypeId { + self.insert_tuple( + engines, + elements.into_iter().map(|type_id| type_id.into()).collect(), + ) + } + + /// Inserts a new [TypeInfo::Array] into the [TypeEngine] and returns + /// its [TypeId], or returns a [TypeId] of an existing shareable array type + /// that corresponds to the array given by the `elem_type` and the `length`. + pub(crate) fn insert_array( + &self, + engines: &Engines, + elem_type: TypeArgument, + length: Length, + ) -> TypeId { + let source_id = self.get_array_fallback_source_id(&elem_type, &length); + let is_shareable_type = self.is_shareable_array(engines, &elem_type, &length); + let type_info = TypeInfo::Array(elem_type, length); + self.insert_or_replace_type_source_info( + engines, + type_info, + source_id, + is_shareable_type, + None, + ) + } + + /// Same as [Self::insert_array], but intended to insert arrays without annotations. + // TODO: Unlike `insert_array`, once the https://github.com/FuelLabs/sway/issues/6603 gets implemented, + // this method will get the additional `use_site_source_id` parameter. + pub(crate) fn insert_array_without_annotations( + &self, + engines: &Engines, + elem_type: TypeId, + length: usize, + ) -> TypeId { + self.insert_array(engines, elem_type.into(), Length::new(length)) + } + + /// Inserts a new [TypeInfo::StringArray] into the [TypeEngine] and returns + /// its [TypeId], or returns a [TypeId] of an existing shareable string array type + /// that corresponds to the string array given by the `length`. + pub(crate) fn insert_string_array(&self, engines: &Engines, length: Length) -> TypeId { + let source_id = Self::get_string_array_fallback_source_id(&length); + let is_shareable_type = self.is_shareable_string_array(&length); + let type_info = TypeInfo::StringArray(length); + self.insert_or_replace_type_source_info( + engines, + type_info, + source_id, + is_shareable_type, + None, + ) + } + + /// Same as [Self::insert_string_array], but intended to insert string arrays without annotations. + // TODO: Unlike `insert_string_array`, once the https://github.com/FuelLabs/sway/issues/6603 gets implemented, + // this method will get the additional `use_site_source_id` parameter. + pub(crate) fn insert_string_array_without_annotations( + &self, + engines: &Engines, + length: usize, + ) -> TypeId { + self.insert_string_array(engines, Length::new(length)) + } + + /// Inserts a new [TypeInfo::ContractCaller] into the [TypeEngine] and returns its [TypeId]. + /// + /// [TypeInfo::ContractCaller] is not a shareable type and the method + /// guarantees that a new (or unused) [TypeId] will be returned on every + /// call. + pub(crate) fn new_contract_caller( + &self, + engines: &Engines, + abi_name: AbiName, + address: Option>, + ) -> TypeId { + // The contract caller type shareability would be calculated as: + // + // !(Self::is_replaceable_contract_caller(abi_name, address) + // || + // Self::is_contract_caller_distinguishable_by_annotations(abi_name, address)) + // + // If the contract caller is replaceable, either the `abi_name` id `Deferred` or the `address` is `None`. + // On the other hand, if the `abi_name` is `Known` or the `address` is `Some`, it will be distinguishable by annotations. + // Which means, it will be either replaceable or distinguishable by annotations, which makes the condition always + // evaluating to false. + // + // The fact that we cannot share `ContractCaller`s is not an issue. In any real-life project, the number of contract callers + // will be negligible, order of magnitude of ~10. + let source_id = Self::get_contract_caller_fallback_source_id(&abi_name, &address); + let type_info = TypeInfo::ContractCaller { abi_name, address }; + self.insert_or_replace_type_source_info(engines, type_info, source_id, false, None) + } + + /// Inserts a new [TypeInfo::Alias] into the [TypeEngine] and returns its [TypeId]. + /// + /// [TypeInfo::Alias] is not a shareable type and the method + /// guarantees that a new (or unused) [TypeId] will be returned on every + /// call. + pub(crate) fn new_alias(&self, engines: &Engines, name: Ident, ty: TypeArgument) -> TypeId { + // The alias type shareability would be calculated as `!(false || true) ==>> false`. + let source_id = self.get_alias_fallback_source_id(&name, &ty); + let type_info = TypeInfo::Alias { name, ty }; + self.insert_or_replace_type_source_info(engines, type_info, source_id, false, None) + } + + /// Inserts a new [TypeInfo::Custom] into the [TypeEngine] and returns its [TypeId]. + /// + /// [TypeInfo::Custom] is not a shareable type and the method + /// guarantees that a new (or unused) [TypeId] will be returned on every + /// call. + pub(crate) fn new_custom( + &self, + engines: &Engines, + qualified_call_path: QualifiedCallPath, + type_arguments: Option>, + ) -> TypeId { + let source_id = self.get_custom_fallback_source_id(&qualified_call_path, &type_arguments); + // The custom type shareability would be calculated as `!(true || true) ==>> false`. + // TODO: Improve handling of `TypeInfo::Custom` and `TypeInfo::TraitType`` within the `TypeEngine`: + // https://github.com/FuelLabs/sway/issues/6601 + let is_shareable_type = false; + let type_info = TypeInfo::Custom { + qualified_call_path, + type_arguments, + }; + self.insert_or_replace_type_source_info( + engines, + type_info, + source_id, + is_shareable_type, + None, + ) + } + + /// Inserts a new [TypeInfo::Custom] into the [TypeEngine] and returns its [TypeId]. + /// The custom type is defined only by its `name`. In other words, it does not have + /// the qualified call path or type arguments. This is a very common situation in + /// the code that just uses the type name, like, e.g., when instantiating structs: + /// + /// ```ignore + /// let _ = Struct { }; + /// ``` + /// + /// [TypeInfo::Custom] is not a shareable type and the method + /// guarantees that a new (or unused) [TypeId] will be returned on every + /// call. + pub(crate) fn new_custom_from_name(&self, engines: &Engines, name: Ident) -> TypeId { + self.new_custom(engines, name.into(), None) + } + + /// Creates a new [TypeInfo::Custom] that represents a Self type. + /// + /// The `span` must either be a [Span::dummy] or a span pointing + /// to text "Self" or "self", otherwise the method panics. + /// + /// [TypeInfo::Custom] is not a shareable type and the method + /// guarantees that a new (or unused) [TypeId] will be returned on every + /// call. + pub(crate) fn new_self_type(&self, engines: &Engines, span: Span) -> TypeId { + let source_id = span.source_id().copied(); + // The custom type shareability would be calculated as `!(true || true) ==>> false`. + // TODO: Improve handling of `TypeInfo::Custom` and `TypeInfo::TraitType`` within the `TypeEngine`: + // https://github.com/FuelLabs/sway/issues/6601 + let is_shareable_type = false; + let type_info = TypeInfo::new_self_type(span); + self.insert_or_replace_type_source_info( + engines, + type_info, + source_id, + is_shareable_type, + None, + ) + } + + /// Inserts a new [TypeInfo::Slice] into the [TypeEngine] and returns + /// its [TypeId], or returns a [TypeId] of an existing shareable slice type + /// that corresponds to the slice given by the `elem_type`. + pub(crate) fn insert_slice(&self, engines: &Engines, elem_type: TypeArgument) -> TypeId { + let source_id = self.get_slice_fallback_source_id(&elem_type); + let is_shareable_type = self.is_shareable_slice(engines, &elem_type); + let type_info = TypeInfo::Slice(elem_type); + self.insert_or_replace_type_source_info( + engines, + type_info, + source_id, + is_shareable_type, + None, + ) + } + + /// Inserts a new [TypeInfo::Ptr] into the [TypeEngine] and returns + /// its [TypeId], or returns a [TypeId] of an existing shareable pointer type + /// that corresponds to the pointer given by the `pointee_type`. + pub(crate) fn insert_ptr(&self, engines: &Engines, pointee_type: TypeArgument) -> TypeId { + let source_id = self.get_ptr_fallback_source_id(&pointee_type); + let is_shareable_type = self.is_shareable_ptr(engines, &pointee_type); + let type_info = TypeInfo::Ptr(pointee_type); + self.insert_or_replace_type_source_info( + engines, + type_info, + source_id, + is_shareable_type, + None, + ) + } + + /// Inserts a new [TypeInfo::Ref] into the [TypeEngine] and returns + /// its [TypeId], or returns a [TypeId] of an existing shareable reference type + /// that corresponds to the reference given by the `referenced_type` and `to_mutable_value`. + pub(crate) fn insert_ref( + &self, + engines: &Engines, + to_mutable_value: bool, + referenced_type: TypeArgument, + ) -> TypeId { + let source_id = self.get_ref_fallback_source_id(&referenced_type); + let is_shareable_type = self.is_shareable_ref(engines, &referenced_type); + let type_info = TypeInfo::Ref { + to_mutable_value, + referenced_type, + }; + self.insert_or_replace_type_source_info( + engines, + type_info, + source_id, + is_shareable_type, + None, + ) + } + + /// Inserts a new [TypeInfo::TraitType] into the [TypeEngine] and returns + /// its [TypeId], or returns a [TypeId] of an existing shareable trait type type + /// that corresponds to the trait type given by the `name` and `trait_type_id`. + pub(crate) fn insert_trait_type( + &self, + engines: &Engines, + name: Ident, + trait_type_id: TypeId, + ) -> TypeId { + let source_id = self.get_trait_type_fallback_source_id(&name, &trait_type_id); + // The trait type type shareability would be calculated as `!(false || false) ==>> true`. + // TODO: Improve handling of `TypeInfo::Custom` and `TypeInfo::TraitType`` within the `TypeEngine`: + // https://github.com/FuelLabs/sway/issues/6601 + let is_shareable_type = true; + let type_info = TypeInfo::TraitType { + name, + trait_type_id, + }; + self.insert_or_replace_type_source_info( + engines, + type_info, + source_id, + is_shareable_type, + None, + ) + } + + /// Same as [Self::insert_ref], but intended to insert references without annotations. + // TODO: Unlike `insert_ref`, once the https://github.com/FuelLabs/sway/issues/6603 gets implemented, + // this method will get the additional `use_site_source_id` parameter. + pub(crate) fn insert_ref_without_annotations( + &self, + engines: &Engines, + to_mutable_value: bool, + referenced_type: TypeId, + ) -> TypeId { + self.insert_ref(engines, to_mutable_value, referenced_type.into()) + } + /// Inserts a [TypeInfo] into the [TypeEngine] and returns a [TypeId] /// referring to that [TypeInfo]. pub(crate) fn insert( @@ -69,37 +800,1071 @@ impl TypeEngine { ty: TypeInfo, source_id: Option<&SourceId>, ) -> TypeId { - let source_id = source_id.copied().or_else(|| info_to_source_id(&ty)); - let tsi = TypeSourceInfo { - type_info: ty.clone().into(), - source_id, + // Avoid all of the heavy lifting of inserting and replacing logic, if `ty` is a shareable built-in type. + // + // Note that we are ignoring here the eventual `source_id` that could be provided by the caller. + // Ideally, for shareable built-in types that should never be the case, but `insert` is called in + // rare cases where the `ty` is not known and not inspected and is usually providing the use site span. + // + // The reason for ignoring the `source_id` is, because we want these types to be reused and "live forever" + // and never be garbage-collected and thus we do not assign any source id to them. + if let Some(type_id) = self.get_shareable_built_in_type_id(&ty) { + return type_id; + } + + // Same for the replaceable types, avoid heavy lifting. + // Note that we don't want to pack this `match` into a method, because we want to avoid cloning + // of `ty` in the case of it being a `Placeholder` or `UnknownGeneric`. + // + // TODO: Also, note that also here we are ignoring the `source_id` provided by the caller. + // This is only temporary until https://github.com/FuelLabs/sway/issues/6603 gets implemented. + // Until then, this shortcut corresponds to the current `TypeEngine` behavior: + // - `Unknown`s and `Numeric`s never have `source_id` assigned. + // - for `Placeholder`s and `UnknownGeneric`s, the `source_id` is extracted from the call site. + match ty { + TypeInfo::Unknown => return self.new_unknown(), + TypeInfo::Numeric => return self.new_numeric(), + TypeInfo::Placeholder(_) => return self.new_placeholder_impl(ty), + TypeInfo::UnknownGeneric { .. } => return self.new_unknown_generic_impl(ty), + _ => (), + } + + let is_shareable_type = self.is_type_shareable(engines, &ty); + let source_id = source_id + .copied() + .or_else(|| self.get_type_fallback_source_id(engines, &ty)); + + self.insert_or_replace_type_source_info(engines, ty, source_id, is_shareable_type, None) + } + + /// This method performs two actions, depending on the `replace_at_type_id`. + /// + /// If the `replace_at_type_id` is `Some`, this indicates that we want to unconditionally replace the [TypeSourceInfo] + /// currently located at `replace_at_type_id` with the one made of the `ty` + `source_id` pair. + /// In the case of replacement the method always return the [TypeId] provided in `replace_at_type_id`. + /// + /// If the `replace_at_type_id` is `None`, this indicates that we want to insert the [TypeSourceInfo], made of the + /// `ty` + `source_id` pair, into the `TypeEngine`. The insertion into the engine might require a new insert into + /// the `slab` or just returning a [TypeId] of an existing shareable [TypeSourceInfo] that is equal to the one defined by + /// the `ty` + `source_id` pair. + /// + /// If a new insertion is always made, or a reuse is possible, depends on the shareability of `ty` that is given by + /// `is_shareable_type`. + fn insert_or_replace_type_source_info( + &self, + engines: &Engines, + ty: TypeInfo, + source_id: Option, + is_shareable_type: bool, + replace_at_type_id: Option, + ) -> TypeId { + if !is_shareable_type { + let tsi = TypeSourceInfo { + type_info: ty.into(), + source_id, + }; + match replace_at_type_id { + Some(existing_id) => { + self.slab.replace(existing_id.index(), tsi); + existing_id + } + None => TypeId::new(self.slab.insert(tsi)), + } + } else { + let mut shareable_types = self.shareable_types.write(); + + let hash_builder = shareable_types.hasher().clone(); + let ty_hash = + self.compute_hash_without_heap_allocation(engines, &hash_builder, &ty, &source_id); + + let raw_entry = shareable_types.raw_entry_mut().from_hash(ty_hash, |x| { + // Not that the equality with engines of the types contained in the + // `shareable_types` is "strict" in the sense that only one element can equal. + // This is because the types that have annotation fields, a.k.a. distinguishable by + // annotations types, will never end up in the hash map because they are considered + // not to be shareable. + x.equals(&ty, &source_id, &PartialEqWithEnginesContext::new(engines)) + }); + match raw_entry { + RawEntryMut::Occupied(o) => match replace_at_type_id { + Some(existing_id) => { + let existing_type_source_info = o.key(); + self.slab + .replace_arc(existing_id.index(), existing_type_source_info.clone()); + existing_id + } + None => *o.get(), + }, + RawEntryMut::Vacant(v) => { + let tsi = TypeSourceInfo { + type_info: ty.into(), + source_id, + }; + let tsi_arc = Arc::new(tsi); + let type_id = TypeId::new(self.slab.insert_arc(tsi_arc.clone())); + v.insert_with_hasher( + ty_hash, + tsi_arc.clone(), + type_id, + make_hasher(&hash_builder, engines), + ); + match replace_at_type_id { + Some(existing_id) => { + self.slab.replace_arc(existing_id.index(), tsi_arc); + existing_id + } + None => type_id, + } + } + } + } + } + + /// Computes the same hash as the [Hasher] returned by [make_hasher] but without + /// allocating a new [TypeInfo] on the heap. + fn compute_hash_without_heap_allocation( + &self, + engines: &Engines, + hash_builder: &impl BuildHasher, + type_info: &TypeInfo, + source_id: &Option, + ) -> u64 { + let mut state = hash_builder.build_hasher(); + type_info.hash(&mut state, engines); + source_id.hash(&mut state); + state.finish() + } + + /// Returns true if the `ty` is a type that can be replaced by using + /// the [Self::replace] method during the type unification. + fn is_replaceable_type(ty: &TypeInfo) -> bool { + match ty { + TypeInfo::Unknown + | TypeInfo::Numeric + | TypeInfo::Placeholder(_) + | TypeInfo::UnknownGeneric { .. } => true, + TypeInfo::ContractCaller { abi_name, address } => { + Self::is_replaceable_contract_caller(abi_name, address) + } + _ => false, + } + } + + fn is_replaceable_contract_caller( + abi_name: &AbiName, + address: &Option>, + ) -> bool { + address.is_none() || matches!(abi_name, AbiName::Deferred) + } + + /// Returns true if the `ty` is a shareable type. + /// + /// A shareable type instance can be reused by the engine and is put into the [Self::shareable_types]. + fn is_type_shareable(&self, engines: &Engines, ty: &TypeInfo) -> bool { + !(self.is_type_changeable(engines, ty) || self.is_type_distinguishable_by_annotations(ty)) + } + + /// Returns true if the `ty` is a changeable type. A changeable type is either: + /// - a type that can be replaced during the type unification (by calling [Self::replace]). + /// We call such types replaceable types. A typical example would be [TypeInfo::UnknownGeneric]. + /// - or a type that is recursively defined over one or more replaceable types. E.g., a + /// generic enum type `SomeEnum` that is still not monomorphized is a changeable type. + /// Note that a monomorphized version of `SomeEnum`, like e.g., `SomeEnum` *is not + /// changeable*. + /// + /// Note that the changeability of a type is tightly related to the unification process + /// and the process of handling the types within the [TypeEngine]. As such, it is not + /// seen as a property of a type itself, but rather as an information on how the [TypeEngine] + /// treats the type. That's why the definition of the changeability of a type resides + /// inside of the [TypeEngine]. + pub(crate) fn is_type_changeable(&self, engines: &Engines, ty: &TypeInfo) -> bool { + let decl_engine = engines.de(); + let parsed_decl_engine = engines.pe(); + match ty { + // Shareable built-in types are unchangeable by definition. + // These type have only one shared `TypeInfo` instance per type + // (and one for each unsigned integer). + TypeInfo::StringSlice + | TypeInfo::UnsignedInteger(_) + | TypeInfo::Boolean + | TypeInfo::B256 + | TypeInfo::RawUntypedPtr + | TypeInfo::RawUntypedSlice + | TypeInfo::ErrorRecovery(_) + | TypeInfo::Contract + | TypeInfo::Never => false, + + // Note that `TypeParam` is currently not used at all. + TypeInfo::TypeParam(_) => false, + + // `StringArray`s are not changeable. We will have one shared + // `TypeInfo` instance for every string size. Note that in case + // of explicitly defined string arrays, e.g. in the storage or type ascriptions + // like `str[5]`, we can also have different instances for string + // arrays of the same size, because the `Length` in that case contains + // as well the span of the size (`5` in the example). + TypeInfo::StringArray(_) => false, + + // Replaceable types are, by definition, changeable. + TypeInfo::Unknown + | TypeInfo::Numeric + | TypeInfo::Placeholder(_) + | TypeInfo::UnknownGeneric { .. } => true, + + // The `ContractCaller` can be replaceable, and thus, sometimes changeable. + TypeInfo::ContractCaller { abi_name, address } => { + Self::is_replaceable_contract_caller(abi_name, address) + } + + // For the types are defined over other types, inspect recursively their constituting types. + TypeInfo::Enum(decl_id) => { + let decl = decl_engine.get_enum(decl_id); + self.is_changeable_enum(engines, &decl) + } + TypeInfo::UntypedEnum(decl_id) => { + let decl = parsed_decl_engine.get_enum(decl_id); + self.is_changeable_untyped_enum(engines, &decl) + } + TypeInfo::Struct(decl_id) => { + let decl = decl_engine.get_struct(decl_id); + self.is_changeable_struct(engines, &decl) + } + TypeInfo::UntypedStruct(decl_id) => { + let decl = parsed_decl_engine.get_struct(decl_id); + self.is_changeable_untyped_struct(engines, &decl) + } + TypeInfo::Tuple(elements) => self.is_changeable_tuple(engines, elements), + + // Currently, we support only non-generic aliases. Which means the alias + // will never be changeable. + // TODO: (GENERIC-TYPE-ALIASES) If we ever introduce generic type aliases, update this accordingly. + TypeInfo::Alias { name: _, ty: _ } => false, + + // The following types are changeable if their type argument is changeable. + TypeInfo::Array(ta, _) + | TypeInfo::Slice(ta) + | TypeInfo::Ptr(ta) + | TypeInfo::Ref { + referenced_type: ta, + .. + } => self.is_changeable_type_argument(engines, ta), + + // TODO: Improve handling of `TypeInfo::Custom` and `TypeInfo::TraitType`` within the `TypeEngine`: + // https://github.com/FuelLabs/sway/issues/6601 + TypeInfo::Custom { .. } => true, + TypeInfo::TraitType { .. } => false, + } + } + + /// Returns true if two [TypeInfo] instances that are equal (with engines) and have same hashes (with engines) + /// should potentially still be treated, within the type engine, as different types. + /// + /// [TypeParameter]s, [TypeArgument]s, and [Length]s can be "annotated". This means that, aside from the information they + /// provide, like, e.g., [TypeArgument::type_id] or [Length::val], they can also, optionally, provide additional information + /// most notably various spans. + /// + /// Same is with [Ident]s. From the hashing and equality (with engines) perspective, only the string value matters, + /// but from the strict equality point of view, [Ident]'s span is also relevant. + /// + /// Thus, from the unification and type equivalence perspective, two [TypeArgument]s with the same `type_id` represent + /// the same type. But if those two type arguments differ in their annotations, the [TypeEngine] must be able to distinguish between + /// the equal (from the unification perspective) types that use those two different type arguments. + /// + /// In this example: + /// + /// ```ignore + /// let a: [u64;3] = (0, 0, 0); + /// let b: [u64;3] = (0, 0, 0); + /// ``` + /// + /// `a` and `b` will have the same type, but the span annotations in their [TypeArgument]s and [Length]s will be different + /// (different spans pointing to two "u64"s and two "3"s) and thus the [TypeEngine] must treat those two types as two + /// different types and when inserting them, assign them two different [TypeId]s, although the types themselves are not + /// changeable. + /// + /// To sum it up: + /// - if the `ty` consists of [TypeArgument]s, [TypeParameter]s, or [Length]s, they myst be check for annotations. + /// - if the `ty` contains, e.g., [Ident]s, it is considered to be distinguishable by annotations. + fn is_type_distinguishable_by_annotations(&self, ty: &TypeInfo) -> bool { + match ty { + // Types that do not have any annotations. + TypeInfo::StringSlice + | TypeInfo::UnsignedInteger(_) + | TypeInfo::Boolean + | TypeInfo::B256 + | TypeInfo::RawUntypedPtr + | TypeInfo::RawUntypedSlice + | TypeInfo::ErrorRecovery(_) + | TypeInfo::Never + | TypeInfo::Unknown + | TypeInfo::Numeric + | TypeInfo::Contract + | TypeInfo::TypeParam(_) => false, + + // Types that are always distinguishable because they have the `name: Ident`. + // + // Let's explain this in more detail, taking the `TypeInfo::Alias` as an example. + // `TypeInfo::Alias` consists of the `name: Ident` and the `ty: TypeArgument`. + // + // Consider that we have two aliases with the same name and aliasing the same type but defined in different modules. + // Thus, they would be two _different_ alias types. But because the spans in the `name` and `ty` do not count + // neither for the equality check nor for the hash calculation, those two types will always be equal (with engines) + // and also have the same hashes (with engines). + // + // This means that the `TypeEngine` would see them as the same type which would be wrong. + // The fact that they are always distinguishable by annotations (span in the `name` and spans in the `ty`) + // is actually a fortunate fact here, because it will help the `TypeEngine` to distinguish them. + // + // The consequence of this fact is, that all `TypeInfo::Alias`es are _always distinguishable by annotations_. + // + // The downside is that repeated usages of an actually *same* alias type will create + // unnecessary new instances in the `TypeEngine` for every usage :-( + // + // Luckily, `TraitType`s and `Alias`es are rarely used and the number of their instances + // within the `TypeEngine` will always be negligible, so we don't need to worry about this downside. + // (At the time of writing this comment, out of ~200,000 types in the `TypeEngine` in a + // realistic real-world project only ~20 were type aliases and only ~5 were trait types.) + // And the `UnknownGeneric` is anyhow a changeable type. + TypeInfo::UnknownGeneric { .. } + // | TypeInfo::TraitType { .. } + | TypeInfo::Alias { .. } => true, + + TypeInfo::StringArray(l) => l.is_annotated(), + + // If the contract caller has the `abi_name` defined (AbiName::Know) the span information + // that comes with the `Ident`s of the `CallPath` is not relevant for the equality + // and hashing (with engines) but makes two same names distinguishable. The same thing is + // with the `address` expression. It can be, e.g., the same literal, but it will have different + // spans. Moreover, the same `abi_name`, depending on the context, can represent different + // ABI declarations, like in the example below: + // + // fn a() { + // use ::lib_a::Abi as Abi; // <<<--- `Abi` coming from `lib_**a**`. + // let _ = abi(Abi, 0x1111111111111111111111111111111111111111111111111111111111111111); + // } + + // fn b() { + // use ::lib_b::Abi as Abi; // <<<--- `Abi` coming from `lib_**b**`. + // let _ = abi(Abi, 0x1111111111111111111111111111111111111111111111111111111111111111); + // } + // + // This all means, if a `ContractCaller` has either the `abi_name` or the `address` defined, + // it is distinguishable by annotations. + TypeInfo::ContractCaller { abi_name, address } => Self::is_contract_caller_distinguishable_by_annotations(abi_name, address), + + // Enums `decl`s are either coming from enum declarations, + // or from their monomorphizations. If an enum declaration is generic, + // its type parameters will always be annotated, having, e.g., spans of + // generic parameter names, like, e.g., "T". + // Also, all the enum variants have `TypeArguments` that are _always_ annotated + // with the type span. + // + // In other words, all `TyEnumDecl`s are annotated. + // The question is, if the monomorphization can produce two same `decl`s that + // are differently annotated. E.g., when unifying the generic parameter "T" with "u64", + // like in the below example, will the span of the type parameter "T" change + // to "u64": + // + // let _ = GenericEnum::::A(42u64); + // let _ = GenericEnum::::A(42u64); + // + // In that case, the two equal `decl`s obtained via two monomorphizations above, + // would be differently annotated, and thus, distinguishable by annotations. + // + // The answer is *no*. The monomorphization changes only the `TypeId`s of the + // `TypeParameter`s and `TypeArgument`s but leaves the original spans untouched. + // Therefore, we can never end up in a situation that an annotation differs from + // the one in the original `TyEnumDecl` coming from the enum declaration. + // + // Thus, any two equal `TyEnumDecl`s are never distinguishable by annotations. + TypeInfo::Enum(_) => false, + + // The same argument as above applies to struct and `TyStructDecl`s. + TypeInfo::Struct(_) => false, + + // TODO: (UNTYPED-TYPES) Reassess this once `UntypedEnum` and `UntypedStruct` + // start getting logic. + TypeInfo::UntypedEnum(_) => false, + + // TODO: (UNTYPED-TYPES) Reassess this once `UntypedEnum` and `UntypedStruct` + // start getting logic. + TypeInfo::UntypedStruct(_) => false, + + // Equal (with engines) tuple types can have different annotations and are in that case + // distinguishable by those annotations. E.g., in the example below, the two + // `(u64, u8)` tuples will have different spans for two "u64"s and two "u8"s. + // + // let _: (u64, u8) = (64u64, 8u8); + // let _: (u64, u8) = (64u64, 8u8); + // + // Note that _all the tuples used in code will always be distinguishable by annotations_, + // because they will always have spans either pointing to the values like in `(64u64, 8u8)` + // or to types like in `(u64, u8)`. + // + // Only the tuples used in generated code will not be distinguishable by annotations, + // as well as tuples representing unit types. + TypeInfo::Tuple(elements) => self.is_tuple_distinguishable_by_annotations(elements), + + // The below types are those have `TypeArgument`s (`ta`s) in their definitions. + // Note that we are checking only if those `ta`s are annotated, but not + // recursively if the types they "reference" are annotated ;-) + // We don't need to recursively check if the types behind + // the `ta.type_id`s are distinguishable by annotations. + // This is because two equal (with engines) parent types + // containing `ta`s that pass the above check are also equal in + // case when their full type argument content is compared, + // because the type arguments will be equal in all their fields. + + TypeInfo::Slice(ta) + | TypeInfo::Ptr(ta) + | TypeInfo::Ref { referenced_type: ta, .. } => ta.is_annotated(), + + TypeInfo::Array(ta, l) => { + ta.is_annotated() || l.is_annotated() + } + + // The above reasoning for `TypeArgument`s applies also for the `TypeParameter`s. + // We only need to check if the `tp` is annotated. + TypeInfo::Placeholder(tp) => tp.is_annotated(), + + // TODO: Improve handling of `TypeInfo::Custom` and `TypeInfo::TraitType`` within the `TypeEngine`: + // https://github.com/FuelLabs/sway/issues/6601 + TypeInfo::Custom { .. } => true, + TypeInfo::TraitType { .. } => false, + } + } + + fn is_tuple_distinguishable_by_annotations(&self, elements: &[TypeArgument]) -> bool { + if elements.is_empty() { + false + } else { + elements.iter().any(|ta| ta.is_annotated()) + } + } + + fn is_contract_caller_distinguishable_by_annotations( + abi_name: &AbiName, + address: &Option>, + ) -> bool { + address.is_some() || matches!(abi_name, AbiName::Known(_)) + } + + /// Returns true if the `type_id` represents a changeable type. + /// For the type changeability see [Self::is_type_changeable]. + fn is_type_id_of_changeable_type(&self, engines: &Engines, type_id: TypeId) -> bool { + self.is_type_changeable(engines, &self.slab.get(type_id.index()).type_info) + } + + fn is_changeable_type_argument(&self, engines: &Engines, ta: &TypeArgument) -> bool { + self.is_type_id_of_changeable_type(engines, ta.type_id) + } + + fn is_changeable_enum(&self, engines: &Engines, decl: &TyEnumDecl) -> bool { + self.are_changeable_type_parameters(engines, &decl.type_parameters) + // TODO: Remove once https://github.com/FuelLabs/sway/issues/6687 is fixed. + || + self.module_might_outlive_type_parameters(engines, decl.span.source_id(), &decl.type_parameters) + } + + fn is_changeable_untyped_enum(&self, engines: &Engines, decl: &EnumDeclaration) -> bool { + self.are_changeable_type_parameters(engines, &decl.type_parameters) + // TODO: Remove once https://github.com/FuelLabs/sway/issues/6687 is fixed. + || + self.module_might_outlive_type_parameters(engines, decl.span.source_id(), &decl.type_parameters) + } + + fn is_changeable_struct(&self, engines: &Engines, decl: &TyStructDecl) -> bool { + self.are_changeable_type_parameters(engines, &decl.type_parameters) + // TODO: Remove once https://github.com/FuelLabs/sway/issues/6687 is fixed. + || + self.module_might_outlive_type_parameters(engines, decl.span.source_id(), &decl.type_parameters) + } + + fn is_changeable_untyped_struct(&self, engines: &Engines, decl: &StructDeclaration) -> bool { + self.are_changeable_type_parameters(engines, &decl.type_parameters) + // TODO: Remove once https://github.com/FuelLabs/sway/issues/6687 is fixed. + || + self.module_might_outlive_type_parameters(engines, decl.span.source_id(), &decl.type_parameters) + } + + fn is_changeable_tuple(&self, engines: &Engines, elements: &[TypeArgument]) -> bool { + if elements.is_empty() { + false + } else { + elements + .iter() + .any(|ta| self.is_type_id_of_changeable_type(engines, ta.type_id)) + } + } + + fn are_changeable_type_parameters( + &self, + engines: &Engines, + type_parameters: &[TypeParameter], + ) -> bool { + if type_parameters.is_empty() { + false + } else { + type_parameters + .iter() + .any(|tp| self.is_type_id_of_changeable_type(engines, tp.type_id)) + } + } + + // TODO: Remove this and all `module_might_outlive_xyz` methods once https://github.com/FuelLabs/sway/issues/6687 is fixed. + // + // This method represents the best effort to partially mitigate the issue + // described in https://github.com/FuelLabs/sway/issues/6687, by doing changes only in the `TypeEngine`. + // + // Enum and struct types use it to restrict their shareability and reduce the chance of accessing + // GCed types. + // + // The method takes an **existing** `type_id` and the source id of a particular module (`module_source_id`) + // and checks if the module represented by the `module_source_id` **might** survive LSP garbage collection + // even if the module to which `type_id` is bound gets GCed. + // + // E.g., if the `module_source_id` points to the `Option` declaration of a monomorphized `Option`, + // this method will return true if the `type_id` represents `MyStruct`, because if the `MyStruct`'s module + // gets GCed, the `Option`'s module will "survive" and outlive it, thus pointing via its `TypeArgument` to a + // non-existing, GCed, `MyStruct` type. + // + // E.g., if the `module_source_id` points to the `Option` declaration of a monomorphized `Option`, + // this method will return false if the `type_id` represents `u64`, because the `u64` is not bound to + // any module, and thus, can never be GCed. This means that the `Option`'s module can never outlive it. + fn module_might_outlive_type( + &self, + engines: &Engines, + module_source_id: Option<&SourceId>, + type_id: TypeId, + ) -> bool { + fn module_might_outlive_type_source_id( + module_source_id: Option<&SourceId>, + type_source_id: Option, + ) -> bool { + // If the type represented by the `type_id` is not bound to a source id (`type_source_id.is_none()`) + // it cannot be outlived by the module. + // Otherwise, if `type_source_id.is_some()` but is the same as the `module_source_id`, it can be GCed only if + // the `module_source_id` is GCed. + // Otherwise, we cannot guarantee that the module will not outlive the type's module and we must + // be pessimistic and return false. + type_source_id.is_some() && type_source_id != module_source_id.copied() + } + + let tsi = self.slab.get(type_id.index()); + let type_info = &*tsi.type_info; + let type_source_id = tsi.source_id; + + let decl_engine = engines.de(); + let parsed_decl_engine = engines.pe(); + + // We always must check the `type_id` itself, like, e.h., `MyStruct` in `Option`, ... + module_might_outlive_type_source_id(module_source_id, type_source_id) + || + // ... and also all types it transitively depends on, like, e.g., in `Option>`. + match type_info { + // If a type does not transitively depends on other types, just return `false`. + TypeInfo::StringSlice + | TypeInfo::UnsignedInteger(_) + | TypeInfo::Boolean + | TypeInfo::B256 + | TypeInfo::RawUntypedPtr + | TypeInfo::RawUntypedSlice + | TypeInfo::ErrorRecovery(_) + | TypeInfo::Contract + | TypeInfo::Never => false, + + // Note that `TypeParam` is currently not used at all. + TypeInfo::TypeParam(_) => false, + + TypeInfo::StringArray(_) => false, + + TypeInfo::Unknown + | TypeInfo::Numeric => false, + + TypeInfo::Placeholder(tp) => self.module_might_outlive_type_parameter(engines, module_source_id, tp), + TypeInfo::UnknownGeneric { trait_constraints, parent, .. } => { + parent.is_some_and(|parent_type_id| self.module_might_outlive_type(engines, module_source_id, parent_type_id)) + || + self.module_might_outlive_trait_constraints(engines, module_source_id, trait_constraints) + }, + + TypeInfo::ContractCaller { .. } => false, + + TypeInfo::Enum(decl_id) => { + let decl = decl_engine.get_enum(decl_id); + self.module_might_outlive_type_parameters(engines, module_source_id, &decl.type_parameters) + } + TypeInfo::UntypedEnum(decl_id) => { + let decl = parsed_decl_engine.get_enum(decl_id); + self.module_might_outlive_type_parameters(engines, module_source_id, &decl.type_parameters) + } + TypeInfo::Struct(decl_id) => { + let decl = decl_engine.get_struct(decl_id); + self.module_might_outlive_type_parameters(engines, module_source_id, &decl.type_parameters) + } + TypeInfo::UntypedStruct(decl_id) => { + let decl = parsed_decl_engine.get_struct(decl_id); + self.module_might_outlive_type_parameters(engines, module_source_id, &decl.type_parameters) + } + TypeInfo::Tuple(elements) => self.module_might_outlive_type_arguments(engines, module_source_id, elements), + + TypeInfo::Alias { ty, .. } => self.module_might_outlive_type_argument(engines, module_source_id, ty), + + TypeInfo::Array(ta, _) + | TypeInfo::Slice(ta) + | TypeInfo::Ptr(ta) + | TypeInfo::Ref { + referenced_type: ta, + .. + } => self.module_might_outlive_type_argument(engines, module_source_id, ta), + + TypeInfo::Custom { type_arguments, .. } => + type_arguments.as_ref().is_some_and(|type_arguments| + self.module_might_outlive_type_arguments(engines, module_source_id, type_arguments)), + TypeInfo::TraitType { trait_type_id, .. } => self.module_might_outlive_type(engines, module_source_id, *trait_type_id) + } + } + + fn module_might_outlive_type_parameter( + &self, + engines: &Engines, + module_source_id: Option<&SourceId>, + type_parameter: &TypeParameter, + ) -> bool { + self.module_might_outlive_type(engines, module_source_id, type_parameter.type_id) + || self.module_might_outlive_type( + engines, + module_source_id, + type_parameter.initial_type_id, + ) + || self.module_might_outlive_trait_constraints( + engines, + module_source_id, + &type_parameter.trait_constraints, + ) + } + + fn module_might_outlive_type_parameters( + &self, + engines: &Engines, + module_source_id: Option<&SourceId>, + type_parameters: &[TypeParameter], + ) -> bool { + if type_parameters.is_empty() { + false + } else { + type_parameters + .iter() + .any(|tp| self.module_might_outlive_type_parameter(engines, module_source_id, tp)) + } + } + + fn module_might_outlive_type_argument( + &self, + engines: &Engines, + module_source_id: Option<&SourceId>, + type_argument: &TypeArgument, + ) -> bool { + self.module_might_outlive_type(engines, module_source_id, type_argument.type_id) + || self.module_might_outlive_type( + engines, + module_source_id, + type_argument.initial_type_id, + ) + } + + fn module_might_outlive_type_arguments( + &self, + engines: &Engines, + module_source_id: Option<&SourceId>, + type_arguments: &[TypeArgument], + ) -> bool { + if type_arguments.is_empty() { + false + } else { + type_arguments + .iter() + .any(|ta| self.module_might_outlive_type_argument(engines, module_source_id, ta)) + } + } + + fn module_might_outlive_trait_constraint( + &self, + _engines: &Engines, + _module_source_id: Option<&SourceId>, + trait_constraint: &TraitConstraint, + ) -> bool { + // `TraitConstraint`s can contain `TypeArgument`s that can cause endless recursion, + // unless we track already visited types. This happens in cases of recursive generic + // traits like, e.g., `T: Trait`. + // + // We deliberately decide not to track visited types because: + // - `module_might_outlive_type` represents a best effort to mitigate the issue of modules outliving their types. + // It is already not exact. + // - trait constraints with type arguments are rather rare. + // - tracking already visited types is expensive and `module_might_outlive_type` already adds an overhead. + // + // Instead, if the `trait_constraint` contains type arguments, we will bail out and + // conclude that the module might outlive the types in the trait constraint. + !trait_constraint.type_arguments.is_empty() + } + + fn module_might_outlive_trait_constraints( + &self, + engines: &Engines, + module_source_id: Option<&SourceId>, + trait_constraint: &[TraitConstraint], + ) -> bool { + trait_constraint + .iter() + .any(|tc| self.module_might_outlive_trait_constraint(engines, module_source_id, tc)) + } + + // In the `is_shareable_` methods we reuse the logic from the + // `is_type_changeable` and `is_type_distinguishable_by_annotations`. + // This is a very slight and minimal copy of logic, that improves performance + // (Inlining, no additional fetching from the `DeclEngine`, no intensive function + // calls, etc. Don't forget that this is all on a *very* hot path.) + + fn is_shareable_enum(&self, engines: &Engines, decl: &TyEnumDecl) -> bool { + // !(self.is_changeable_enum(decl_engine, decl) || false) + !self.is_changeable_enum(engines, decl) + } + + fn is_shareable_struct(&self, engines: &Engines, decl: &TyStructDecl) -> bool { + // !(self.is_changeable_struct(decl_engine, decl) || false) + !self.is_changeable_struct(engines, decl) + } + + fn is_shareable_tuple(&self, engines: &Engines, elements: &[TypeArgument]) -> bool { + !(self.is_changeable_tuple(engines, elements) + || self.is_tuple_distinguishable_by_annotations(elements)) + } + + fn is_shareable_array( + &self, + engines: &Engines, + elem_type: &TypeArgument, + length: &Length, + ) -> bool { + !(self.is_changeable_type_argument(engines, elem_type) + || elem_type.is_annotated() + || length.is_annotated()) + } + + fn is_shareable_string_array(&self, length: &Length) -> bool { + // !(false || length.is_annotated()) + !length.is_annotated() + } + + fn is_shareable_slice(&self, engines: &Engines, elem_type: &TypeArgument) -> bool { + !(self.is_changeable_type_argument(engines, elem_type) || elem_type.is_annotated()) + } + + fn is_shareable_ptr(&self, engines: &Engines, pointee_type: &TypeArgument) -> bool { + !(self.is_changeable_type_argument(engines, pointee_type) || pointee_type.is_annotated()) + } + + fn is_shareable_ref(&self, engines: &Engines, referenced_type: &TypeArgument) -> bool { + !(self.is_changeable_type_argument(engines, referenced_type) + || referenced_type.is_annotated()) + } + + // TODO: This and other, type-specific, methods that calculate `source_id` have `fallback` in their name. + // They will be called if the `source_id` is not provided in `new` or `insert` methods, + // thus, fallbacks. + // However, some of them actually do calculate the appropriate `source_id` which will for certain + // types and situations always be extracted from the `TypeInfo` and not allowed to be provided + // in `new` or `insert` methods. + // Until https://github.com/FuelLabs/sway/issues/6603 gets implemented, we will call them all + // fallbacks, which corresponds to the current usage, and eventually rename them accordingly + // once we optimize the `TypeEngine` for garbage collection (#6603). + + fn get_type_fallback_source_id(&self, engines: &Engines, ty: &TypeInfo) -> Option { + let decl_engine = engines.de(); + let parsed_decl_engine = engines.pe(); + match ty { + TypeInfo::Unknown + | TypeInfo::Never + | TypeInfo::TypeParam(_) + | TypeInfo::UnsignedInteger(_) + | TypeInfo::Boolean + | TypeInfo::B256 + | TypeInfo::Numeric + | TypeInfo::ErrorRecovery(_) + | TypeInfo::RawUntypedPtr + | TypeInfo::RawUntypedSlice + | TypeInfo::Contract + | TypeInfo::StringSlice => None, + + TypeInfo::UnknownGeneric { .. } => Self::get_unknown_generic_fallback_source_id(ty), + TypeInfo::Placeholder(_) => self.get_placeholder_fallback_source_id(ty), + TypeInfo::StringArray(length) => Self::get_source_id_from_length(length), + TypeInfo::Enum(decl_id) => { + let decl = decl_engine.get_enum(decl_id); + Self::get_enum_fallback_source_id(&decl) + } + TypeInfo::UntypedEnum(decl_id) => { + let decl = parsed_decl_engine.get_enum(decl_id); + Self::get_untyped_enum_fallback_source_id(&decl) + } + TypeInfo::Struct(decl_id) => { + let decl = decl_engine.get_struct(decl_id); + Self::get_struct_fallback_source_id(&decl) + } + TypeInfo::UntypedStruct(decl_id) => { + let decl = parsed_decl_engine.get_struct(decl_id); + Self::get_untyped_struct_fallback_source_id(&decl) + } + TypeInfo::Tuple(elements) => self.get_tuple_fallback_source_id(elements), + TypeInfo::Array(elem_type, length) => { + self.get_array_fallback_source_id(elem_type, length) + } + + TypeInfo::ContractCaller { abi_name, address } => { + Self::get_contract_caller_fallback_source_id(abi_name, address) + } + + TypeInfo::Alias { name, ty } => self.get_alias_fallback_source_id(name, ty), + + TypeInfo::Ptr(ta) + | TypeInfo::Slice(ta) + | TypeInfo::Ref { + referenced_type: ta, + .. + } => self.get_source_id_from_type_argument(ta), + + TypeInfo::Custom { + qualified_call_path, + type_arguments, + } => self.get_custom_fallback_source_id(qualified_call_path, type_arguments), + + TypeInfo::TraitType { + name, + trait_type_id, + } => self.get_trait_type_fallback_source_id(name, trait_type_id), + } + } + + fn get_source_id_from_length(length: &Length) -> Option { + length.span().source_id().copied() + } + + fn get_source_id_from_type_argument(&self, ta: &TypeArgument) -> Option { + // If the `ta` is span-annotated, take the source id from its `span`, + // otherwise, take the source id of the type it represents. + ta.span + .source_id() + .copied() + .or_else(|| self.get_type_source_id(ta.type_id)) + } + + fn get_source_id_from_type_arguments( + &self, + type_arguments: &[TypeArgument], + ) -> Option { + // For type arguments, if they are annotated, we take the use site source file. + // In semantically valid usages, in a vector of `TypeArgument`s, the use site source file + // will be the same for all the elements, so we are taking it from the + // first one that is annotated (which will be the first one or none). + // E.g., in a `TypeInfo::Tuple`, all the `TypeArgument`s will either not be annotated, or will + // all be annotated and situated within the same file. + // + // If the type arguments are not annotated, we are taking the source file of the first type + // pointed by a type argument, that has a source id. + if type_arguments.is_empty() { + None + } else { + type_arguments + .iter() + .find_map(|ta| ta.span.source_id().copied()) + .or_else(|| { + type_arguments + .iter() + .find_map(|ta| self.get_type_source_id(ta.type_id)) + }) + } + } + + fn get_source_id_from_type_parameter(&self, tp: &TypeParameter) -> Option { + // If the `tp` is span-annotated, take the source id from its `span`, + // otherwise, take the source id of the type it represents. + tp.name + .span() + .source_id() + .copied() + .or_else(|| self.get_type_source_id(tp.type_id)) + } + + fn get_placeholder_fallback_source_id(&self, placeholder: &TypeInfo) -> Option { + // `TypeInfo::Placeholder` is an always replaceable type and we know we will + // get a new instance of it in the engine for every "_" occurrence. This means + // that it can never happen that instances from different source files point + // to the same `TypeSourceInfo`. Therefore, we can safely remove an instance + // of a `Placeholder` from the engine if its source file is garbage collected. + // + // The source file itself is always the one in which the `name`, means "_", + // is situated. + let TypeInfo::Placeholder(tp) = &placeholder else { + unreachable!("The `placeholder` is checked to be of variant `TypeInfo::Placeholder`."); + }; + + self.get_source_id_from_type_parameter(tp) + } + + fn get_unknown_generic_fallback_source_id(unknown_generic: &TypeInfo) -> Option { + // `TypeInfo::UnknownGeneric` is an always replaceable type and we know we will + // get a new instance of it in the engine for every, e.g., "", "", etc. occurrence. + // This means that it can never happen that instances from different source files point + // to the same `TypeSourceInfo`. Therefore, we can safely remove an instance + // of an `UnknownGeneric` from the engine if its source file is garbage collected. + // + // The source file itself is always the one in which the `name`, means, e.g. "T1", "T2", etc. + // is situated. + let TypeInfo::UnknownGeneric { name, .. } = &unknown_generic else { + unreachable!( + "The `unknown_generic` is checked to be of variant `TypeInfo::UnknownGeneric`." + ); }; - let mut id_map = self.id_map.write(); + name.span().source_id().copied() + } + + fn get_enum_fallback_source_id(decl: &TyEnumDecl) -> Option { + // For `TypeInfo::Enum`, we are taking the source file in which the enum is declared. + decl.span.source_id().copied() + } + + fn get_untyped_enum_fallback_source_id(decl: &EnumDeclaration) -> Option { + // For `TypeInfo::UntypedEnum`, we are taking the source file in which the enum is declared. + decl.span.source_id().copied() + } + + fn get_struct_fallback_source_id(decl: &TyStructDecl) -> Option { + // For `TypeInfo::Struct`, we are taking the source file in which the struct is declared. + decl.span.source_id().copied() + } + + fn get_untyped_struct_fallback_source_id(decl: &StructDeclaration) -> Option { + // For `TypeInfo::UntypedStruct`, we are taking the source file in which the struct is declared. + decl.span.source_id().copied() + } + + fn get_tuple_fallback_source_id(&self, elements: &[TypeArgument]) -> Option { + self.get_source_id_from_type_arguments(elements) + } + + fn get_array_fallback_source_id( + &self, + elem_type: &TypeArgument, + length: &Length, + ) -> Option { + // For `TypeInfo::Array`, if it is annotated, we take the use site source file. + // This can be found in the `elem_type` and the `length`. + // + // If the array type is not annotated, we are taking the source file of the array element. + assert_eq!( + elem_type.span.source_id(), + length.span().source_id(), + "If an array is annotated, the type argument and the length spans must have the same source id." + ); - let hash_builder = id_map.hasher().clone(); - let ty_hash = make_hasher(&hash_builder, engines)(&tsi); + self.get_source_id_from_type_argument(elem_type) + } - let raw_entry = id_map.raw_entry_mut().from_hash(ty_hash, |x| { - x.eq(&tsi, &PartialEqWithEnginesContext::new(engines)) - }); - match raw_entry { - RawEntryMut::Occupied(o) => return *o.get(), - RawEntryMut::Vacant(_) if ty.can_change(engines) => TypeId::new(self.slab.insert(tsi)), - RawEntryMut::Vacant(v) => { - let type_id = TypeId::new(self.slab.insert(tsi.clone())); - v.insert_with_hasher(ty_hash, tsi, type_id, make_hasher(&hash_builder, engines)); - type_id + fn get_string_array_fallback_source_id(length: &Length) -> Option { + // For `TypeInfo::StringArray`, if it is annotated, we take the use site source file found in the `length`. + Self::get_source_id_from_length(length) + } + + fn get_contract_caller_fallback_source_id( + abi_name: &AbiName, + address: &Option>, + ) -> Option { + // For `TypeInfo::ContractCaller`, if it has an `address`, we take the use site source file found in the it. + // Otherwise, if it has an `abi_name`, we take the source file of the ABI definition. + match address { + Some(addr_expr) => addr_expr.span.source_id().copied(), + None => { + if let AbiName::Known(name) = abi_name { + name.span().source_id().copied() + } else { + None + } } } } + fn get_alias_fallback_source_id(&self, name: &Ident, ty: &TypeArgument) -> Option { + // For `TypeInfo::Alias`, we take the source file in which the alias is declared, if it exists. + // Otherwise, we take the source file of the aliased type `ty`. + name.span() + .source_id() + .copied() + .or_else(|| self.get_source_id_from_type_argument(ty)) + } + + fn get_slice_fallback_source_id(&self, elem_type: &TypeArgument) -> Option { + self.get_source_id_from_type_argument(elem_type) + } + + fn get_ptr_fallback_source_id(&self, pointee_type: &TypeArgument) -> Option { + self.get_source_id_from_type_argument(pointee_type) + } + + fn get_ref_fallback_source_id(&self, referenced_type: &TypeArgument) -> Option { + self.get_source_id_from_type_argument(referenced_type) + } + + fn get_custom_fallback_source_id( + &self, + qualified_call_path: &QualifiedCallPath, + type_arguments: &Option>, + ) -> Option { + // For `TypeInfo::Custom`, we take the source file in which the custom type is used, extracted from the `qualified_call_path`. + // For non-generated source code, this will always exists. + // For potential situation of having a `qualified_call_path` without spans in generated code, we do a fallback and + // extract the source id from the remaining parameters. + qualified_call_path + .call_path + .suffix + .span() + .source_id() + .copied() + .or_else(|| { + type_arguments + .as_ref() + .and_then(|tas| self.get_source_id_from_type_arguments(tas)) + }) + } + + fn get_trait_type_fallback_source_id( + &self, + name: &Ident, + trait_type_id: &TypeId, + ) -> Option { + // For `TypeInfo::TraitType`, we take the source file in which the trait type is declared, extracted from the `name`. + // For non-generated source code, this will always exists. + // For potential situation of having a `name` without spans in generated code, we do a fallback and + // extract the source id from the `trait_type_id`. + name.span() + .source_id() + .copied() + .or_else(|| self.get_type_source_id(*trait_type_id)) + } + + /// Returns the known [SourceId] of a type that already exists + /// in the [TypeEngine]. The type is given by its `type_id`. + fn get_type_source_id(&self, type_id: TypeId) -> Option { + self.slab.get(type_id.index()).source_id + } + fn clear_items(&mut self, keep: F) where F: Fn(&SourceId) -> bool, { self.slab .retain(|_, tsi| tsi.source_id.as_ref().map_or(true, &keep)); - self.id_map + self.shareable_types .write() .retain(|tsi, _| tsi.source_id.as_ref().map_or(true, &keep)); } @@ -114,12 +1879,69 @@ impl TypeEngine { self.clear_items(|id| id != source_id); } - pub fn replace(&self, engines: &Engines, id: TypeId, new_value: TypeSourceInfo) { - if !(*self.slab.get(id.index())).eq(&new_value, &PartialEqWithEnginesContext::new(engines)) - { + /// Replaces the replaceable type behind the `type_id` with the `new_value`. + /// The existing source id will be preserved. + /// + /// Note that, if the `new_value` represents a shareable built-in type, + /// the existing source id will be removed (replaced by `None`). + /// + /// Panics if the type behind the `type_id` is not a replaceable type. + pub fn replace(&self, engines: &Engines, type_id: TypeId, new_value: TypeInfo) { + // We keep the existing source id. `replace_with_new_source_id` is treated just as a common implementation. + let source_id = self.slab.get(type_id.index()).source_id; + self.replace_with_new_source_id(engines, type_id, new_value, source_id); + } + + /// Replaces the replaceable type behind the `type_id` with the `new_value`. + /// The existing source id will also be replaced with the `new_source_id`. + /// + /// Note that, if the `new_value` represents a shareable built-in type, + /// the existing source id will be removed (replaced by `None`). + /// + /// Panics if the type behind the `type_id` is not a replaceable type. + // TODO: Once https://github.com/FuelLabs/sway/issues/6603 gets implemented and we further optimize + // the `TypeEngine` for garbage collection, this variant of `replace` will actually not be + // needed any more. The version of `replace` that uses the initially provided `source_id` will + // be sufficient. + pub fn replace_with_new_source_id( + &self, + engines: &Engines, + id: TypeId, + new_value: TypeInfo, + new_source_id: Option, + ) { + let type_source_info = self.slab.get(id.index()); + assert!( + Self::is_replaceable_type(&type_source_info.type_info), + "The type requested to be replaced is not a replaceable type. The type was: {:#?}.", + &type_source_info.type_info + ); + + if !type_source_info.equals( + &new_value, + &new_source_id, + &PartialEqWithEnginesContext::new(engines), + ) { self.touch_last_replace(); } - self.slab.replace(id.index(), new_value); + let is_shareable_type = self.is_type_shareable(engines, &new_value); + // Shareable built-in types like, e.g., `u64`, should "live forever" and never be + // garbage-collected. When replacing types, like e.g., unknown generics, that + // might be bound to a source id, we will still remove that source id, if the + // replaced type is replaced by a shareable built-in type. This maximizes the + // reuse of sharable built-in types, and also ensures that they are never GCed. + let source_id = if self.is_shareable_built_in_type(&new_value) { + None + } else { + new_source_id + }; + self.insert_or_replace_type_source_info( + engines, + new_value, + source_id, + is_shareable_type, + Some(id), + ); } /// Performs a lookup of `id` into the [TypeEngine]. @@ -386,7 +2208,6 @@ impl TypeEngine { | TypeInfo::B256 | TypeInfo::Contract | TypeInfo::ErrorRecovery(..) - | TypeInfo::Storage { .. } | TypeInfo::RawUntypedPtr | TypeInfo::RawUntypedSlice | TypeInfo::Alias { .. } @@ -453,25 +2274,12 @@ impl TypeEngine { | TypeInfo::B256 | TypeInfo::Contract | TypeInfo::ErrorRecovery(..) - | TypeInfo::Storage { .. } | TypeInfo::RawUntypedPtr | TypeInfo::RawUntypedSlice | TypeInfo::Alias { .. } | TypeInfo::TraitType { .. } => {} TypeInfo::Numeric => { - self.unify( - handler, - engines, - type_id, - self.insert( - engines, - TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), - span.source_id(), - ), - span, - "", - None, - ); + self.unify(handler, engines, type_id, self.id_of_u64(), span, "", None); } } Ok(()) @@ -491,23 +2299,3 @@ impl TypeEngine { builder } } - -/// Maps specific [TypeInfo] variants to a reserved [SourceId], returning `None` for non-mapped types. -fn info_to_source_id(ty: &TypeInfo) -> Option { - match ty { - TypeInfo::Unknown - | TypeInfo::UnsignedInteger(_) - | TypeInfo::Numeric - | TypeInfo::Boolean - | TypeInfo::B256 - | TypeInfo::RawUntypedPtr - | TypeInfo::RawUntypedSlice - | TypeInfo::StringSlice - | TypeInfo::Contract - | TypeInfo::StringArray(_) - | TypeInfo::Array(_, _) - | TypeInfo::Ref { .. } => Some(SourceId::reserved()), - TypeInfo::Tuple(v) if v.is_empty() => Some(SourceId::reserved()), - _ => None, - } -} diff --git a/sway-core/src/type_system/id.rs b/sway-core/src/type_system/id.rs index 7a7480fe838..090ed6b370a 100644 --- a/sway-core/src/type_system/id.rs +++ b/sway-core/src/type_system/id.rs @@ -80,7 +80,7 @@ impl CollectTypesMetadata for TypeId { } TypeInfo::Placeholder(type_param) => { res.push(TypeMetadata::UnresolvedType( - type_param.name_ident.clone(), + type_param.name.clone(), ctx.call_site_get(self), )); } @@ -108,7 +108,7 @@ impl SubstTypes for TypeId { } impl TypeId { - pub(super) fn new(index: usize) -> TypeId { + pub(super) const fn new(index: usize) -> TypeId { TypeId(index) } @@ -383,19 +383,6 @@ impl TypeId { .extract_any_including_self(engines, filter_fn, vec![], depth + 1), ); } - TypeInfo::Storage { fields } => { - for field in fields { - extend( - &mut found, - field.type_argument.type_id.extract_any_including_self( - engines, - filter_fn, - vec![], - depth + 1, - ), - ); - } - } TypeInfo::Alias { name: _, ty } => { extend( &mut found, @@ -697,13 +684,7 @@ impl TypeId { EnforceTypeArguments::No, None, ) - .unwrap_or_else(|err| { - engines.te().insert( - engines, - TypeInfo::ErrorRecovery(err), - None, - ) - }), + .unwrap_or_else(|err| engines.te().id_of_error_recovery(err)), ctx.resolve_type( handler, t2.type_id, @@ -711,13 +692,7 @@ impl TypeId { EnforceTypeArguments::No, None, ) - .unwrap_or_else(|err| { - engines.te().insert( - engines, - TypeInfo::ErrorRecovery(err), - None, - ) - }), + .unwrap_or_else(|err| engines.te().id_of_error_recovery(err)), ) }) }, diff --git a/sway-core/src/type_system/info.rs b/sway-core/src/type_system/info.rs index 29767d81fc0..dc089c9c25f 100644 --- a/sway-core/src/type_system/info.rs +++ b/sway-core/src/type_system/info.rs @@ -16,13 +16,12 @@ use sway_error::{ error::{CompileError, InvalidImplementingForType}, handler::{ErrorEmitted, Handler}, }; -use sway_types::{integer_bits::IntegerBits, span::Span, SourceId}; +use sway_types::{integer_bits::IntegerBits, span::Span}; use std::{ cmp::Ordering, fmt, hash::{Hash, Hasher}, - sync::Arc, }; #[derive(Debug, Clone, Hash, Eq, PartialEq, PartialOrd, Ord)] @@ -71,28 +70,6 @@ impl PartialEqWithEngines for VecSet { } } -/// Encapsulates type information and its optional source identifier. -#[derive(Debug, Default, Clone)] -pub struct TypeSourceInfo { - pub(crate) type_info: Arc, - /// The source id that created this type. - pub(crate) source_id: Option, -} - -impl HashWithEngines for TypeSourceInfo { - fn hash(&self, state: &mut H, engines: &Engines) { - self.type_info.hash(state, engines); - self.source_id.hash(state); - } -} - -impl EqWithEngines for TypeSourceInfo {} -impl PartialEqWithEngines for TypeSourceInfo { - fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool { - self.type_info.eq(&other.type_info, ctx) && self.source_id == other.source_id - } -} - /// Type information without an associated value, used for type inferencing and definition. #[derive(Debug, Clone, Default)] pub enum TypeInfo { @@ -162,12 +139,6 @@ pub enum TypeInfo { ErrorRecovery(ErrorEmitted), // Static, constant size arrays. Array(TypeArgument, Length), - /// Represents the entire storage declaration struct - /// Stored without initializers here, as typed struct fields, - /// so type checking is able to treat it as a struct with fields. - Storage { - fields: Vec, - }, /// Pointers. /// These are represented in memory as u64 but are a different type since pointers only make /// sense in the context they were created in. Users can obtain pointers via standard library @@ -178,8 +149,12 @@ pub enum TypeInfo { RawUntypedSlice, Ptr(TypeArgument), Slice(TypeArgument), - /// Type Alias. This type and the type `ty` it encapsulates always coerce. They are effectively - /// interchangeable + /// Type aliases. + /// This type and the type `ty` it encapsulates always coerce. They are effectively + /// interchangeable. + /// Currently, we support only non-generic type aliases. + // TODO: (GENERIC-TYPE-ALIASES) If we ever introduce generic type aliases, update the logic + // in the `TypeEngine` accordingly, e.g., the `is_type_changeable`. Alias { name: Ident, ty: TypeArgument, @@ -242,9 +217,6 @@ impl HashWithEngines for TypeInfo { call_path.hash(state, engines); type_arguments.as_deref().hash(state, engines); } - TypeInfo::Storage { fields } => { - fields.hash(state, engines); - } TypeInfo::Array(elem_ty, count) => { elem_ty.hash(state, engines); count.hash(state); @@ -355,16 +327,7 @@ impl PartialEqWithEngines for TypeInfo { && l_decl.fields.eq(&r_decl.fields, ctx) && l_decl.type_parameters.eq(&r_decl.type_parameters, ctx) } - (Self::Tuple(l), Self::Tuple(r)) => l - .iter() - .zip(r.iter()) - .map(|(l, r)| { - (l.type_id == r.type_id) - || type_engine - .get(l.type_id) - .eq(&type_engine.get(r.type_id), ctx) - }) - .all(|x| x), + (Self::Tuple(l), Self::Tuple(r)) => l.eq(r, ctx), ( Self::ContractCaller { abi_name: l_abi_name, @@ -386,9 +349,6 @@ impl PartialEqWithEngines for TypeInfo { .eq(&type_engine.get(r0.type_id), ctx)) && l1.val() == r1.val() } - (Self::Storage { fields: l_fields }, Self::Storage { fields: r_fields }) => { - l_fields.eq(r_fields, ctx) - } ( Self::Alias { name: l_name, @@ -522,9 +482,6 @@ impl OrdWithEngines for TypeInfo { .get(l0.type_id) .cmp(&type_engine.get(r0.type_id), ctx) .then_with(|| l1.val().cmp(&r1.val())), - (TypeInfo::Storage { fields: l_fields }, TypeInfo::Storage { fields: r_fields }) => { - l_fields.cmp(r_fields, ctx) - } ( Self::Alias { name: l_name, @@ -576,7 +533,7 @@ impl DisplayWithEngines for TypeInfo { Unknown => "{unknown}".into(), Never => "!".into(), UnknownGeneric { name, .. } => name.to_string(), - Placeholder(type_param) => type_param.name_ident.to_string(), + Placeholder(type_param) => type_param.name.to_string(), TypeParam(n) => format!("{n}"), StringSlice => "str".into(), StringArray(x) => format!("str[{}]", x.val()), @@ -640,7 +597,6 @@ impl DisplayWithEngines for TypeInfo { Array(elem_ty, count) => { format!("[{}; {}]", engines.help_out(elem_ty), count.val()) } - Storage { .. } => "storage".into(), RawUntypedPtr => "pointer".into(), RawUntypedSlice => "slice".into(), Ptr(ty) => { @@ -780,7 +736,6 @@ impl DebugWithEngines for TypeInfo { Array(elem_ty, count) => { format!("[{:?}; {}]", engines.help_out(elem_ty), count.val()) } - Storage { .. } => "contract storage".into(), RawUntypedPtr => "raw untyped ptr".into(), RawUntypedSlice => "raw untyped slice".into(), Ptr(ty) => { @@ -834,23 +789,31 @@ impl TypeInfo { TypeInfo::Contract => 13, TypeInfo::ErrorRecovery(_) => 14, TypeInfo::Array(_, _) => 15, - TypeInfo::Storage { .. } => 16, - TypeInfo::RawUntypedPtr => 17, - TypeInfo::RawUntypedSlice => 18, - TypeInfo::TypeParam(_) => 19, - TypeInfo::Alias { .. } => 20, - TypeInfo::Ptr(..) => 21, - TypeInfo::Slice(..) => 22, - TypeInfo::StringSlice => 23, - TypeInfo::TraitType { .. } => 24, - TypeInfo::Ref { .. } => 25, - TypeInfo::Never => 26, - TypeInfo::UntypedEnum(_) => 27, - TypeInfo::UntypedStruct(_) => 28, + TypeInfo::RawUntypedPtr => 16, + TypeInfo::RawUntypedSlice => 17, + TypeInfo::TypeParam(_) => 18, + TypeInfo::Alias { .. } => 19, + TypeInfo::Ptr(..) => 20, + TypeInfo::Slice(..) => 21, + TypeInfo::StringSlice => 22, + TypeInfo::TraitType { .. } => 23, + TypeInfo::Ref { .. } => 24, + TypeInfo::Never => 25, + TypeInfo::UntypedEnum(_) => 26, + TypeInfo::UntypedStruct(_) => 27, } } + /// Creates a new [TypeInfo::Custom] that represents a Self type. + /// + /// The `span` must either be a [Span::dummy] or a span pointing + /// to text "Self" or "self", otherwise the method panics. pub(crate) fn new_self_type(span: Span) -> TypeInfo { + assert!( + span.is_dummy() || span.as_str() == "Self" || span.as_str() == "self", + "The Self type span must either be a dummy span, or a span pointing to text \"Self\" or \"self\". The span was pointing to text: \"{}\".", + span.as_str() + ); TypeInfo::Custom { qualified_call_path: QualifiedCallPath { call_path: CallPath { @@ -1302,7 +1265,6 @@ impl TypeInfo { | TypeInfo::Contract | TypeInfo::ErrorRecovery(_) | TypeInfo::Array(_, _) - | TypeInfo::Storage { .. } | TypeInfo::Placeholder(_) | TypeInfo::TypeParam(_) | TypeInfo::Alias { .. } @@ -1380,7 +1342,6 @@ impl TypeInfo { | TypeInfo::ContractCaller { .. } | TypeInfo::Custom { .. } | TypeInfo::Contract - | TypeInfo::Storage { .. } | TypeInfo::Placeholder(_) | TypeInfo::TypeParam(_) | TypeInfo::TraitType { .. } => { @@ -1444,7 +1405,6 @@ impl TypeInfo { )), TypeInfo::Unknown | TypeInfo::ContractCaller { .. } - | TypeInfo::Storage { .. } | TypeInfo::Placeholder(_) | TypeInfo::TypeParam(_) => Err(handler.emit_err( CompileError::TypeIsNotValidAsImplementingFor { @@ -1457,54 +1417,6 @@ impl TypeInfo { } } - pub(crate) fn can_change(&self, engines: &Engines) -> bool { - // TODO: there might be an optimization here that if the type params hold - // only non-dynamic types, then it doesn't matter that there are type params - match self { - TypeInfo::UntypedEnum(decl_id) => { - let decl = engines.pe().get_enum(decl_id); - !decl.type_parameters.is_empty() - } - TypeInfo::UntypedStruct(decl_id) => { - let decl = engines.pe().get_struct(decl_id); - !decl.type_parameters.is_empty() - } - TypeInfo::Enum(decl_ref) => { - let decl = engines.de().get_enum(decl_ref); - !decl.type_parameters.is_empty() - } - TypeInfo::Struct(decl_ref) => { - let decl = engines.de().get_struct(decl_ref); - !decl.type_parameters.is_empty() - } - TypeInfo::StringArray(_) - | TypeInfo::StringSlice - | TypeInfo::UnsignedInteger(_) - | TypeInfo::Boolean - | TypeInfo::B256 - | TypeInfo::RawUntypedPtr - | TypeInfo::RawUntypedSlice - | TypeInfo::Ptr(_) - | TypeInfo::ErrorRecovery(_) - | TypeInfo::TraitType { .. } - | TypeInfo::Never => false, - TypeInfo::Unknown - | TypeInfo::UnknownGeneric { .. } - | TypeInfo::ContractCaller { .. } - | TypeInfo::Custom { .. } - | TypeInfo::Tuple(_) - | TypeInfo::Array(_, _) - | TypeInfo::Slice(_) - | TypeInfo::Contract - | TypeInfo::Storage { .. } - | TypeInfo::Numeric - | TypeInfo::Placeholder(_) - | TypeInfo::TypeParam(_) - | TypeInfo::Alias { .. } - | TypeInfo::Ref { .. } => true, - } - } - /// Checks if a given [TypeInfo] has a valid constructor. pub(crate) fn has_valid_constructor(&self, decl_engine: &DeclEngine) -> bool { match self { @@ -1807,7 +1719,6 @@ impl TypeInfo { length.val() ) } - Storage { .. } => "contract storage".into(), RawUntypedPtr => "raw untyped ptr".into(), RawUntypedSlice => "raw untyped slice".into(), Ptr(ty) => { diff --git a/sway-core/src/type_system/mod.rs b/sway-core/src/type_system/mod.rs index 37446b5843c..fedf09bb480 100644 --- a/sway-core/src/type_system/mod.rs +++ b/sway-core/src/type_system/mod.rs @@ -77,32 +77,22 @@ fn generic_enum_resolution() { a: _ } */ - let generic_type = engines.te().insert( - &engines, - TypeInfo::UnknownGeneric { - name: generic_name.clone(), - trait_constraints: VecSet(Vec::new()), - parent: None, - is_from_type_parameter: false, - }, - None, - ); - let placeholder_type = engines.te().insert( - &engines, - TypeInfo::Placeholder(TypeParameter { - type_id: generic_type, - initial_type_id: generic_type, - name_ident: generic_name.clone(), - trait_constraints: vec![], - trait_constraints_span: sp.clone(), - is_from_parent: false, - }), - None, - ); + let generic_type = + engines + .te() + .new_unknown_generic(generic_name.clone(), VecSet(vec![]), None, false); + let placeholder_type = engines.te().new_placeholder(TypeParameter { + type_id: generic_type, + initial_type_id: generic_type, + name: generic_name.clone(), + trait_constraints: vec![], + trait_constraints_span: sp.clone(), + is_from_parent: false, + }); let placeholder_type_param = TypeParameter { type_id: placeholder_type, initial_type_id: placeholder_type, - name_ident: generic_name.clone(), + name: generic_name.clone(), trait_constraints: vec![], trait_constraints_span: sp.clone(), is_from_parent: false, @@ -133,16 +123,14 @@ fn generic_enum_resolution() { }, None, ); - let ty_1 = engines - .te() - .insert(&engines, TypeInfo::Enum(*decl_ref_1.id()), None); + let ty_1 = engines.te().insert_enum(&engines, *decl_ref_1.id()); /* Result { a: bool } */ - let boolean_type = engines.te().insert(&engines, TypeInfo::Boolean, None); + let boolean_type = engines.te().id_of_bool(); let variant_types = vec![ty::TyEnumVariant { name: a_name, tag: 0, @@ -158,7 +146,7 @@ fn generic_enum_resolution() { let type_param = TypeParameter { type_id: boolean_type, initial_type_id: boolean_type, - name_ident: generic_name, + name: generic_name, trait_constraints: vec![], trait_constraints_span: sp.clone(), is_from_parent: false, @@ -177,9 +165,7 @@ fn generic_enum_resolution() { }, None, ); - let ty_2 = engines - .te() - .insert(&engines, TypeInfo::Enum(*decl_ref_2.id()), None); + let ty_2 = engines.te().insert_enum(&engines, *decl_ref_2.id()); // Unify them together... let h = Handler::default(); @@ -206,12 +192,8 @@ fn basic_numeric_unknown() { let sp = Span::dummy(); // numerics - let id = engines.te().insert(&engines, TypeInfo::Numeric, None); - let id2 = engines.te().insert( - &engines, - TypeInfo::UnsignedInteger(IntegerBits::Eight), - None, - ); + let id = engines.te().new_numeric(); + let id2 = engines.te().id_of_u8(); // Unify them together... let h = Handler::default(); @@ -232,12 +214,8 @@ fn unify_numerics() { let sp = Span::dummy(); // numerics - let id = engines.te().insert(&engines, TypeInfo::Numeric, None); - let id2 = engines.te().insert( - &engines, - TypeInfo::UnsignedInteger(IntegerBits::Eight), - None, - ); + let id = engines.te().new_numeric(); + let id2 = engines.te().id_of_u8(); // Unify them together... let h = Handler::default(); @@ -259,12 +237,8 @@ fn unify_numerics_2() { let sp = Span::dummy(); // numerics - let id = type_engine.insert(&engines, TypeInfo::Numeric, None); - let id2 = type_engine.insert( - &engines, - TypeInfo::UnsignedInteger(IntegerBits::Eight), - None, - ); + let id = engines.te().new_numeric(); + let id2 = engines.te().id_of_u8(); // Unify them together... let h = Handler::default(); diff --git a/sway-core/src/type_system/monomorphization.rs b/sway-core/src/type_system/monomorphization.rs index 674650896db..ffe432f2292 100644 --- a/sway-core/src/type_system/monomorphization.rs +++ b/sway-core/src/type_system/monomorphization.rs @@ -14,7 +14,7 @@ use crate::{ semantic_analysis::type_resolve::resolve_type, type_system::ast_elements::create_type_id::CreateTypeId, EnforceTypeArguments, Engines, Namespace, SubstTypes, SubstTypesContext, TypeArgument, TypeId, - TypeInfo, TypeParameter, TypeSubstMap, + TypeParameter, TypeSubstMap, }; pub(crate) trait MonomorphizeHelper { @@ -130,11 +130,7 @@ where self_type, subst_ctx, ) - .unwrap_or_else(|err| { - engines - .te() - .insert(engines, TypeInfo::ErrorRecovery(err), None) - }); + .unwrap_or_else(|err| engines.te().id_of_error_recovery(err)); } let type_mapping = TypeSubstMap::from_type_parameters_and_type_arguments( value @@ -259,11 +255,7 @@ pub(crate) fn type_decl_opt_to_type_id( ); // create the type id from the copy - type_engine.insert( - engines, - TypeInfo::Struct(*new_decl_ref.id()), - new_decl_ref.span().source_id(), - ) + type_engine.insert_struct(engines, *new_decl_ref.id()) } Some(ResolvedDeclaration::Typed(ty::TyDecl::EnumDecl(ty::EnumDecl { decl_id: original_id, @@ -293,11 +285,7 @@ pub(crate) fn type_decl_opt_to_type_id( ); // create the type id from the copy - type_engine.insert( - engines, - TypeInfo::Enum(*new_decl_ref.id()), - new_decl_ref.span().source_id(), - ) + type_engine.insert_enum(engines, *new_decl_ref.id()) } Some(ResolvedDeclaration::Typed(ty::TyDecl::TypeAliasDecl(ty::TypeAliasDecl { decl_id: original_id, @@ -305,8 +293,8 @@ pub(crate) fn type_decl_opt_to_type_id( }))) => { let new_copy = decl_engine.get_type_alias(&original_id); - // TODO: monomorphize the copy, in place, when generic type aliases are - // supported + // TODO: (GENERIC-TYPE-ALIASES) Monomorphize the copy, in place, once generic type aliases are + // supported. new_copy.create_type_id(engines) } @@ -321,14 +309,7 @@ pub(crate) fn type_decl_opt_to_type_id( if let Some(ty) = &decl_type.ty { ty.type_id } else if let Some(implementing_type) = self_type { - type_engine.insert( - engines, - TypeInfo::TraitType { - name: decl_type.name.clone(), - trait_type_id: implementing_type, - }, - decl_type.name.span().source_id(), - ) + type_engine.insert_trait_type(engines, decl_type.name.clone(), implementing_type) } else { return Err(handler.emit_err(CompileError::Internal( "Self type not provided.", @@ -341,7 +322,7 @@ pub(crate) fn type_decl_opt_to_type_id( name: call_path.to_string(), span: call_path.span(), }); - type_engine.insert(engines, TypeInfo::ErrorRecovery(err), None) + type_engine.id_of_error_recovery(err) } }) } diff --git a/sway-core/src/type_system/priv_prelude.rs b/sway-core/src/type_system/priv_prelude.rs index fdf2a4138a9..477cf76f169 100644 --- a/sway-core/src/type_system/priv_prelude.rs +++ b/sway-core/src/type_system/priv_prelude.rs @@ -22,5 +22,5 @@ pub use super::{ engine::IsConcrete, engine::TypeEngine, id::{IncludeSelf, TreatNumericAs, TypeId}, - info::{AbiEncodeSizeHint, AbiName, TypeInfo, TypeSourceInfo}, + info::{AbiEncodeSizeHint, AbiName, TypeInfo}, }; diff --git a/sway-core/src/type_system/substitute/subst_map.rs b/sway-core/src/type_system/substitute/subst_map.rs index 4b1a9fa93c7..36de9b4846a 100644 --- a/sway-core/src/type_system/substitute/subst_map.rs +++ b/sway-core/src/type_system/substitute/subst_map.rs @@ -8,7 +8,6 @@ use crate::{ type_system::priv_prelude::*, }; use std::{collections::BTreeMap, fmt}; -use sway_types::Spanned; type SourceType = TypeId; type DestinationType = TypeId; @@ -94,11 +93,7 @@ impl TypeSubstMap { .map(|type_param| { ( type_param.type_id, - type_engine.insert( - engines, - TypeInfo::Placeholder(type_param.clone()), - type_param.name_ident.span().source_id(), - ), + type_engine.new_placeholder(type_param.clone()), ) }) .collect(); @@ -256,29 +251,6 @@ impl TypeSubstMap { vec![type_argument.type_id], ) } - ( - TypeInfo::Storage { - fields: type_parameters, - }, - TypeInfo::Storage { - fields: type_arguments, - }, - ) => { - let type_parameters = type_parameters - .iter() - .map(|x| x.type_argument.type_id) - .collect::>(); - let type_arguments = type_arguments - .iter() - .map(|x| x.type_argument.type_id) - .collect::>(); - TypeSubstMap::from_superset_and_subset_helper( - type_engine, - decl_engine, - type_parameters, - type_arguments, - ) - } (TypeInfo::Unknown, TypeInfo::Unknown) | (TypeInfo::Boolean, TypeInfo::Boolean) | (TypeInfo::B256, TypeInfo::B256) @@ -350,10 +322,10 @@ impl TypeSubstMap { /// A match is potentially created (i.e. a new [TypeId] is created) in these /// circumstances: /// - `type_id` is one of the following: [TypeInfo::Struct], [TypeInfo::Enum], - /// [TypeInfo::Array], [TypeInfo::Tuple], [TypeInfo::Storage], [TypeInfo::Alias], - /// [TypeInfo::Alias], [TypeInfo::Ptr], [TypeInfo::Slice], or [TypeInfo::Ref], - /// and one of the contained types (e.g. a struct field, or a referenced type) - /// finds a match in a recursive call to `find_match`. + /// [TypeInfo::Array], [TypeInfo::Tuple], [TypeInfo::Alias], [TypeInfo::Ptr], + /// [TypeInfo::Slice], or [TypeInfo::Ref], + /// - and one of the contained types (e.g. a struct field, or a referenced type) + /// finds a match in a recursive call to `find_match`. /// /// A match cannot be found in any other circumstance. pub(crate) fn find_match(&self, type_id: TypeId, engines: &Engines) -> Option { @@ -440,11 +412,7 @@ impl TypeSubstMap { if need_to_create_new { let new_decl_ref = decl_engine.insert(decl, decl_engine.get_parsed_decl_id(&decl_id).as_ref()); - Some(type_engine.insert( - engines, - TypeInfo::Struct(*new_decl_ref.id()), - new_decl_ref.decl_span().source_id(), - )) + Some(type_engine.insert_struct(engines, *new_decl_ref.id())) } else { None } @@ -469,75 +437,37 @@ impl TypeSubstMap { if need_to_create_new { let new_decl_ref = decl_engine.insert(decl, decl_engine.get_parsed_decl_id(&decl_id).as_ref()); - Some(type_engine.insert( - engines, - TypeInfo::Enum(*new_decl_ref.id()), - new_decl_ref.decl_span().source_id(), - )) + Some(type_engine.insert_enum(engines, *new_decl_ref.id())) } else { None } } - TypeInfo::Array(mut elem_ty, count) => { - self.find_match(elem_ty.type_id, engines).map(|type_id| { - elem_ty.type_id = type_id; - type_engine.insert( - engines, - TypeInfo::Array(elem_ty.clone(), count.clone()), - elem_ty.span.source_id(), - ) + TypeInfo::Array(mut elem_type, length) => { + self.find_match(elem_type.type_id, engines).map(|type_id| { + elem_type.type_id = type_id; + type_engine.insert_array(engines, elem_type, length) }) } - TypeInfo::Slice(mut elem_ty) => { - let type_id = self.find_match(elem_ty.type_id, engines)?; - elem_ty.type_id = type_id; - Some(type_engine.insert( - engines, - TypeInfo::Slice(elem_ty.clone()), - elem_ty.span.source_id(), - )) + TypeInfo::Slice(mut elem_type) => { + self.find_match(elem_type.type_id, engines).map(|type_id| { + elem_type.type_id = type_id; + type_engine.insert_slice(engines, elem_type) + }) } TypeInfo::Tuple(fields) => { let mut need_to_create_new = false; - let mut source_id = None; let fields = fields .into_iter() .map(|mut field| { if let Some(type_id) = self.find_match(field.type_id, engines) { need_to_create_new = true; - source_id = field.span.source_id().cloned(); field.type_id = type_id; } field.clone() }) .collect::>(); if need_to_create_new { - Some(type_engine.insert(engines, TypeInfo::Tuple(fields), source_id.as_ref())) - } else { - None - } - } - TypeInfo::Storage { fields } => { - let mut need_to_create_new = false; - let mut source_id = None; - let fields = fields - .into_iter() - .map(|mut field| { - if let Some(type_id) = self.find_match(field.type_argument.type_id, engines) - { - need_to_create_new = true; - source_id = field.span.source_id().copied(); - field.type_argument.type_id = type_id; - } - field.clone() - }) - .collect::>(); - if need_to_create_new { - Some(type_engine.insert( - engines, - TypeInfo::Storage { fields }, - source_id.as_ref(), - )) + Some(type_engine.insert_tuple(engines, fields)) } else { None } @@ -545,19 +475,12 @@ impl TypeSubstMap { TypeInfo::Alias { name, mut ty } => { self.find_match(ty.type_id, engines).map(|type_id| { ty.type_id = type_id; - type_engine.insert( - engines, - TypeInfo::Alias { - name: name.clone(), - ty: ty.clone(), - }, - ty.span.source_id(), - ) + type_engine.new_alias(engines, name, ty) }) } TypeInfo::Ptr(mut ty) => self.find_match(ty.type_id, engines).map(|type_id| { ty.type_id = type_id; - type_engine.insert(engines, TypeInfo::Ptr(ty.clone()), ty.span.source_id()) + type_engine.insert_ptr(engines, ty) }), TypeInfo::TraitType { .. } => iter_for_match(engines, self, &type_info), TypeInfo::Ref { @@ -565,14 +488,7 @@ impl TypeSubstMap { referenced_type: mut ty, } => self.find_match(ty.type_id, engines).map(|type_id| { ty.type_id = type_id; - type_engine.insert( - engines, - TypeInfo::Ref { - to_mutable_value, - referenced_type: ty.clone(), - }, - ty.span.source_id(), - ) + type_engine.insert_ref(engines, to_mutable_value, ty) }), TypeInfo::Unknown | TypeInfo::Never @@ -607,7 +523,7 @@ fn iter_for_match( TypeInfo::Placeholder(current_type_param), ) = ((*source_type_info).clone(), type_info) { - if source_type_param.name_ident.as_str() == current_type_param.name_ident.as_str() + if source_type_param.name.as_str() == current_type_param.name.as_str() && current_type_param .trait_constraints .iter() diff --git a/sway-core/src/type_system/unify/unifier.rs b/sway-core/src/type_system/unify/unifier.rs index 41b72802602..b77bd83fe9a 100644 --- a/sway-core/src/type_system/unify/unifier.rs +++ b/sway-core/src/type_system/unify/unifier.rs @@ -61,15 +61,11 @@ impl<'a> Unifier<'a> { expected_type_info: &TypeInfo, span: &Span, ) { - let type_engine = self.engines.te(); - let source_id = span.source_id().copied(); - type_engine.replace( + self.engines.te().replace_with_new_source_id( self.engines, received, - TypeSourceInfo { - type_info: expected_type_info.clone().into(), - source_id, - }, + expected_type_info.clone(), + span.source_id().copied(), ); } @@ -80,15 +76,11 @@ impl<'a> Unifier<'a> { received_type_info: &TypeInfo, span: &Span, ) { - let type_engine = self.engines.te(); - let source_id = span.source_id().copied(); - type_engine.replace( + self.engines.te().replace_with_new_source_id( self.engines, expected, - TypeSourceInfo { - type_info: received_type_info.clone().into(), - source_id, - }, + received_type_info.clone(), + span.source_id().copied(), ); } diff --git a/sway-core/src/type_system/unify/unify_check.rs b/sway-core/src/type_system/unify/unify_check.rs index 9adb491678c..ed8cdbbbb2b 100644 --- a/sway-core/src/type_system/unify/unify_check.rs +++ b/sway-core/src/type_system/unify/unify_check.rs @@ -527,7 +527,6 @@ impl<'a> UnifyCheck<'a> { // engine (TypeInfo::Unknown, TypeInfo::Unknown) => false, (TypeInfo::Numeric, TypeInfo::Numeric) => false, - (TypeInfo::Storage { .. }, TypeInfo::Storage { .. }) => false, // these cases are able to be directly compared (TypeInfo::Contract, TypeInfo::Contract) => true, diff --git a/sway-lsp/README.md b/sway-lsp/README.md index 940ec11a269..ffae83b3f0c 100644 --- a/sway-lsp/README.md +++ b/sway-lsp/README.md @@ -27,3 +27,13 @@ _Coming Soon_ 1. Install the [Fuel toolchain](https://fuellabs.github.io/fuelup/master/installation/index.html). 1. Ensure `forc-lsp` is installed correctly by entering `forc-lsp --version` into your terminal. 1. Install the [Sway VSCode plugin](https://marketplace.visualstudio.com/items?itemName=FuelLabs.sway-vscode-plugin). + +## Trying out the local version + +To try out the local LSP version: + +1. Install the local version of the server: `cargo install --path ./forc-plugins/forc-lsp`. +1. Open VSCode settings and set the `Sway-lsp › Diagnostic: Bin Path` to the installed `forc-lsp` binary. The path to the binary will be listed at the end of the `cargo install` command and is usually: `/home//.cargo/bin/forc-lsp`. +1. Open an arbitrary Sway project. E.g., `./examples/arrays`. +1. Open the _Output_ window in VSCode and select _Sway Language Server_ from the drop down menu. +1. Start coding and observe the LSP output in the _Output_ window. This window will also show any `dbg!` or `eprintln!` lines. \ No newline at end of file diff --git a/sway-lsp/src/capabilities/code_actions/common/generate_impl.rs b/sway-lsp/src/capabilities/code_actions/common/generate_impl.rs index 8b64838e1c3..d12bbd402b1 100644 --- a/sway-lsp/src/capabilities/code_actions/common/generate_impl.rs +++ b/sway-lsp/src/capabilities/code_actions/common/generate_impl.rs @@ -21,7 +21,7 @@ pub(crate) trait GenerateImplCodeAction<'a, T: Spanned>: CodeAction<'a, T> { Some( type_params .iter() - .map(|param| param.name_ident.to_string()) + .map(|param| param.name.to_string()) .collect::>() .join(", "), ) diff --git a/sway-lsp/src/server_state.rs b/sway-lsp/src/server_state.rs index 5e2a227f3f5..cafb4bb5fe6 100644 --- a/sway-lsp/src/server_state.rs +++ b/sway-lsp/src/server_state.rs @@ -130,13 +130,9 @@ impl ServerState { while let Ok(msg) = rx.recv() { match msg { TaskMessage::CompilationContext(ctx) => { - dbg!(); let uri = ctx.uri.as_ref().unwrap().clone(); - dbg!(); let session = ctx.session.as_ref().unwrap().clone(); - dbg!(); let mut engines_clone = session.engines.read().clone(); - dbg!(); // Perform garbage collection if enabled to manage memory usage. if ctx.gc_options.gc_enabled { @@ -151,16 +147,13 @@ impl ServerState { ); } } - dbg!(); let lsp_mode = Some(LspConfig { optimized_build: ctx.optimized_build, file_versions: ctx.file_versions, }); - dbg!(); // Set the is_compiling flag to true so that the wait_for_parsing function knows that we are compiling is_compiling.store(true, Ordering::SeqCst); - dbg!(); match session::parse_project( &uri, &engines_clone, @@ -170,10 +163,10 @@ impl ServerState { ) { Ok(()) => { let path = uri.to_file_path().unwrap(); - // Find the module id from the path + // Find the program id from the path match session::program_id_from_path(&path, &engines_clone) { Ok(program_id) => { - // Use the module id to get the metrics for the module + // Use the program id to get the metrics for the program if let Some(metrics) = session.metrics.get(&program_id) { // It's very important to check if the workspace AST was reused to determine if we need to overwrite the engines. // Because the engines_clone has garbage collection applied. If the workspace AST was reused, we need to keep the old engines @@ -202,26 +195,21 @@ impl ServerState { } } Err(_err) => { - dbg!(_err); *last_compilation_state.write() = LastCompilationState::Failed; } } - dbg!(); // Reset the flags to false is_compiling.store(false, Ordering::SeqCst); retrigger_compilation.store(false, Ordering::SeqCst); - dbg!(); // Make sure there isn't any pending compilation work if rx.is_empty() { // finished compilation, notify waiters finished_compilation.notify_waiters(); } - dbg!(); } TaskMessage::Terminate => { - dbg!(); // If we receive a terminate message, we need to exit the thread return; } @@ -305,7 +293,6 @@ impl ServerState { session: Arc, ) { let diagnostics = self.diagnostics(&uri, session.clone()); - dbg!(&diagnostics); // Note: Even if the computed diagnostics vec is empty, we still have to push the empty Vec // in order to clear former diagnostics. Newly pushed diagnostics always replace previously pushed diagnostics. if let Some(client) = self.client.as_ref() { diff --git a/sway-lsp/src/traverse/parsed_tree.rs b/sway-lsp/src/traverse/parsed_tree.rs index 87f30cd8017..1578975143e 100644 --- a/sway-lsp/src/traverse/parsed_tree.rs +++ b/sway-lsp/src/traverse/parsed_tree.rs @@ -1059,7 +1059,7 @@ impl Parse for EnumVariant { impl Parse for TypeParameter { fn parse(&self, ctx: &ParseContext) { ctx.tokens.insert( - ctx.ident(&self.name_ident), + ctx.ident(&self.name), Token::from_parsed( ParsedAstToken::TypeParameter(self.clone()), SymbolKind::TypeParameter, diff --git a/sway-lsp/src/traverse/typed_tree.rs b/sway-lsp/src/traverse/typed_tree.rs index 9d23bae7316..7fc3461abca 100644 --- a/sway-lsp/src/traverse/typed_tree.rs +++ b/sway-lsp/src/traverse/typed_tree.rs @@ -659,7 +659,7 @@ impl Parse for ty::FunctionDecl { ctx, type_param.type_id, &typed_token, - type_param.name_ident.span(), + type_param.name.span(), ); }); collect_type_argument(ctx, &func_decl.return_type); @@ -672,8 +672,8 @@ impl Parse for ty::FunctionDecl { if let Some(param_decl_ident) = func_decl .type_parameters .par_iter() - .find_any(|type_param| type_param.name_ident.as_str() == ident.as_str()) - .map(|type_param| type_param.name_ident.clone()) + .find_any(|type_param| type_param.name.as_str() == ident.as_str()) + .map(|type_param| type_param.name.clone()) { token.type_def = Some(TypeDefinition::Ident(param_decl_ident)); } @@ -732,7 +732,7 @@ impl Parse for ty::StructDecl { adaptive_iter(&struct_decl.type_parameters, |type_param| { if let Some(mut token) = ctx .tokens - .try_get_mut_with_retry(&ctx.ident(&type_param.name_ident)) + .try_get_mut_with_retry(&ctx.ident(&type_param.name)) { token.ast_node = TokenAstNode::Typed(TypedAstToken::TypedParameter(type_param.clone())); @@ -759,7 +759,7 @@ impl Parse for ty::ImplSelfOrTrait { ctx, param.type_id, &TypedAstToken::TypedParameter(param.clone()), - param.name_ident.span(), + param.name.span(), ); }); adaptive_iter(&trait_name.prefixes, |ident| { @@ -958,7 +958,7 @@ impl Parse for ty::TyFunctionDecl { ctx, type_param.type_id, &typed_token, - type_param.name_ident.span(), + type_param.name.span(), ); }); collect_type_argument(ctx, &self.return_type); @@ -971,8 +971,8 @@ impl Parse for ty::TyFunctionDecl { if let Some(param_decl_ident) = self .type_parameters .par_iter() - .find_any(|type_param| type_param.name_ident.as_str() == ident.as_str()) - .map(|type_param| type_param.name_ident.clone()) + .find_any(|type_param| type_param.name.as_str() == ident.as_str()) + .map(|type_param| type_param.name.clone()) { token.type_def = Some(TypeDefinition::Ident(param_decl_ident)); } @@ -1329,7 +1329,7 @@ fn collect_type_id( ctx, param.type_id, &TypedAstToken::TypedParameter(param.clone()), - param.name_ident.span(), + param.name.span(), ); }); adaptive_iter(&decl.variants, |variant| { @@ -1349,7 +1349,7 @@ fn collect_type_id( ctx, param.type_id, &TypedAstToken::TypedParameter(param.clone()), - param.name_ident.span(), + param.name.span(), ); }); adaptive_iter(&decl.fields, |field| { @@ -1373,11 +1373,6 @@ fn collect_type_id( }); } } - TypeInfo::Storage { fields } => { - adaptive_iter(fields, |field| { - field.parse(ctx); - }); - } _ => { if let Some(token) = ctx .tokens @@ -1458,7 +1453,7 @@ fn collect_enum(ctx: &ParseContext, decl_id: &DeclId, declaratio adaptive_iter(&enum_decl.type_parameters, |type_param| { if let Some(mut token) = ctx .tokens - .try_get_mut_with_retry(&ctx.ident(&type_param.name_ident)) + .try_get_mut_with_retry(&ctx.ident(&type_param.name)) { token.ast_node = TokenAstNode::Typed(TypedAstToken::TypedParameter(type_param.clone())); token.type_def = Some(TypeDefinition::TypeId(type_param.type_id)); diff --git a/sway-lsp/tests/lib.rs b/sway-lsp/tests/lib.rs index c377db53bf5..39e9174a96f 100644 --- a/sway-lsp/tests/lib.rs +++ b/sway-lsp/tests/lib.rs @@ -5,18 +5,18 @@ pub mod integration; use crate::integration::{code_actions, lsp}; use lsp_types::*; use rayon::prelude::*; -use std::{fs, panic, path::PathBuf, process::Command, sync::Mutex}; +use std::{ + fs, panic, + path::PathBuf, + process::{Command, Stdio}, + sync::Mutex, +}; use sway_lsp::{ config::LspClient, handlers::{notification, request}, server_state::ServerState, }; -use sway_lsp_test_utils::{ - assert_server_requests, dir_contains_forc_manifest, doc_comments_dir, e2e_language_dir, - e2e_test_dir, generic_impl_self_dir, get_fixture, load_sway_example, random_delay, - runnables_test_dir, self_impl_reassignment_dir, setup_panic_hook, sway_workspace_dir, - test_fixtures_dir, -}; +use sway_lsp_test_utils::*; use tower_lsp::LspService; /// Holds the information needed to check the response of a goto definition request. @@ -2161,35 +2161,75 @@ async fn garbage_collection_runner(path: PathBuf) { shutdown_and_exit(&mut service).await; } +/// Contains representable individual projects suitable for GC tests, +/// as well as projects in which GC was failing, and that are not +/// included in [garbage_collection_all_language_tests]. #[test] -fn garbage_collection_storage() { - let p = sway_workspace_dir() - .join("sway-lsp/tests/fixtures/garbage_collection/storage_contract") - .join("src/main.sw"); - run_async!({ - garbage_collection_runner(p).await; - }); +fn garbage_collection_tests() -> Result<(), String> { + let mut tests = vec![ + // TODO: Enable this test once https://github.com/FuelLabs/sway/issues/6687 is fixed. + // ( + // "option_eq".into(), + // sway_workspace_dir() + // .join(e2e_stdlib_dir()) + // .join("option_eq") + // .join("src/main.sw"), + // ), + ( + "arrays".into(), + sway_workspace_dir() + .join("examples/arrays") + .join("src/main.sw"), + ), + ( + "minimal_script".into(), + sway_workspace_dir() + .join("sway-lsp/tests/fixtures/garbage_collection/minimal_script") + .join("src/main.sw"), + ), + ( + "paths".into(), + test_fixtures_dir().join("tokens/paths/src/main.sw"), + ), + ( + "storage_contract".into(), + sway_workspace_dir() + .join("sway-lsp/tests/fixtures/garbage_collection/storage_contract") + .join("src/main.sw"), + ), + ]; + + tests.sort(); + + run_garbage_collection_tests(&tests, None) } #[test] -fn garbage_collection_paths() { - let p = test_fixtures_dir().join("tokens/paths/src/main.sw"); - run_async!({ - garbage_collection_runner(p).await; - }); +fn garbage_collection_all_language_tests() -> Result<(), String> { + run_garbage_collection_tests_from_projects_dir(e2e_language_dir()) } #[test] -fn garbage_collection_minimal_script() { - let p = sway_workspace_dir() - .join("sway-lsp/tests/fixtures/garbage_collection/minimal_script") - .join("src/main.sw"); - run_async!({ - garbage_collection_runner(p).await; - }); +#[ignore = "Additional stress test for GC. Run it locally when working on code that affects GC."] +fn garbage_collection_all_should_pass_tests() -> Result<(), String> { + run_garbage_collection_tests_from_projects_dir(e2e_should_pass_dir()) } -/// Tests garbage collection across all language test examples in parallel. +#[test] +#[ignore = "Additional stress test for GC. Run it locally when working on code that affects GC."] +fn garbage_collection_all_should_fail_tests() -> Result<(), String> { + run_garbage_collection_tests_from_projects_dir(e2e_should_fail_dir()) +} + +#[test] +#[ignore = "Additional stress test for GC. Run it locally when working on code that affects GC."] +fn garbage_collection_all_stdlib_tests() -> Result<(), String> { + run_garbage_collection_tests_from_projects_dir(e2e_stdlib_dir()) +} + +/// Parallel test runner for garbage collection tests across Sway projects defined by `tests`. +/// Each test in `tests` consists of a project name and the path to the file that will +/// be changed during the test (keystroke simulation will be in that file). /// /// # Overview /// This test suite takes a unique approach to handling test isolation and error reporting: @@ -2206,76 +2246,130 @@ fn garbage_collection_minimal_script() { /// examples need garbage collection fixes. /// /// # Implementation Details -/// - Uses std::process::Command to spawn each test in isolation -/// - Collects results through a thread-safe Mutex +/// - Uses [std::process::Command] to spawn each test in isolation +/// - Collects results through a thread-safe [Mutex] /// - Provides detailed error reporting for failed tests /// - Categorizes different types of failures (exit codes vs signals) -// #[test] -#[allow(dead_code)] -fn run_all_garbage_collection_tests() { - let base_dir = sway_workspace_dir().join(e2e_language_dir()); - let entries: Vec<_> = std::fs::read_dir(base_dir) - .unwrap() - .filter_map(|e| e.ok()) - .filter(|e| e.file_type().map(|ft| ft.is_dir()).unwrap_or(false)) - .collect(); - - let results = Mutex::new(Vec::new()); - +fn run_garbage_collection_tests( + tests: &[(String, PathBuf)], + base_dir: Option, +) -> Result<(), String> { println!("\n=== Starting Garbage Collection Tests ===\n"); - entries.par_iter().for_each(|entry| { - let project_dir = entry.path(); - let project_name = project_dir - .file_name() - .unwrap() - .to_string_lossy() - .to_string(); - let main_file = project_dir.join("src/main.sw"); + match base_dir { + Some(base_dir) => { + println!("▶ Testing {} project(s) in '{base_dir}'\n", tests.len()); + } + None => { + println!("▶ Testing {} project(s):", tests.len()); + let max_project_name_len = tests + .iter() + .map(|(project_name, _)| project_name.len()) + .max() + .unwrap_or_default(); + tests.iter().for_each(|(project_name, test_file)| { + println!( + "- {project_name: 0 { - println!("\nFailed Projects:"); - for (name, _, error) in results.iter().filter(|r| !r.1) { - println!("- {} (Error: {})", name, error.as_ref().unwrap()); + println!("Failed projects:"); + for (project_name, test_file, _, error) in results.iter().filter(|r| !r.2) { + println!("- Project: {project_name}"); + println!(" Path: {test_file}"); + println!(" Error: {}", error.as_ref().unwrap()); } - panic!("{} projects failed garbage collection testing", failed); + println!(); + + Err(format!( + "{} project(s) failed garbage collection testing", + failed + )) + } else { + Ok(()) } } +/// Test runner for garbage collection tests across all Sway projects found in the `projects_dir`. +/// Tests run in parallel and include only the projects that have `src/main.sw` file. +fn run_garbage_collection_tests_from_projects_dir(projects_dir: PathBuf) -> Result<(), String> { + let base_dir = sway_workspace_dir().join(projects_dir); + let mut tests: Vec<_> = std::fs::read_dir(base_dir.clone()) + .unwrap() + .filter_map(|e| e.ok()) + .filter(|e| e.file_type().map(|ft| ft.is_dir()).unwrap_or(false)) + .map(|dir_entry| { + let project_dir = dir_entry.path(); + let project_name = project_dir + .file_name() + .unwrap() + .to_string_lossy() + .to_string(); + let main_file = project_dir.join("src/main.sw"); + (project_name, main_file) + }) + .filter(|(_, main_file)| main_file.exists()) + .collect(); + + tests.sort(); + + run_garbage_collection_tests(&tests, Some(base_dir.to_string_lossy().to_string())) +} + /// Individual test runner executed in a separate process for each test. /// /// This function is called by the main test runner through a new process invocation @@ -2287,12 +2381,11 @@ fn run_all_garbage_collection_tests() { /// 1. Tests are completely isolated from each other /// 2. Panics in one test don't affect others /// 3. Resource cleanup happens automatically on process exit -// #[tokio::test] -#[allow(dead_code)] -async fn test_single_project() { - if let Ok(file) = std::env::var("TEST_FILE") { - println!("Running single test for file: {}", file); - let path = PathBuf::from(file); +#[tokio::test] +#[ignore = "This test is meant to be run only indirectly through the tests that run GC in parallel."] +async fn test_single_garbage_collection_project() { + if let Ok(test_file) = std::env::var("TEST_FILE") { + let path = PathBuf::from(test_file); garbage_collection_runner(path).await; } else { panic!("TEST_FILE environment variable not set"); diff --git a/sway-lsp/tests/utils/src/lib.rs b/sway-lsp/tests/utils/src/lib.rs index be741f8798b..6f42b4d3f08 100644 --- a/sway-lsp/tests/utils/src/lib.rs +++ b/sway-lsp/tests/utils/src/lib.rs @@ -28,6 +28,18 @@ pub fn e2e_language_dir() -> PathBuf { PathBuf::from("test/src/e2e_vm_tests/test_programs/should_pass/language") } +pub fn e2e_should_pass_dir() -> PathBuf { + PathBuf::from("test/src/e2e_vm_tests/test_programs/should_pass") +} + +pub fn e2e_should_fail_dir() -> PathBuf { + PathBuf::from("test/src/e2e_vm_tests/test_programs/should_fail") +} + +pub fn e2e_stdlib_dir() -> PathBuf { + PathBuf::from("test/src/e2e_vm_tests/test_programs/should_pass/stdlib") +} + pub fn e2e_unit_dir() -> PathBuf { PathBuf::from("test/src/e2e_vm_tests/test_programs/should_pass/unit_tests") } diff --git a/sway-types/src/lib.rs b/sway-types/src/lib.rs index 5d8e1cf95c1..b45471dcba2 100644 --- a/sway-types/src/lib.rs +++ b/sway-types/src/lib.rs @@ -88,47 +88,34 @@ impl Instruction { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, PartialOrd, Ord)] -pub struct ProgramId { - id: u16, -} +pub struct ProgramId(u16); impl ProgramId { pub fn new(id: u16) -> Self { - Self { id } + Self(id) } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, PartialOrd, Ord)] -pub struct SourceId { - id: u32, -} +pub struct SourceId(u32); impl SourceId { - const RESERVED: u16 = 0; const SOURCE_ID_BITS: u32 = 20; const SOURCE_ID_MASK: u32 = (1 << Self::SOURCE_ID_BITS) - 1; - /// Create a combined ID from module and source IDs. + /// Create a combined ID from program and source IDs. pub fn new(program_id: u16, source_id: u32) -> Self { - SourceId { - id: ((program_id as u32) << Self::SOURCE_ID_BITS) | source_id, - } - } - - /// Create a reserved source_id. This is assigned to internal types - /// that should not be cleared during garbage collection. - pub fn reserved() -> Self { - Self::new(Self::RESERVED, Self::RESERVED as u32) + SourceId(((program_id as u32) << Self::SOURCE_ID_BITS) | source_id) } - /// The program_id that this source_id was created from. + /// The [ProgramId] that this [SourceId] was created from. pub fn program_id(&self) -> ProgramId { - ProgramId::new((self.id >> Self::SOURCE_ID_BITS) as u16) + ProgramId::new((self.0 >> Self::SOURCE_ID_BITS) as u16) } - /// Id of the source file without the program_id component. + /// ID of the source file without the [ProgramId] component. pub fn source_id(&self) -> u32 { - self.id & Self::SOURCE_ID_MASK + self.0 & Self::SOURCE_ID_MASK } } diff --git a/sway-types/src/source_engine.rs b/sway-types/src/source_engine.rs index 95ea5d94775..7a3124a3de2 100644 --- a/sway-types/src/source_engine.rs +++ b/sway-types/src/source_engine.rs @@ -81,7 +81,7 @@ impl SourceEngine { } } - let source_id = SourceId::new(program_id.id, *self.next_source_id.read()); + let source_id = SourceId::new(program_id.0, *self.next_source_id.read()); { let mut next_id = self.next_source_id.write(); *next_id += 1; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/abi_cast_nested_method/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/abi_cast_nested_method/src/main.sw index 6f08f7204de..2058833a235 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/abi_cast_nested_method/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/abi_cast_nested_method/src/main.sw @@ -3,6 +3,7 @@ script; abi AMM { fn pool() -> Option; } + abi Exchange { fn swap_exact_output(); } @@ -12,9 +13,6 @@ fn main() { let exchange_contract_id = amm_contract.pool(); - // let a = exchange_contract_id.unwrap().into(); - // let exchange_contract = abi(Exchange, a); - let exchange_contract = abi(Exchange, exchange_contract_id.unwrap().into()); exchange_contract.swap_exact_output(); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_or/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_or/test.toml index 2a24c489834..1d19796346b 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_or/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_or/test.toml @@ -2,4 +2,4 @@ category = "run" expected_result = { action = "return", value = 42 } expected_result_new_encoding = { action = "return_data", value = "000000000000002A" } validate_abi = true -expected_warnings = 7 #TODO: Set number of warnings to minimum once TODOs in tests are solved. +expected_warnings = 7 #TODO: Set number of warnings to minimum once TODOs in tests are solved. From 9c4a339dfff53af6c130c2f7a069c0b904550101 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaya=20G=C3=B6kalp?= Date: Wed, 6 Nov 2024 01:42:25 -0800 Subject: [PATCH 100/115] chore: remove unmaintained `ansi_term` in favor of `ansiterm` (#6696) ## Description related to #2601. Removes ansi_term dependency from sway crates. To remove the dependency completely from dep tree we need a release of sway repo to get a new version of forc_util and use it in forc_wallet as forc_wallet is depending on `forc-util v0.47.0` which uses `ansi_term`. Once that is done we can close #2601 --- Cargo.lock | 72 +++++++++------------------------- Cargo.toml | 2 +- forc-pkg/Cargo.toml | 2 +- forc-pkg/src/lock.rs | 4 +- forc-pkg/src/pkg.rs | 6 +-- forc-pkg/src/source/git/mod.rs | 6 +-- forc-pkg/src/source/ipfs.rs | 6 +-- forc-tracing/Cargo.toml | 4 +- forc-tracing/src/lib.rs | 2 +- forc-util/Cargo.toml | 2 +- forc-util/src/cli.rs | 2 +- forc-util/src/lib.rs | 4 +- forc/Cargo.toml | 2 +- forc/src/cli/commands/test.rs | 2 +- swayfmt/Cargo.toml | 2 +- swayfmt/test_macros/Cargo.toml | 2 +- 16 files changed, 38 insertions(+), 82 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 07c201f8f60..b28a9aacc7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -190,6 +190,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "ansiterm" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ab587f5395da16dd2e6939adf53dede583221b320cadfb94e02b5b7b9bf24cc" +dependencies = [ + "winapi", +] + [[package]] name = "anstream" version = "0.6.15" @@ -2672,7 +2681,7 @@ name = "forc" version = "0.66.4" dependencies = [ "annotate-snippets", - "ansi_term", + "ansiterm", "anyhow", "clap 4.5.20", "clap_complete", @@ -2845,7 +2854,7 @@ dependencies = [ "forc-pkg", "forc-tracing 0.66.4", "forc-util", - "prettydiff 0.7.0", + "prettydiff", "sway-core", "sway-utils", "swayfmt", @@ -2868,7 +2877,7 @@ dependencies = [ name = "forc-pkg" version = "0.66.4" dependencies = [ - "ansi_term", + "ansiterm", "anyhow", "byte-unit", "cid", @@ -2934,7 +2943,7 @@ dependencies = [ name = "forc-tracing" version = "0.66.4" dependencies = [ - "ansi_term", + "ansiterm", "tracing", "tracing-subscriber", "tracing-test", @@ -2960,7 +2969,7 @@ name = "forc-util" version = "0.66.4" dependencies = [ "annotate-snippets", - "ansi_term", + "ansiterm", "anyhow", "clap 4.5.20", "dirs 5.0.1", @@ -3906,15 +3915,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "heck" version = "0.4.1" @@ -5881,18 +5881,6 @@ dependencies = [ "yansi 1.0.1", ] -[[package]] -name = "prettydiff" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ff1fec61082821f8236cf6c0c14e8172b62ce8a72a0eedc30d3b247bb68dc11" -dependencies = [ - "ansi_term", - "pad", - "prettytable-rs", - "structopt", -] - [[package]] name = "prettydiff" version = "0.7.0" @@ -7470,30 +7458,6 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "structopt" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" -dependencies = [ - "clap 2.34.0", - "lazy_static", - "structopt-derive", -] - -[[package]] -name = "structopt-derive" -version = "0.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" -dependencies = [ - "heck 0.3.3", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "strum" version = "0.24.1" @@ -7667,7 +7631,7 @@ dependencies = [ "itertools 0.13.0", "once_cell", "peg", - "prettydiff 0.7.0", + "prettydiff", "rustc-hash 1.1.0", "slotmap", "sway-features", @@ -7805,7 +7769,7 @@ dependencies = [ "forc-tracing 0.66.4", "indoc", "paste", - "prettydiff 0.6.4", + "prettydiff", "ropey", "serde", "serde_ignored", @@ -8121,7 +8085,7 @@ dependencies = [ "insta", "libtest-mimic", "normalize-path", - "prettydiff 0.7.0", + "prettydiff", "rand", "regex", "revm", @@ -8144,7 +8108,7 @@ name = "test-macros" version = "0.0.0" dependencies = [ "paste", - "prettydiff 0.6.4", + "prettydiff", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index cc4f22bd5c7..dea5fb29407 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -108,7 +108,7 @@ forc-wallet = "0.11" # annotate-snippets = "0.10" -ansi_term = "0.12" +ansiterm = "0.12" anyhow = "1.0" assert-json-diff = "2.0" async-trait = "0.1" diff --git a/forc-pkg/Cargo.toml b/forc-pkg/Cargo.toml index 7b1bc68587b..20dcf7436cc 100644 --- a/forc-pkg/Cargo.toml +++ b/forc-pkg/Cargo.toml @@ -9,7 +9,7 @@ license.workspace = true repository.workspace = true [dependencies] -ansi_term.workspace = true +ansiterm.workspace = true anyhow.workspace = true byte-unit.workspace = true cid.workspace = true diff --git a/forc-pkg/src/lock.rs b/forc-pkg/src/lock.rs index 594c107bc09..f5db529cc7b 100644 --- a/forc-pkg/src/lock.rs +++ b/forc-pkg/src/lock.rs @@ -354,7 +354,7 @@ where }; println_action_red( "Removing", - &format!("{}{src}", ansi_term::Style::new().bold().paint(&pkg.name)), + &format!("{}{src}", ansiterm::Style::new().bold().paint(&pkg.name)), ); } } @@ -372,7 +372,7 @@ where }; println_action_green( "Adding", - &format!("{}{src}", ansi_term::Style::new().bold().paint(&pkg.name)), + &format!("{}{src}", ansiterm::Style::new().bold().paint(&pkg.name)), ); } } diff --git a/forc-pkg/src/pkg.rs b/forc-pkg/src/pkg.rs index 19291e0d0ce..4a798f01f48 100644 --- a/forc-pkg/src/pkg.rs +++ b/forc-pkg/src/pkg.rs @@ -2244,13 +2244,13 @@ pub fn build_with_options(build_options: &BuildOpts) -> Result { fn print_pkg_summary_header(built_pkg: &BuiltPackage) { let prog_ty_str = forc_util::program_type_str(&built_pkg.tree_type); - // The ansi_term formatters ignore the `std::fmt` right-align + // The ansiterm formatters ignore the `std::fmt` right-align // formatter, so we manually calculate the padding to align the program // type and name around the 10th column ourselves. let padded_ty_str = format!("{prog_ty_str:>10}"); let padding = &padded_ty_str[..padded_ty_str.len() - prog_ty_str.len()]; - let ty_ansi = ansi_term::Colour::Green.bold().paint(prog_ty_str); - let name_ansi = ansi_term::Style::new() + let ty_ansi = ansiterm::Colour::Green.bold().paint(prog_ty_str); + let name_ansi = ansiterm::Style::new() .bold() .paint(&built_pkg.descriptor.name); debug!("{padding}{ty_ansi} {name_ansi}"); diff --git a/forc-pkg/src/source/git/mod.rs b/forc-pkg/src/source/git/mod.rs index a89e77f3128..d1a74c13f34 100644 --- a/forc-pkg/src/source/git/mod.rs +++ b/forc-pkg/src/source/git/mod.rs @@ -206,11 +206,7 @@ impl source::Fetch for Pinned { if !repo_path.exists() { println_action_green( "Fetching", - &format!( - "{} {}", - ansi_term::Style::new().bold().paint(ctx.name), - self - ), + &format!("{} {}", ansiterm::Style::new().bold().paint(ctx.name), self), ); fetch(ctx.fetch_id(), ctx.name(), self)?; } diff --git a/forc-pkg/src/source/ipfs.rs b/forc-pkg/src/source/ipfs.rs index 1391348834c..4d465ff23f6 100644 --- a/forc-pkg/src/source/ipfs.rs +++ b/forc-pkg/src/source/ipfs.rs @@ -69,11 +69,7 @@ impl source::Fetch for Pinned { if !repo_path.exists() { println_action_green( "Fetching", - &format!( - "{} {}", - ansi_term::Style::new().bold().paint(ctx.name), - self - ), + &format!("{} {}", ansiterm::Style::new().bold().paint(ctx.name), self), ); let cid = &self.0; let ipfs_client = ipfs_client(); diff --git a/forc-tracing/Cargo.toml b/forc-tracing/Cargo.toml index 85240eec345..871e04df5a0 100644 --- a/forc-tracing/Cargo.toml +++ b/forc-tracing/Cargo.toml @@ -9,9 +9,9 @@ license.workspace = true repository.workspace = true [dependencies] -ansi_term.workspace = true +ansiterm.workspace = true tracing.workspace = true tracing-subscriber = { workspace = true, features = ["ansi", "env-filter", "json"] } [dev-dependencies] -tracing-test = "0.2" \ No newline at end of file +tracing-test = "0.2" diff --git a/forc-tracing/src/lib.rs b/forc-tracing/src/lib.rs index 656cb14ca14..c331b0a8a71 100644 --- a/forc-tracing/src/lib.rs +++ b/forc-tracing/src/lib.rs @@ -1,6 +1,6 @@ //! Utility items shared between forc crates. -use ansi_term::Colour; +use ansiterm::Colour; use std::str; use std::{env, io}; use tracing::{Level, Metadata}; diff --git a/forc-util/Cargo.toml b/forc-util/Cargo.toml index f224c3028cb..b2b5cdded43 100644 --- a/forc-util/Cargo.toml +++ b/forc-util/Cargo.toml @@ -10,7 +10,7 @@ repository.workspace = true [dependencies] annotate-snippets.workspace = true -ansi_term.workspace = true +ansiterm.workspace = true anyhow.workspace = true clap = { workspace = true, features = ["cargo", "derive", "env"] } dirs.workspace = true diff --git a/forc-util/src/cli.rs b/forc-util/src/cli.rs index f8f6ed5662e..d5dc863ddcd 100644 --- a/forc-util/src/cli.rs +++ b/forc-util/src/cli.rs @@ -103,7 +103,7 @@ macro_rules! cli_examples { fn help() -> &'static str { - Box::leak(format!("{}\n{}", forc_util::ansi_term::Colour::Yellow.paint("EXAMPLES:"), examples()).into_boxed_str()) + Box::leak(format!("{}\n{}", forc_util::ansiterm::Colour::Yellow.paint("EXAMPLES:"), examples()).into_boxed_str()) } pub fn examples() -> &'static str { diff --git a/forc-util/src/lib.rs b/forc-util/src/lib.rs index 7cf7f45b2b4..970b30aed5a 100644 --- a/forc-util/src/lib.rs +++ b/forc-util/src/lib.rs @@ -29,7 +29,7 @@ pub mod restricted; #[macro_use] pub mod cli; -pub use ansi_term; +pub use ansiterm; pub use paste; pub use regex::Regex; pub use serial_test; @@ -347,7 +347,7 @@ pub fn print_compiling(ty: Option<&TreeType>, name: &str, src: &dyn std::fmt::Di }; println_action_green( "Compiling", - &format!("{ty}{} ({src})", ansi_term::Style::new().bold().paint(name)), + &format!("{ty}{} ({src})", ansiterm::Style::new().bold().paint(name)), ); } diff --git a/forc/Cargo.toml b/forc/Cargo.toml index 578e427cee8..7c83e28884f 100644 --- a/forc/Cargo.toml +++ b/forc/Cargo.toml @@ -18,7 +18,7 @@ path = "src/main.rs" [dependencies] annotate-snippets.workspace = true -ansi_term.workspace = true +ansiterm.workspace = true anyhow.workspace = true clap = { workspace = true, features = ["cargo", "derive", "env"] } clap_complete.workspace = true diff --git a/forc/src/cli/commands/test.rs b/forc/src/cli/commands/test.rs index d556af6b790..c67e9140b81 100644 --- a/forc/src/cli/commands/test.rs +++ b/forc/src/cli/commands/test.rs @@ -1,5 +1,5 @@ use crate::cli; -use ansi_term::Colour; +use ansiterm::Colour; use clap::Parser; use forc_pkg as pkg; use forc_test::{decode_log_data, TestFilter, TestRunnerCount, TestedPackage}; diff --git a/swayfmt/Cargo.toml b/swayfmt/Cargo.toml index 475cbe5d1b2..85749c30ab2 100644 --- a/swayfmt/Cargo.toml +++ b/swayfmt/Cargo.toml @@ -26,6 +26,6 @@ toml = { workspace = true, features = ["parse"] } [dev-dependencies] paste = "1.0" -prettydiff = "0.6" +prettydiff = "0.7" similar = "2.0" test-macros = { path = "test_macros" } diff --git a/swayfmt/test_macros/Cargo.toml b/swayfmt/test_macros/Cargo.toml index 89e0debe297..f08138e89dc 100644 --- a/swayfmt/test_macros/Cargo.toml +++ b/swayfmt/test_macros/Cargo.toml @@ -15,7 +15,7 @@ repository.workspace = true [dev-dependencies] paste = "1.0" -prettydiff = "0.6" +prettydiff = "0.7" [package.metadata.cargo-udeps.ignore] development = ["paste", "prettydiff"] From 5330d3c16dc0a3dadf19586e160beaf8c4a6267d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Matos?= Date: Wed, 6 Nov 2024 10:24:21 +0000 Subject: [PATCH 101/115] Remove `forc` help test. (#6682) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description This test has shown itself to apparently not be deterministic, so remove it as it is causing issues when merging https://github.com/FuelLabs/sway/pull/6565. @xunilrj I think you added this test originally, so cc'ing you to make sure there is no issue with this. ## 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. Co-authored-by: Kaya Gökalp --- .../should_pass/forc/help/snapshot.toml | 16 - .../should_pass/forc/help/stdout.snap | 597 ------------------ 2 files changed, 613 deletions(-) delete mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/forc/help/snapshot.toml delete mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/forc/help/stdout.snap diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/forc/help/snapshot.toml b/test/src/e2e_vm_tests/test_programs/should_pass/forc/help/snapshot.toml deleted file mode 100644 index b9151f7a736..00000000000 --- a/test/src/e2e_vm_tests/test_programs/should_pass/forc/help/snapshot.toml +++ /dev/null @@ -1,16 +0,0 @@ -cmds = [ - "forc addr2line -h", - "forc build -h", - "forc check -h", - "forc clean -h", - "forc completions -h", - "forc new -h", - "forc init -h", - "forc parse-bytecode -h", - "forc test -h", - "forc update -h", - "forc plugins -h", - "forc template -h", - "forc contract-id -h", - "forc predicate-root -h", -] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/forc/help/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/forc/help/stdout.snap deleted file mode 100644 index 8dd4a804aae..00000000000 --- a/test/src/e2e_vm_tests/test_programs/should_pass/forc/help/stdout.snap +++ /dev/null @@ -1,597 +0,0 @@ ---- -source: test/tests/tests.rs ---- -> forc addr2line -h -exit status: 0 -output: -Show location and context of an opcode address in its source file - -Usage: forc addr2line [OPTIONS] --sourcemap-path --opcode-index - -Options: - -S, --search-dir Where to search for the project root [default: .] - -g, --sourcemap-path Source file mapping in JSON format - -c, --context How many lines of context to show [default: 2] - -i, --opcode-index Opcode index - -v, --verbose... Use verbose output - -s, --silent Silence all output - -L, --log-level Set the log level - -h, --help Print help - -> forc build -h -exit status: 0 -output: -Compile the current or target project - -Usage: forc build [OPTIONS] - -Options: - -p, --path - Path to the project - --offline - Offline mode - -t, --terse - Terse mode - --output-directory - The directory in which Forc output artifacts are placed - --locked - Requires that the Forc.lock file is up-to-date - --ipfs-node - The IPFS node to use for fetching IPFS sources - --ast - Print the generated Sway AST (Abstract Syntax Tree) - --dca-graph - Print the computed Sway DCA (Dead Code Analysis) graph - --dca-graph-url-format - URL format to be used in the generated DCA graph .dot file. - --asm ... - Print the generated ASM (assembler). [possible values: virtual, allocated, abstract, final, all] - --bytecode - Print the bytecode - --ir ... - Print the generated Sway IR (Intermediate Representation). [possible values: initial, final, all, modified, inline, simplify-cfg, sroa, dce, fn-dce, fn-dedup-release, fn-dedup-debug, mem2reg, memcpyopt, const-folding, arg-demotion, const-demotion, ret-demotion, misc-demotion] - --time-phases - Output the time elapsed over each part of the compilation process - --reverse-order - Output build errors and warnings in reverse order - --metrics-outfile - Output compilation metrics into the specified file - -v, --verbose... - Use verbose output - --json-abi - Minify JSON ABI files - -s, --silent - Silence all output - --json-storage-slots - Minify JSON storage slot files - -L, --log-level - Set the log level - -o, --output-bin - Create a binary file at the provided path representing the final bytecode - -g, --output-debug - Create a file at the provided path containing debug information - --build-profile - The name of the build profile to use [default: debug] - --release - Use the release build profile - --error-on-warnings - Treat warnings as errors - --build-target - Build target to use for code generation [default: fuel] [possible values: fuel, evm] - --tests - Also build all tests within the project - --experimental - Comma separated list of all experimental features that will be enabled [possible values: new_encoding] - --no-experimental - Comma separated list of all experimental features that will be disabled [possible values: new_encoding] - -h, --help - Print help (see more with '--help') - -V, --version - Print version - -EXAMPLES: - # Compile the current projectx - forc build - - # Compile the current project from a different path - forc build --path - - # Compile the current project without updating dependencies - forc build --path --locked - -> forc check -h -exit status: 0 -output: -Check the current or target project and all of its dependencies for errors - -Usage: forc check [OPTIONS] [BUILD_TARGET] - -Arguments: - [BUILD_TARGET] Build target to use for code generation [default: fuel] [possible values: fuel, evm] - -Options: - -p, --path - Path to the project, if not specified, current working directory will be used - --offline - Offline mode, prevents Forc from using the network when managing dependencies. Meaning it will only try to use previously downloaded dependencies - --locked - Requires that the Forc.lock file is up-to-date. If the lock file is missing, or it needs to be updated, Forc will exit with an error - -t, --terse - Terse mode. Limited warning and error output - --disable-tests - Disable checking unit tests - --ipfs-node - The IPFS Node to use for fetching IPFS sources - --experimental - Comma separated list of all experimental features that will be enabled [possible values: new_encoding] - --no-experimental - Comma separated list of all experimental features that will be disabled [possible values: new_encoding] - -v, --verbose... - Use verbose output - -s, --silent - Silence all output - -L, --log-level - Set the log level - -h, --help - Print help (see more with '--help') - -V, --version - Print version - -EXAMPLES: - # Check the current project - forc check - - # Check the current project with a different path - forc check --path - - # Check the current project without updating dependencies - forc check --locked - -> forc clean -h -exit status: 0 -output: -Removes the default forc compiler output artifact directory, i.e. `/out` - -Usage: forc clean [OPTIONS] - -Options: - -p, --path Path to the project, if not specified, current working directory will be used - -v, --verbose... Use verbose output - -s, --silent Silence all output - -L, --log-level Set the log level - -h, --help Print help - -V, --version Print version - -EXAMPLES: - # Clean project - forc clean - - # Clean project with a custom path - forc clean --path - -> forc completions -h -exit status: 0 -output: -Generate tab-completion scripts for your shell - -Usage: forc completions [OPTIONS] --target - -Options: - -T, --target Specify shell to enable tab-completion for [possible values: bash, elvish, fish, power-shell, zsh, fig] - -v, --verbose... Use verbose output - -s, --silent Silence all output - -L, --log-level Set the log level - -h, --help Print help (see more with '--help') - -> forc new -h -exit status: 0 -output: -Create a new Forc project at `` - -Usage: forc new [OPTIONS] - -Arguments: - The path at which the project directory will be created - -Options: - --contract The default program type. Excluding all flags or adding this flag creates a basic contract program - --script Adding this flag creates an empty script program - --predicate Adding this flag creates an empty predicate program - --library Adding this flag creates an empty library program - --workspace Adding this flag creates an empty workspace - --name Set the package name. Defaults to the directory name - -v, --verbose... Use verbose output - -s, --silent Silence all output - -L, --log-level Set the log level - -h, --help Print help - -V, --version Print version - -EXAMPLES: - # Create a new project - forc new --contract --name my_project - - # Create a new workspace - forc new --workspace --name my_workspace - - # Create a new Forc project with a predicate - forc new --predicate - - # Create a new Forc library project - forc new --library - -> forc init -h -exit status: 0 -output: -Create a new Forc project in an existing directory - -Usage: forc init [OPTIONS] - -Options: - --path The directory in which the forc project will be initialized - --contract The default program type, excluding all flags or adding this flag creates a basic contract program - --script Create a package with a script target (src/main.sw) - --predicate Create a package with a predicate target (src/predicate.rs) - --library Create a package with a library target (src/lib.sw) - --workspace Adding this flag creates an empty workspace - --name Set the package name. Defaults to the directory name - -v, --verbose... Use verbose output - -s, --silent Silence all output - -L, --log-level Set the log level - -h, --help Print help - -V, --version Print version - -EXAMPLES: - # Initialize a new Forc project - forc init --path - - # Initialize a new Forc project as workspace - forc init --path --workspace - - # Initialize a new Forc project with a predicate - forc init --path --predicate - - # Initialize a new Forc library project - forc init --path --library - -> forc parse-bytecode -h -exit status: 0 -output: -Parse bytecode file into a debug format - -Usage: forc parse-bytecode [OPTIONS] - -Arguments: - - -Options: - -v, --verbose... Use verbose output - -s, --silent Silence all output - -L, --log-level Set the log level - -h, --help Print help - -V, --version Print version - -EXAMPLES: - # Parse bytecode - forc parse-bytecode - -> forc test -h -exit status: 0 -output: -Run the Sway unit tests for the current project - -Usage: forc test [OPTIONS] [FILTER] - -Arguments: - [FILTER] When specified, only tests containing the given string will be executed - -Options: - -p, --path - Path to the project - --offline - Offline mode - -t, --terse - Terse mode - --output-directory - The directory in which Forc output artifacts are placed - --locked - Requires that the Forc.lock file is up-to-date - --ipfs-node - The IPFS node to use for fetching IPFS sources - --ast - Print the generated Sway AST (Abstract Syntax Tree) - --dca-graph - Print the computed Sway DCA (Dead Code Analysis) graph - --dca-graph-url-format - URL format to be used in the generated DCA graph .dot file. - --asm ... - Print the generated ASM (assembler). [possible values: virtual, allocated, abstract, final, all] - --bytecode - Print the bytecode - --ir ... - Print the generated Sway IR (Intermediate Representation). [possible values: initial, final, all, modified, inline, simplify-cfg, sroa, dce, fn-dce, fn-dedup-release, fn-dedup-debug, mem2reg, memcpyopt, const-folding, arg-demotion, const-demotion, ret-demotion, misc-demotion] - --time-phases - Output the time elapsed over each part of the compilation process - --reverse-order - Output build errors and warnings in reverse order - --metrics-outfile - Output compilation metrics into the specified file - -v, --verbose... - Use verbose output - --json-abi - Minify JSON ABI files - -s, --silent - Silence all output - --json-storage-slots - Minify JSON storage slot files - -L, --log-level - Set the log level - -o, --output-bin - Create a binary file at the provided path representing the final bytecode - -g, --output-debug - Create a file at the provided path containing debug information - --build-profile - The name of the build profile to use [default: debug] - --release - Use the release build profile - --error-on-warnings - Treat warnings as errors - --build-target - Build target to use for code generation [default: fuel] [possible values: fuel, evm] - --pretty - Pretty-print the logs emitted from tests - -l, --logs - Print `Log` and `LogData` receipts for tests - --raw-logs - Print the raw logs for tests - --filter-exact - When specified, only the test exactly matching the given string will be executed - --test-threads - Number of threads to utilize when running the tests. By default, this is the number of threads available in your system - --experimental - Comma separated list of all experimental features that will be enabled [possible values: new_encoding] - --no-experimental - Comma separated list of all experimental features that will be disabled [possible values: new_encoding] - -h, --help - Print help (see more with '--help') - -V, --version - Print version - -EXAMPLES: - # Run test - forc test - - # Run test with a filter - forc test $filter - - # Run test without any output - forc test --silent - - # Run test without creating or update the lock file - forc test --locked - -> forc update -h -exit status: 0 -output: -Update dependencies in the Forc dependencies directory - -Usage: forc update [OPTIONS] - -Options: - -p, --path Path to the project, if not specified, current working directory will be used - -d Dependency to be updated. If not set, all dependencies will be updated - -c, --check Checks if the dependencies have newer versions. Won't actually perform the update, will output which ones are up-to-date and outdated - --ipfs-node The IPFS Node to use for fetching IPFS sources - -v, --verbose... Use verbose output - -s, --silent Silence all output - -L, --log-level Set the log level - -h, --help Print help (see more with '--help') - -V, --version Print version - -EXAMPLES: - # Update dependencies - forc update - - # Update a specific dependency - forc update -d std - - # Check if dependencies have newer versions - forc update --check - -> forc plugins -h -exit status: 0 -output: -List all forc plugins - -Usage: forc plugins [OPTIONS] - -Options: - -p, --paths Prints the absolute path to each discovered plugin - -d, --describe Prints the long description associated with each listed plugin - -v, --verbose... Use verbose output - -s, --silent Silence all output - -L, --log-level Set the log level - -h, --help Print help (see more with '--help') - -V, --version Print version - -EXAMPLES: - # List all plugins - forc plugins - - # List all plugins with their paths - forc plugins --paths - - # List all plugins with their descriptions - forc plugins --describe - - # List all plugins with their paths and descriptions - forc plugins --paths --describe - -> forc template -h -exit status: 0 -output: -Create a new Forc project from a git template - -Usage: forc template [OPTIONS] - -Arguments: - The name of the project that will be created - -Options: - -u, --url The template url, should be a git repo [default: https://github.com/fuellabs/sway] - -t, --template-name The name of the template that needs to be fetched and used from git repo provided - -v, --verbose... Use verbose output - -s, --silent Silence all output - -L, --log-level Set the log level - -h, --help Print help - -V, --version Print version - -EXAMPLES: - # Create a new Forc project from an option template - forc template new-path --template-name option - -> forc contract-id -h -exit status: 0 -output: -Determine contract-id for a contract. For workspaces outputs all contract ids in the workspace - -Usage: forc contract-id [OPTIONS] - -Options: - -p, --path - Path to the project - --offline - Offline mode - -t, --terse - Terse mode - --output-directory - The directory in which Forc output artifacts are placed - --locked - Requires that the Forc.lock file is up-to-date - --ipfs-node - The IPFS node to use for fetching IPFS sources - --json-abi - Minify JSON ABI files - --json-storage-slots - Minify JSON storage slot files - --ast - Print the generated Sway AST (Abstract Syntax Tree) - --dca-graph - Print the computed Sway DCA (Dead Code Analysis) graph - --dca-graph-url-format - URL format to be used in the generated DCA graph .dot file. - --asm ... - Print the generated ASM (assembler). [possible values: virtual, allocated, abstract, final, all] - --bytecode - Print the bytecode - --ir ... - Print the generated Sway IR (Intermediate Representation). [possible values: initial, final, all, modified, inline, simplify-cfg, sroa, dce, fn-dce, fn-dedup-release, fn-dedup-debug, mem2reg, memcpyopt, const-folding, arg-demotion, const-demotion, ret-demotion, misc-demotion] - --time-phases - Output the time elapsed over each part of the compilation process - -v, --verbose... - Use verbose output - --reverse-order - Output build errors and warnings in reverse order - -s, --silent - Silence all output - -L, --log-level - Set the log level - --metrics-outfile - Output compilation metrics into the specified file - -o, --output-bin - Create a binary file at the provided path representing the final bytecode - -g, --output-debug - Create a file at the provided path containing debug information - --build-profile - The name of the build profile to use [default: debug] - --release - Use the release build profile - --error-on-warnings - Treat warnings as errors - --salt - Added salt used to derive the contract ID - --experimental - Comma separated list of all experimental features that will be enabled [possible values: new_encoding] - --no-experimental - Comma separated list of all experimental features that will be disabled [possible values: new_encoding] - -h, --help - Print help (see more with '--help') - -V, --version - Print version - -EXAMPLES: - # Get contract id - forc contract-id - - # Get contract id from a different path - forc contract-id --path - -> forc predicate-root -h -exit status: 0 -output: -Determine predicate-root for a predicate. For workspaces outputs all predicate roots in the workspace - -Usage: forc predicate-root [OPTIONS] - -Options: - -p, --path - Path to the project - --offline - Offline mode - -t, --terse - Terse mode - --output-directory - The directory in which Forc output artifacts are placed - --locked - Requires that the Forc.lock file is up-to-date - --ipfs-node - The IPFS node to use for fetching IPFS sources - --json-abi - Minify JSON ABI files - --json-storage-slots - Minify JSON storage slot files - --ast - Print the generated Sway AST (Abstract Syntax Tree) - --dca-graph - Print the computed Sway DCA (Dead Code Analysis) graph - --dca-graph-url-format - URL format to be used in the generated DCA graph .dot file. - --asm ... - Print the generated ASM (assembler). [possible values: virtual, allocated, abstract, final, all] - --bytecode - Print the bytecode - --ir ... - Print the generated Sway IR (Intermediate Representation). [possible values: initial, final, all, modified, inline, simplify-cfg, sroa, dce, fn-dce, fn-dedup-release, fn-dedup-debug, mem2reg, memcpyopt, const-folding, arg-demotion, const-demotion, ret-demotion, misc-demotion] - --time-phases - Output the time elapsed over each part of the compilation process - -v, --verbose... - Use verbose output - --reverse-order - Output build errors and warnings in reverse order - -s, --silent - Silence all output - -L, --log-level - Set the log level - --metrics-outfile - Output compilation metrics into the specified file - -o, --output-bin - Create a binary file at the provided path representing the final bytecode - -g, --output-debug - Create a file at the provided path containing debug information - --build-profile - The name of the build profile to use [default: debug] - --release - Use the release build profile - --error-on-warnings - Treat warnings as errors - --experimental - Comma separated list of all experimental features that will be enabled [possible values: new_encoding] - --no-experimental - Comma separated list of all experimental features that will be disabled [possible values: new_encoding] - -h, --help - Print help (see more with '--help') - -V, --version - Print version - -EXAMPLES: - # Get predicate root - forc predicate-root From ccd86925f99658f2dd72fedfe05b68a71e4acba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaya=20G=C3=B6kalp?= Date: Wed, 6 Nov 2024 05:46:40 -0800 Subject: [PATCH 102/115] chore: remove `uwuify` feature (#6698) --- Cargo.lock | 187 +++++++---------------------------- Cargo.toml | 1 - forc-util/src/lib.rs | 6 +- forc/Cargo.toml | 2 - sway-error/Cargo.toml | 2 - sway-error/src/diagnostic.rs | 25 ----- 6 files changed, 37 insertions(+), 186 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b28a9aacc7b..45b88125184 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -450,17 +450,6 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - [[package]] name = "aurora-engine-modexp" version = "1.1.0" @@ -1216,21 +1205,6 @@ dependencies = [ "inout", ] -[[package]] -name = "clap" -version = "2.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" -dependencies = [ - "ansi_term", - "atty", - "bitflags 1.3.2", - "strsim 0.8.0", - "textwrap 0.11.0", - "unicode-width", - "vec_map", -] - [[package]] name = "clap" version = "4.5.20" @@ -1260,7 +1234,7 @@ version = "4.5.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9646e2e245bf62f45d39a0f3f36f1171ad1ea0d6967fd114bca72cb02a8fcdfb" dependencies = [ - "clap 4.5.20", + "clap", ] [[package]] @@ -1269,7 +1243,7 @@ version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d494102c8ff3951810c72baf96910b980fb065ca5d3101243e6a8dc19747c86b" dependencies = [ - "clap 4.5.20", + "clap", "clap_complete", ] @@ -1455,7 +1429,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c93ab3577cca16b4a1d80a88c2e0cd8b6e969e51696f0bbb0d1dcb0157109832" dependencies = [ "caseless", - "clap 4.5.20", + "clap", "derive_builder", "entities", "memchr", @@ -1602,7 +1576,7 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.5.20", + "clap", "criterion-plot", "is-terminal", "itertools 0.10.5", @@ -1894,7 +1868,7 @@ dependencies = [ "hashbrown 0.14.5", "lock_api", "once_cell", - "parking_lot_core 0.9.10", + "parking_lot_core", ] [[package]] @@ -1908,7 +1882,7 @@ dependencies = [ "hashbrown 0.14.5", "lock_api", "once_cell", - "parking_lot_core 0.9.10", + "parking_lot_core", ] [[package]] @@ -2683,7 +2657,7 @@ dependencies = [ "annotate-snippets", "ansiterm", "anyhow", - "clap 4.5.20", + "clap", "clap_complete", "clap_complete_fig", "completest-pty", @@ -2709,7 +2683,6 @@ dependencies = [ "toml_edit", "tracing", "url", - "uwuify", "walkdir", "whoami", ] @@ -2723,7 +2696,7 @@ dependencies = [ "aws-config", "aws-sdk-kms", "chrono", - "clap 4.5.20", + "clap", "devault", "dialoguer", "forc", @@ -2768,7 +2741,7 @@ version = "0.66.4" dependencies = [ "anyhow", "async-trait", - "clap 4.5.20", + "clap", "criterion", "forc-tracing 0.66.4", "forc-util", @@ -2797,7 +2770,7 @@ name = "forc-debug" version = "0.66.4" dependencies = [ "anyhow", - "clap 4.5.20", + "clap", "dap", "escargot", "forc-pkg", @@ -2824,7 +2797,7 @@ name = "forc-doc" version = "0.66.4" dependencies = [ "anyhow", - "clap 4.5.20", + "clap", "comrak", "dir_indexer", "expect-test", @@ -2850,7 +2823,7 @@ name = "forc-fmt" version = "0.66.4" dependencies = [ "anyhow", - "clap 4.5.20", + "clap", "forc-pkg", "forc-tracing 0.66.4", "forc-util", @@ -2867,7 +2840,7 @@ name = "forc-lsp" version = "0.66.4" dependencies = [ "anyhow", - "clap 4.5.20", + "clap", "sway-lsp", "tikv-jemallocator", "tokio", @@ -2954,7 +2927,7 @@ name = "forc-tx" version = "0.66.4" dependencies = [ "anyhow", - "clap 4.5.20", + "clap", "devault", "forc-util", "fuel-tx", @@ -2971,7 +2944,7 @@ dependencies = [ "annotate-snippets", "ansiterm", "anyhow", - "clap 4.5.20", + "clap", "dirs 5.0.1", "fd-lock", "forc-tracing 0.66.4", @@ -2998,7 +2971,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e6ad4498ecab72fa7c5e134ade0137279d1b8f4a6df50963bb3803fdeb69dac" dependencies = [ "anyhow", - "clap 4.5.20", + "clap", "eth-keystore", "forc-tracing 0.47.0", "fuel-crypto", @@ -3137,7 +3110,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94a1c3eb92040d95d27f7c658801bb5c04ad4aaf67de380cececbeed5aab6e61" dependencies = [ "once_cell", - "parking_lot 0.12.3", + "parking_lot", "pin-project-lite", "prometheus-client", "regex", @@ -3175,7 +3148,7 @@ dependencies = [ "async-trait", "fuel-core-metrics", "futures", - "parking_lot 0.12.3", + "parking_lot", "pin-project-lite", "tokio", "tracing", @@ -3927,15 +3900,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - [[package]] name = "hermit-abi" version = "0.3.9" @@ -4451,15 +4415,6 @@ dependencies = [ "similar", ] -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if 1.0.0", -] - [[package]] name = "ipfs-api-backend-hyper" version = "0.6.0" @@ -4792,7 +4747,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc0bda45ed5b3a2904262c1bb91e526127aa70e7ef3758aba2ef93cf896b9b58" dependencies = [ - "clap 4.5.20", + "clap", "escape8259", "termcolor", "threadpool", @@ -4891,7 +4846,7 @@ checksum = "b45a38e19bd200220ef07c892b0157ad3d2365e5b5a267ca01ad12182491eea5" dependencies = [ "anyhow", "chrono", - "clap 4.5.20", + "clap", "clap_complete", "env_logger", "handlebars", @@ -4914,7 +4869,7 @@ name = "mdbook-forc-documenter" version = "0.0.0" dependencies = [ "anyhow", - "clap 4.5.20", + "clap", "mdbook", "semver 1.0.23", "serde", @@ -4967,7 +4922,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aa3f302fe0f8de065d4a2d1ed64f60204623cac58b80cd3c2a83a25d5a7d437" dependencies = [ - "clap 4.5.20", + "clap", ] [[package]] @@ -5481,12 +5436,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" -[[package]] -name = "owo-colors" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2386b4ebe91c2f7f51082d4cefa145d030e33a1842a96b12e4885cc3c01f7a55" - [[package]] name = "owo-colors" version = "3.5.0" @@ -5540,17 +5489,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - [[package]] name = "parking_lot" version = "0.12.3" @@ -5558,21 +5496,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", - "parking_lot_core 0.9.10", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if 1.0.0", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] @@ -5887,7 +5811,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abec3fb083c10660b3854367697da94c674e9e82aa7511014dc958beeb7215e9" dependencies = [ - "owo-colors 3.5.0", + "owo-colors", "pad", "prettytable-rs", ] @@ -5988,7 +5912,7 @@ checksum = "504ee9ff529add891127c4827eb481bd69dc0ebc72e9a682e187db4caa60c3ca" dependencies = [ "dtoa", "itoa", - "parking_lot 0.12.3", + "parking_lot", "prometheus-client-derive-encode", ] @@ -6214,15 +6138,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.4.1" @@ -7177,7 +7092,7 @@ dependencies = [ "futures", "log", "once_cell", - "parking_lot 0.12.3", + "parking_lot", "scc", "serial_test_derive", ] @@ -7440,12 +7355,6 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9557cb6521e8d009c51a8666f09356f4b817ba9ba0981a305bd86aee47bd35c" -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - [[package]] name = "strsim" version = "0.10.0" @@ -7556,7 +7465,7 @@ dependencies = [ name = "sway-core" version = "0.66.4" dependencies = [ - "clap 4.5.20", + "clap", "derivative", "dirs 5.0.1", "either", @@ -7574,7 +7483,7 @@ dependencies = [ "itertools 0.13.0", "lazy_static", "object", - "parking_lot 0.12.3", + "parking_lot", "paste", "pest", "pest_derive", @@ -7609,14 +7518,13 @@ dependencies = [ "strsim 0.11.1", "sway-types", "thiserror", - "uwuify", ] [[package]] name = "sway-features" version = "0.66.4" dependencies = [ - "clap 4.5.20", + "clap", "paste", ] @@ -7670,7 +7578,7 @@ dependencies = [ "lsp-types", "notify", "notify-debouncer-mini", - "parking_lot 0.12.3", + "parking_lot", "pretty_assertions", "proc-macro2", "quote", @@ -7746,7 +7654,7 @@ dependencies = [ "lazy_static", "num-bigint", "num-traits", - "parking_lot 0.12.3", + "parking_lot", "rustc-hash 1.1.0", "serde", "sway-utils", @@ -8068,7 +7976,7 @@ version = "0.0.0" dependencies = [ "anyhow", "bytes", - "clap 4.5.20", + "clap", "colored", "duct", "filecheck", @@ -8096,7 +8004,7 @@ dependencies = [ "sway-ir", "sway-types", "sway-utils", - "textwrap 0.16.1", + "textwrap", "tokio", "toml 0.8.19", "tracing", @@ -8117,15 +8025,6 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233" -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - [[package]] name = "textwrap" version = "0.16.1" @@ -8290,7 +8189,7 @@ dependencies = [ "bytes", "libc", "mio 1.0.2", - "parking_lot 0.12.3", + "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", @@ -8794,18 +8693,6 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" -[[package]] -name = "uwuify" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db6840b7adcfd2e866c79157cc890ecdbbc1f739607134039ae64eaa6c07e24" -dependencies = [ - "clap 2.34.0", - "owo-colors 1.3.0", - "parking_lot 0.11.2", - "thiserror", -] - [[package]] name = "valuable" version = "0.1.0" @@ -8824,12 +8711,6 @@ version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eab68b56840f69efb0fefbe3ab6661499217ffdc58e2eef7c3f6f69835386322" -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - [[package]] name = "version_check" version = "0.9.5" diff --git a/Cargo.toml b/Cargo.toml index dea5fb29407..15363bd5c55 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -228,7 +228,6 @@ unicode-bidi = "0.3" unicode-xid = "0.2" url = "2.2" urlencoding = "2.1" -uwuify = "^0.2" vec1 = "1.8" vte = "0.13" walkdir = "2.3" diff --git a/forc-util/src/lib.rs b/forc-util/src/lib.rs index 970b30aed5a..003d50898ad 100644 --- a/forc-util/src/lib.rs +++ b/forc-util/src/lib.rs @@ -510,7 +510,7 @@ fn format_diagnostic(diagnostic: &Diagnostic) { label: if issue.is_in_source() { None } else { - Some(issue.friendly_text()) + Some(issue.text()) }, id: None, annotation_type, @@ -532,7 +532,7 @@ fn format_diagnostic(diagnostic: &Diagnostic) { origin: Some(issue.source_path().unwrap().as_str()), fold: false, annotations: vec![SourceAnnotation { - label: issue.friendly_text(), + label: issue.text(), annotation_type, range: (start_pos, end_pos), }], @@ -594,7 +594,7 @@ fn construct_slice(labels: Vec<&Label>) -> Slice { for message in labels { annotations.push(SourceAnnotation { - label: message.friendly_text(), + label: message.text(), annotation_type: label_type_to_annotation_type(message.label_type()), range: get_annotation_range(message.span(), source_code, shift_in_bytes), }); diff --git a/forc/Cargo.toml b/forc/Cargo.toml index 7c83e28884f..b94be79b3cc 100644 --- a/forc/Cargo.toml +++ b/forc/Cargo.toml @@ -44,7 +44,6 @@ toml = { workspace = true, features = ["parse"] } toml_edit.workspace = true tracing.workspace = true url.workspace = true -uwuify = { workspace = true, optional = true } walkdir.workspace = true whoami.workspace = true @@ -52,7 +51,6 @@ whoami.workspace = true default = [] test = [] util = [] -uwu = ["uwuify"] [dev-dependencies] completest-pty = "0.5.0" diff --git a/sway-error/Cargo.toml b/sway-error/Cargo.toml index c8810d96b91..9a9744a5d7c 100644 --- a/sway-error/Cargo.toml +++ b/sway-error/Cargo.toml @@ -16,11 +16,9 @@ smallvec.workspace = true strsim.workspace = true sway-types.workspace = true thiserror.workspace = true -uwuify = { workspace = true, optional = true } [features] default = [] -uwu = ["uwuify"] [lints.clippy] iter_over_hash_type = "deny" diff --git a/sway-error/src/diagnostic.rs b/sway-error/src/diagnostic.rs index ddfe86bfb92..504734309e8 100644 --- a/sway-error/src/diagnostic.rs +++ b/sway-error/src/diagnostic.rs @@ -154,7 +154,6 @@ pub struct Label { label_type: LabelType, span: Span, text: String, - friendly_text: String, source_path: Option, } @@ -176,13 +175,11 @@ impl Label { } fn new(source_engine: &SourceEngine, label_type: LabelType, span: Span, text: String) -> Label { - let friendly_text = Self::maybe_uwuify(text.as_str()); let source_path = Self::get_source_path(source_engine, &span); Label { label_type, span, text, - friendly_text, source_path, } } @@ -204,10 +201,6 @@ impl Label { self.text.as_ref() } - pub fn friendly_text(&self) -> &str { - self.friendly_text.as_ref() - } - pub fn source_path(&self) -> Option<&SourcePath> { self.source_path.as_ref() } @@ -227,23 +220,6 @@ impl Label { _ => None, } } - - #[cfg(all(feature = "uwu", any(target_arch = "x86", target_arch = "x86_64")))] - fn maybe_uwuify(raw: &str) -> String { - use uwuifier::uwuify_str_sse; - uwuify_str_sse(raw) - } - - #[cfg(all(feature = "uwu", not(any(target_arch = "x86", target_arch = "x86_64"))))] - fn maybe_uwuify(raw: &str) -> String { - compile_error!("The `uwu` feature only works on x86 or x86_64 processors."); - Default::default() - } - - #[cfg(not(feature = "uwu"))] - fn maybe_uwuify(raw: &str) -> String { - raw.to_string() - } } impl Default for Label { @@ -252,7 +228,6 @@ impl Default for Label { label_type: LabelType::Info, span: Span::dummy(), text: "".to_string(), - friendly_text: "".to_string(), source_path: None, } } From efa4aab3ce99190fab2e8e76dee1e5b236013017 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaya=20G=C3=B6kalp?= Date: Fri, 8 Nov 2024 18:37:57 -0800 Subject: [PATCH 103/115] fix: forc-deploy asks for password before checking if the wallet exists (#6704) --- forc-plugins/forc-client/src/op/deploy.rs | 9 +++++++-- forc-plugins/forc-client/src/util/tx.rs | 3 --- forc-plugins/forc-client/tests/deploy.rs | 7 +++---- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/forc-plugins/forc-client/src/op/deploy.rs b/forc-plugins/forc-client/src/op/deploy.rs index ace89c3ddae..8f86c333672 100644 --- a/forc-plugins/forc-client/src/op/deploy.rs +++ b/forc-plugins/forc-client/src/op/deploy.rs @@ -7,8 +7,8 @@ use crate::{ pkg::{built_pkgs, create_proxy_contract, update_proxy_address_in_manifest}, target::Target, tx::{ - prompt_forc_wallet_password, select_account, update_proxy_contract_target, - SignerSelectionMode, + check_and_create_wallet_at_default_path, prompt_forc_wallet_password, select_account, + update_proxy_contract_target, SignerSelectionMode, }, }, }; @@ -1002,6 +1002,11 @@ async fn setup_deployment_account( } else if let Some(arn) = &command.aws_kms_signer { SignerSelectionMode::AwsSigner(arn.clone()) } else { + // Check if we have a wallet in the default path + // If there is one we will ask for the password + // If not we will ask the user to either create a new one or import one + let wallet_path = default_wallet_path(); + check_and_create_wallet_at_default_path(&wallet_path)?; println_action_green("", &format!("Wallet: {}", default_wallet_path().display())); let password = prompt_forc_wallet_password()?; SignerSelectionMode::ForcWallet(password) diff --git a/forc-plugins/forc-client/src/util/tx.rs b/forc-plugins/forc-client/src/util/tx.rs index e9f8b220121..dd9002a8055 100644 --- a/forc-plugins/forc-client/src/util/tx.rs +++ b/forc-plugins/forc-client/src/util/tx.rs @@ -170,9 +170,6 @@ pub(crate) async fn select_account( match wallet_mode { SignerSelectionMode::ForcWallet(password) => { let wallet_path = default_wallet_path(); - check_and_create_wallet_at_default_path(&wallet_path)?; - // TODO: This is a very simple TUI, we should consider adding a nice TUI - // capabilities for selections and answer collection. let accounts = collect_user_accounts(&wallet_path, password)?; let account_balances = collect_account_balances(&accounts, provider).await?; let base_asset_id = provider.base_asset_id(); diff --git a/forc-plugins/forc-client/tests/deploy.rs b/forc-plugins/forc-client/tests/deploy.rs index afabb238e82..b06d6aa96ed 100644 --- a/forc-plugins/forc-client/tests/deploy.rs +++ b/forc-plugins/forc-client/tests/deploy.rs @@ -693,7 +693,7 @@ async fn test_non_owner_fails_to_set_target() { // It would also require overriding `default_wallet_path` function for tests, so as not to interfere with the user's wallet. #[test] -fn test_deploy_interactive_wrong_password() -> Result<(), rexpect::error::Error> { +fn test_deploy_interactive_missing_wallet() -> Result<(), rexpect::error::Error> { let (mut node, port) = run_node(); let node_url = format!("http://127.0.0.1:{}/v1/graphql", port); @@ -711,9 +711,8 @@ fn test_deploy_interactive_wrong_password() -> Result<(), rexpect::error::Error> process .exp_string("\u{1b}[1;32mConfirming\u{1b}[0m transactions [deploy standalone_contract]")?; process.exp_string(&format!("Network: {node_url}"))?; - process.exp_string("Wallet: ")?; - process.exp_string("Wallet password")?; - process.send_line("mock_password")?; + process.exp_regex("Could not find a wallet at")?; + process.send_line("n")?; process.process.exit()?; node.kill().unwrap(); From f933f557e432e00b8ed89a96539da4894a701dc8 Mon Sep 17 00:00:00 2001 From: zees-dev Date: Sun, 10 Nov 2024 09:32:37 +1300 Subject: [PATCH 104/115] Forc-deploy import wallet support if non-existent wallet (#6680) ## Description - Adds support for importing a wallet on `forc-deploy` - Resolves https://github.com/FuelLabs/forc-wallet/issues/139 --- Cargo.lock | 8 ++--- forc-plugins/forc-client/src/util/tx.rs | 44 +++++++++++++++++-------- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 45b88125184..f29c1ad4299 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2966,9 +2966,9 @@ dependencies = [ [[package]] name = "forc-wallet" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e6ad4498ecab72fa7c5e134ade0137279d1b8f4a6df50963bb3803fdeb69dac" +checksum = "6ed94e0de4d8265fe744704544932bf1285ffa16ee5feb18062194904d299f9f" dependencies = [ "anyhow", "clap", @@ -5270,7 +5270,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate 3.2.0", + "proc-macro-crate 1.1.3", "proc-macro2", "quote", "syn 2.0.79", @@ -8503,7 +8503,7 @@ version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 0.1.10", "static_assertions", ] diff --git a/forc-plugins/forc-client/src/util/tx.rs b/forc-plugins/forc-client/src/util/tx.rs index dd9002a8055..a1dad6a3fcd 100644 --- a/forc-plugins/forc-client/src/util/tx.rs +++ b/forc-plugins/forc-client/src/util/tx.rs @@ -10,6 +10,7 @@ use forc_wallet::{ balance::{ collect_accounts_with_verification, AccountBalances, AccountVerification, AccountsMap, }, + import::{import_wallet_cli, Import}, new::{new_wallet_cli, New}, utils::default_wallet_path, }; @@ -45,6 +46,15 @@ fn ask_user_yes_no_question(question: &str) -> Result { Ok(answer) } +fn ask_user_with_options(question: &str, options: &[&str], default: usize) -> Result { + let selection = Select::with_theme(&ColorfulTheme::default()) + .with_prompt(question) + .items(options) + .default(default) + .interact()?; + Ok(selection) +} + fn collect_user_accounts( wallet_path: &Path, password: &str, @@ -71,21 +81,27 @@ pub(crate) fn prompt_forc_wallet_password() -> Result { pub(crate) fn check_and_create_wallet_at_default_path(wallet_path: &Path) -> Result<()> { if !wallet_path.exists() { - let question = format!("Could not find a wallet at {wallet_path:?}, would you like to create a new one? [y/N]: "); - let accepted = ask_user_yes_no_question(&question)?; - let new_options = New { - force: false, - cache_accounts: None, - }; - if accepted { - new_wallet_cli(wallet_path, new_options)?; - println!("Wallet created successfully."); - // Derive first account for the fresh wallet we created. - new_at_index_cli(wallet_path, 0)?; - println!("Account derived successfully."); - } else { - anyhow::bail!("Refused to create a new wallet. If you don't want to use forc-wallet, you can sign this transaction manually with --manual-signing flag.") + let question = + format!("Could not find a wallet at {wallet_path:?}, please select an option: "); + let wallet_options = ask_user_with_options( + &question, + &["Create new wallet", "Import existing wallet"], + 0, + )?; + match wallet_options { + 0 => { + new_wallet_cli(wallet_path, New { force: false, cache_accounts: None })?; + println!("Wallet created successfully."); + } + 1 => { + import_wallet_cli(wallet_path, Import { force: false, cache_accounts: None })?; + println!("Wallet imported successfully."); + }, + _ => anyhow::bail!("Refused to create or import a new wallet. If you don't want to use forc-wallet, you can sign this transaction manually with --manual-signing flag."), } + // Derive first account for the fresh wallet we created. + new_at_index_cli(wallet_path, 0)?; + println!("Account derived successfully."); } Ok(()) } From cbf0c6229da7ba23f79b9b17274d68f70a2a85f7 Mon Sep 17 00:00:00 2001 From: Sophie Dankel <47993817+sdankel@users.noreply.github.com> Date: Mon, 11 Nov 2024 21:34:31 -0800 Subject: [PATCH 105/115] chore: upgrade fuels sdk to 66.10 (#6715) ## Description This latest version of the fuels sdk should unblock the CI pipeline. ## Checklist - [ ] 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. - [ ] 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). - [ ] I have requested a review from the relevant team or maintainers. --- Cargo.lock | 752 ++++++++++----- Cargo.toml | 6 +- test/src/sdk-harness/Cargo.lock | 1555 ++++++++++++++++++------------- test/src/sdk-harness/Cargo.toml | 2 +- 4 files changed, 1441 insertions(+), 874 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f29c1ad4299..d0e9ea139dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,9 +73,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.18" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9" [[package]] name = "alloy-eip2930" @@ -102,9 +102,9 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.8.8" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f35429a652765189c1c5092870d8360ee7b7769b09b06d89ebaefd34676446" +checksum = "fd58d377699e6cfeab52c4a9d28bdc4ef37e2bd235ff2db525071fe37a2e9af5" dependencies = [ "alloy-rlp", "bytes", @@ -112,7 +112,7 @@ dependencies = [ "const-hex", "derive_more 1.0.0", "foldhash", - "hashbrown 0.15.0", + "hashbrown 0.15.1", "hex-literal", "indexmap 2.6.0", "itoa", @@ -130,9 +130,9 @@ dependencies = [ [[package]] name = "alloy-rlp" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26154390b1d205a4a7ac7352aa2eb4f81f391399d4e2f546fb81a2f8bb383f62" +checksum = "da0822426598f95e45dd1ea32a738dac057529a709ee645fcc516ffa4cbde08f" dependencies = [ "alloy-rlp-derive", "arrayvec", @@ -141,13 +141,13 @@ dependencies = [ [[package]] name = "alloy-rlp-derive" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d0f2d905ebd295e7effec65e5f6868d153936130ae718352771de3e7d03c75c" +checksum = "2b09cae092c27b6f1bde952653a22708691802e57bfef4a2973b80bea21efd3f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -201,9 +201,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -216,43 +216,43 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.89" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" [[package]] name = "arc-swap" @@ -432,7 +432,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -468,7 +468,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -479,9 +479,9 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "aws-config" -version = "1.5.8" +version = "1.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7198e6f03240fdceba36656d8be440297b6b82270325908c7381f37d826a74f6" +checksum = "9b49afaa341e8dd8577e1a2200468f98956d6eda50bcf4a53246cc00174ba924" dependencies = [ "aws-credential-types", "aws-runtime", @@ -546,9 +546,9 @@ dependencies = [ [[package]] name = "aws-sdk-kms" -version = "1.47.0" +version = "1.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "564a597a3c71a957d60a2e4c62c93d78ee5a0d636531e15b760acad983a5c18e" +checksum = "bfd059dacda4dfd5b57f2bd453fc6555f9acb496cb77508d517da24cf5d73167" dependencies = [ "aws-credential-types", "aws-runtime", @@ -568,9 +568,9 @@ dependencies = [ [[package]] name = "aws-sdk-sso" -version = "1.46.0" +version = "1.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc2faec3205d496c7e57eff685dd944203df7ce16a4116d0281c44021788a7b" +checksum = "09677244a9da92172c8dc60109b4a9658597d4d298b188dd0018b6a66b410ca4" dependencies = [ "aws-credential-types", "aws-runtime", @@ -590,9 +590,9 @@ dependencies = [ [[package]] name = "aws-sdk-ssooidc" -version = "1.47.0" +version = "1.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c93c241f52bc5e0476e259c953234dab7e2a35ee207ee202e86c0095ec4951dc" +checksum = "81fea2f3a8bb3bd10932ae7ad59cc59f65f270fc9183a7e91f501dc5efbef7ee" dependencies = [ "aws-credential-types", "aws-runtime", @@ -612,9 +612,9 @@ dependencies = [ [[package]] name = "aws-sdk-sts" -version = "1.46.0" +version = "1.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b259429be94a3459fa1b00c5684faee118d74f9577cc50aebadc36e507c63b5f" +checksum = "53dcf5e7d9bd1517b8b998e170e650047cea8a2b85fe1835abe3210713e541b7" dependencies = [ "aws-credential-types", "aws-runtime", @@ -635,9 +635,9 @@ dependencies = [ [[package]] name = "aws-sigv4" -version = "1.2.4" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc8db6904450bafe7473c6ca9123f88cc11089e41a025408f992db4e22d3be68" +checksum = "5619742a0d8f253be760bfbb8e8e8368c69e3587e4637af5754e488a611499b1" dependencies = [ "aws-credential-types", "aws-smithy-http", @@ -708,9 +708,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime" -version = "1.7.2" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a065c0fe6fdbdf9f11817eb68582b2ab4aff9e9c39e986ae48f7ec576c6322db" +checksum = "be28bd063fa91fd871d131fc8b68d7cd4c5fa0869bea68daca50dcb1cbd76be2" dependencies = [ "aws-smithy-async", "aws-smithy-http", @@ -735,9 +735,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime-api" -version = "1.7.2" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e086682a53d3aa241192aa110fa8dfce98f2f5ac2ead0de84d41582c7e8fdb96" +checksum = "92165296a47a812b267b4f41032ff8069ab7ff783696d217f0994a0d7ab585cd" dependencies = [ "aws-smithy-async", "aws-smithy-types", @@ -752,9 +752,9 @@ dependencies = [ [[package]] name = "aws-smithy-types" -version = "1.2.7" +version = "1.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147100a7bea70fa20ef224a6bad700358305f5dc0f84649c53769761395b355b" +checksum = "4fbd94a32b3a7d55d3806fe27d98d3ad393050439dd05eb53ece36ec5e3d3510" dependencies = [ "base64-simd", "bytes", @@ -965,9 +965,9 @@ dependencies = [ [[package]] name = "borsh" -version = "1.5.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6362ed55def622cddc70a4746a68554d7b687713770de539e59a739b249f8ed" +checksum = "f5327f6c99920069d1fe374aa743be1af0031dea9f250852cdf1ae6a0861ee24" dependencies = [ "borsh-derive", "cfg_aliases", @@ -975,16 +975,15 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.5.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" +checksum = "10aedd8f1a81a8aafbfde924b0e3061cd6fedd6f6bbcfc6a76e6fd426d7bfe26" dependencies = [ "once_cell", "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.79", - "syn_derive", + "syn 2.0.87", ] [[package]] @@ -1004,7 +1003,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" dependencies = [ "memchr", - "regex-automata 0.4.8", + "regex-automata 0.4.9", "serde", ] @@ -1022,9 +1021,9 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "byte-unit" -version = "5.1.4" +version = "5.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ac19bdf0b2665407c39d82dbc937e951e7e2001609f0fb32edd0af45a2d63e" +checksum = "e1cd29c3c585209b0cbc7309bfe3ed7efd8c84c21b7af29c8bfae908f8777174" dependencies = [ "rust_decimal", "serde", @@ -1067,9 +1066,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" [[package]] name = "bytes-utils" @@ -1114,9 +1113,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.1.30" +version = "1.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945" +checksum = "40545c26d092346d8a8dab71ee48e7685a7a9cba76e634790c215b41a4a7b4cf" dependencies = [ "jobserver", "libc", @@ -1191,7 +1190,7 @@ checksum = "3147d8272e8fa0ccd29ce51194dd98f79ddfb8191ba9e3409884e751798acf3a" dependencies = [ "core2", "multibase", - "multihash 0.19.1", + "multihash 0.19.2", "unsigned-varint 0.8.0", ] @@ -1230,9 +1229,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.33" +version = "4.5.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9646e2e245bf62f45d39a0f3f36f1171ad1ea0d6967fd114bca72cb02a8fcdfb" +checksum = "11611dca53440593f38e6b25ec629de50b14cdfa63adc0fb856115a2c6d97595" dependencies = [ "clap", ] @@ -1256,7 +1255,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -1356,9 +1355,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "colored" @@ -1551,9 +1550,9 @@ checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636" [[package]] name = "cpufeatures" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6" dependencies = [ "libc", ] @@ -1683,9 +1682,9 @@ dependencies = [ [[package]] name = "csv" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf" dependencies = [ "csv-core", "itoa", @@ -1734,7 +1733,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -1833,7 +1832,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -1855,7 +1854,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core 0.20.10", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -1971,7 +1970,7 @@ dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -1981,7 +1980,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -1994,7 +1993,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -2014,7 +2013,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", "unicode-xid", ] @@ -2143,6 +2142,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "dissimilar" version = "1.0.9" @@ -2283,9 +2293,9 @@ checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "encoding_rs" -version = "0.8.34" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if 1.0.0", ] @@ -2319,7 +2329,7 @@ checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -2332,7 +2342,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -2343,7 +2353,7 @@ checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -2409,9 +2419,9 @@ checksum = "5692dd7b5a1978a5aeb0ce83b7655c58ca8efdcb79d21036ea249da95afec2c6" [[package]] name = "escargot" -version = "0.5.12" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c000f23e9d459aef148b7267e02b03b94a0aaacf4ec64c65612f67e02f525fb6" +checksum = "05a3ac187a16b5382fef8c69fd1bad123c67b7cf3932240a2d43dcdd32cded88" dependencies = [ "log", "once_cell", @@ -2508,7 +2518,7 @@ checksum = "dd65f1b59dd22d680c7a626cc4a000c1e03d241c51c3e034d2bc9f1e90734f9b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -2535,9 +2545,9 @@ checksum = "a2a2b11eda1d40935b26cf18f6833c526845ae8c41e58d09af6adeb6f0269183" [[package]] name = "fastrand" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" [[package]] name = "fastrlp" @@ -2864,7 +2874,7 @@ dependencies = [ "ipfs-api-backend-hyper", "petgraph", "regex", - "reqwest 0.12.8", + "reqwest 0.12.9", "semver 1.0.23", "serde", "serde_ignored", @@ -3042,7 +3052,7 @@ dependencies = [ "regex", "serde", "serde_json", - "syn 2.0.79", + "syn 2.0.87", "thiserror", ] @@ -3223,7 +3233,7 @@ checksum = "ab0bc46a3552964bae5169e79b383761a54bd115ea66951a1a7a229edcefa55a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", "synstructure 0.13.1", ] @@ -3365,9 +3375,9 @@ dependencies = [ [[package]] name = "fuels" -version = "0.66.9" +version = "0.66.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed08053e72bdb285d5a167c27a7a0d10f1dc4e27d1e6e5296dd2a67813bd13f" +checksum = "25bf359dceffcbab4163bca473a03658b912686c3aa81a223f828260729dd474" dependencies = [ "fuel-core-client", "fuel-crypto", @@ -3381,9 +3391,9 @@ dependencies = [ [[package]] name = "fuels-accounts" -version = "0.66.9" +version = "0.66.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49fee90e8f3a4fc9392a6cde3010c561fa50da0f805d66fdb659eaa4d5d8a504" +checksum = "4b0b09d6ce3a12196f6944c74bdd795c39950d32ebaaf56b2943741a5e4308a1" dependencies = [ "async-trait", "chrono", @@ -3407,9 +3417,9 @@ dependencies = [ [[package]] name = "fuels-code-gen" -version = "0.66.9" +version = "0.66.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f857b7ff658400506ca6be57bb84fedda44b566e78f5f0a8d0782242f41615c0" +checksum = "78bf5f7b37ec598514fb3767abdae5372a9fa0919d350703f5d627ec2eb33456" dependencies = [ "Inflector", "fuel-abi-types", @@ -3418,14 +3428,14 @@ dependencies = [ "quote", "regex", "serde_json", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] name = "fuels-core" -version = "0.66.9" +version = "0.66.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baccbdd81e624f57950dcb136b32b853c520dd954badf26b9f58de33f3d71c7e" +checksum = "ab66cdf52fa6ef98dbc9cc7b4ce19c6a340b2a4710c5d5f87eae39ffb868bad7" dependencies = [ "async-trait", "bech32", @@ -3452,22 +3462,22 @@ dependencies = [ [[package]] name = "fuels-macros" -version = "0.66.9" +version = "0.66.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da75294c5e9da312bdc49239736699ee84ea9c5bfbc19a61a8ee588a1247aa1" +checksum = "1471d221453d13d4643c9a698212781f0e8ac40f515a8566538db87409e30752" dependencies = [ "fuels-code-gen", "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] name = "fuels-programs" -version = "0.66.9" +version = "0.66.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32675ed1c08edd28ddb648dfae0c60a1946d4368a69ddfa6434f2316e33f0520" +checksum = "7a854561a68ef4088972119cf31023d2d1afd58584da203bcb7dfbd1e84dd8fc" dependencies = [ "async-trait", "fuel-abi-types", @@ -3484,9 +3494,9 @@ dependencies = [ [[package]] name = "fuels-test-helpers" -version = "0.66.9" +version = "0.66.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02176c0fb1bf8cf58b8a9e5372efb650324740abcd4847b45bd0b041a0f133a2" +checksum = "5a7b428c35a54e4d667343b4051f07a7397e6039bd110411c37647db4478086e" dependencies = [ "fuel-core-chain-config", "fuel-core-client", @@ -3568,7 +3578,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -3682,9 +3692,9 @@ dependencies = [ [[package]] name = "gix-path" -version = "0.10.11" +version = "0.10.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebfc4febd088abdcbc9f1246896e57e37b7a34f6909840045a1767c6dafac7af" +checksum = "c04e5a94fdb56b1e91eb7df2658ad16832428b8eeda24ff1a0f0288de2bce554" dependencies = [ "bstr", "gix-trace", @@ -3695,9 +3705,9 @@ dependencies = [ [[package]] name = "gix-trace" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cae0e8661c3ff92688ce1c8b8058b3efb312aba9492bbe93661a21705ab431b" +checksum = "04bdde120c29f1fc23a24d3e115aeeea3d60d8e65bab92cc5f9d90d9302eb952" [[package]] name = "gix-url" @@ -3729,7 +3739,7 @@ dependencies = [ "aho-corasick", "bstr", "log", - "regex-automata 0.4.8", + "regex-automata 0.4.9", "regex-syntax 0.8.5", ] @@ -3815,11 +3825,12 @@ dependencies = [ [[package]] name = "handlebars" -version = "5.1.2" +version = "6.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d08485b96a0e6393e9e4d1b8d48cf74ad6c063cd905eb33f42c1ce3f0377539b" +checksum = "fd4ccde012831f9a071a637b0d4e31df31c0f6c525784b35ae76a9ac6bc1e315" dependencies = [ "log", + "num-order", "pest", "pest_derive", "serde", @@ -3867,9 +3878,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" dependencies = [ "foldhash", ] @@ -4139,7 +4150,7 @@ dependencies = [ "http 1.1.0", "hyper 1.5.0", "hyper-util", - "rustls 0.23.15", + "rustls 0.23.16", "rustls-pki-types", "tokio", "tokio-rustls 0.26.0", @@ -4176,9 +4187,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" dependencies = [ "bytes", "futures-channel", @@ -4216,6 +4227,124 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -4234,12 +4363,23 @@ dependencies = [ [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", ] [[package]] @@ -4285,26 +4425,26 @@ dependencies = [ [[package]] name = "impl-tools" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82c305b1081f1a99fda262883c788e50ab57d36c00830bdd7e0a82894ad965c" +checksum = "8a84bc8d2baf8da56e93b4247067d918e1a44829bbbe3e4b875aaf8d7d3c7bc9" dependencies = [ "autocfg", "impl-tools-lib", - "proc-macro-error", - "syn 2.0.79", + "proc-macro-error2", + "syn 2.0.87", ] [[package]] name = "impl-tools-lib" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85d3946d886eaab0702fa0c6585adcced581513223fa9df7ccfabbd9fa331a88" +checksum = "a795a1e201125947a063b967c79de6ae152143ab522f481d4f493c44835ba37a" dependencies = [ - "proc-macro-error", + "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -4361,7 +4501,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.15.0", + "hashbrown 0.15.1", "rayon", "serde", ] @@ -4403,9 +4543,9 @@ dependencies = [ [[package]] name = "insta" -version = "1.40.0" +version = "1.41.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6593a41c7a73841868772495db7dc1e8ecab43bb5c0b6da2059246c4b506ab60" +checksum = "7e9ffc4d4892617c50a928c52b2961cb5174b6fc6ebf252b2fac9d21955c48b8" dependencies = [ "console", "lazy_static", @@ -4605,9 +4745,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.161" +version = "0.2.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" +checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" [[package]] name = "libdbus-sys" @@ -4635,9 +4775,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.8" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] name = "libp2p-identity" @@ -4649,7 +4789,7 @@ dependencies = [ "bs58", "hkdf", "libsecp256k1", - "multihash 0.19.1", + "multihash 0.19.2", "quick-protobuf", "sha2 0.10.8", "thiserror", @@ -4777,6 +4917,12 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "litemap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" + [[package]] name = "lock_api" version = "0.4.12" @@ -4840,9 +4986,9 @@ dependencies = [ [[package]] name = "mdbook" -version = "0.4.40" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45a38e19bd200220ef07c892b0157ad3d2365e5b5a267ca01ad12182491eea5" +checksum = "7624879735513024d323e7267a0b3a7176aceb0db537939beb4ee31d9e8945e3" dependencies = [ "anyhow", "chrono", @@ -4918,9 +5064,9 @@ dependencies = [ [[package]] name = "minifier" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aa3f302fe0f8de065d4a2d1ed64f60204623cac58b80cd3c2a83a25d5a7d437" +checksum = "bd559bbf5d350ac7f2c1cf92ed71a869b847a92bce0c1318b47932a5b5f65cdd" dependencies = [ "clap", ] @@ -5001,12 +5147,12 @@ dependencies = [ [[package]] name = "multihash" -version = "0.19.1" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076d548d76a0e2a0d4ab471d0b1c36c577786dfc4471242035d97a12a735c492" +checksum = "cc41f430805af9d1cf4adae4ed2149c759b877b01d909a1f40256188d09345d2" dependencies = [ "core2", - "unsigned-varint 0.7.2", + "unsigned-varint 0.8.0", ] [[package]] @@ -5224,6 +5370,21 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-modular" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17bb261bf36fa7d83f4c294f834e91256769097b3cb505d44831e0a179ac647f" + +[[package]] +name = "num-order" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537b596b97c40fcf8056d153049eb22f481c17ebce72a513ec9286e4986d1bb6" +dependencies = [ + "num-modular", +] + [[package]] name = "num-rational" version = "0.4.2" @@ -5270,10 +5431,10 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate 1.1.3", + "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -5296,7 +5457,7 @@ checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "crc32fast", "flate2", - "hashbrown 0.15.0", + "hashbrown 0.15.1", "indexmap 2.6.0", "memchr", "ruzstd", @@ -5377,7 +5538,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -5388,9 +5549,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "300.3.2+3.3.2" +version = "300.4.0+3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a211a18d945ef7e648cc6e0058f4c548ee46aab922ea203e0d30e966ea23647b" +checksum = "a709e02f2b4aca747929cca5ed248880847c650233cf8b8cdc48f40aaf4898a6" dependencies = [ "cc", ] @@ -5601,7 +5762,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -5657,7 +5818,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -5671,29 +5832,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf123a161dde1e524adf36f90bc5d8d3462824a9c43553ad07a8183161189ec" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -5895,11 +6056,32 @@ dependencies = [ "version_check", ] +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", +] + [[package]] name = "proc-macro2" -version = "1.0.88" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ "unicode-ident", ] @@ -5924,7 +6106,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -6175,13 +6357,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.8", + "regex-automata 0.4.9", "regex-syntax 0.8.5", ] @@ -6196,9 +6378,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -6277,9 +6459,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.8" +version = "0.12.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b" +checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" dependencies = [ "base64 0.22.1", "bytes", @@ -6624,9 +6806,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.37" +version = "0.38.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" dependencies = [ "bitflags 2.6.0", "errno", @@ -6649,9 +6831,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.15" +version = "0.23.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fbb44d7acc4e873d613422379f69f237a1b141928c02f6bc6ccfddddc2d7993" +checksum = "eee87ff5d9b36712a58574e12e9f0ea80f915a5b0ac518d322b24a465617925e" dependencies = [ "once_cell", "rustls-pki-types", @@ -6792,9 +6974,9 @@ dependencies = [ [[package]] name = "scc" -version = "2.2.2" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2c1f7fc6deb21665a9060dfc7d271be784669295a31babdcd4dd2c79ae8cbfb" +checksum = "d8d25269dd3a12467afe2e510f69fb0b46b698e5afb296b59f2145259deaf8e8" dependencies = [ "sdd", ] @@ -6931,9 +7113,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.12.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" +checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2" dependencies = [ "core-foundation-sys", "libc", @@ -6968,22 +7150,22 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.210" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -6997,9 +7179,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.129" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbcf9b78a125ee667ae19388837dd12294b858d101fdd393cb9d5501ef09eb2" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" dependencies = [ "indexmap 2.6.0", "itoa", @@ -7016,7 +7198,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -7067,7 +7249,7 @@ dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -7085,9 +7267,9 @@ dependencies = [ [[package]] name = "serial_test" -version = "3.1.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b4b487fe2acf240a021cf57c6b2b4903b1e78ca0ecd862a71b71d2a51fed77d" +checksum = "1b258109f244e1d6891bf1053a55d63a5cd4f8f4c30cf9a1280989f80e7a1fa9" dependencies = [ "futures", "log", @@ -7099,13 +7281,13 @@ dependencies = [ [[package]] name = "serial_test_derive" -version = "3.1.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82fe9db325bcef1fbcde82e078a5cc4efdf787e96b3b9cf45b50b529f2083d67" +checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -7351,9 +7533,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "str_indices" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9557cb6521e8d009c51a8666f09356f4b817ba9ba0981a305bd86aee47bd35c" +checksum = "d08889ec5408683408db66ad89e0e1f93dff55c73a4ccc71c427d5b277ee47e6" [[package]] name = "strsim" @@ -7414,7 +7596,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -7427,7 +7609,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -7555,7 +7737,7 @@ dependencies = [ "itertools 0.13.0", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -7597,7 +7779,7 @@ dependencies = [ "sway-types", "sway-utils", "swayfmt", - "syn 2.0.79", + "syn 2.0.87", "tempfile", "thiserror", "tikv-jemallocator", @@ -7706,27 +7888,15 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.79" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] -[[package]] -name = "syn_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.79", -] - [[package]] name = "sync_wrapper" version = "0.1.2" @@ -7762,7 +7932,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -7847,9 +8017,9 @@ dependencies = [ [[package]] name = "tai64" -version = "4.0.0" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed7401421025f4132e6c1f7af5e7f8287383969f36e6628016cd509b8d3da9dc" +checksum = "014639506e4f425c78e823eabf56e71c093f940ae55b43e58f682e7bc2f5887a" dependencies = [ "serde", ] @@ -7883,9 +8053,9 @@ dependencies = [ [[package]] name = "tar" -version = "0.4.42" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ff6c40d3aedb5e06b57c6f669ad17ab063dd1e63d977c6a88e7f4dfa4f04020" +checksum = "c65998313f8e17d0d553d28f91a0df93e4dbbbf770279c7bc21ca0f09ea1a1f6" dependencies = [ "filetime", "libc", @@ -7894,9 +8064,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if 1.0.0", "fastrand", @@ -8038,22 +8208,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.64" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.64" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -8154,6 +8324,16 @@ dependencies = [ "crunchy", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinytemplate" version = "1.2.1" @@ -8181,9 +8361,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.40.0" +version = "1.41.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" dependencies = [ "backtrace", "bytes", @@ -8215,7 +8395,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -8244,7 +8424,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.15", + "rustls 0.23.16", "rustls-pki-types", "tokio", ] @@ -8387,7 +8567,7 @@ checksum = "84fd902d4e0b9a4b27f2f440108dc034e1758628a9b702f8ec61ad66355422fa" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -8415,7 +8595,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -8488,7 +8668,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04659ddb06c87d233c566112c1c9c5b9e98256d9af50ec3bc9c8327f873a7568" dependencies = [ "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -8503,7 +8683,7 @@ version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "static_assertions", ] @@ -8556,12 +8736,9 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicase" -version = "2.7.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] +checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" [[package]] name = "unicode-bidi" @@ -8649,12 +8826,12 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.2" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" dependencies = [ "form_urlencoded", - "idna 0.5.0", + "idna 1.0.3", "percent-encoding", "serde", ] @@ -8665,12 +8842,24 @@ version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + [[package]] name = "utf8-width" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -8835,7 +9024,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", "wasm-bindgen-shared", ] @@ -8869,7 +9058,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -9162,6 +9351,18 @@ version = "0.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "wyz" version = "0.5.1" @@ -9215,6 +9416,30 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" +[[package]] +name = "yoke" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", + "synstructure 0.13.1", +] + [[package]] name = "zerocopy" version = "0.7.35" @@ -9233,7 +9458,28 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", +] + +[[package]] +name = "zerofrom" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", + "synstructure 0.13.1", ] [[package]] @@ -9253,5 +9499,27 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", ] diff --git a/Cargo.toml b/Cargo.toml index 15363bd5c55..31bc6386951 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -89,9 +89,9 @@ fuel-core-types = { version = "0.40", default-features = false } # Dependencies from the `fuels-rs` repository: -fuels = "0.66.9" -fuels-core = "0.66.9" -fuels-accounts = "0.66.9" +fuels = "0.66.10" +fuels-core = "0.66.10" +fuels-accounts = "0.66.10" # Dependencies from the `fuel-vm` repository: fuel-asm = "0.58" diff --git a/test/src/sdk-harness/Cargo.lock b/test/src/sdk-harness/Cargo.lock index dad11fa0e14..54d09476c97 100644 --- a/test/src/sdk-harness/Cargo.lock +++ b/test/src/sdk-harness/Cargo.lock @@ -14,18 +14,18 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.21.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ - "gimli", + "gimli 0.31.1", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "aead" @@ -85,9 +85,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.18" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9" [[package]] name = "android-tzdata" @@ -106,9 +106,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.14" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -121,61 +121,61 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.7" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.3" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.3" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.83" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" [[package]] name = "arbitrary" -version = "1.3.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" [[package]] name = "arrayref" -version = "0.3.7" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "ascii" @@ -185,9 +185,9 @@ checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" [[package]] name = "asn1-rs" -version = "0.5.2" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" +checksum = "5493c3bedbacf7fd7382c6346bbd66687d12bbaad3a89a2d2c303ee6cf20b048" dependencies = [ "asn1-rs-derive", "asn1-rs-impl", @@ -201,25 +201,25 @@ dependencies = [ [[package]] name = "asn1-rs-derive" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" +checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", - "synstructure 0.12.6", + "syn 2.0.87", + "synstructure", ] [[package]] name = "asn1-rs-impl" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" +checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.87", ] [[package]] @@ -251,7 +251,7 @@ dependencies = [ "futures-timer", "futures-util", "http 1.1.0", - "indexmap 2.2.6", + "indexmap 2.6.0", "mime", "multer", "num-traits", @@ -280,7 +280,7 @@ dependencies = [ "proc-macro2", "quote", "strum 0.26.3", - "syn 2.0.63", + "syn 2.0.87", "thiserror", ] @@ -303,16 +303,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef5ec94176a12a8cbe985cd73f2e54dc9c702c88c766bdef12f1f3a67cedbee1" dependencies = [ "bytes", - "indexmap 2.2.6", + "indexmap 2.6.0", "serde", "serde_json", ] [[package]] name = "async-io" -version = "2.3.2" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcccb0f599cfa2f8ace422d3555572f47424da5648a4382a9dd0310ff8210884" +checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" dependencies = [ "async-lock", "cfg-if", @@ -324,14 +324,14 @@ dependencies = [ "rustix", "slab", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "async-lock" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" dependencies = [ "event-listener", "event-listener-strategy", @@ -340,9 +340,9 @@ dependencies = [ [[package]] name = "async-stream" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" dependencies = [ "async-stream-impl", "futures-core", @@ -351,24 +351,24 @@ dependencies = [ [[package]] name = "async-stream-impl" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] name = "async-trait" -version = "0.1.80" +version = "0.1.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] @@ -419,9 +419,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "axum" @@ -472,18 +472,18 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.71" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", - "object 0.32.2", + "object", "rustc-demangle", "serde", + "windows-targets 0.52.6", ] [[package]] @@ -536,9 +536,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" dependencies = [ "serde", ] @@ -606,22 +606,22 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" dependencies = [ "serde", ] [[package]] name = "cc" -version = "1.0.97" +version = "1.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" +checksum = "40545c26d092346d8a8dab71ee48e7685a7a9cba76e634790c215b41a4a7b4cf" dependencies = [ "jobserver", "libc", - "once_cell", + "shlex", ] [[package]] @@ -630,6 +630,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chacha20" version = "0.9.1" @@ -666,7 +672,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -682,9 +688,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.4" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", "clap_derive", @@ -692,9 +698,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstream", "anstyle", @@ -704,21 +710,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.4" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "cobs" @@ -780,9 +786,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "combine" @@ -871,9 +877,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "core2" @@ -895,27 +901,27 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6" dependencies = [ "libc", ] [[package]] name = "cranelift-bforest" -version = "0.110.2" +version = "0.110.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "305d51c180ebdc46ef61bc60c54ae6512db3bc9a05842a1f1e762e45977019ab" +checksum = "4a41b85213deedf877555a7878ca9fb680ccba8183611c4bb8030ed281b2ad83" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-bitset" -version = "0.110.2" +version = "0.110.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3247afacd9b13d620033f3190d9e49d1beefc1acb33d5604a249956c9c13709" +checksum = "690d8ae6c73748e5ce3d8fe59034dceadb8823e6c8994ba324141c5eae909b0e" dependencies = [ "serde", "serde_derive", @@ -923,9 +929,9 @@ dependencies = [ [[package]] name = "cranelift-codegen" -version = "0.110.2" +version = "0.110.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd7ca95e831c18d1356da783765c344207cbdffea91e13e47fa9327dbb2e0719" +checksum = "0ce027a7b16f8b86f60ff6819615273635186d607a0c225ee6ac340d7d18f978" dependencies = [ "bumpalo", "cranelift-bforest", @@ -935,44 +941,44 @@ dependencies = [ "cranelift-control", "cranelift-entity", "cranelift-isle", - "gimli", + "gimli 0.28.1", "hashbrown 0.14.5", "log", "regalloc2", - "rustc-hash", + "rustc-hash 1.1.0", "smallvec", "target-lexicon", ] [[package]] name = "cranelift-codegen-meta" -version = "0.110.2" +version = "0.110.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "450c105fa1e51bfba4e95a86e926504a867ad5639d63f31d43fe3b7ec1f1c9ef" +checksum = "f0a2d2ab65e6cbf91f81781d8da65ec2005510f18300eff21a99526ed6785863" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.110.2" +version = "0.110.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5479117cd1266881479908d383086561cee37e49affbea9b1e6b594cc21cc220" +checksum = "efcff860573cf3db9ae98fbd949240d78b319df686cc306872e7fab60e9c84d7" [[package]] name = "cranelift-control" -version = "0.110.2" +version = "0.110.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34378804f0abfdd22c068a741cfeed86938b92375b2a96fb0b42c878e0141bfb" +checksum = "69d70e5b75c2d5541ef80a99966ccd97aaa54d2a6af19ea31759a28538e1685a" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.110.2" +version = "0.110.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a48cb0a194c9ba82fec35a1e492055388d89b2e3c03dee9dcf2488892be8004d" +checksum = "d21d3089714278920030321829090d9482c91e5ff2339f2f697f8425bffdcba3" dependencies = [ "cranelift-bitset", "serde", @@ -981,9 +987,9 @@ dependencies = [ [[package]] name = "cranelift-frontend" -version = "0.110.2" +version = "0.110.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8327afc6c1c05f4be62fefce5b439fa83521c65363a322e86ea32c85e7ceaf64" +checksum = "7308482930f2a2fad4fe25a06054f6f9a4ee1ab97264308c661b037cb60001a3" dependencies = [ "cranelift-codegen", "log", @@ -993,15 +999,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.110.2" +version = "0.110.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56b08621c00321efcfa3eee6a3179adc009e21ea8d24ca7adc3c326184bc3f48" +checksum = "ab4c59e259dab0e6958dabcc536b30845574f027ba6e5000498cdaf7e7ed2d30" [[package]] name = "cranelift-native" -version = "0.110.2" +version = "0.110.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51180b147c8557c1196c77b098f04140c91962e135ea152cd2fcabf40cf365c" +checksum = "d77ac3dfb61ef3159998105116acdfeaec75e4296c43ee2dcc4ea39838c0080e" dependencies = [ "cranelift-codegen", "libc", @@ -1010,9 +1016,9 @@ dependencies = [ [[package]] name = "cranelift-wasm" -version = "0.110.2" +version = "0.110.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "019e3dccb7f15e0bc14f0ddc034ec608a66df8e05c9e1e16f75a7716f8461799" +checksum = "1d883f1b8d3d1dab4797407117bc8a1824f4a1fe86654aee2ee3205613f77d3e" dependencies = [ "cranelift-codegen", "cranelift-entity", @@ -1035,9 +1041,9 @@ dependencies = [ [[package]] name = "critical-section" -version = "1.1.2" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" [[package]] name = "crossbeam-deque" @@ -1060,9 +1066,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crunchy" @@ -1114,16 +1120,15 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.1.2" +version = "4.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", "digest 0.10.7", "fiat-crypto", - "platforms", "rustc_version", "subtle", "zeroize", @@ -1137,7 +1142,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] @@ -1225,7 +1230,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] @@ -1247,7 +1252,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core 0.20.10", "quote", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] @@ -1288,9 +1293,9 @@ dependencies = [ [[package]] name = "der-parser" -version = "8.2.0" +version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" +checksum = "5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553" dependencies = [ "asn1-rs", "displaydoc", @@ -1323,15 +1328,15 @@ dependencies = [ [[package]] name = "derive_more" -version = "0.99.17" +version = "0.99.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "convert_case", "proc-macro2", "quote", "rustc_version", - "syn 1.0.109", + "syn 2.0.87", ] [[package]] @@ -1390,13 +1395,13 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] @@ -1452,9 +1457,9 @@ dependencies = [ [[package]] name = "either" -version = "1.11.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "elliptic-curve" @@ -1481,6 +1486,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + [[package]] name = "encode_unicode" version = "0.3.6" @@ -1489,23 +1500,23 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.34" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if", ] [[package]] name = "enum-as-inner" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" +checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] @@ -1525,7 +1536,7 @@ checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] @@ -1574,9 +1585,9 @@ checksum = "b90ca2580b73ab6a1f724b76ca11ab632df820fd6040c336200d2c1df7b3c82c" [[package]] name = "event-listener" -version = "4.0.3" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" dependencies = [ "concurrent-queue", "parking", @@ -1585,9 +1596,9 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.4.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" dependencies = [ "event-listener", "pin-project-lite", @@ -1617,9 +1628,9 @@ checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" [[package]] name = "fastrand" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" [[package]] name = "ff" @@ -1667,6 +1678,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -1695,7 +1712,7 @@ dependencies = [ "regex", "serde", "serde_json", - "syn 2.0.63", + "syn 2.0.87", "thiserror", ] @@ -1705,7 +1722,7 @@ version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "122c27ab46707017063bf1c6e0b4f3de881e22e81b4059750a0dc95033d9cc26" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "fuel-types 0.56.0", "serde", "strum 0.24.1", @@ -1717,7 +1734,7 @@ version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f325971bf9047ec70004f80a989e03456316bc19cbef3ff3a39a38b192ab56e" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "fuel-types 0.58.2", "serde", "strum 0.24.1", @@ -1783,7 +1800,7 @@ dependencies = [ "tower", "tower-http 0.4.4", "tracing", - "uuid 1.8.0", + "uuid 1.11.0", ] [[package]] @@ -2189,8 +2206,8 @@ checksum = "3f49fdbfc1615d88d2849650afc2b0ac2fecd69661ebadd31a073d8416747764" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", - "synstructure 0.13.1", + "syn 2.0.87", + "synstructure", ] [[package]] @@ -2201,8 +2218,8 @@ checksum = "ab0bc46a3552964bae5169e79b383761a54bd115ea66951a1a7a229edcefa55a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", - "synstructure 0.13.1", + "syn 2.0.87", + "synstructure", ] [[package]] @@ -2263,7 +2280,7 @@ version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13aae44611588d199dd119e4a0ebd8eb7ae4cde6bf8b4d12715610b1f5e5b731" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "derivative", "derive_more", "fuel-asm 0.56.0", @@ -2285,7 +2302,7 @@ version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6723bb8710ba2b70516ac94d34459593225870c937670fb3afaf82e0354667ac" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "derivative", "derive_more", "fuel-asm 0.58.2", @@ -2333,7 +2350,7 @@ checksum = "64fc4695efac9207276f6229f2dd9811848b328a13604a698f7bce1d452bd986" dependencies = [ "async-trait", "backtrace", - "bitflags 2.5.0", + "bitflags 2.6.0", "derivative", "derive_more", "ethnum", @@ -2365,7 +2382,7 @@ dependencies = [ "anyhow", "async-trait", "backtrace", - "bitflags 2.5.0", + "bitflags 2.6.0", "derivative", "derive_more", "ethnum", @@ -2393,9 +2410,9 @@ dependencies = [ [[package]] name = "fuels" -version = "0.66.9" +version = "0.66.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed08053e72bdb285d5a167c27a7a0d10f1dc4e27d1e6e5296dd2a67813bd13f" +checksum = "25bf359dceffcbab4163bca473a03658b912686c3aa81a223f828260729dd474" dependencies = [ "fuel-core-client", "fuel-crypto 0.58.2", @@ -2409,9 +2426,9 @@ dependencies = [ [[package]] name = "fuels-accounts" -version = "0.66.9" +version = "0.66.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49fee90e8f3a4fc9392a6cde3010c561fa50da0f805d66fdb659eaa4d5d8a504" +checksum = "4b0b09d6ce3a12196f6944c74bdd795c39950d32ebaaf56b2943741a5e4308a1" dependencies = [ "async-trait", "chrono", @@ -2435,9 +2452,9 @@ dependencies = [ [[package]] name = "fuels-code-gen" -version = "0.66.9" +version = "0.66.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f857b7ff658400506ca6be57bb84fedda44b566e78f5f0a8d0782242f41615c0" +checksum = "78bf5f7b37ec598514fb3767abdae5372a9fa0919d350703f5d627ec2eb33456" dependencies = [ "Inflector", "fuel-abi-types", @@ -2446,14 +2463,14 @@ dependencies = [ "quote", "regex", "serde_json", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] name = "fuels-core" -version = "0.66.9" +version = "0.66.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baccbdd81e624f57950dcb136b32b853c520dd954badf26b9f58de33f3d71c7e" +checksum = "ab66cdf52fa6ef98dbc9cc7b4ce19c6a340b2a4710c5d5f87eae39ffb868bad7" dependencies = [ "async-trait", "bech32", @@ -2480,22 +2497,22 @@ dependencies = [ [[package]] name = "fuels-macros" -version = "0.66.9" +version = "0.66.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da75294c5e9da312bdc49239736699ee84ea9c5bfbc19a61a8ee588a1247aa1" +checksum = "1471d221453d13d4643c9a698212781f0e8ac40f515a8566538db87409e30752" dependencies = [ "fuels-code-gen", "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] name = "fuels-programs" -version = "0.66.9" +version = "0.66.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32675ed1c08edd28ddb648dfae0c60a1946d4368a69ddfa6434f2316e33f0520" +checksum = "7a854561a68ef4088972119cf31023d2d1afd58584da203bcb7dfbd1e84dd8fc" dependencies = [ "async-trait", "fuel-abi-types", @@ -2512,9 +2529,9 @@ dependencies = [ [[package]] name = "fuels-test-helpers" -version = "0.66.9" +version = "0.66.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02176c0fb1bf8cf58b8a9e5372efb650324740abcd4847b45bd0b041a0f133a2" +checksum = "5a7b428c35a54e4d667343b4051f07a7397e6039bd110411c37647db4478086e" dependencies = [ "fuel-core", "fuel-core-chain-config", @@ -2543,9 +2560,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -2558,9 +2575,9 @@ dependencies = [ [[package]] name = "futures-bounded" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e2774cc104e198ef3d3e1ff4ab40f86fa3245d6cb6a3a46174f21463cee173" +checksum = "91f328e7fb845fc832912fb6a34f40cf6d1888c92f974d1893a54e97b5ff542e" dependencies = [ "futures-timer", "futures-util", @@ -2568,9 +2585,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -2578,15 +2595,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -2596,15 +2613,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-lite" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +checksum = "cef40d21ae2c515b51041df9ed313ed21e572df340ea58a922a0aefe7e8891a1" dependencies = [ "futures-core", "pin-project-lite", @@ -2612,36 +2629,37 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] name = "futures-rustls" -version = "0.24.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35bd3cf68c183738046838e300353e4716c674dc5e56890de4826801a6622a28" +checksum = "a8f2f12607f92c69b12ed746fabf9ca4f5c482cba46679c1a75b874ed7c26adb" dependencies = [ "futures-io", - "rustls", + "rustls 0.23.16", + "rustls-pki-types", ] [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-ticker" @@ -2662,9 +2680,9 @@ checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -2717,10 +2735,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" dependencies = [ "fallible-iterator", - "indexmap 2.2.6", + "indexmap 2.6.0", "stable_deref_trait", ] +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + [[package]] name = "graphql-parser" version = "0.4.0" @@ -2754,7 +2778,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.2.6", + "indexmap 2.6.0", "slab", "tokio", "tokio-util", @@ -2796,6 +2820,17 @@ dependencies = [ "serde", ] +[[package]] +name = "hashbrown" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + [[package]] name = "heapless" version = "0.7.17" @@ -2828,6 +2863,12 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + [[package]] name = "hex" version = "0.4.3" @@ -2989,9 +3030,9 @@ checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" [[package]] name = "httpdate" @@ -3001,9 +3042,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.28" +version = "0.14.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" dependencies = [ "bytes", "futures-channel", @@ -3033,7 +3074,7 @@ dependencies = [ "http 0.2.12", "hyper", "log", - "rustls", + "rustls 0.21.12", "rustls-native-certs", "tokio", "tokio-rustls", @@ -3054,9 +3095,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -3075,6 +3116,124 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "id-arena" version = "2.2.1" @@ -3109,12 +3268,23 @@ dependencies = [ [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", ] [[package]] @@ -3167,26 +3337,26 @@ dependencies = [ [[package]] name = "impl-tools" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82c305b1081f1a99fda262883c788e50ab57d36c00830bdd7e0a82894ad965c" +checksum = "8a84bc8d2baf8da56e93b4247067d918e1a44829bbbe3e4b875aaf8d7d3c7bc9" dependencies = [ "autocfg", "impl-tools-lib", - "proc-macro-error", - "syn 2.0.63", + "proc-macro-error2", + "syn 2.0.87", ] [[package]] name = "impl-tools-lib" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85d3946d886eaab0702fa0c6585adcced581513223fa9df7ccfabbd9fa331a88" +checksum = "a795a1e201125947a063b967c79de6ae152143ab522f481d4f493c44835ba37a" dependencies = [ - "proc-macro-error", + "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] @@ -3202,12 +3372,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.1", "serde", ] @@ -3235,9 +3405,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", ] @@ -3262,15 +3432,15 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.9.0" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" [[package]] name = "is_terminal_polyfill" -version = "1.70.0" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" @@ -3307,18 +3477,18 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" dependencies = [ "wasm-bindgen", ] [[package]] name = "k256" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ "cfg-if", "ecdsa", @@ -3339,9 +3509,9 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "leb128" @@ -3351,15 +3521,15 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.154" +version = "0.2.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" +checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" [[package]] name = "libm" -version = "0.2.8" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] name = "libp2p" @@ -3423,15 +3593,14 @@ dependencies = [ [[package]] name = "libp2p-core" -version = "0.41.2" +version = "0.41.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8130a8269e65a2554d55131c770bdf4bcd94d2b8d4efb24ca23699be65066c05" +checksum = "a5a8920cbd8540059a01950c1e5c96ea8d89eb50c51cd366fc18bdf540a6e48f" dependencies = [ "either", "fnv", "futures", "futures-timer", - "instant", "libp2p-identity", "multiaddr", "multihash", @@ -3447,6 +3616,7 @@ dependencies = [ "tracing", "unsigned-varint 0.8.0", "void", + "web-time", ] [[package]] @@ -3521,9 +3691,9 @@ dependencies = [ [[package]] name = "libp2p-identity" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "999ec70441b2fb35355076726a6bc466c932e9bdc66f6a11c6c0aa17c7ab9be0" +checksum = "55cca1eb2bc1fd29f099f3daaab7effd01e1a54b7c577d0ed082521034d912e8" dependencies = [ "asn1_der", "bs58", @@ -3654,9 +3824,9 @@ dependencies = [ [[package]] name = "libp2p-quic" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0375cdfee57b47b313ef1f0fdb625b78aed770d33a40cf1c294a371ff5e6666" +checksum = "c67296ad4e092e23f92aea3d2bdb6f24eab79c0929ed816dfb460ea2f4567d2b" dependencies = [ "bytes", "futures", @@ -3668,8 +3838,8 @@ dependencies = [ "parking_lot", "quinn", "rand", - "ring 0.16.20", - "rustls", + "ring 0.17.8", + "rustls 0.23.16", "socket2", "thiserror", "tokio", @@ -3678,9 +3848,9 @@ dependencies = [ [[package]] name = "libp2p-request-response" -version = "0.26.2" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6946e5456240b3173187cc37a17cb40c3cd1f7138c76e2c773e0d792a42a8de1" +checksum = "c314fe28368da5e3a262553fb0ad575c1c8934c461e10de10265551478163836" dependencies = [ "async-trait", "futures", @@ -3729,7 +3899,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] @@ -3751,18 +3921,18 @@ dependencies = [ [[package]] name = "libp2p-tls" -version = "0.3.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ce7e3c2e7569d685d08ec795157981722ff96e9e9f9eae75df3c29d02b07a5" +checksum = "72b7b831e55ce2aa6c354e6861a85fdd4dd0a2b97d5e276fabac0e4810a71776" dependencies = [ "futures", "futures-rustls", "libp2p-core", "libp2p-identity", "rcgen", - "ring 0.16.20", - "rustls", - "rustls-webpki", + "ring 0.17.8", + "rustls 0.23.16", + "rustls-webpki 0.101.7", "thiserror", "x509-parser", "yasna", @@ -3786,9 +3956,9 @@ dependencies = [ [[package]] name = "libp2p-websocket" -version = "0.43.0" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4846d51afd08180e164291c3754ba30dd4fbac6fac65571be56403c16431a5e" +checksum = "85b953b6803a1f3161a989538974d72511c4e48a4af355337b6fb90723c56c05" dependencies = [ "either", "futures", @@ -3799,6 +3969,7 @@ dependencies = [ "pin-project-lite", "rw-stream-sink", "soketto", + "thiserror", "tracing", "url", "webpki-roots", @@ -3806,9 +3977,9 @@ dependencies = [ [[package]] name = "libp2p-yamux" -version = "0.45.1" +version = "0.45.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200cbe50349a44760927d50b431d77bed79b9c0a3959de1af8d24a63434b71e5" +checksum = "ddd5265f6b80f94d48a3963541aad183cc598a645755d2f1805a373e41e0716b" dependencies = [ "either", "futures", @@ -3816,7 +3987,7 @@ dependencies = [ "thiserror", "tracing", "yamux 0.12.1", - "yamux 0.13.2", + "yamux 0.13.3", ] [[package]] @@ -3825,7 +3996,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "libc", ] @@ -3885,9 +4056,15 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "litemap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" [[package]] name = "lock_api" @@ -3901,17 +4078,17 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "lru" -version = "0.12.3" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.14.5", + "hashbrown 0.15.1", ] [[package]] @@ -3946,9 +4123,9 @@ checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb" [[package]] name = "memchr" -version = "2.7.2" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memfd" @@ -3973,22 +4150,23 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", ] [[package]] name = "mio" -version = "0.8.11" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ + "hermit-abi 0.3.9", "libc", "wasi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -4037,9 +4215,9 @@ dependencies = [ [[package]] name = "multiaddr" -version = "0.18.1" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b852bc02a2da5feed68cd14fa50d0774b92790a5bdbfa932a813926c8472070" +checksum = "fe6351f60b488e04c1d21bc69e56b89cb3f5e8f5d22557d6e8031bdfd79b6961" dependencies = [ "arrayref", "byteorder", @@ -4050,7 +4228,7 @@ dependencies = [ "percent-encoding", "serde", "static_assertions", - "unsigned-varint 0.7.2", + "unsigned-varint 0.8.0", "url", ] @@ -4067,12 +4245,12 @@ dependencies = [ [[package]] name = "multihash" -version = "0.19.1" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076d548d76a0e2a0d4ab471d0b1c36c577786dfc4471242035d97a12a735c492" +checksum = "cc41f430805af9d1cf4adae4ed2149c759b877b01d909a1f40256188d09345d2" dependencies = [ "core2", - "unsigned-varint 0.7.2", + "unsigned-varint 0.8.0", ] [[package]] @@ -4190,9 +4368,9 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "num-bigint" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", @@ -4239,29 +4417,29 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", ] [[package]] name = "num_enum" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" dependencies = [ "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] @@ -4272,39 +4450,30 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "object" -version = "0.32.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" -dependencies = [ - "memchr", -] - -[[package]] -name = "object" -version = "0.36.4" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "crc32fast", - "hashbrown 0.14.5", - "indexmap 2.2.6", + "hashbrown 0.15.1", + "indexmap 2.6.0", "memchr", ] [[package]] name = "oid-registry" -version = "0.6.1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" +checksum = "a8d8034d9489cdaf79228eb9f6a3b8d7bb32ba00d6645ebd48eef4077ceb5bd9" dependencies = [ "asn1-rs", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "opaque-debug" @@ -4332,15 +4501,15 @@ dependencies = [ [[package]] name = "parking" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -4356,7 +4525,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -4402,9 +4571,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.13" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9" +checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" dependencies = [ "memchr", "thiserror", @@ -4418,34 +4587,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.2.6", + "indexmap 2.6.0", ] [[package]] name = "pin-project" -version = "1.1.5" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.5" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -4465,29 +4634,23 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" - -[[package]] -name = "platforms" -version = "3.4.0" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "polling" -version = "3.7.0" +version = "3.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645493cf344456ef24219d02a768cf1fb92ddf8c92161679ae3d91b91a637be3" +checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" dependencies = [ "cfg-if", "concurrent-queue", - "hermit-abi", + "hermit-abi 0.4.0", "pin-project-lite", "rustix", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4515,9 +4678,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.6.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" +checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" [[package]] name = "portpicker" @@ -4530,12 +4693,13 @@ dependencies = [ [[package]] name = "postcard" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55c51ee6c0db07e68448e336cf8ea4131a620edefebf9893e759b2d793420f8" +checksum = "5f7f0a8d620d71c457dd1d47df76bb18960378da56af4527aaa10f515eee732e" dependencies = [ "cobs", - "embedded-io", + "embedded-io 0.4.0", + "embedded-io 0.6.1", "heapless", "serde", ] @@ -4548,9 +4712,12 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "predicates" @@ -4568,15 +4735,15 @@ dependencies = [ [[package]] name = "predicates-core" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174" +checksum = "ae8177bee8e75d6846599c6b9ff679ed51e882816914eec639944d7c9aa11931" [[package]] name = "predicates-tree" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf" +checksum = "41b740d195ed3166cd147c8047ec98db0e22ec019eb8eeb76d343b795304fb13" dependencies = [ "predicates-core", "termtree", @@ -4584,9 +4751,9 @@ dependencies = [ [[package]] name = "pretty_assertions" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" dependencies = [ "diff", "yansi", @@ -4613,50 +4780,48 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ - "toml_edit 0.21.1", + "toml_edit", ] [[package]] -name = "proc-macro-error" -version = "1.0.4" +name = "proc-macro-error-attr2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" dependencies = [ - "proc-macro-error-attr", "proc-macro2", "quote", - "version_check", ] [[package]] -name = "proc-macro-error-attr" -version = "1.0.4" +name = "proc-macro-error2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" dependencies = [ + "proc-macro-error-attr2", "proc-macro2", "quote", - "version_check", ] [[package]] name = "proc-macro2" -version = "1.0.82" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ "unicode-ident", ] [[package]] name = "prometheus-client" -version = "0.22.2" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ca959da22a332509f2a73ae9e5f23f9dcfc31fd3a54d71f159495bd5909baa" +checksum = "504ee9ff529add891127c4827eb481bd69dc0ebc72e9a682e187db4caa60c3ca" dependencies = [ "dtoa", "itoa", @@ -4672,7 +4837,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] @@ -4730,17 +4895,18 @@ dependencies = [ [[package]] name = "quinn" -version = "0.10.2" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cc2c5017e4b43d5995dcea317bc46c1e09404c0a9664d2908f7f02dfe943d75" +checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684" dependencies = [ "bytes", "futures-io", "pin-project-lite", "quinn-proto", "quinn-udp", - "rustc-hash", - "rustls", + "rustc-hash 2.0.0", + "rustls 0.23.16", + "socket2", "thiserror", "tokio", "tracing", @@ -4748,15 +4914,15 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.10.6" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "141bf7dfde2fbc246bfd3fe12f2455aa24b0fbd9af535d8c86c7bd1381ff2b1a" +checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" dependencies = [ "bytes", "rand", - "ring 0.16.20", - "rustc-hash", - "rustls", + "ring 0.17.8", + "rustc-hash 2.0.0", + "rustls 0.23.16", "slab", "thiserror", "tinyvec", @@ -4765,22 +4931,23 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.4.1" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7" +checksum = "7d5a626c6807713b15cac82a6acaccd6043c9a5408c24baae07611fec3f243da" dependencies = [ - "bytes", + "cfg_aliases", "libc", + "once_cell", "socket2", "tracing", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -4855,11 +5022,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.1" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", ] [[package]] @@ -4881,16 +5048,16 @@ checksum = "ad156d539c879b7a24a363a2016d77961786e71f48f2e2fc8302a92abd2429a6" dependencies = [ "hashbrown 0.13.2", "log", - "rustc-hash", + "rustc-hash 1.1.0", "slice-group-by", "smallvec", ] [[package]] name = "regex" -version = "1.10.4" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -4900,9 +5067,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -4911,9 +5078,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" @@ -4940,7 +5107,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls", + "rustls 0.21.12", "rustls-pemfile", "serde", "serde_json", @@ -5044,11 +5211,17 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc-hash" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" + [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] @@ -5064,11 +5237,11 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -5083,10 +5256,24 @@ checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", "ring 0.17.8", - "rustls-webpki", + "rustls-webpki 0.101.7", "sct", ] +[[package]] +name = "rustls" +version = "0.23.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee87ff5d9b36712a58574e12e9f0ea80f915a5b0ac518d322b24a465617925e" +dependencies = [ + "once_cell", + "ring 0.17.8", + "rustls-pki-types", + "rustls-webpki 0.102.8", + "subtle", + "zeroize", +] + [[package]] name = "rustls-native-certs" version = "0.6.3" @@ -5108,6 +5295,12 @@ dependencies = [ "base64 0.21.7", ] +[[package]] +name = "rustls-pki-types" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" + [[package]] name = "rustls-webpki" version = "0.101.7" @@ -5118,11 +5311,22 @@ dependencies = [ "untrusted 0.9.0", ] +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring 0.17.8", + "rustls-pki-types", + "untrusted 0.9.0", +] + [[package]] name = "rustversion" -version = "1.0.16" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092474d1a01ea8278f69e6a358998405fae5b8b963ddaeb2b0b04a128bf1dfb0" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] name = "rw-stream-sink" @@ -5152,11 +5356,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -5257,11 +5461,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "core-foundation", "core-foundation-sys", "libc", @@ -5270,9 +5474,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.11.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" +checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2" dependencies = [ "core-foundation-sys", "libc", @@ -5286,40 +5490,41 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.201" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.201" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] [[package]] name = "serde_spanned" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] @@ -5338,15 +5543,15 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.8.1" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20" +checksum = "8e28bdad6db2b8340e449f7108f020b3b092e8583a9e3fb82713e1d4e71fe817" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.2.6", + "indexmap 2.6.0", "serde", "serde_derive", "serde_json", @@ -5356,27 +5561,25 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.8.1" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2" +checksum = "9d846214a9854ef724f3da161b426242d8de7c1fc7de2f89bb1efcb154dca79d" dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] -name = "sha-1" -version = "0.9.8" +name = "sha1" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ - "block-buffer 0.9.0", "cfg-if", "cpufeatures", - "digest 0.9.0", - "opaque-debug", + "digest 0.10.7", ] [[package]] @@ -5413,6 +5616,12 @@ dependencies = [ "keccak", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook-registry" version = "1.4.2" @@ -5485,17 +5694,17 @@ dependencies = [ [[package]] name = "soketto" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" +checksum = "37468c595637c10857701c990f93a40ce0e357cedb0953d1c26c8d8027f9bb53" dependencies = [ - "base64 0.13.1", + "base64 0.22.1", "bytes", "futures", "httparse", "log", "rand", - "sha-1", + "sha1", ] [[package]] @@ -5609,7 +5818,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] @@ -5622,14 +5831,14 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" @@ -5644,9 +5853,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.63" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -5659,18 +5868,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" -[[package]] -name = "synstructure" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "unicode-xid", -] - [[package]] name = "synstructure" version = "0.13.1" @@ -5679,7 +5876,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] @@ -5705,9 +5902,9 @@ dependencies = [ [[package]] name = "tai64" -version = "4.0.0" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed7401421025f4132e6c1f7af5e7f8287383969f36e6628016cd509b8d3da9dc" +checksum = "014639506e4f425c78e823eabf56e71c093f940ae55b43e58f682e7bc2f5887a" dependencies = [ "serde", ] @@ -5726,14 +5923,15 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tempfile" -version = "3.10.1" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", "fastrand", + "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -5772,22 +5970,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.60" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.60" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] @@ -5821,11 +6019,21 @@ dependencies = [ "time-core", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -5838,21 +6046,20 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.37.0" +version = "1.41.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -5867,13 +6074,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] @@ -5892,15 +6099,15 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls", + "rustls 0.21.12", "tokio", ] [[package]] name = "tokio-stream" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" dependencies = [ "futures-core", "pin-project-lite", @@ -5910,9 +6117,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes", "futures-core", @@ -5923,47 +6130,36 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.12" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.12", + "toml_edit", ] [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.21.1" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap 2.2.6", - "toml_datetime", - "winnow 0.5.40", -] - -[[package]] -name = "toml_edit" -version = "0.22.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef" -dependencies = [ - "indexmap 2.2.6", + "indexmap 2.6.0", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.18", + "winnow", ] [[package]] @@ -6008,7 +6204,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "bytes", "futures-core", "futures-util", @@ -6024,15 +6220,15 @@ dependencies = [ [[package]] name = "tower-layer" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" @@ -6054,7 +6250,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] @@ -6092,9 +6288,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "ucd-trie" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" [[package]] name = "uint" @@ -6110,36 +6306,36 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.15" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] [[package]] name = "unicode-width" -version = "0.1.12" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-xid" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "universal-hash" @@ -6190,20 +6386,32 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.0" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" dependencies = [ "form_urlencoded", - "idna 0.5.0", + "idna 1.0.3", "percent-encoding", ] +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" @@ -6217,18 +6425,18 @@ dependencies = [ [[package]] name = "uuid" -version = "1.8.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" dependencies = [ "getrandom", ] [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "void" @@ -6253,34 +6461,35 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.42" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" dependencies = [ "cfg-if", "js-sys", @@ -6290,9 +6499,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6300,22 +6509,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] name = "wasm-encoder" @@ -6333,9 +6542,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d28bc49ba1e5c5b61ffa7a2eace10820443c4b7d1c0b144109261d14570fdf8" dependencies = [ "ahash", - "bitflags 2.5.0", + "bitflags 2.6.0", "hashbrown 0.14.5", - "indexmap 2.2.6", + "indexmap 2.6.0", "semver", "serde", ] @@ -6353,23 +6562,23 @@ dependencies = [ [[package]] name = "wasmtime" -version = "23.0.2" +version = "23.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07232e0b473af36112da7348f51e73fa8b11047a6cb546096da3812930b7c93a" +checksum = "fe501caefeb9f7b15360bdd7e47ad96e20223846f1c7db485ae5820ba5acc3d2" dependencies = [ "anyhow", - "bitflags 2.5.0", + "bitflags 2.6.0", "bumpalo", "cc", "cfg-if", "hashbrown 0.14.5", - "indexmap 2.2.6", + "indexmap 2.6.0", "libc", "libm", "log", "mach2", "memfd", - "object 0.36.4", + "object", "once_cell", "paste", "postcard", @@ -6395,18 +6604,18 @@ dependencies = [ [[package]] name = "wasmtime-asm-macros" -version = "23.0.2" +version = "23.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a9c42562d879c749288d9a26acc0d95d2ca069e30c2ec2efce84461c4d62b3" +checksum = "c904a057d74bfa0ad9369a3fd99231d81ba0345f059d03c9148c3bb2abbf310f" dependencies = [ "cfg-if", ] [[package]] name = "wasmtime-cache" -version = "23.0.2" +version = "23.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d5d5aac98c8ae87cf5244495da7722e3fa022aa6f3f4fcd5e3d6e5699ce422" +checksum = "8dff4d467d6b5bd0d137f5426f45178222e40b59e49ab3a7361420262b9f00df" dependencies = [ "anyhow", "base64 0.21.7", @@ -6424,14 +6633,14 @@ dependencies = [ [[package]] name = "wasmtime-component-macro" -version = "23.0.2" +version = "23.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0c3f57c4bc96f9b4a6ff4d6cb6e837913eff32e98d09e2b6d79b5c4647b415b" +checksum = "3a96185dab1c14ffb986ff2b3a2185d15acf2b801ca7895aa35ee80328e2ce38" dependencies = [ "anyhow", "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", "wasmtime-component-util", "wasmtime-wit-bindgen", "wit-parser", @@ -6439,15 +6648,15 @@ dependencies = [ [[package]] name = "wasmtime-component-util" -version = "23.0.2" +version = "23.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1da707969bc31a565da9b32d087eb2370c95c6f2087c5539a15f2e3b27e77203" +checksum = "71a40200d42a8985edadb4007a0ed320756cbe28065b83e0027e39524c1b1b22" [[package]] name = "wasmtime-cranelift" -version = "23.0.2" +version = "23.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62cb6135ec46994299be711b78b03acaa9480de3715f827d450f0c947a84977c" +checksum = "b099ef9b7808fa8d18cad32243e78e9c07a4a8aacfa913d88dc08704b1643c49" dependencies = [ "anyhow", "cfg-if", @@ -6457,9 +6666,9 @@ dependencies = [ "cranelift-frontend", "cranelift-native", "cranelift-wasm", - "gimli", + "gimli 0.28.1", "log", - "object 0.36.4", + "object", "target-lexicon", "thiserror", "wasmparser", @@ -6469,17 +6678,17 @@ dependencies = [ [[package]] name = "wasmtime-environ" -version = "23.0.2" +version = "23.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bcaa3b42a0718e9123da7fb75e8e13fc95df7db2a7e32e2f2f4f0d3333b7d6f" +checksum = "e2f1765f6ca1a166927bee13ad4aed7bf18269f34c0cd7d6d523889a0b52e6ee" dependencies = [ "anyhow", "cranelift-bitset", "cranelift-entity", - "gimli", - "indexmap 2.2.6", + "gimli 0.28.1", + "indexmap 2.6.0", "log", - "object 0.36.4", + "object", "postcard", "serde", "serde_derive", @@ -6492,9 +6701,9 @@ dependencies = [ [[package]] name = "wasmtime-jit-icache-coherence" -version = "23.0.2" +version = "23.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cfee42dac5148fc2664ab1f5cb8d7fa77a28d1a2cf1d9483abc2c3d751a58b9" +checksum = "1e1a826e4ccd0803b2f7463289cad104f40d09d06bc8acf1a614230a47b4d96f" dependencies = [ "anyhow", "cfg-if", @@ -6504,15 +6713,15 @@ dependencies = [ [[package]] name = "wasmtime-slab" -version = "23.0.2" +version = "23.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42eb8f6515708ec67974998c3e644101db4186308985f5ef7c2ef324ff33c948" +checksum = "f92a137c17c992eb5eaacfa0f0590353471e49dbb4bdbdf9cf7536d66109e63a" [[package]] name = "wasmtime-types" -version = "23.0.2" +version = "23.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046873fb8fb3e9652f3fd76fe99c8c8129007695c3d73b2e307fdae40f6e324c" +checksum = "a6072ac3267866d99ca726b6a4f157df9b733aac8082e902d527368f07c303ba" dependencies = [ "anyhow", "cranelift-entity", @@ -6524,32 +6733,42 @@ dependencies = [ [[package]] name = "wasmtime-versioned-export-macros" -version = "23.0.2" +version = "23.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99c02af2e9dbeb427304d1a08787d70ed0dbfec1af2236616f84c9f1f03e7969" +checksum = "a2bde986038b819bc43a21fef0610aeb47aabfe3ea09ca3533a7b81023b84ec6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", ] [[package]] name = "wasmtime-wit-bindgen" -version = "23.0.2" +version = "23.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75f528f8b8a2376a3dacaf497d960216dd466d324425361e1e00e26de0a7705c" +checksum = "8f88e49a9b81746ec0cede5505e40a4012c92cb5054cd7ef4300dc57c36f26b1" dependencies = [ "anyhow", "heck 0.4.1", - "indexmap 2.2.6", + "indexmap 2.6.0", "wit-parser", ] [[package]] name = "web-sys" -version = "0.3.69" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", "wasm-bindgen", @@ -6563,9 +6782,9 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "which" -version = "6.0.1" +version = "6.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8211e4f58a2b2805adfbefbc07bab82958fc91e3836339b1ab7ae32465dce0d7" +checksum = "b4ee928febd44d98f2f459a4a79bd4d928591333a494a10a868418ac1b39cf1f" dependencies = [ "either", "home", @@ -6601,7 +6820,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -6635,7 +6854,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -6653,7 +6872,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -6673,18 +6901,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -6695,9 +6923,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -6707,9 +6935,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -6719,15 +6947,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -6737,9 +6965,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -6749,9 +6977,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -6761,9 +6989,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -6773,24 +7001,15 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" - -[[package]] -name = "winnow" -version = "0.5.40" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] @@ -6819,7 +7038,7 @@ checksum = "ceeb0424aa8679f3fcf2d6e3cfa381f3d6fa6179976a2c05a6249dd2bb426716" dependencies = [ "anyhow", "id-arena", - "indexmap 2.2.6", + "indexmap 2.6.0", "log", "semver", "serde", @@ -6829,6 +7048,18 @@ dependencies = [ "wasmparser", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "wyz" version = "0.5.1" @@ -6852,9 +7083,9 @@ dependencies = [ [[package]] name = "x509-parser" -version = "0.15.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7069fba5b66b9193bd2c5d3d4ff12b839118f6bcbef5328efafafb5395cf63da" +checksum = "fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69" dependencies = [ "asn1-rs", "data-encoding", @@ -6869,9 +7100,9 @@ dependencies = [ [[package]] name = "xml-rs" -version = "0.8.20" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193" +checksum = "af310deaae937e48a26602b730250b4949e125f468f11e6990be3e5304ddd96f" [[package]] name = "xmltree" @@ -6899,25 +7130,25 @@ dependencies = [ [[package]] name = "yamux" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f97202f6b125031b95d83e01dc57292b529384f80bfae4677e4bbc10178cf72" +checksum = "a31b5e376a8b012bee9c423acdbb835fc34d45001cfa3106236a624e4b738028" dependencies = [ "futures", - "instant", "log", "nohash-hasher", "parking_lot", "pin-project", "rand", "static_assertions", + "web-time", ] [[package]] name = "yansi" -version = "0.5.1" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "yasna" @@ -6928,31 +7159,77 @@ dependencies = [ "time", ] +[[package]] +name = "yoke" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", + "synstructure", +] + [[package]] name = "zerocopy" -version = "0.7.34" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.34" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "zerofrom" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", + "synstructure", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ "zeroize_derive", ] @@ -6965,7 +7242,29 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.87", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", ] [[package]] diff --git a/test/src/sdk-harness/Cargo.toml b/test/src/sdk-harness/Cargo.toml index 3d28c7b1506..7a2a74da1f1 100644 --- a/test/src/sdk-harness/Cargo.toml +++ b/test/src/sdk-harness/Cargo.toml @@ -18,7 +18,7 @@ fuel-core-client = { version = "0.40.0", default-features = false } fuel-vm = { version = "0.58", features = ["random"] } # Dependencies from the `fuels-rs` repository: -fuels = { version = "0.66.9", features = ["fuel-core-lib"] } +fuels = { version = "0.66.10", features = ["fuel-core-lib"] } hex = "0.4" paste = "1.0" From ae9f17200502dd8552b27ba55de3929e3a6a20ff Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite Date: Tue, 12 Nov 2024 07:48:14 -0300 Subject: [PATCH 106/115] Send method arguments with numerics to the second pass (#6700) ## Description This PR brings back encode/decode buffer ownership tests and closes https://github.com/FuelLabs/sway/issues/6567. The original issue was that an error in the CI file was hiding that these tests were not compiling anymore. IR generation now also tests the expression and the variant type match, giving a better error than before. ## Checklist - [x] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. --- sway-core/src/ir_generation/function.rs | 17 ++++++- .../typed_expression/method_application.rs | 12 ++++- sway-lib-std/src/bytes.sw | 47 +++++++++---------- sway-lib-std/src/vec.sw | 47 +++++++++---------- 4 files changed, 73 insertions(+), 50 deletions(-) diff --git a/sway-core/src/ir_generation/function.rs b/sway-core/src/ir_generation/function.rs index c97ad7a94ff..54fd1d31f75 100644 --- a/sway-core/src/ir_generation/function.rs +++ b/sway-core/src/ir_generation/function.rs @@ -3975,8 +3975,9 @@ impl<'eng> FnCompiler<'eng> { if field_tys.len() != 1 && contents.is_some() { // Insert the value too. // Only store if the value does not diverge. + let contents_expr = contents.unwrap(); let contents_value = return_on_termination_or_extract!( - self.compile_expression_to_value(context, md_mgr, contents.unwrap())? + self.compile_expression_to_value(context, md_mgr, contents_expr)? ); let contents_type = contents_value.get_type(context).ok_or_else(|| { CompileError::Internal( @@ -3984,6 +3985,20 @@ impl<'eng> FnCompiler<'eng> { enum_decl.span.clone(), ) })?; + + let variant_type = field_tys[1].get_field_type(context, tag as u64).unwrap(); + if contents_type != variant_type { + return Err(CompileError::Internal( + format!( + "Expression type \"{}\" and Variant type \"{}\" do not match", + contents_type.as_string(context), + variant_type.as_string(context) + ) + .leak(), + contents_expr.span.clone(), + )); + } + let gep_val = self .current_block .append(context) diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs index d7d724caea1..6a836f56f3c 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs @@ -52,7 +52,17 @@ pub(crate) fn type_check_method_application( let arg_handler = Handler::default(); let arg_opt = ty::TyExpression::type_check(&arg_handler, ctx, arg).ok(); - let needs_second_pass = arg_handler.has_errors(); + let has_errors = arg_handler.has_errors(); + let has_numerics = arg_opt + .as_ref() + .map(|x| { + x.return_type + .extract_inner_types(engines, IncludeSelf::Yes) + .iter() + .any(|x| matches!(&*engines.te().get(*x), TypeInfo::Numeric)) + }) + .unwrap_or_default(); + let needs_second_pass = has_errors || has_numerics; if index == 0 { // We want to emit errors in the self parameter and ignore TraitConstraintNotSatisfied with Placeholder diff --git a/sway-lib-std/src/bytes.sw b/sway-lib-std/src/bytes.sw index 1296e940826..b1fd11327ad 100644 --- a/sway-lib-std/src/bytes.sw +++ b/sway-lib-std/src/bytes.sw @@ -927,27 +927,26 @@ impl AbiDecode for Bytes { } } -// TODO: Uncomment when fixed. https://github.com/FuelLabs/sway/issues/6567 -// #[test] -// fn ok_bytes_buffer_ownership() { -// let mut original_array = [1u8, 2u8, 3u8, 4u8]; -// let slice = raw_slice::from_parts::(__addr_of(original_array), 4); - -// // Check Bytes duplicates the original slice -// let mut bytes = Bytes::from(slice); -// bytes.set(0, 5); -// assert(original_array[0] == 1); - -// // At this point, slice equals [5, 2, 3, 4] -// let encoded_slice = encode(bytes); - -// // `Bytes` should duplicate the underlying buffer, -// // so when we write to it, it should not change -// // `encoded_slice` -// let mut bytes = abi_decode::(encoded_slice); -// bytes.set(0, 6); -// assert(bytes.get(0) == Some(6)); - -// let mut bytes = abi_decode::(encoded_slice); -// assert(bytes.get(0) == Some(5)); -// } +#[test] +fn ok_bytes_buffer_ownership() { + let mut original_array = [1u8, 2u8, 3u8, 4u8]; + let slice = raw_slice::from_parts::(__addr_of(original_array), 4); + + // Check Bytes duplicates the original slice + let mut bytes = Bytes::from(slice); + bytes.set(0, 5); + assert(original_array[0] == 1); + + // At this point, slice equals [5, 2, 3, 4] + let encoded_slice = encode(bytes); + + // `Bytes` should duplicate the underlying buffer, + // so when we write to it, it should not change + // `encoded_slice` + let mut bytes = abi_decode::(encoded_slice); + bytes.set(0, 6); + assert(bytes.get(0) == Some(6)); + + let mut bytes = abi_decode::(encoded_slice); + assert(bytes.get(0) == Some(5)); +} diff --git a/sway-lib-std/src/vec.sw b/sway-lib-std/src/vec.sw index 8ae7fe65da7..5b7830b848c 100644 --- a/sway-lib-std/src/vec.sw +++ b/sway-lib-std/src/vec.sw @@ -705,27 +705,26 @@ impl Iterator for VecIter { } } -// TODO: Uncomment when fixed. https://github.com/FuelLabs/sway/issues/6567 -// #[test] -// fn ok_vec_buffer_ownership() { -// let mut original_array = [1u8, 2u8, 3u8, 4u8]; -// let slice = raw_slice::from_parts::(__addr_of(original_array), 4); - -// // Check Vec duplicates the original slice -// let mut bytes = Vec::::from(slice); -// bytes.set(0, 5); -// assert(original_array[0] == 1); - -// // At this point, slice equals [5, 2, 3, 4] -// let encoded_slice = encode(bytes); - -// // `Vec` should duplicate the underlying buffer, -// // so when we write to it, it should not change -// // `encoded_slice` -// let mut bytes = abi_decode::>(encoded_slice); -// bytes.set(0, 6); -// assert(bytes.get(0) == Some(6)); - -// let mut bytes = abi_decode::>(encoded_slice); -// assert(bytes.get(0) == Some(5)); -// } +#[test] +fn ok_vec_buffer_ownership() { + let mut original_array = [1u8, 2u8, 3u8, 4u8]; + let slice = raw_slice::from_parts::(__addr_of(original_array), 4); + + // Check Vec duplicates the original slice + let mut bytes = Vec::::from(slice); + bytes.set(0, 5); + assert(original_array[0] == 1); + + // At this point, slice equals [5, 2, 3, 4] + let encoded_slice = encode(bytes); + + // `Vec` should duplicate the underlying buffer, + // so when we write to it, it should not change + // `encoded_slice` + let mut bytes = abi_decode::>(encoded_slice); + bytes.set(0, 6); + assert(bytes.get(0) == Some(6)); + + let mut bytes = abi_decode::>(encoded_slice); + assert(bytes.get(0) == Some(5)); +} From d0deb79a59bd808bf1fbea7f2e4ea1a72cfd2f2f Mon Sep 17 00:00:00 2001 From: IGI-111 Date: Wed, 13 Nov 2024 12:05:45 +0700 Subject: [PATCH 107/115] Add verifications-complete job (#6716) ## Description Add a single job that depends on all the CI checks so we can make a single job required. ## Checklist - [ ] 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. - [ ] 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). - [ ] I have requested a review from the relevant team or maintainers. --- .github/workflows/ci.yml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a6b251402bc..35bbf0a657a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,6 +19,42 @@ env: NIGHTLY_RUST_VERSION: nightly-2024-10-21 jobs: + verifications-complete: + needs: + - build-sway-lib-core + - build-sway-lib-std + - build-sway-examples + - build-reference-examples + - forc-fmt-check-sway-lib-core + - forc-fmt-check-sway-lib-std + - forc-fmt-check-sway-examples + - forc-fmt-check-panic + - check-sdk-harness-test-suite-compatibility + - build-mdbook + - build-forc-doc-sway-lib-std + - build-forc-test-project + - cargo-build-workspace + - cargo-clippy + - cargo-toml-fmt-check + - cargo-fmt-check + - cargo-run-e2e-test-evm + - cargo-test-lib-std + - forc-run-benchmarks + - forc-unit-tests + - forc-pkg-fuels-deps-check + - cargo-test-sway-lsp + - cargo-test-forc + - cargo-test-workspace + - cargo-unused-deps-check + - pre-publish-check + - cargo-run-e2e-test + - cargo-run-e2e-test-release + - cargo-test-forc-debug + - cargo-test-forc-client + - notify-slack-on-failure + runs-on: ubuntu-latest + steps: + - run: echo "pass" get-fuel-core-version: runs-on: buildjet-4vcpu-ubuntu-2204 outputs: From f39a49404b91f0bc163f593e65c9415e29b4830c Mon Sep 17 00:00:00 2001 From: Sophie Dankel <47993817+sdankel@users.noreply.github.com> Date: Wed, 13 Nov 2024 00:26:52 -0800 Subject: [PATCH 108/115] Add modules to forc-doc search index (#6711) ## Description Closes https://github.com/FuelLabs/sway/issues/6710 Modules such as `math` in the std library now show up in search results. image ## Checklist - [ ] 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. - [ ] 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). - [ ] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: Joshua Batty --- forc-plugins/forc-doc/src/render/search.rs | 4 +- forc-plugins/forc-doc/src/search.rs | 47 +++++++++++++++++-- .../forc-doc/src/static.files/swaydoc.css | 1 + .../src/tests/expects/impl_trait/mod.rs | 8 ++-- 4 files changed, 51 insertions(+), 9 deletions(-) diff --git a/forc-plugins/forc-doc/src/render/search.rs b/forc-plugins/forc-doc/src/render/search.rs index 9213c17210d..584256189e6 100644 --- a/forc-plugins/forc-doc/src/render/search.rs +++ b/forc-plugins/forc-doc/src/render/search.rs @@ -47,7 +47,9 @@ pub(crate) fn generate_searchbar(module_info: &ModuleInfo) -> Box if (results.length > 0) {{ const resultList = results.map(item => {{ const formattedName = `${{item.name}}`; - const name = [...item.module_info, formattedName].join("::"); + const name = item.type_name === "module" + ? [...item.module_info.slice(0, -1), formattedName].join("::") + : [...item.module_info, formattedName].join("::"); const path = ["{}", ...item.module_info, item.html_filename].join("/"); const left = `${{name}}`; const right = `

${{item.preview}}

`; diff --git a/forc-plugins/forc-doc/src/search.rs b/forc-plugins/forc-doc/src/search.rs index 2506292a21e..2073fc750a6 100644 --- a/forc-plugins/forc-doc/src/search.rs +++ b/forc-plugins/forc-doc/src/search.rs @@ -1,13 +1,17 @@ -use crate::doc::{Document, Documentation}; +use crate::doc::{module::ModuleInfo, Document, Documentation}; use anyhow::Result; use serde::{Deserialize, Serialize}; -use std::{collections::HashMap, fs, path::Path}; +use std::{ + collections::{BTreeMap, HashMap}, + fs, + path::Path, +}; const JS_SEARCH_FILE_NAME: &str = "search.js"; /// Creates the search index javascript file for the search bar. pub fn write_search_index(doc_path: &Path, docs: &Documentation) -> Result<()> { - let json_data = docs.to_json_value()?; + let json_data = docs.to_search_index_json_value()?; let module_export = "\"object\"==typeof exports&&\"undefined\"!=typeof module&&(module.exports=SEARCH_INDEX);"; let js_data = format!("var SEARCH_INDEX={json_data};\n{module_export}"); @@ -17,14 +21,28 @@ pub fn write_search_index(doc_path: &Path, docs: &Documentation) -> Result<()> { impl Documentation { /// Generates a mapping of program name to a vector of documentable items within the program /// and returns the map as a `serde_json::Value`. - fn to_json_value(&self) -> Result { + fn to_search_index_json_value(&self) -> Result { let mut map = HashMap::with_capacity(self.len()); + let mut modules = BTreeMap::new(); for doc in self.iter() { let project_name = doc.module_info.project_name().to_string(); map.entry(project_name) .or_insert_with(Vec::new) .push(JsonSearchItem::from(doc)); + modules.insert( + doc.module_info.module_prefixes.join("::"), + doc.module_info.clone(), + ); } + + // Insert the modules themselves into the map. + for (_, module) in modules.iter() { + let project_name = module.project_name().to_string(); + map.entry(project_name) + .or_insert_with(Vec::new) + .push(JsonSearchItem::from(module)); + } + serde_json::to_value(map) } } @@ -57,3 +75,24 @@ impl<'a> From<&'a Document> for JsonSearchItem { } } } + +impl<'a> From<&'a ModuleInfo> for JsonSearchItem { + fn from(value: &'a ModuleInfo) -> Self { + Self { + name: value + .module_prefixes + .last() + .unwrap_or(&String::new()) + .to_string(), + html_filename: "index.html".into(), + module_info: value.module_prefixes.clone(), + preview: value + .preview_opt() + .unwrap_or_default() + .replace("
", "") + .replace("

", "") + .replace("

", ""), + type_name: "module".into(), + } + } +} diff --git a/forc-plugins/forc-doc/src/static.files/swaydoc.css b/forc-plugins/forc-doc/src/static.files/swaydoc.css index 9ed50926ad1..193f3e77586 100644 --- a/forc-plugins/forc-doc/src/static.files/swaydoc.css +++ b/forc-plugins/forc-doc/src/static.files/swaydoc.css @@ -952,6 +952,7 @@ table, .search-results .type.trait { color: #B78CF2; } +.search-results .type.module, .search-results .type.constant { color: #D2991D; } diff --git a/forc-plugins/forc-doc/src/tests/expects/impl_trait/mod.rs b/forc-plugins/forc-doc/src/tests/expects/impl_trait/mod.rs index 9ead7b2f1dc..d68364e7e4f 100644 --- a/forc-plugins/forc-doc/src/tests/expects/impl_trait/mod.rs +++ b/forc-plugins/forc-doc/src/tests/expects/impl_trait/mod.rs @@ -30,13 +30,13 @@ fn test_impl_traits_default() { &doc_path, project_name, &expect![[r##" - Bar in bar - Sway
pub struct Bar {}

Implementations

fn foo_bar()

Trait Implementations

fn abi_encode(self, buffer: Buffer) -> Buffer

fn abi_decode(refmut _buffer: BufferReader) -> Self

fn foo()

something more about foo();

+ Bar in bar - Sway
pub struct Bar {}

Implementations

fn foo_bar()

Trait Implementations

fn abi_encode(self, buffer: Buffer) -> Buffer

fn abi_decode(refmut _buffer: BufferReader) -> Self

fn foo()

something more about foo();

fn add(self, other: Self) -> Self

fn subtract(self, other: Self) -> Self

"##]], ); assert_search_js( &doc_path, &expect![[r#" - var SEARCH_INDEX={"core":[{"html_filename":"trait.AsRawSlice.html","module_info":["core","raw_slice"],"name":"AsRawSlice","preview":"Trait to return a type as a raw_slice.\n","type_name":"trait"},{"html_filename":"fn.from_str_array.html","module_info":["core","str"],"name":"from_str_array","preview":"","type_name":"function"},{"html_filename":"trait.Add.html","module_info":["core","ops"],"name":"Add","preview":"Trait for the addition of two values.\n","type_name":"trait"},{"html_filename":"trait.Subtract.html","module_info":["core","ops"],"name":"Subtract","preview":"Trait for the subtraction of two values.\n","type_name":"trait"},{"html_filename":"trait.Multiply.html","module_info":["core","ops"],"name":"Multiply","preview":"Trait for the multiplication of two values.\n","type_name":"trait"},{"html_filename":"trait.Divide.html","module_info":["core","ops"],"name":"Divide","preview":"Trait for the division of two values.\n","type_name":"trait"},{"html_filename":"trait.Mod.html","module_info":["core","ops"],"name":"Mod","preview":"Trait for the modulo of two values.\n","type_name":"trait"},{"html_filename":"trait.Not.html","module_info":["core","ops"],"name":"Not","preview":"Trait to invert a type.\n","type_name":"trait"},{"html_filename":"trait.Eq.html","module_info":["core","ops"],"name":"Eq","preview":"Trait to evaluate if two types are equal.\n","type_name":"trait"},{"html_filename":"trait.Ord.html","module_info":["core","ops"],"name":"Ord","preview":"Trait to evaluate if one value is greater or less than another of the same type.\n","type_name":"trait"},{"html_filename":"trait.BitwiseAnd.html","module_info":["core","ops"],"name":"BitwiseAnd","preview":"Trait to bitwise AND two values of the same type.\n","type_name":"trait"},{"html_filename":"trait.BitwiseOr.html","module_info":["core","ops"],"name":"BitwiseOr","preview":"Trait to bitwise OR two values of the same type.\n","type_name":"trait"},{"html_filename":"trait.BitwiseXor.html","module_info":["core","ops"],"name":"BitwiseXor","preview":"Trait to bitwise XOR two values of the same type.\n","type_name":"trait"},{"html_filename":"trait.Shift.html","module_info":["core","ops"],"name":"Shift","preview":"Trait to bit shift a value.\n","type_name":"trait"},{"html_filename":"trait.TotalOrd.html","module_info":["core","ops"],"name":"TotalOrd","preview":"Trait to compare values of the same type.\n","type_name":"trait"},{"html_filename":"fn.ok_str_eq.html","module_info":["core","ops"],"name":"ok_str_eq","preview":"","type_name":"function"},{"html_filename":"struct.StorageKey.html","module_info":["core","storage"],"name":"StorageKey","preview":"Describes a location in storage.\n","type_name":"struct"},{"html_filename":"struct.Buffer.html","module_info":["core","codec"],"name":"Buffer","preview":"","type_name":"struct"},{"html_filename":"struct.BufferReader.html","module_info":["core","codec"],"name":"BufferReader","preview":"","type_name":"struct"},{"html_filename":"trait.AbiDecode.html","module_info":["core","codec"],"name":"AbiDecode","preview":"","type_name":"trait"},{"html_filename":"trait.AbiEncode.html","module_info":["core","codec"],"name":"AbiEncode","preview":"","type_name":"trait"},{"html_filename":"fn.encode.html","module_info":["core","codec"],"name":"encode","preview":"","type_name":"function"},{"html_filename":"fn.abi_decode.html","module_info":["core","codec"],"name":"abi_decode","preview":"","type_name":"function"},{"html_filename":"fn.abi_decode_in_place.html","module_info":["core","codec"],"name":"abi_decode_in_place","preview":"","type_name":"function"},{"html_filename":"fn.contract_call.html","module_info":["core","codec"],"name":"contract_call","preview":"","type_name":"function"},{"html_filename":"fn.decode_script_data.html","module_info":["core","codec"],"name":"decode_script_data","preview":"","type_name":"function"},{"html_filename":"fn.decode_predicate_data.html","module_info":["core","codec"],"name":"decode_predicate_data","preview":"","type_name":"function"},{"html_filename":"fn.decode_predicate_data_by_index.html","module_info":["core","codec"],"name":"decode_predicate_data_by_index","preview":"","type_name":"function"},{"html_filename":"fn.decode_first_param.html","module_info":["core","codec"],"name":"decode_first_param","preview":"","type_name":"function"},{"html_filename":"fn.decode_second_param.html","module_info":["core","codec"],"name":"decode_second_param","preview":"","type_name":"function"},{"html_filename":"primitive.u256.html","module_info":["core"],"name":"u256","preview":"256-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.u64.html","module_info":["core"],"name":"u64","preview":"64-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.u32.html","module_info":["core"],"name":"u32","preview":"32-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.u16.html","module_info":["core"],"name":"u16","preview":"16-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.u8.html","module_info":["core"],"name":"u8","preview":"8-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.b256.html","module_info":["core"],"name":"b256","preview":"256 bits (32 bytes), i.e. a hash","type_name":"primitive"},{"html_filename":"primitive.str.html","module_info":["core"],"name":"str","preview":"string slice","type_name":"primitive"},{"html_filename":"primitive.bool.html","module_info":["core"],"name":"bool","preview":"Boolean true or false","type_name":"primitive"},{"html_filename":"primitive.str[0].html","module_info":["core"],"name":"str[0]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[1].html","module_info":["core"],"name":"str[1]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[2].html","module_info":["core"],"name":"str[2]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[3].html","module_info":["core"],"name":"str[3]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[4].html","module_info":["core"],"name":"str[4]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[5].html","module_info":["core"],"name":"str[5]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[6].html","module_info":["core"],"name":"str[6]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[7].html","module_info":["core"],"name":"str[7]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[8].html","module_info":["core"],"name":"str[8]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[9].html","module_info":["core"],"name":"str[9]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[10].html","module_info":["core"],"name":"str[10]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[11].html","module_info":["core"],"name":"str[11]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[12].html","module_info":["core"],"name":"str[12]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[13].html","module_info":["core"],"name":"str[13]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[14].html","module_info":["core"],"name":"str[14]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[15].html","module_info":["core"],"name":"str[15]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[16].html","module_info":["core"],"name":"str[16]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[17].html","module_info":["core"],"name":"str[17]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[18].html","module_info":["core"],"name":"str[18]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[19].html","module_info":["core"],"name":"str[19]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[20].html","module_info":["core"],"name":"str[20]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[21].html","module_info":["core"],"name":"str[21]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[22].html","module_info":["core"],"name":"str[22]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[23].html","module_info":["core"],"name":"str[23]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[24].html","module_info":["core"],"name":"str[24]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[25].html","module_info":["core"],"name":"str[25]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[26].html","module_info":["core"],"name":"str[26]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[27].html","module_info":["core"],"name":"str[27]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[28].html","module_info":["core"],"name":"str[28]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[29].html","module_info":["core"],"name":"str[29]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[30].html","module_info":["core"],"name":"str[30]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[31].html","module_info":["core"],"name":"str[31]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[32].html","module_info":["core"],"name":"str[32]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[33].html","module_info":["core"],"name":"str[33]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[34].html","module_info":["core"],"name":"str[34]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[35].html","module_info":["core"],"name":"str[35]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[36].html","module_info":["core"],"name":"str[36]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[37].html","module_info":["core"],"name":"str[37]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[38].html","module_info":["core"],"name":"str[38]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[39].html","module_info":["core"],"name":"str[39]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[40].html","module_info":["core"],"name":"str[40]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[41].html","module_info":["core"],"name":"str[41]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[42].html","module_info":["core"],"name":"str[42]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[43].html","module_info":["core"],"name":"str[43]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[44].html","module_info":["core"],"name":"str[44]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[45].html","module_info":["core"],"name":"str[45]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[46].html","module_info":["core"],"name":"str[46]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[47].html","module_info":["core"],"name":"str[47]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[48].html","module_info":["core"],"name":"str[48]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[49].html","module_info":["core"],"name":"str[49]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[50].html","module_info":["core"],"name":"str[50]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[51].html","module_info":["core"],"name":"str[51]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[52].html","module_info":["core"],"name":"str[52]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[53].html","module_info":["core"],"name":"str[53]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[54].html","module_info":["core"],"name":"str[54]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[55].html","module_info":["core"],"name":"str[55]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[56].html","module_info":["core"],"name":"str[56]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[57].html","module_info":["core"],"name":"str[57]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[58].html","module_info":["core"],"name":"str[58]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[59].html","module_info":["core"],"name":"str[59]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[60].html","module_info":["core"],"name":"str[60]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[61].html","module_info":["core"],"name":"str[61]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[62].html","module_info":["core"],"name":"str[62]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[63].html","module_info":["core"],"name":"str[63]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[64].html","module_info":["core"],"name":"str[64]","preview":"fixed-length string","type_name":"primitive"}],"impl_traits":[{"html_filename":"trait.Foo.html","module_info":["impl_traits","foo"],"name":"Foo","preview":"","type_name":"trait"},{"html_filename":"trait.Baz.html","module_info":["impl_traits","foo"],"name":"Baz","preview":"","type_name":"trait"},{"html_filename":"struct.Bar.html","module_info":["impl_traits","bar"],"name":"Bar","preview":"","type_name":"struct"}]}; + var SEARCH_INDEX={"core":[{"html_filename":"trait.AsRawSlice.html","module_info":["core","raw_slice"],"name":"AsRawSlice","preview":"Trait to return a type as a raw_slice.\n","type_name":"trait"},{"html_filename":"fn.from_str_array.html","module_info":["core","str"],"name":"from_str_array","preview":"","type_name":"function"},{"html_filename":"trait.Add.html","module_info":["core","ops"],"name":"Add","preview":"Trait for the addition of two values.\n","type_name":"trait"},{"html_filename":"trait.Subtract.html","module_info":["core","ops"],"name":"Subtract","preview":"Trait for the subtraction of two values.\n","type_name":"trait"},{"html_filename":"trait.Multiply.html","module_info":["core","ops"],"name":"Multiply","preview":"Trait for the multiplication of two values.\n","type_name":"trait"},{"html_filename":"trait.Divide.html","module_info":["core","ops"],"name":"Divide","preview":"Trait for the division of two values.\n","type_name":"trait"},{"html_filename":"trait.Mod.html","module_info":["core","ops"],"name":"Mod","preview":"Trait for the modulo of two values.\n","type_name":"trait"},{"html_filename":"trait.Not.html","module_info":["core","ops"],"name":"Not","preview":"Trait to invert a type.\n","type_name":"trait"},{"html_filename":"trait.Eq.html","module_info":["core","ops"],"name":"Eq","preview":"Trait to evaluate if two types are equal.\n","type_name":"trait"},{"html_filename":"trait.Ord.html","module_info":["core","ops"],"name":"Ord","preview":"Trait to evaluate if one value is greater or less than another of the same type.\n","type_name":"trait"},{"html_filename":"trait.BitwiseAnd.html","module_info":["core","ops"],"name":"BitwiseAnd","preview":"Trait to bitwise AND two values of the same type.\n","type_name":"trait"},{"html_filename":"trait.BitwiseOr.html","module_info":["core","ops"],"name":"BitwiseOr","preview":"Trait to bitwise OR two values of the same type.\n","type_name":"trait"},{"html_filename":"trait.BitwiseXor.html","module_info":["core","ops"],"name":"BitwiseXor","preview":"Trait to bitwise XOR two values of the same type.\n","type_name":"trait"},{"html_filename":"trait.Shift.html","module_info":["core","ops"],"name":"Shift","preview":"Trait to bit shift a value.\n","type_name":"trait"},{"html_filename":"trait.TotalOrd.html","module_info":["core","ops"],"name":"TotalOrd","preview":"Trait to compare values of the same type.\n","type_name":"trait"},{"html_filename":"fn.ok_str_eq.html","module_info":["core","ops"],"name":"ok_str_eq","preview":"","type_name":"function"},{"html_filename":"struct.StorageKey.html","module_info":["core","storage"],"name":"StorageKey","preview":"Describes a location in storage.\n","type_name":"struct"},{"html_filename":"struct.Buffer.html","module_info":["core","codec"],"name":"Buffer","preview":"","type_name":"struct"},{"html_filename":"struct.BufferReader.html","module_info":["core","codec"],"name":"BufferReader","preview":"","type_name":"struct"},{"html_filename":"trait.AbiDecode.html","module_info":["core","codec"],"name":"AbiDecode","preview":"","type_name":"trait"},{"html_filename":"trait.AbiEncode.html","module_info":["core","codec"],"name":"AbiEncode","preview":"","type_name":"trait"},{"html_filename":"fn.encode.html","module_info":["core","codec"],"name":"encode","preview":"","type_name":"function"},{"html_filename":"fn.abi_decode.html","module_info":["core","codec"],"name":"abi_decode","preview":"","type_name":"function"},{"html_filename":"fn.abi_decode_in_place.html","module_info":["core","codec"],"name":"abi_decode_in_place","preview":"","type_name":"function"},{"html_filename":"fn.contract_call.html","module_info":["core","codec"],"name":"contract_call","preview":"","type_name":"function"},{"html_filename":"fn.decode_script_data.html","module_info":["core","codec"],"name":"decode_script_data","preview":"","type_name":"function"},{"html_filename":"fn.decode_predicate_data.html","module_info":["core","codec"],"name":"decode_predicate_data","preview":"","type_name":"function"},{"html_filename":"fn.decode_predicate_data_by_index.html","module_info":["core","codec"],"name":"decode_predicate_data_by_index","preview":"","type_name":"function"},{"html_filename":"fn.decode_first_param.html","module_info":["core","codec"],"name":"decode_first_param","preview":"","type_name":"function"},{"html_filename":"fn.decode_second_param.html","module_info":["core","codec"],"name":"decode_second_param","preview":"","type_name":"function"},{"html_filename":"primitive.u256.html","module_info":["core"],"name":"u256","preview":"256-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.u64.html","module_info":["core"],"name":"u64","preview":"64-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.u32.html","module_info":["core"],"name":"u32","preview":"32-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.u16.html","module_info":["core"],"name":"u16","preview":"16-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.u8.html","module_info":["core"],"name":"u8","preview":"8-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.b256.html","module_info":["core"],"name":"b256","preview":"256 bits (32 bytes), i.e. a hash","type_name":"primitive"},{"html_filename":"primitive.str.html","module_info":["core"],"name":"str","preview":"string slice","type_name":"primitive"},{"html_filename":"primitive.bool.html","module_info":["core"],"name":"bool","preview":"Boolean true or false","type_name":"primitive"},{"html_filename":"primitive.str[0].html","module_info":["core"],"name":"str[0]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[1].html","module_info":["core"],"name":"str[1]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[2].html","module_info":["core"],"name":"str[2]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[3].html","module_info":["core"],"name":"str[3]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[4].html","module_info":["core"],"name":"str[4]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[5].html","module_info":["core"],"name":"str[5]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[6].html","module_info":["core"],"name":"str[6]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[7].html","module_info":["core"],"name":"str[7]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[8].html","module_info":["core"],"name":"str[8]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[9].html","module_info":["core"],"name":"str[9]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[10].html","module_info":["core"],"name":"str[10]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[11].html","module_info":["core"],"name":"str[11]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[12].html","module_info":["core"],"name":"str[12]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[13].html","module_info":["core"],"name":"str[13]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[14].html","module_info":["core"],"name":"str[14]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[15].html","module_info":["core"],"name":"str[15]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[16].html","module_info":["core"],"name":"str[16]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[17].html","module_info":["core"],"name":"str[17]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[18].html","module_info":["core"],"name":"str[18]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[19].html","module_info":["core"],"name":"str[19]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[20].html","module_info":["core"],"name":"str[20]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[21].html","module_info":["core"],"name":"str[21]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[22].html","module_info":["core"],"name":"str[22]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[23].html","module_info":["core"],"name":"str[23]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[24].html","module_info":["core"],"name":"str[24]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[25].html","module_info":["core"],"name":"str[25]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[26].html","module_info":["core"],"name":"str[26]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[27].html","module_info":["core"],"name":"str[27]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[28].html","module_info":["core"],"name":"str[28]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[29].html","module_info":["core"],"name":"str[29]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[30].html","module_info":["core"],"name":"str[30]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[31].html","module_info":["core"],"name":"str[31]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[32].html","module_info":["core"],"name":"str[32]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[33].html","module_info":["core"],"name":"str[33]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[34].html","module_info":["core"],"name":"str[34]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[35].html","module_info":["core"],"name":"str[35]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[36].html","module_info":["core"],"name":"str[36]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[37].html","module_info":["core"],"name":"str[37]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[38].html","module_info":["core"],"name":"str[38]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[39].html","module_info":["core"],"name":"str[39]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[40].html","module_info":["core"],"name":"str[40]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[41].html","module_info":["core"],"name":"str[41]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[42].html","module_info":["core"],"name":"str[42]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[43].html","module_info":["core"],"name":"str[43]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[44].html","module_info":["core"],"name":"str[44]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[45].html","module_info":["core"],"name":"str[45]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[46].html","module_info":["core"],"name":"str[46]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[47].html","module_info":["core"],"name":"str[47]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[48].html","module_info":["core"],"name":"str[48]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[49].html","module_info":["core"],"name":"str[49]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[50].html","module_info":["core"],"name":"str[50]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[51].html","module_info":["core"],"name":"str[51]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[52].html","module_info":["core"],"name":"str[52]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[53].html","module_info":["core"],"name":"str[53]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[54].html","module_info":["core"],"name":"str[54]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[55].html","module_info":["core"],"name":"str[55]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[56].html","module_info":["core"],"name":"str[56]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[57].html","module_info":["core"],"name":"str[57]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[58].html","module_info":["core"],"name":"str[58]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[59].html","module_info":["core"],"name":"str[59]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[60].html","module_info":["core"],"name":"str[60]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[61].html","module_info":["core"],"name":"str[61]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[62].html","module_info":["core"],"name":"str[62]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[63].html","module_info":["core"],"name":"str[63]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[64].html","module_info":["core"],"name":"str[64]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"index.html","module_info":["core"],"name":"core","preview":"","type_name":"module"},{"html_filename":"index.html","module_info":["core","codec"],"name":"codec","preview":"","type_name":"module"},{"html_filename":"index.html","module_info":["core","ops"],"name":"ops","preview":"","type_name":"module"},{"html_filename":"index.html","module_info":["core","raw_slice"],"name":"raw_slice","preview":"","type_name":"module"},{"html_filename":"index.html","module_info":["core","storage"],"name":"storage","preview":"","type_name":"module"},{"html_filename":"index.html","module_info":["core","str"],"name":"str","preview":"","type_name":"module"}],"impl_traits":[{"html_filename":"trait.Foo.html","module_info":["impl_traits","foo"],"name":"Foo","preview":"","type_name":"trait"},{"html_filename":"trait.Baz.html","module_info":["impl_traits","foo"],"name":"Baz","preview":"","type_name":"trait"},{"html_filename":"struct.Bar.html","module_info":["impl_traits","bar"],"name":"Bar","preview":"","type_name":"struct"},{"html_filename":"index.html","module_info":["impl_traits","bar"],"name":"bar","preview":"","type_name":"module"},{"html_filename":"index.html","module_info":["impl_traits","foo"],"name":"foo","preview":"","type_name":"module"}]}; "object"==typeof exports&&"undefined"!=typeof module&&(module.exports=SEARCH_INDEX);"#]], ); assert_file_tree( @@ -180,13 +180,13 @@ fn test_impl_traits_no_deps() { &doc_path, project_name, &expect![[r##" - Bar in bar - Sway
pub struct Bar {}

Implementations

fn foo_bar()

Trait Implementations

fn abi_encode(self, buffer: Buffer) -> Buffer

fn abi_decode(refmut _buffer: BufferReader) -> Self

fn foo()

something more about foo();

+ Bar in bar - Sway
pub struct Bar {}

Implementations

fn foo_bar()

Trait Implementations

fn abi_encode(self, buffer: Buffer) -> Buffer

fn abi_decode(refmut _buffer: BufferReader) -> Self

fn foo()

something more about foo();

fn add(self, other: Self) -> Self

fn subtract(self, other: Self) -> Self

"##]], ); assert_search_js( &doc_path, &expect![[ - r#"var SEARCH_INDEX={"impl_traits_clone":[{"html_filename":"trait.Foo.html","module_info":["impl_traits_clone","foo"],"name":"Foo","preview":"","type_name":"trait"},{"html_filename":"trait.Baz.html","module_info":["impl_traits_clone","foo"],"name":"Baz","preview":"","type_name":"trait"},{"html_filename":"struct.Bar.html","module_info":["impl_traits_clone","bar"],"name":"Bar","preview":"","type_name":"struct"}]}; + r#"var SEARCH_INDEX={"impl_traits_clone":[{"html_filename":"trait.Foo.html","module_info":["impl_traits_clone","foo"],"name":"Foo","preview":"","type_name":"trait"},{"html_filename":"trait.Baz.html","module_info":["impl_traits_clone","foo"],"name":"Baz","preview":"","type_name":"trait"},{"html_filename":"struct.Bar.html","module_info":["impl_traits_clone","bar"],"name":"Bar","preview":"","type_name":"struct"},{"html_filename":"index.html","module_info":["impl_traits_clone","bar"],"name":"bar","preview":"","type_name":"module"},{"html_filename":"index.html","module_info":["impl_traits_clone","foo"],"name":"foo","preview":"","type_name":"module"}]}; "object"==typeof exports&&"undefined"!=typeof module&&(module.exports=SEARCH_INDEX);"# ]], ); From 861ca10a06c0572cbd3b11cf342fc9dd9df8118a Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite Date: Wed, 13 Nov 2024 16:35:46 -0300 Subject: [PATCH 109/115] Test encoding raw slices does not allows buffer overflows (#6699) ## Description Test for https://github.com/FuelLabs/sway/pull/6686 buffer overflow on `Bytes` encoding. This test fails without the fix and pass with it. ## 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. --------- Co-authored-by: Joshua Batty Co-authored-by: Sophie Dankel <47993817+sdankel@users.noreply.github.com> --- sway-lib-std/src/bytes.sw | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/sway-lib-std/src/bytes.sw b/sway-lib-std/src/bytes.sw index b1fd11327ad..c02b097811f 100644 --- a/sway-lib-std/src/bytes.sw +++ b/sway-lib-std/src/bytes.sw @@ -950,3 +950,33 @@ fn ok_bytes_buffer_ownership() { let mut bytes = abi_decode::(encoded_slice); assert(bytes.get(0) == Some(5)); } + +#[test] +fn ok_bytes_bigger_than_3064() { + let mut v: Bytes = Bytes::new(); + + // We allocate 1024 bytes initially, this is throw away because + // it is not big enough for the buffer. + // Then we used to double the buffer to 2048. + // Then we write an `u64` with the length of the buffer. + // Then we write the buffer itself. + // (1024 + 2048) - 8 = 3064 + // Thus, we need a buffer with 3065 bytes to write into the red zone + let mut a = 3065; + while a > 0 { + v.push(1u8); + a -= 1; + } + + // This red zone should not be overwritten + let red_zone = asm(size: 1024) { + aloc size; + hp: raw_ptr + }; + red_zone.write(0xFFFFFFFFFFFFFFFF); + assert(red_zone.read::() == 0xFFFFFFFFFFFFFFFF); + + let _ = encode(v); + + assert(red_zone.read::() == 0xFFFFFFFFFFFFFFFF); +} From f7fa086f5a7a720fe41f5e5314b3e5ada3c3cb4d Mon Sep 17 00:00:00 2001 From: SwayStar123 <46050679+SwayStar123@users.noreply.github.com> Date: Thu, 14 Nov 2024 18:31:39 +0530 Subject: [PATCH 110/115] Add revert with log function to std lib (#6717) ## Description Adds a `revert_with_log` function that reverts unconditionally with a message Closes #6629 ## Checklist - [ ] 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. - [ ] 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). - [ ] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: Sophie Dankel <47993817+sdankel@users.noreply.github.com> --- sway-lib-std/src/error_signals.sw | 7 ++++ sway-lib-std/src/prelude.sw | 2 +- sway-lib-std/src/revert.sw | 34 ++++++++++++++++++- .../revert_inline_tests/src/main.sw | 5 +++ 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/sway-lib-std/src/error_signals.sw b/sway-lib-std/src/error_signals.sw index bbc4f6f291b..87f86699378 100644 --- a/sway-lib-std/src/error_signals.sw +++ b/sway-lib-std/src/error_signals.sw @@ -35,3 +35,10 @@ pub const FAILED_ASSERT_SIGNAL = 0xffff_ffff_ffff_0004; /// /// The value is: 18446744073709486085 pub const FAILED_ASSERT_NE_SIGNAL = 0xffff_ffff_ffff_0005; + +/// A revert with this value signals that it was caused by a call to `std::revert::revert_with_log`. +/// +/// # Additional Information +/// +/// The value is: 18446744073709486086 +pub const REVERT_WITH_LOG_SIGNAL = 0xffff_ffff_ffff_0006; diff --git a/sway-lib-std/src/prelude.sw b/sway-lib-std/src/prelude.sw index 6f207cc7b45..f8d42cf0044 100644 --- a/sway-lib-std/src/prelude.sw +++ b/sway-lib-std/src/prelude.sw @@ -21,7 +21,7 @@ pub use ::vec::{Vec, VecIter}; pub use ::assert::{assert, assert_eq, assert_ne}; pub use ::option::Option::{self, *}; pub use ::result::Result::{self, *}; -pub use ::revert::{require, revert}; +pub use ::revert::{require, revert, revert_with_log}; // Convert pub use ::convert::From; diff --git a/sway-lib-std/src/revert.sw b/sway-lib-std/src/revert.sw index ba6ddeadf88..f53dd5378d2 100644 --- a/sway-lib-std/src/revert.sw +++ b/sway-lib-std/src/revert.sw @@ -2,7 +2,7 @@ library; use ::logging::log; -use ::error_signals::FAILED_REQUIRE_SIGNAL; +use ::error_signals::{FAILED_REQUIRE_SIGNAL, REVERT_WITH_LOG_SIGNAL}; /// Will either panic or revert with a given number depending on the context. /// @@ -71,3 +71,35 @@ where revert(FAILED_REQUIRE_SIGNAL) } } + +/// Reverts unconditionally and logs `value`. +/// +/// # Arguments +/// +/// * `value`: [T] - The value which will be logged. +/// +/// # Reverts +/// +/// * Reverts unconditionally. +/// +/// # Examples +/// +/// ```sway +/// fn foo() { +/// revert_with_log("Example error message"); +/// } +/// ``` +#[cfg(experimental_new_encoding = false)] +pub fn revert_with_log(value: T) { + log(value); + revert(REVERT_WITH_LOG_SIGNAL) +} + +#[cfg(experimental_new_encoding = true)] +pub fn revert_with_log(value: T) +where + T: AbiEncode, +{ + log(value); + revert(REVERT_WITH_LOG_SIGNAL) +} diff --git a/test/src/in_language_tests/test_programs/revert_inline_tests/src/main.sw b/test/src/in_language_tests/test_programs/revert_inline_tests/src/main.sw index cff1e49fc0e..64c74e30b63 100644 --- a/test/src/in_language_tests/test_programs/revert_inline_tests/src/main.sw +++ b/test/src/in_language_tests/test_programs/revert_inline_tests/src/main.sw @@ -14,3 +14,8 @@ fn revert_revert_require() { fn pass_revert_require() { require(true, "error"); } + +#[test(should_revert)] +fn revert_revert_with_log() { + revert_with_log("error") +} \ No newline at end of file From 9951c1da7165b18ceccb281c335129b363fa2105 Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite Date: Thu, 14 Nov 2024 13:02:04 -0300 Subject: [PATCH 111/115] Transmute intrinsics (#6692) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description This PR implements the `__transmute` intrinsic. As Rust this intrinsic should be a no-op semantically equal to a pointer cast. Although this PR does not aim that it is 100% no-op yet. At the moment some trade-offs were taken: 1 - References, pointers etc... are not allowed at the moment; 2 - `u16` and `u32` actually occupy 64bits. To allow transmute to work in complex aggregates, this PR is accepting them as `u64`. Doing otherwise would forbid `__transmute` to be no-op. Specially in complex aggregates; ## 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. - [ ] 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). - [ ] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: João Matos --- sway-ast/src/intrinsics.rs | 3 + sway-core/src/ir_generation/const_eval.rs | 135 +++++++++++++++++- sway-core/src/ir_generation/function.rs | 63 +++++++- .../ast_node/expression/intrinsic_function.rs | 110 ++++++++++++++ .../semantic_analysis/cei_pattern_analysis.rs | 3 +- sway-error/src/error.rs | 3 + .../language/intrinsics/transmute/.gitignore | 2 + .../language/intrinsics/transmute/Forc.lock | 8 ++ .../language/intrinsics/transmute/Forc.toml | 8 ++ .../transmute/debug/transmute-abi.json | 28 ++++ .../transmute/debug/transmute-bin-hash | 1 + .../intrinsics/transmute/debug/transmute.bin | Bin 0 -> 1088 bytes .../intrinsics/transmute/snapshot.toml | 0 .../language/intrinsics/transmute/src/main.sw | 16 +++ .../language/intrinsics/transmute/stdout.snap | 62 ++++++++ .../language/intrinsics/transmute/.gitignore | 2 + .../language/intrinsics/transmute/Forc.lock | 8 ++ .../language/intrinsics/transmute/Forc.toml | 8 ++ .../json_abi_oracle_new_encoding.json | 28 ++++ .../language/intrinsics/transmute/src/main.sw | 121 ++++++++++++++++ .../language/intrinsics/transmute/test.toml | 4 + 21 files changed, 608 insertions(+), 5 deletions(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/.gitignore create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/debug/transmute-abi.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/debug/transmute-bin-hash create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/debug/transmute.bin create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/snapshot.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/stdout.snap create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/.gitignore create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/json_abi_oracle_new_encoding.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/test.toml diff --git a/sway-ast/src/intrinsics.rs b/sway-ast/src/intrinsics.rs index 182d47fa3d9..30dea17436d 100644 --- a/sway-ast/src/intrinsics.rs +++ b/sway-ast/src/intrinsics.rs @@ -43,6 +43,7 @@ pub enum Intrinsic { EncodeBufferAsRawSlice, // let slice: raw_slice = __encode_buffer_as_raw_slice(buffer) Slice, // let ref_to_slice = __slice::(item: T, inclusive_start_index, exclusive_end_index) ElemAt, // let elem: &T = __elem_at::(item: T, index) + Transmute, // let dst: B = __transmute::(src) } impl fmt::Display for Intrinsic { @@ -89,6 +90,7 @@ impl fmt::Display for Intrinsic { Intrinsic::EncodeBufferAsRawSlice => "encode_buffer_as_raw_slice", Intrinsic::Slice => "slice", Intrinsic::ElemAt => "elem_at", + Intrinsic::Transmute => "transmute", }; write!(f, "{s}") } @@ -139,6 +141,7 @@ impl Intrinsic { "__encode_buffer_as_raw_slice" => EncodeBufferAsRawSlice, "__slice" => Slice, "__elem_at" => ElemAt, + "__transmute" => Transmute, _ => return None, }) } diff --git a/sway-core/src/ir_generation/const_eval.rs b/sway-core/src/ir_generation/const_eval.rs index 258d63cb6d2..9a986c54656 100644 --- a/sway-core/src/ir_generation/const_eval.rs +++ b/sway-core/src/ir_generation/const_eval.rs @@ -1,4 +1,7 @@ -use std::ops::{BitAnd, BitOr, BitXor, Not, Rem}; +use std::{ + io::Read, + ops::{BitAnd, BitOr, BitXor, Not, Rem}, +}; use crate::{ engine_threading::*, @@ -1363,6 +1366,136 @@ fn const_eval_intrinsic( }), } } + Intrinsic::Transmute => { + let src_type = &intrinsic.type_arguments[0]; + let src_ir_type = convert_resolved_type_id( + lookup.engines.te(), + lookup.engines.de(), + lookup.context, + src_type.type_id, + &src_type.span, + ) + .unwrap(); + + let dst_type = &intrinsic.type_arguments[1]; + let dst_ir_type = convert_resolved_type_id( + lookup.engines.te(), + lookup.engines.de(), + lookup.context, + dst_type.type_id, + &dst_type.span, + ) + .unwrap(); + + // check IR sizes match + let src_ir_type_in_bytes = src_ir_type.size(lookup.context).in_bytes(); + let dst_ir_type_in_bytes = dst_ir_type.size(lookup.context).in_bytes(); + if src_ir_type_in_bytes != dst_ir_type_in_bytes { + return Err(ConstEvalError::CompileError); + } + + fn append_bytes( + ctx: &Context<'_>, + bytes: &mut Vec, + t: &Type, + value: &ConstantValue, + ) -> Result<(), ConstEvalError> { + match t.get_content(ctx) { + TypeContent::Array(item_type, size) => match value { + ConstantValue::Array(items) => { + assert!(*size as usize == items.len()); + for item in items { + append_bytes(ctx, bytes, item_type, &item.value)?; + } + } + _ => unreachable!(), + }, + TypeContent::Uint(8) => match value { + ConstantValue::Uint(v) => { + bytes.extend((*v as u8).to_be_bytes()); + } + _ => unreachable!(), + }, + TypeContent::Uint(16) => match value { + ConstantValue::Uint(v) => { + bytes.extend([0u8, 0u8, 0u8, 0u8, 0u8, 0u8]); + bytes.extend((*v as u16).to_be_bytes()); + } + _ => unreachable!(), + }, + TypeContent::Uint(32) => match value { + ConstantValue::Uint(v) => { + bytes.extend([0u8, 0u8, 0u8, 0u8]); + bytes.extend((*v as u32).to_be_bytes()); + } + _ => unreachable!(), + }, + TypeContent::Uint(64) => match value { + ConstantValue::Uint(v) => { + bytes.extend((*v).to_be_bytes()); + } + _ => unreachable!(), + }, + _ => return Err(ConstEvalError::CompileError), + } + Ok(()) + } + + fn transmute_bytes( + ctx: &Context<'_>, + bytes: &mut std::io::Cursor>, + t: &Type, + ) -> Result { + Ok(match t.get_content(ctx) { + TypeContent::Uint(8) => { + let mut buffer = [0u8]; + let _ = bytes.read_exact(&mut buffer); + Constant { + ty: Type::get_uint8(ctx), + value: ConstantValue::Uint(buffer[0] as u64), + } + } + TypeContent::Uint(16) => { + let mut buffer = [0u8; 8]; // u16 = u64 at runtime + let _ = bytes.read_exact(&mut buffer); + let buffer = [buffer[6], buffer[7]]; + Constant { + ty: Type::get_uint16(ctx), + value: ConstantValue::Uint(u16::from_be_bytes(buffer) as u64), + } + } + TypeContent::Uint(32) => { + let mut buffer = [0u8; 8]; // u32 = u64 at runtime + let _ = bytes.read_exact(&mut buffer); + let buffer = [buffer[4], buffer[5], buffer[6], buffer[7]]; + Constant { + ty: Type::get_uint32(ctx), + value: ConstantValue::Uint(u32::from_be_bytes(buffer) as u64), + } + } + TypeContent::Uint(64) => { + let mut buffer = [0u8; 8]; + let _ = bytes.read_exact(&mut buffer); + Constant { + ty: Type::get_uint64(ctx), + value: ConstantValue::Uint(u64::from_be_bytes(buffer)), + } + } + _ => return Err(ConstEvalError::CompileError), + }) + } + + let mut runtime_bytes = vec![]; + append_bytes( + lookup.context, + &mut runtime_bytes, + &src_ir_type, + &args[0].value, + )?; + let mut cursor = std::io::Cursor::new(runtime_bytes); + let c = transmute_bytes(lookup.context, &mut cursor, &dst_ir_type)?; + Ok(Some(c)) + } } } diff --git a/sway-core/src/ir_generation/function.rs b/sway-core/src/ir_generation/function.rs index 54fd1d31f75..f3a7064568e 100644 --- a/sway-core/src/ir_generation/function.rs +++ b/sway-core/src/ir_generation/function.rs @@ -660,9 +660,13 @@ impl<'eng> FnCompiler<'eng> { span_md_idx, ) } - ty::TyExpressionVariant::IntrinsicFunction(kind) => { - self.compile_intrinsic_function(context, md_mgr, kind, ast_expr.span.clone()) - } + ty::TyExpressionVariant::IntrinsicFunction(kind) => self.compile_intrinsic_function( + context, + md_mgr, + kind, + ast_expr.span.clone(), + ast_expr.return_type, + ), ty::TyExpressionVariant::AbiName(_) => { let val = Value::new_constant(context, Constant::new_unit(context)); Ok(TerminatorValue::new(val, context)) @@ -869,6 +873,7 @@ impl<'eng> FnCompiler<'eng> { span: _, }: &ty::TyIntrinsicFunctionKind, span: Span, + return_type: TypeId, ) -> Result { fn store_key_in_local_mem( compiler: &mut FnCompiler, @@ -2174,9 +2179,61 @@ impl<'eng> FnCompiler<'eng> { } Intrinsic::Slice => self.compile_intrinsic_slice(arguments, context, md_mgr), Intrinsic::ElemAt => self.compile_intrinsic_elem_at(arguments, context, md_mgr), + Intrinsic::Transmute => { + self.compile_intrinsic_transmute(arguments, return_type, context, md_mgr, &span) + } } } + fn compile_intrinsic_transmute( + &mut self, + arguments: &[ty::TyExpression], + return_type: TypeId, + context: &mut Context, + md_mgr: &mut MetadataManager, + span: &Span, + ) -> Result { + assert!(arguments.len() == 1); + + let te = self.engines.te(); + let de = self.engines.de(); + + let return_type_ir_type = convert_resolved_type_id(te, de, context, return_type, span)?; + let return_type_ir_type_ptr = Type::new_ptr(context, return_type_ir_type); + + let first_argument_expr = &arguments[0]; + let first_argument_value = return_on_termination_or_extract!( + self.compile_expression_to_value(context, md_mgr, first_argument_expr)? + ); + let first_argument_type = first_argument_value + .get_type(context) + .expect("transmute first argument type not found"); + let first_argument_ptr = save_to_local_return_ptr(self, context, first_argument_value)?; + + // check IR sizes match + let first_arg_size = first_argument_type.size(context).in_bytes(); + let return_type_size = return_type_ir_type.size(context).in_bytes(); + if first_arg_size != return_type_size { + return Err(CompileError::Internal( + "Types size do not match", + span.clone(), + )); + } + + let u64 = Type::get_uint64(context); + let first_argument_ptr = self + .current_block + .append(context) + .ptr_to_int(first_argument_ptr, u64); + let first_argument_ptr = self + .current_block + .append(context) + .int_to_ptr(first_argument_ptr, return_type_ir_type_ptr); + + let final_value = self.current_block.append(context).load(first_argument_ptr); + Ok(TerminatorValue::new(final_value, context)) + } + fn ptr_to_first_element( &mut self, context: &mut 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 3ed6c9de234..421509fbc81 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 @@ -106,8 +106,118 @@ impl ty::TyIntrinsicFunctionKind { type_check_slice(handler, ctx, kind, arguments, type_arguments, span) } Intrinsic::ElemAt => type_check_elem_at(arguments, handler, kind, span, ctx), + Intrinsic::Transmute => { + type_check_transmute(arguments, handler, kind, type_arguments, span, ctx) + } + } + } +} + +fn type_check_transmute( + arguments: &[Expression], + handler: &Handler, + kind: Intrinsic, + type_arguments: &[TypeArgument], + span: Span, + mut ctx: TypeCheckContext, +) -> Result<(TyIntrinsicFunctionKind, TypeId), ErrorEmitted> { + if arguments.len() != 1 { + return Err(handler.emit_err(CompileError::IntrinsicIncorrectNumArgs { + name: kind.to_string(), + expected: 1, + span, + })); + } + + let engines = ctx.engines(); + + // Both type arguments needs to be explicitly defined + if type_arguments.len() != 2 { + return Err(handler.emit_err(CompileError::IntrinsicIncorrectNumTArgs { + name: kind.to_string(), + expected: 2, + span, + })); + } + + let src_type = ctx + .resolve_type( + handler, + type_arguments[0].type_id, + &type_arguments[0].span, + EnforceTypeArguments::Yes, + None, + ) + .unwrap_or_else(|err| engines.te().id_of_error_recovery(err)); + let return_type = ctx + .resolve_type( + handler, + type_arguments[1].type_id, + &type_arguments[1].span, + EnforceTypeArguments::Yes, + None, + ) + .unwrap_or_else(|err| engines.te().id_of_error_recovery(err)); + + // Forbid ref and ptr types + fn forbid_ref_ptr_types( + engines: &Engines, + handler: &Handler, + t: TypeId, + span: &Span, + ) -> Result<(), ErrorEmitted> { + let types = t.extract_any_including_self( + engines, + &|t| { + matches!( + t, + TypeInfo::StringSlice + | TypeInfo::RawUntypedPtr + | TypeInfo::RawUntypedSlice + | TypeInfo::Ptr(_) + | TypeInfo::Slice(_) + | TypeInfo::Ref { .. } + ) + }, + vec![], + 0, + ); + if !types.is_empty() { + Err(handler.emit_err(CompileError::TypeNotAllowed { + reason: sway_error::error::TypeNotAllowedReason::NotAllowedInTransmute, + span: span.clone(), + })) + } else { + Ok(()) } } + + forbid_ref_ptr_types(engines, handler, src_type, &type_arguments[0].span)?; + forbid_ref_ptr_types(engines, handler, return_type, &type_arguments[1].span)?; + + // check first argument + let arg_type = engines.te().get(src_type); + let first_argument_typed_expr = { + let ctx = ctx + .by_ref() + .with_help_text("") + .with_type_annotation(engines.te().insert( + engines, + (*arg_type).clone(), + type_arguments[0].span.source_id(), + )); + ty::TyExpression::type_check(handler, ctx, &arguments[0]).unwrap() + }; + + Ok(( + TyIntrinsicFunctionKind { + kind, + arguments: vec![first_argument_typed_expr], + type_arguments: type_arguments.to_vec(), + span, + }, + return_type, + )) } fn type_check_elem_at( diff --git a/sway-core/src/semantic_analysis/cei_pattern_analysis.rs b/sway-core/src/semantic_analysis/cei_pattern_analysis.rs index 1dbad596ed4..1f40ad03ac7 100644 --- a/sway-core/src/semantic_analysis/cei_pattern_analysis.rs +++ b/sway-core/src/semantic_analysis/cei_pattern_analysis.rs @@ -649,7 +649,8 @@ fn effects_of_intrinsic(intr: &sway_ast::Intrinsic) -> HashSet { | EncodeBufferAppend | EncodeBufferAsRawSlice | Slice - | ElemAt => HashSet::new(), + | ElemAt + | Transmute => HashSet::new(), } } diff --git a/sway-error/src/error.rs b/sway-error/src/error.rs index 3998426f92e..fb129fa9903 100644 --- a/sway-error/src/error.rs +++ b/sway-error/src/error.rs @@ -2812,6 +2812,9 @@ pub enum TypeNotAllowedReason { #[error("slices or types containing slices on `const` are not allowed.")] SliceInConst, + + #[error("references, pointers, slices, string slices or types containing any of these are not allowed.")] + NotAllowedInTransmute, } #[derive(Debug, Clone, PartialEq, Eq, Hash)] diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/.gitignore b/test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/.gitignore new file mode 100644 index 00000000000..77d3844f58c --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/.gitignore @@ -0,0 +1,2 @@ +out +target diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/Forc.lock new file mode 100644 index 00000000000..f9932679777 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/Forc.lock @@ -0,0 +1,8 @@ +[[package]] +name = "core" +source = "path+from-root-E4EB5F90E61EC58F" + +[[package]] +name = "transmute" +source = "member" +dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/Forc.toml new file mode 100644 index 00000000000..457f84ef26a --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +license = "Apache-2.0" +entry = "main.sw" +name = "transmute" + +[dependencies] +core = { path = "../../../../../../../../sway-lib-core" } diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/debug/transmute-abi.json b/test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/debug/transmute-abi.json new file mode 100644 index 00000000000..c42f6cefac2 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/debug/transmute-abi.json @@ -0,0 +1,28 @@ +{ + "programType": "script", + "specVersion": "1", + "encodingVersion": "1", + "concreteTypes": [ + { + "type": "u64", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "metadataTypes": [], + "functions": [ + { + "inputs": [], + "name": "main", + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "attributes": null + } + ], + "loggedTypes": [ + { + "logId": "1515152261580153489", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "messagesTypes": [], + "configurables": [] +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/debug/transmute-bin-hash b/test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/debug/transmute-bin-hash new file mode 100644 index 00000000000..86a358e416a --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/debug/transmute-bin-hash @@ -0,0 +1 @@ +0x82d76771fa3e7e2cc3c0f9904b45673c9066384f3077cd97e20892c965a096db \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/debug/transmute.bin b/test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/debug/transmute.bin new file mode 100644 index 0000000000000000000000000000000000000000..4c9d69d93cbd0cdf9999c405362669932f70c5c3 GIT binary patch literal 1088 zcmd5*&2G~`82lXE#QcaZ#gU>75k8d4M@!_;<64g8ghuKLgopsw6(^37g%ILWA30JG z&|@FLmN;MS@DHdI+*>i>ujti+c6q6%H>Lj2ORwSVB|nCDM{M5rI``na@;lcB zdL0z+%6o6Df%AH}k=|%)`a|4P!G4LkI_8xwtCgP;eIQEsnL~TX#usGd!Gu&+c4k@8 z_V}}X;!oZae>9?4=(HxFMGOhLhM4zFg<)NePKd#$1~RDp`vxryl|vb10{t|UkJ8JO zrwvzT<~m&k6liT8)Z z{5D1Ywwj5ddIZN|lsi1ittK?yfi9=y!P#WSpABYsmR!Q2GgEoH(4Tf^b?JVIL#ru$ z#_*5+08dN0mJ#=nUDrGS=Qi{(+g(+&7~>k!fZ>Hi@4~_<%W|iPDE1ecVR`mGnczX6a`6ny{y literal 0 HcmV?d00001 diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/snapshot.toml b/test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/snapshot.toml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/src/main.sw new file mode 100644 index 00000000000..6873ab62973 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/src/main.sw @@ -0,0 +1,16 @@ +script; + +fn main() { + // Missing type arguments + let _ = __transmute(1u64); + let _ = __transmute::(1u64); + + // Wrong source type + let _ = __transmute::(1u32); + + // Different sizes + let _ = __transmute::(1u64); + + // Invalid types + let _ = __transmute::<&u64, &u8>(&1u64); +} diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/stdout.snap new file mode 100644 index 00000000000..70f758a10e0 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/stdout.snap @@ -0,0 +1,62 @@ +--- +source: test/tests/tests.rs +snapshot_kind: text +--- +> forc build --path test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute +exit status: 1 +output: + Building test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute + Compiling library core (sway-lib-core) + Compiling script transmute (test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute) +error + --> test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/src/main.sw:5:13 + | +3 | fn main() { +4 | // Missing type arguments +5 | let _ = __transmute(1u64); + | ^^^^^^^^^^^^^^^^^ Call to "transmute" expects 2 type arguments +6 | let _ = __transmute::(1u64); +7 | + | +____ + +error + --> test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/src/main.sw:6:13 + | +4 | // Missing type arguments +5 | let _ = __transmute(1u64); +6 | let _ = __transmute::(1u64); + | ^^^^^^^^^^^^^^^^^^^^^^^^ Call to "transmute" expects 2 type arguments +7 | +8 | // Wrong source type + | +____ + +error + --> test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/src/main.sw:9:36 + | + 7 | + 8 | // Wrong source type + 9 | let _ = __transmute::(1u32); + | ^^^^ Mismatched types. +expected: u64 +found: u32. + +10 | +11 | // Different sizes + | +____ + +error + --> test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/src/main.sw:15:27 + | +13 | +14 | // Invalid types +15 | let _ = __transmute::<&u64, &u8>(&1u64); + | ^^^^ references, pointers, slices, string slices or types containing any of these are not allowed. +16 | } + | +____ + + Aborting due to 4 errors. +error: Failed to compile transmute diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/.gitignore b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/.gitignore new file mode 100644 index 00000000000..77d3844f58c --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/.gitignore @@ -0,0 +1,2 @@ +out +target diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/Forc.lock new file mode 100644 index 00000000000..f9932679777 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/Forc.lock @@ -0,0 +1,8 @@ +[[package]] +name = "core" +source = "path+from-root-E4EB5F90E61EC58F" + +[[package]] +name = "transmute" +source = "member" +dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/Forc.toml new file mode 100644 index 00000000000..457f84ef26a --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +license = "Apache-2.0" +entry = "main.sw" +name = "transmute" + +[dependencies] +core = { path = "../../../../../../../../sway-lib-core" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/json_abi_oracle_new_encoding.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/json_abi_oracle_new_encoding.json new file mode 100644 index 00000000000..7ebeae3ddd5 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/json_abi_oracle_new_encoding.json @@ -0,0 +1,28 @@ +{ + "concreteTypes": [ + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "type": "u64" + } + ], + "configurables": [], + "encodingVersion": "1", + "functions": [ + { + "attributes": null, + "inputs": [], + "name": "main", + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "loggedTypes": [ + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "logId": "1515152261580153489" + } + ], + "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/intrinsics/transmute/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/src/main.sw new file mode 100644 index 00000000000..9bad6776dcc --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/src/main.sw @@ -0,0 +1,121 @@ +script; + +fn assert(v: bool) { + if !v { + __revert(0); + } +} + +enum SomeEnum { + A: u64, + B: u64 +} + +pub struct SomeStruct { + #[allow(dead_code)] + tag: u64, + #[allow(dead_code)] + value: u64 +} + +fn const_transmute() { + // u16 needs 8 bytes as u64 + const U8ARRAY_U16 = __transmute::<[u8; 8], u16>([0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8]); + assert(U8ARRAY_U16 == 0x0102u16); + + // u32 needs 8 bytes as u64 + const U8ARRAY_U32 = __transmute::<[u8; 8], u32>([0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8, 4u8]); + assert(U8ARRAY_U32 == 0x01020304u32); + + const U8ARRAY_U64 = __transmute::<[u8; 8], u64>([1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8]); + assert(U8ARRAY_U64 == 0x0102030405060708u64); + + // u32 <-> u64 + const U32_U64 = __transmute::(1u32); + assert(U32_U64 == 0x0000000000000001u64); + + const U64_U32 = __transmute::(1u64); + assert(U64_U32 == 0x00000001u32); +} + +fn main() { + const_transmute(); + + // Check transmute work as nop + let u8_u8 = __transmute::(1); + assert(u8_u8 == 1); + + let u16_u16 = __transmute::(1); + assert(u16_u16 == 1); + + let u32_u32 = __transmute::(1); + assert(u32_u32 == 1); + + let u64_u64 = __transmute::(1); + assert(u64_u64 == 1); + + // Check transmute arrays + let u8array_u8 = __transmute::<[u8; 1], u8>([1u8]); + assert(u8array_u8 == 1); + + // u16 needs 8 bytes as u64 + let u8array_u16 = __transmute::<[u8; 8], u64>([0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8]); + assert(u8array_u16 == 1); + + // u32 needs 8 bytes as u64 + let u8array_u32 = __transmute::<[u8; 8], u32>([0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8]); + assert(u8array_u32 == 1); + + let u8array_u64 = __transmute::<[u8; 8], u64>([0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8]); + assert(u8array_u64 == 1); + + // u32 <-> u64 + let u32_u64 = __transmute::(1u32); + assert(u32_u64 == 0x0000000000000001u64); + + let u64_u32 = __transmute::(1u64); + assert(u64_u32 == 0x00000001u32); + + // check u256 and b256 are transmutable + let u256_b256 = __transmute::(u256::max()); + assert(u256_b256 == b256::max()); + + // b256 to arrays of u64 and back + let b256_u64array = __transmute::(b256::max()); + assert(b256_u64array[0] == u64::max()); + assert(b256_u64array[1] == u64::max()); + assert(b256_u64array[2] == u64::max()); + assert(b256_u64array[3] == u64::max()); + let u64array_b256 = __transmute::<[u64; 4], b256>(b256_u64array); + assert(u64array_b256 == b256::max()); + + // Check tuples + let b256_tuple_u64 = __transmute::(b256::max()); + assert(b256_tuple_u64.0 == u64::max()); + assert(b256_tuple_u64.1 == u64::max()); + assert(b256_tuple_u64.2 == u64::max()); + assert(b256_tuple_u64.3 == u64::max()); + let tuple_u64_b256 = __transmute::<(u64, u64, u64, u64), b256>(b256_tuple_u64); + assert(tuple_u64_b256 == b256::max()); + + // u16 is actually as big as a u64 + // even inside "structs" + let tuple_u8_u6_u8 = __transmute::<(u8, u16, u8), (u8, u64, u8)>((1, 2, 3)); + assert(tuple_u8_u6_u8.0 == 1); + assert(tuple_u8_u6_u8.1 == 2); + assert(tuple_u8_u6_u8.2 == 3); + + // Check struct to enum + let some_struct: SomeStruct = SomeStruct { tag: 0, value: 1 }; + let some_enum = __transmute::(some_struct); + match some_enum { + SomeEnum::A(v) => assert(v == 1), + _ => {} + }; + + // check enum to struct + let some_enum = SomeEnum::B(1); + let some_struct = __transmute::(some_enum); + assert(some_struct.tag == 1); + assert(some_struct.value == 1); +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/test.toml new file mode 100644 index 00000000000..f656259dc91 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/test.toml @@ -0,0 +1,4 @@ +category = "run" +expected_result = { action = "return", value = 0 } +expected_result_new_encoding = { action = "return_data", value = "" } + From 6e31144e2bb6ac414a8d99769b0bea51c8a21cef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Matos?= Date: Fri, 15 Nov 2024 00:00:23 +0000 Subject: [PATCH 112/115] Profiling support (#6705) ## Description This pull request adds the profile feature in the Sway compiler. It communicates with an external `forc-perf` executable in order to signal the beginning and end of different compilation phases for profiling purposes. (re-opening of https://github.com/FuelLabs/sway/pull/6565) ## 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. --------- Co-authored-by: Camden Smallwood Co-authored-by: GeorgiosDelkos Co-authored-by: IGI-111 --- Cargo.lock | 1 + forc-pkg/Cargo.toml | 1 + forc-pkg/src/manifest/build_profile.rs | 5 + forc-pkg/src/pkg.rs | 95 ++++++++++++++++++- forc-plugins/forc-client/src/op/deploy.rs | 1 + forc-plugins/forc-client/src/op/run/mod.rs | 1 + forc-test/src/lib.rs | 4 + forc/Cargo.toml | 1 + forc/src/cli/commands/test.rs | 1 + forc/src/cli/shared.rs | 3 + forc/src/ops/forc_build.rs | 1 + forc/src/ops/forc_contract_id.rs | 1 + forc/src/ops/forc_predicate_root.rs | 1 + sway-core/src/asm_generation/finalized_asm.rs | 18 ++++ .../src/asm_generation/fuel/data_section.rs | 4 +- sway-core/src/asm_generation/mod.rs | 3 +- sway-core/src/build_config.rs | 6 ++ sway-core/src/lib.rs | 14 ++- sway-ir/Cargo.toml | 1 + sway-ir/src/irtype.rs | 2 +- sway-utils/src/performance.rs | 20 +++- 21 files changed, 173 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d0e9ea139dc..159d6d5f8cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7723,6 +7723,7 @@ dependencies = [ "peg", "prettydiff", "rustc-hash 1.1.0", + "serde", "slotmap", "sway-features", "sway-ir-macros", diff --git a/forc-pkg/Cargo.toml b/forc-pkg/Cargo.toml index 20dcf7436cc..6e0e6431fac 100644 --- a/forc-pkg/Cargo.toml +++ b/forc-pkg/Cargo.toml @@ -45,3 +45,4 @@ regex = "^1.10.2" [target.'cfg(not(target_os = "macos"))'.dependencies] sysinfo = "0.29" + diff --git a/forc-pkg/src/manifest/build_profile.rs b/forc-pkg/src/manifest/build_profile.rs index af5822ec693..a196cd51068 100644 --- a/forc-pkg/src/manifest/build_profile.rs +++ b/forc-pkg/src/manifest/build_profile.rs @@ -24,6 +24,8 @@ pub struct BuildProfile { #[serde(default)] pub time_phases: bool, #[serde(default)] + pub profile: bool, + #[serde(default)] pub metrics_outfile: Option, #[serde(default)] pub include_tests: bool, @@ -52,6 +54,7 @@ impl BuildProfile { print_bytecode_spans: false, terse: false, time_phases: false, + profile: false, metrics_outfile: None, include_tests: false, error_on_warnings: false, @@ -72,6 +75,7 @@ impl BuildProfile { print_bytecode_spans: false, terse: false, time_phases: false, + profile: false, metrics_outfile: None, include_tests: false, error_on_warnings: false, @@ -140,6 +144,7 @@ mod tests { print_bytecode_spans: false, terse: true, time_phases: true, + profile: false, metrics_outfile: Some("metrics_outfile".into()), include_tests: true, error_on_warnings: true, diff --git a/forc-pkg/src/pkg.rs b/forc-pkg/src/pkg.rs index 4a798f01f48..ab4733949b8 100644 --- a/forc-pkg/src/pkg.rs +++ b/forc-pkg/src/pkg.rs @@ -300,6 +300,8 @@ pub struct BuildOpts { pub release: bool, /// Output the time elapsed over each part of the compilation process. pub time_phases: bool, + /// Profile the build process. + pub profile: bool, /// If set, outputs compilation metrics info in JSON format. pub metrics_outfile: Option, /// Warnings must be treated as compiler errors. @@ -1561,6 +1563,7 @@ pub fn sway_build_config( .with_print_ir(build_profile.print_ir.clone()) .with_include_tests(build_profile.include_tests) .with_time_phases(build_profile.time_phases) + .with_profile(build_profile.profile) .with_metrics(build_profile.metrics_outfile.clone()) .with_optimization_level(build_profile.optimization_level); Ok(build_config) @@ -1780,6 +1783,7 @@ pub fn compile( // First, compile to an AST. We'll update the namespace and check for JSON ABI output. let ast_res = time_expr!( + pkg.name, "compile to ast", "compile_to_ast", sway_core::compile_to_ast( @@ -1819,6 +1823,7 @@ pub fn compile( } let asm_res = time_expr!( + pkg.name, "compile ast to asm", "compile_ast_to_asm", sway_core::ast_to_asm( @@ -1839,6 +1844,7 @@ pub fn compile( let mut program_abi = match pkg.target { BuildTarget::Fuel => { let program_abi_res = time_expr!( + pkg.name, "generate JSON ABI program", "generate_json_abi", fuel_abi::generate_program_abi( @@ -1877,6 +1883,7 @@ pub fn compile( }; let abi = time_expr!( + pkg.name, "generate JSON ABI program", "generate_json_abi", evm_abi::generate_abi_program(typed_program, engines), @@ -1899,15 +1906,22 @@ pub fn compile( .map(|finalized_entry| PkgEntry::from_finalized_entry(finalized_entry, engines)) .collect::>()?; - let asm = match asm_res { + let mut asm = match asm_res { Err(_) => return fail(handler), Ok(asm) => asm, }; let bc_res = time_expr!( + pkg.name, "compile asm to bytecode", "compile_asm_to_bytecode", - sway_core::asm_to_bytecode(&handler, asm, source_map, engines.se(), &sway_build_config), + sway_core::asm_to_bytecode( + &handler, + &mut asm, + source_map, + engines.se(), + &sway_build_config + ), Some(sway_build_config.clone()), metrics ); @@ -1957,9 +1971,84 @@ pub fn compile( warnings, metrics, }; + if sway_build_config.profile { + report_assembly_information(&asm, &compiled_package); + } + Ok(compiled_package) } +/// Reports assembly information for a compiled package to an external `dyno` process through `stdout`. +fn report_assembly_information( + compiled_asm: &sway_core::CompiledAsm, + compiled_package: &CompiledPackage, +) { + // Get the bytes of the compiled package. + let mut bytes = compiled_package.bytecode.bytes.clone(); + + // Attempt to get the data section offset out of the compiled package bytes. + let data_offset = u64::from_be_bytes( + bytes + .iter() + .skip(8) + .take(8) + .cloned() + .collect::>() + .try_into() + .unwrap(), + ); + let data_section_size = bytes.len() as u64 - data_offset; + + // Remove the data section from the compiled package bytes. + bytes.truncate(data_offset as usize); + + // Calculate the unpadded size of each data section section. + // Implementation based directly on `sway_core::asm_generation::Entry::to_bytes`, referenced here: + // https://github.com/FuelLabs/sway/blob/afd6a6709e7cb11c676059a5004012cc466e653b/sway-core/src/asm_generation/fuel/data_section.rs#L147 + fn calculate_entry_size(entry: &sway_core::asm_generation::Entry) -> u64 { + match &entry.value { + sway_core::asm_generation::Datum::Byte(value) => std::mem::size_of_val(value) as u64, + + sway_core::asm_generation::Datum::Word(value) => std::mem::size_of_val(value) as u64, + + sway_core::asm_generation::Datum::ByteArray(bytes) + | sway_core::asm_generation::Datum::Slice(bytes) => { + if bytes.len() % 8 == 0 { + bytes.len() as u64 + } else { + ((bytes.len() + 7) & 0xfffffff8_usize) as u64 + } + } + + sway_core::asm_generation::Datum::Collection(items) => { + items.iter().map(calculate_entry_size).sum() + } + } + } + + // Compute the assembly information to be reported. + let asm_information = sway_core::asm_generation::AsmInformation { + bytecode_size: bytes.len() as _, + data_section: sway_core::asm_generation::DataSectionInformation { + size: data_section_size, + used: compiled_asm + .0 + .data_section + .value_pairs + .iter() + .map(calculate_entry_size) + .sum(), + value_pairs: compiled_asm.0.data_section.value_pairs.clone(), + }, + }; + + // Report the assembly information to the `dyno` process through `stdout`. + println!( + "/dyno info {}", + serde_json::to_string(&asm_information).unwrap() + ); +} + impl PkgEntry { /// Returns whether this `PkgEntry` corresponds to a test. pub fn is_test(&self) -> bool { @@ -2062,6 +2151,7 @@ fn build_profile_from_opts( pkg, print, time_phases, + profile: profile_opt, build_profile, release, metrics_outfile, @@ -2102,6 +2192,7 @@ fn build_profile_from_opts( profile.print_bytecode_spans |= print.bytecode_spans; profile.terse |= pkg.terse; profile.time_phases |= time_phases; + profile.profile |= profile_opt; if profile.metrics_outfile.is_none() { profile.metrics_outfile.clone_from(metrics_outfile); } diff --git a/forc-plugins/forc-client/src/op/deploy.rs b/forc-plugins/forc-client/src/op/deploy.rs index 8f86c333672..44eb8eb5442 100644 --- a/forc-plugins/forc-client/src/op/deploy.rs +++ b/forc-plugins/forc-client/src/op/deploy.rs @@ -913,6 +913,7 @@ fn build_opts_from_cmd(cmd: &cmd::Deploy, member_filter: pkg::MemberFilter) -> p reverse_order: cmd.print.reverse_order, }, time_phases: cmd.print.time_phases, + profile: cmd.print.profile, metrics_outfile: cmd.print.metrics_outfile.clone(), minify: pkg::MinifyOpts { json_abi: cmd.minify.json_abi, diff --git a/forc-plugins/forc-client/src/op/run/mod.rs b/forc-plugins/forc-client/src/op/run/mod.rs index debf0579c19..7d21d439e8c 100644 --- a/forc-plugins/forc-client/src/op/run/mod.rs +++ b/forc-plugins/forc-client/src/op/run/mod.rs @@ -267,6 +267,7 @@ fn build_opts_from_cmd(cmd: &cmd::Run) -> pkg::BuildOpts { release: cmd.build_profile.release, error_on_warnings: cmd.build_profile.error_on_warnings, time_phases: cmd.print.time_phases, + profile: cmd.print.profile, metrics_outfile: cmd.print.metrics_outfile.clone(), binary_outfile: cmd.build_output.bin_file.clone(), debug_outfile: cmd.build_output.debug_file.clone(), diff --git a/forc-test/src/lib.rs b/forc-test/src/lib.rs index c7bd19e95fd..bccc4cc0209 100644 --- a/forc-test/src/lib.rs +++ b/forc-test/src/lib.rs @@ -151,6 +151,8 @@ pub struct TestOpts { pub error_on_warnings: bool, /// Output the time elapsed over each part of the compilation process. pub time_phases: bool, + /// Profile the compilation process. + pub profile: bool, /// Output compilation metrics into file. pub metrics_outfile: Option, /// Set of enabled experimental flags @@ -453,6 +455,7 @@ impl From for pkg::BuildOpts { release: val.release, error_on_warnings: val.error_on_warnings, time_phases: val.time_phases, + profile: val.profile, metrics_outfile: val.metrics_outfile, tests: true, member_filter: Default::default(), @@ -476,6 +479,7 @@ impl TestOpts { release: self.release, error_on_warnings: self.error_on_warnings, time_phases: self.time_phases, + profile: self.profile, metrics_outfile: self.metrics_outfile, tests: true, member_filter: Default::default(), diff --git a/forc/Cargo.toml b/forc/Cargo.toml index b94be79b3cc..b3257f1ad1f 100644 --- a/forc/Cargo.toml +++ b/forc/Cargo.toml @@ -51,6 +51,7 @@ whoami.workspace = true default = [] test = [] util = [] +profile = [] [dev-dependencies] completest-pty = "0.5.0" diff --git a/forc/src/cli/commands/test.rs b/forc/src/cli/commands/test.rs index c67e9140b81..685a7d4e9bb 100644 --- a/forc/src/cli/commands/test.rs +++ b/forc/src/cli/commands/test.rs @@ -243,6 +243,7 @@ fn opts_from_cmd(cmd: Command) -> forc_test::TestOpts { reverse_order: cmd.build.print.reverse_order, }, time_phases: cmd.build.print.time_phases, + profile: cmd.build.print.profile, metrics_outfile: cmd.build.print.metrics_outfile, minify: pkg::MinifyOpts { json_abi: cmd.build.minify.json_abi, diff --git a/forc/src/cli/shared.rs b/forc/src/cli/shared.rs index 28b38465df3..23ccdd59cb9 100644 --- a/forc/src/cli/shared.rs +++ b/forc/src/cli/shared.rs @@ -99,6 +99,9 @@ pub struct Print { /// Output the time elapsed over each part of the compilation process. #[clap(long)] pub time_phases: bool, + /// Profile the compilation process. + #[clap(long)] + pub profile: bool, /// Output build errors and warnings in reverse order. #[clap(long)] pub reverse_order: bool, diff --git a/forc/src/ops/forc_build.rs b/forc/src/ops/forc_build.rs index 1118bdb5d54..2ec40cca931 100644 --- a/forc/src/ops/forc_build.rs +++ b/forc/src/ops/forc_build.rs @@ -30,6 +30,7 @@ fn opts_from_cmd(cmd: BuildCommand) -> pkg::BuildOpts { reverse_order: cmd.build.print.reverse_order, }, time_phases: cmd.build.print.time_phases, + profile: cmd.build.print.profile, metrics_outfile: cmd.build.print.metrics_outfile, minify: pkg::MinifyOpts { json_abi: cmd.build.minify.json_abi, diff --git a/forc/src/ops/forc_contract_id.rs b/forc/src/ops/forc_contract_id.rs index f80f4f5262f..9cc18edcfeb 100644 --- a/forc/src/ops/forc_contract_id.rs +++ b/forc/src/ops/forc_contract_id.rs @@ -64,6 +64,7 @@ fn build_opts_from_cmd(cmd: &ContractIdCommand) -> pkg::BuildOpts { reverse_order: cmd.print.reverse_order, }, time_phases: cmd.print.time_phases, + profile: cmd.print.profile, metrics_outfile: cmd.print.metrics_outfile.clone(), minify: pkg::MinifyOpts { json_abi: cmd.minify.json_abi, diff --git a/forc/src/ops/forc_predicate_root.rs b/forc/src/ops/forc_predicate_root.rs index 34be42c4117..41b7c5020a8 100644 --- a/forc/src/ops/forc_predicate_root.rs +++ b/forc/src/ops/forc_predicate_root.rs @@ -33,6 +33,7 @@ fn build_opts_from_cmd(cmd: PredicateRootCommand) -> pkg::BuildOpts { reverse_order: cmd.print.reverse_order, }, time_phases: cmd.print.time_phases, + profile: cmd.print.profile, metrics_outfile: cmd.print.metrics_outfile, minify: pkg::MinifyOpts { json_abi: cmd.minify.json_abi, diff --git a/sway-core/src/asm_generation/finalized_asm.rs b/sway-core/src/asm_generation/finalized_asm.rs index ce3c81e3a56..1bb66535693 100644 --- a/sway-core/src/asm_generation/finalized_asm.rs +++ b/sway-core/src/asm_generation/finalized_asm.rs @@ -19,6 +19,24 @@ use sway_types::SourceEngine; use either::Either; use std::{collections::BTreeMap, fmt}; +/// Represents an ASM set which has had register allocation, jump elimination, and optimization +/// applied to it +#[derive(Clone, serde::Serialize)] +pub struct AsmInformation { + pub bytecode_size: u64, + pub data_section: DataSectionInformation, +} + +#[derive(Default, Clone, Debug, serde::Serialize)] +pub struct DataSectionInformation { + /// The total size of the data section in bytes + pub size: u64, + /// The used size of the data section in bytes + pub used: u64, + /// The data to be put in the data section of the asm + pub value_pairs: Vec, +} + /// Represents an ASM set which has had register allocation, jump elimination, and optimization /// applied to it #[derive(Clone)] diff --git a/sway-core/src/asm_generation/fuel/data_section.rs b/sway-core/src/asm_generation/fuel/data_section.rs index 3db12443f4f..76f3300c705 100644 --- a/sway-core/src/asm_generation/fuel/data_section.rs +++ b/sway-core/src/asm_generation/fuel/data_section.rs @@ -4,7 +4,7 @@ use std::{fmt, iter::repeat}; // An entry in the data section. It's important for the size to be correct, especially for unions // where the size could be larger than the represented value. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, serde::Serialize)] pub struct Entry { pub value: Datum, pub padding: Padding, @@ -13,7 +13,7 @@ pub struct Entry { pub name: Option, } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, serde::Serialize)] pub enum Datum { Byte(u8), Word(u64), diff --git a/sway-core/src/asm_generation/mod.rs b/sway-core/src/asm_generation/mod.rs index 2cd0e7d0605..dc7be862366 100644 --- a/sway-core/src/asm_generation/mod.rs +++ b/sway-core/src/asm_generation/mod.rs @@ -8,7 +8,8 @@ pub mod fuel; pub mod instruction_set; mod finalized_asm; -pub use finalized_asm::{CompiledBytecode, FinalizedAsm, FinalizedEntry}; +pub use finalized_asm::*; +pub use fuel::data_section::{Datum, Entry}; #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum ProgramKind { diff --git a/sway-core/src/build_config.rs b/sway-core/src/build_config.rs index 711ceb014d4..4f4ad896662 100644 --- a/sway-core/src/build_config.rs +++ b/sway-core/src/build_config.rs @@ -188,6 +188,7 @@ pub struct BuildConfig { pub(crate) include_tests: bool, pub(crate) optimization_level: OptLevel, pub time_phases: bool, + pub profile: bool, pub metrics_outfile: Option, pub lsp_mode: Option, } @@ -234,6 +235,7 @@ impl BuildConfig { print_ir: PrintIr::default(), include_tests: false, time_phases: false, + profile: false, metrics_outfile: None, optimization_level: OptLevel::Opt0, lsp_mode: None, @@ -280,6 +282,10 @@ impl BuildConfig { } } + pub fn with_profile(self, a: bool) -> Self { + Self { profile: a, ..self } + } + pub fn with_metrics(self, a: Option) -> Self { Self { metrics_outfile: a, diff --git a/sway-core/src/lib.rs b/sway-core/src/lib.rs index d66b8e779eb..d59970de1b0 100644 --- a/sway-core/src/lib.rs +++ b/sway-core/src/lib.rs @@ -740,6 +740,7 @@ pub fn compile_to_ast( // Parse the program to a concrete syntax tree (CST). let parse_program_opt = time_expr!( + package_name, "parse the program to a concrete syntax tree (CST)", "parse_cst", parse(input, handler, engines, build_config, experimental), @@ -764,6 +765,7 @@ pub fn compile_to_ast( // Type check (+ other static analysis) the CST to a typed AST. let typed_res = time_expr!( + package_name, "parse the concrete syntax tree (CST) to a typed AST", "parse_ast", parsed_to_ast( @@ -980,7 +982,7 @@ pub fn compile_to_bytecode( package_name: &str, experimental: ExperimentalFeatures, ) -> Result { - let asm_res = compile_to_asm( + let mut asm_res = compile_to_asm( handler, engines, input, @@ -989,13 +991,19 @@ pub fn compile_to_bytecode( package_name, experimental, )?; - asm_to_bytecode(handler, asm_res, source_map, engines.se(), build_config) + asm_to_bytecode( + handler, + &mut asm_res, + source_map, + engines.se(), + build_config, + ) } /// Given the assembly (opcodes), compile to [CompiledBytecode], containing the asm in bytecode form. pub fn asm_to_bytecode( handler: &Handler, - mut asm: CompiledAsm, + asm: &mut CompiledAsm, source_map: &mut SourceMap, source_engine: &SourceEngine, build_config: &BuildConfig, diff --git a/sway-ir/Cargo.toml b/sway-ir/Cargo.toml index 331302af16b..c4264f9281c 100644 --- a/sway-ir/Cargo.toml +++ b/sway-ir/Cargo.toml @@ -18,6 +18,7 @@ once_cell.workspace = true peg.workspace = true prettydiff.workspace = true rustc-hash.workspace = true +serde = { version = "1.0", features = ["derive"] } slotmap.workspace = true sway-features.workspace = true sway-ir-macros.workspace = true diff --git a/sway-ir/src/irtype.rs b/sway-ir/src/irtype.rs index 1771ca954bc..dc96427d56a 100644 --- a/sway-ir/src/irtype.rs +++ b/sway-ir/src/irtype.rs @@ -642,7 +642,7 @@ impl TypeSize { /// the value in aggregates. E.g., in an array of `u8`, each `u8` is "padded" /// to its size of one byte while as a struct field, it will be right padded /// to 8 bytes. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, serde::Serialize)] pub enum Padding { Left { target_size: usize }, Right { target_size: usize }, diff --git a/sway-utils/src/performance.rs b/sway-utils/src/performance.rs index cbf53cc5510..479c229c5e3 100644 --- a/sway-utils/src/performance.rs +++ b/sway-utils/src/performance.rs @@ -14,12 +14,28 @@ pub struct PerformanceData { pub reused_programs: u64, } +#[derive(serde::Serialize, Clone)] +pub struct FunctionEntryPoint { + /// The original entry point function name. + pub fn_name: String, + /// The immediate instruction offset at which the entry function begins. + pub imm: u64, + /// The function selector (only `Some` for contract ABI methods). + pub selector: Option<[u8; 4]>, +} + #[macro_export] // Time the given expression and print/save the result. macro_rules! time_expr { - ($description:expr, $key:expr, $expression:expr, $build_config:expr, $data:expr) => {{ + ($pkg_name:expr, $description:expr, $key:expr, $expression:expr, $build_config:expr, $data:expr) => {{ + use std::io::{BufRead, Read, Write}; if let Some(cfg) = $build_config { - if cfg.time_phases || cfg.metrics_outfile.is_some() { + if cfg.profile { + println!("/dyno start {} {}", $pkg_name, $description); + let output = { $expression }; + println!("/dyno stop {} {}", $pkg_name, $description); + output + } else if cfg.time_phases || cfg.metrics_outfile.is_some() { let expr_start = std::time::Instant::now(); let output = { $expression }; let elapsed = expr_start.elapsed(); From 3b07f499c2a23934359c5d7585a48d9f5fc0f447 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ron=C4=8Devi=C4=87?= Date: Fri, 15 Nov 2024 04:46:56 +0100 Subject: [PATCH 113/115] Storage domains (#6466) ## Description This PR fixes #6317 by implementing `storage_domains` experimental feature. This feature introduces two _storage domains_, one for the storage fields defined inside of the `storage` declaration, and a different one for storage slots generated inside of the `StorageMap`. The PR strictly fixes the issue described in #6317 by applying the recommendation proposed in the issue. A general approach to storage key domains will be discussed as a part of the [Configurable and composable storage RFC](https://github.com/FuelLabs/sway-rfcs/pull/40). Additionally, the PR: - adds expressive diagnostics for the duplicated storage keys warning. - removes the misleading internal compiler error that always followed the storage key type mismatch error (see demo below). Closes #6317, #6701. ## Breaking Changes The PR changes the way how storage keys are generated for `storage` fields. Instead of `sha256("storage::ns1::ns2.field_name")` we now use `sha256((0u8, "storage::ns1::ns2.field_name"))`. This is a breaking change for those who relied on the storage key calculation. ## Demo Before, every type-mismatch was always followed by an ICE, because the compilation continued despite the type-mismatch. ![Mismatched types and ICE - Before](https://github.com/user-attachments/assets/ac7915f7-3458-409e-a2bb-118dd4925234) This is solved now, and the type-mismatch has a dedicated help message. ![Mismatched types and ICE - After](https://github.com/user-attachments/assets/570aedd3-4c9c-4945-bfd0-5f12d68dbead) ## 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: Sophie Dankel <47993817+sdankel@users.noreply.github.com> Co-authored-by: IGI-111 --- sway-core/src/ir_generation/function.rs | 11 +- sway-core/src/ir_generation/storage.rs | 73 +- .../src/language/ty/declaration/storage.rs | 20 +- .../ast_node/declaration/declaration.rs | 34 +- .../ast_node/declaration/storage.rs | 42 +- .../typed_expression/enum_instantiation.rs | 6 +- .../typed_expression/struct_instantiation.rs | 6 +- sway-error/src/warning.rs | 70 +- sway-features/src/lib.rs | 3 + sway-ir/tests/tests.rs | 2 + sway-lib-std/src/storage/storage_map.sw | 34 +- sway-utils/src/constants.rs | 3 +- test/src/e2e_vm_tests/harness.rs | 64 +- test/src/e2e_vm_tests/mod.rs | 22 +- .../should_fail/invalid_cfg_arg/stdout.snap | 2 +- .../Forc.lock | 8 + .../Forc.toml | 9 + .../src/main.sw | 9 + .../test.toml | 17 + .../duplicated_storage_keys/src/main.sw | 14 +- .../test.storage_domains.toml | 30 + .../duplicated_storage_keys/test.toml | 34 +- .../call_basic_storage/src/main.sw | 2 +- .../call_storage_enum/src/main.sw | 2 +- .../storage_slot_key_calculation/Forc.lock | 13 + .../storage_slot_key_calculation/Forc.toml | 8 + .../storage_slot_key_calculation/src/main.sw | 53 ++ .../test.storage_domains.toml | 1 + .../storage_slot_key_calculation/test.toml | 2 + .../json_abi_oracle.storage_domains.json | 297 +++++++ ..._storage_slots_oracle.storage_domains.json | 58 ++ .../test_contracts/basic_storage/src/main.sw | 2 - .../basic_storage/test.storage_domains.toml | 1 + .../test_contracts/basic_storage/test.toml | 2 +- .../json_abi_oracle.storage_domains.json | 102 +++ ..._storage_slots_oracle.storage_domains.json | 6 + .../test.storage_domains.toml | 1 + .../json_abi_oracle.storage_domains.json | 769 ++++++++++++++++++ ..._storage_slots_oracle.storage_domains.json | 74 ++ .../test.storage_domains.toml | 1 + .../json_abi_oracle.storage_domains.json | 31 + ..._storage_slots_oracle.storage_domains.json | 62 ++ .../storage_enum_contract/src/main.sw | 12 - .../test.storage_domains.toml | 1 + .../json_abi_oracle.storage_domains.json | 289 +++++++ ..._storage_slots_oracle.storage_domains.json | 54 ++ .../test.storage_domains.toml | 1 + .../storage_namespace/test.toml | 2 +- test/src/ir_generation/mod.rs | 4 +- 49 files changed, 2236 insertions(+), 127 deletions(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/storage_invalid_storage_key_type/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/storage_invalid_storage_key_type/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/storage_invalid_storage_key_type/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/storage_invalid_storage_key_type/test.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/duplicated_storage_keys/test.storage_domains.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/storage_slot_key_calculation/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/storage_slot_key_calculation/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/storage_slot_key_calculation/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/storage_slot_key_calculation/test.storage_domains.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/storage_slot_key_calculation/test.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/basic_storage/json_abi_oracle.storage_domains.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/basic_storage/json_storage_slots_oracle.storage_domains.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/basic_storage/test.storage_domains.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/increment_contract/json_abi_oracle.storage_domains.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/increment_contract/json_storage_slots_oracle.storage_domains.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/increment_contract/test.storage_domains.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_access_contract/json_abi_oracle.storage_domains.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_access_contract/json_storage_slots_oracle.storage_domains.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_access_contract/test.storage_domains.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_enum_contract/json_abi_oracle.storage_domains.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_enum_contract/json_storage_slots_oracle.storage_domains.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_enum_contract/test.storage_domains.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_namespace/json_abi_oracle.storage_domains.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_namespace/json_storage_slots_oracle.storage_domains.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_namespace/test.storage_domains.toml diff --git a/sway-core/src/ir_generation/function.rs b/sway-core/src/ir_generation/function.rs index f3a7064568e..4171056c2e7 100644 --- a/sway-core/src/ir_generation/function.rs +++ b/sway-core/src/ir_generation/function.rs @@ -4338,6 +4338,14 @@ impl<'eng> FnCompiler<'eng> { base_type: &Type, span_md_idx: Option, ) -> Result { + // Use the `struct_field_names` to get a field id that is unique even for zero-sized values that live in the same slot. + // We calculate the `unique_field_id` early, here, before the `storage_filed_names` get consumed by `get_storage_key` below. + let unique_field_id = get_storage_field_id( + &storage_field_names, + &struct_field_names, + context.experimental, + ); + // Get the actual storage key as a `Bytes32` as well as the offset, in words, // within the slot. The offset depends on what field of the top level storage // variable is being accessed. @@ -4371,7 +4379,7 @@ impl<'eng> FnCompiler<'eng> { // particular slot is the remaining offset, in words. ( add_to_b256( - get_storage_key(storage_field_names.clone(), key.clone()), + get_storage_key(storage_field_names, key, context.experimental), offset_in_slots, ), offset_remaining, @@ -4428,7 +4436,6 @@ impl<'eng> FnCompiler<'eng> { .add_metadatum(context, span_md_idx); // Store the field identifier as the third field in the `StorageKey` struct - let unique_field_id = get_storage_field_id(storage_field_names, struct_field_names); // use the struct_field_names to get a field id that is unique even for zero-sized values that live in the same slot let field_id = convert_literal_to_value(context, &Literal::B256(unique_field_id.into())) .add_metadatum(context, span_md_idx); let gep_2_val = diff --git a/sway-core/src/ir_generation/storage.rs b/sway-core/src/ir_generation/storage.rs index 14fd2b8ef00..4f42a74a2e8 100644 --- a/sway-core/src/ir_generation/storage.rs +++ b/sway-core/src/ir_generation/storage.rs @@ -3,6 +3,7 @@ use crate::fuel_prelude::{ fuel_tx::StorageSlot, fuel_types::{Bytes32, Bytes8}, }; +use sway_features::ExperimentalFeatures; use sway_ir::{ constant::{Constant, ConstantValue}, context::Context, @@ -20,28 +21,31 @@ enum InByte8Padding { } /// Hands out storage keys using storage field names or an existing key. -/// Basically returns sha256("storage::::.") +/// Basically returns sha256((0u8, "storage::::.")) /// or key if defined. -pub(super) fn get_storage_key(storage_field_names: Vec, key: Option) -> Bytes32 { - if let Some(key) = key { - return key.to_be_bytes().into(); +pub(super) fn get_storage_key( + storage_field_names: Vec, + key: Option, + experimental: ExperimentalFeatures, +) -> Bytes32 { + match key { + Some(key) => key.to_be_bytes().into(), + None => hash_storage_key_string(get_storage_key_string(&storage_field_names), experimental), } - - Hasher::hash(get_storage_key_string(storage_field_names)) } -pub fn get_storage_key_string(storage_field_names: Vec) -> String { +pub fn get_storage_key_string(storage_field_names: &[String]) -> String { if storage_field_names.len() == 1 { format!( "{}{}{}", - sway_utils::constants::STORAGE_DOMAIN, + sway_utils::constants::STORAGE_TOP_LEVEL_NAMESPACE, sway_utils::constants::STORAGE_FIELD_SEPARATOR, storage_field_names.last().unwrap(), ) } else { format!( "{}{}{}{}{}", - sway_utils::constants::STORAGE_DOMAIN, + sway_utils::constants::STORAGE_TOP_LEVEL_NAMESPACE, sway_utils::constants::STORAGE_NAMESPACE_SEPARATOR, storage_field_names .iter() @@ -56,10 +60,11 @@ pub fn get_storage_key_string(storage_field_names: Vec) -> String { } /// Hands out unique storage field ids using storage field names and struct field names. -/// Basically returns sha256("storage::::...") +/// Basically returns sha256((0u8, "storage::::...")). pub(super) fn get_storage_field_id( - storage_field_names: Vec, - struct_field_names: Vec, + storage_field_names: &[String], + struct_field_names: &[String], + experimental: ExperimentalFeatures, ) -> Bytes32 { let data = format!( "{}{}", @@ -74,7 +79,32 @@ pub(super) fn get_storage_field_id( ) } ); - Hasher::hash(data) + + hash_storage_key_string(data, experimental) +} + +fn hash_storage_key_string( + storage_key_string: String, + experimental: ExperimentalFeatures, +) -> Bytes32 { + let mut hasher = Hasher::default(); + // Certain storage types, like, e.g., `StorageMap` allow + // storage slots of their contained elements to be defined + // based on developer's input. E.g., the `key` in a `StorageMap` + // used to calculate the storage slot is a developer input. + // + // To ensure that pre-images of such storage slots can never + // be the same as a pre-image of compiler generated key of storage + // field, we prefix the pre-images with a single byte that denotes + // the domain. Storage types like `StorageMap` must have a different + // domain prefix than the `STORAGE_DOMAIN` which is 0u8. + // + // For detailed elaboration see: https://github.com/FuelLabs/sway/issues/6317 + if experimental.storage_domains { + hasher.input(sway_utils::constants::STORAGE_DOMAIN); + } + hasher.input(storage_key_string); + hasher.finalize() } use uint::construct_uint; @@ -109,17 +139,18 @@ pub fn serialize_to_storage_slots( key: Option, ty: &Type, ) -> Vec { + let experimental = context.experimental; match &constant.value { ConstantValue::Undef => vec![], // If not being a part of an aggregate, single byte values like `bool`, `u8`, and unit // are stored as a byte at the beginning of the storage slot. ConstantValue::Unit if ty.is_unit(context) => vec![StorageSlot::new( - get_storage_key(storage_field_names, key), + get_storage_key(storage_field_names, key, experimental), Bytes32::new([0; 32]), )], ConstantValue::Bool(b) if ty.is_bool(context) => { vec![StorageSlot::new( - get_storage_key(storage_field_names, key), + get_storage_key(storage_field_names, key, experimental), Bytes32::new([ if *b { 1 } else { 0 }, 0, @@ -158,7 +189,7 @@ pub fn serialize_to_storage_slots( } ConstantValue::Uint(b) if ty.is_uint8(context) => { vec![StorageSlot::new( - get_storage_key(storage_field_names, key), + get_storage_key(storage_field_names, key, experimental), Bytes32::new([ *b as u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -168,7 +199,7 @@ pub fn serialize_to_storage_slots( // Similarly, other uint values are stored at the beginning of the storage slot. ConstantValue::Uint(n) if ty.is_uint(context) => { vec![StorageSlot::new( - get_storage_key(storage_field_names, key), + get_storage_key(storage_field_names, key, experimental), Bytes32::new( n.to_be_bytes() .iter() @@ -182,13 +213,13 @@ pub fn serialize_to_storage_slots( } ConstantValue::U256(b) if ty.is_uint_of(context, 256) => { vec![StorageSlot::new( - get_storage_key(storage_field_names, key), + get_storage_key(storage_field_names, key, experimental), Bytes32::new(b.to_be_bytes()), )] } ConstantValue::B256(b) if ty.is_b256(context) => { vec![StorageSlot::new( - get_storage_key(storage_field_names, key), + get_storage_key(storage_field_names, key, experimental), Bytes32::new(b.to_be_bytes()), )] } @@ -224,8 +255,10 @@ pub fn serialize_to_storage_slots( type_size_in_bytes, ty.as_string(context) ); + + let storage_key = get_storage_key(storage_field_names, key, experimental); (0..(type_size_in_bytes + 31) / 32) - .map(|i| add_to_b256(get_storage_key(storage_field_names.clone(), key.clone()), i)) + .map(|i| add_to_b256(storage_key, i)) .zip((0..packed.len() / 4).map(|i| { Bytes32::new( Vec::from_iter((0..4).flat_map(|j| *packed[4 * i + j])) diff --git a/sway-core/src/language/ty/declaration/storage.rs b/sway-core/src/language/ty/declaration/storage.rs index 23e4b7a09ba..abc5a67b20c 100644 --- a/sway-core/src/language/ty/declaration/storage.rs +++ b/sway-core/src/language/ty/declaration/storage.rs @@ -8,8 +8,10 @@ use sway_types::{Ident, Named, Span, Spanned}; use crate::{ engine_threading::*, - language::{parsed::StorageDeclaration, ty::*}, + ir_generation::storage::get_storage_key_string, + language::parsed::StorageDeclaration, transform::{self}, + ty::*, type_system::*, Namespace, }; @@ -252,6 +254,22 @@ pub struct TyStorageField { pub attributes: transform::AttributesMap, } +impl TyStorageField { + /// Returns the full name of the [TyStorageField], consisting + /// of its name preceded by its full namespace path. + /// E.g., "storage::ns1::ns1.name". + pub fn full_name(&self) -> String { + get_storage_key_string( + &self + .namespace_names + .iter() + .map(|i| i.as_str().to_string()) + .chain(vec![self.name.as_str().to_string()]) + .collect::>(), + ) + } +} + impl EqWithEngines for TyStorageField {} impl PartialEqWithEngines for TyStorageField { fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool { diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/declaration.rs b/sway-core/src/semantic_analysis/ast_node/declaration/declaration.rs index 0f965bd0d4e..b063fd53028 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/declaration.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/declaration.rs @@ -441,22 +441,32 @@ impl TyDecl { let initializer = ty::TyExpression::type_check(handler, ctx.by_ref(), &initializer)?; - let mut key_ty_expression = None; - if let Some(key_expression) = key_expression { - let mut key_ctx = - ctx.with_type_annotation(engines.te().id_of_b256()); - - key_ty_expression = Some(ty::TyExpression::type_check( - handler, - key_ctx.by_ref(), - &key_expression, - )?); - } + let key_expression = match key_expression { + Some(key_expression) => { + let key_ctx = ctx + .with_type_annotation(engines.te().id_of_b256()) + .with_help_text("Storage keys must have type \"b256\"."); + + // TODO: Remove the `handler.scope` once https://github.com/FuelLabs/sway/issues/5606 gets solved. + // We need it here so that we can short-circuit in case of a `TypeMismatch` error which is + // not treated as an error in the `type_check()`'s result. + let typed_expr = handler.scope(|handler| { + ty::TyExpression::type_check( + handler, + key_ctx, + &key_expression, + ) + })?; + + Some(typed_expr) + } + None => None, + }; fields_buf.push(ty::TyStorageField { name, namespace_names: namespace_names.clone(), - key_expression: key_ty_expression, + key_expression, type_argument, initializer, span: field_span, diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/storage.rs b/sway-core/src/semantic_analysis/ast_node/declaration/storage.rs index 08e0984b7ed..7df2bb722d4 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/storage.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/storage.rs @@ -4,8 +4,7 @@ use crate::{ decl_engine::parsed_id::ParsedDeclId, fuel_prelude::fuel_tx::StorageSlot, ir_generation::{ - const_eval::compile_constant_expression_to_constant, - storage::{get_storage_key_string, serialize_to_storage_slots}, + const_eval::compile_constant_expression_to_constant, storage::serialize_to_storage_slots, }, language::{ parsed::StorageDeclaration, @@ -54,32 +53,27 @@ impl ty::TyStorageDecl { let slots = f.get_initialized_storage_slots(engines, context, md_mgr, module); // Check if slot with same key was already used and throw warning. - if let Ok(slots) = slots.clone() { - for s in slots.into_iter() { + if let Ok(slots) = &slots { + for s in slots.iter() { if let Some(old_field) = slot_fields.insert(*s.key(), f.clone()) { handler.emit_warn(CompileWarning { span: f.span(), warning_content: sway_error::warning::Warning::DuplicatedStorageKey { - key: format!("{:X} ", s.key()), - field1: get_storage_key_string( - old_field - .namespace_names - .iter() - .map(|i| i.as_str().to_string()) - .chain(vec![old_field - .name - .as_str() - .to_string()]) - .collect::>(), - ), - field2: get_storage_key_string( - f.namespace_names - .iter() - .map(|i| i.as_str().to_string()) - .chain(vec![f.name.as_str().to_string()]) - .collect::>(), - ), + first_field: (&old_field.name).into(), + first_field_full_name: old_field.full_name(), + first_field_key_is_compiler_generated: old_field + .key_expression + .is_none(), + second_field: (&f.name).into(), + second_field_full_name: f.full_name(), + second_field_key_is_compiler_generated: f + .key_expression + .is_none(), + key: format!("0x{:x}", s.key()), + experimental_storage_domains: context + .experimental + .storage_domains, }, }) } @@ -151,7 +145,7 @@ impl ty::TyStorageField { Ok(Some(key)) } else { Err(CompileError::Internal( - "Expected B256 key", + "Storage keys must have type \"b256\".", key_expression.span.clone(), )) } diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/enum_instantiation.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/enum_instantiation.rs index 4da63001bb4..742cadb1691 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/enum_instantiation.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/enum_instantiation.rs @@ -136,9 +136,9 @@ pub(crate) fn instantiate_enum( .with_help_text(help_text) .with_type_annotation(enum_variant_type_id); - // TODO-IG: Remove the `handler.scope` once https://github.com/FuelLabs/sway/issues/5606 gets solved. - // We need it here so that we can short-circuit in case of a `TypeMismatch` error which is - // not treated as an error in the `type_check()`'s result. + // TODO: Remove the `handler.scope` once https://github.com/FuelLabs/sway/issues/5606 gets solved. + // We need it here so that we can short-circuit in case of a `TypeMismatch` error which is + // not treated as an error in the `type_check()`'s result. let typed_expr = handler .scope(|handler| ty::TyExpression::type_check(handler, enum_ctx, single_expr))?; diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_instantiation.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_instantiation.rs index 47c190a0c2b..bf52842ea81 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_instantiation.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_instantiation.rs @@ -397,9 +397,9 @@ fn type_check_field_arguments( .with_type_annotation(struct_field.type_argument.type_id) .with_unify_generic(true); - // TODO-IG: Remove the `handler.scope` once https://github.com/FuelLabs/sway/issues/5606 gets solved. - // We need it here so that we can short-circuit in case of a `TypeMismatch` error which is - // not treated as an error in the `type_check()`'s result. + // TODO: Remove the `handler.scope` once https://github.com/FuelLabs/sway/issues/5606 gets solved. + // We need it here so that we can short-circuit in case of a `TypeMismatch` error which is + // not treated as an error in the `type_check()`'s result. let typed_expr = handler .scope(|handler| ty::TyExpression::type_check(handler, ctx, &field.value)); diff --git a/sway-error/src/warning.rs b/sway-error/src/warning.rs index 78a4ac8953b..dce69c85805 100644 --- a/sway-error/src/warning.rs +++ b/sway-error/src/warning.rs @@ -1,4 +1,7 @@ -use crate::diagnostic::{Code, Diagnostic, Hint, Issue, Reason, ToDiagnostic}; +use crate::{ + diagnostic::{Code, Diagnostic, Hint, Issue, Reason, ToDiagnostic}, + formatting::Indent, +}; use core::fmt; @@ -128,9 +131,15 @@ pub enum Warning { message: String, }, DuplicatedStorageKey { + first_field: IdentUnique, + first_field_full_name: String, + first_field_key_is_compiler_generated: bool, + second_field: IdentUnique, + second_field_full_name: String, + second_field_key_is_compiler_generated: bool, key: String, - field1: String, - field2: String, + // True if the experimental feature `storage_domains` is used. + experimental_storage_domains: bool, }, } @@ -279,7 +288,8 @@ impl fmt::Display for Warning { You can enable the new behavior with the --experimental-private-modules flag, which will become the default behavior in a later release. More details are available in the related RFC: https://github.com/FuelLabs/sway-rfcs/blob/master/rfcs/0008-private-modules.md"), UsingDeprecated { message } => write!(f, "{}", message), - DuplicatedStorageKey { key, field1, field2 } => write!(f, "Two storage fields are using the same storage key.\nFirst field: {field1}\nSecond field: {field2}\nKey: {key}"), + DuplicatedStorageKey { first_field_full_name, second_field_full_name, key, .. } => + write!(f, "Two storage fields have the same storage key.\nFirst field: {first_field_full_name}\nSecond field: {second_field_full_name}\nKey: {key}"), } } } @@ -412,6 +422,58 @@ impl ToDiagnostic for CompileWarning { "Consider adding assembly instructions or a return register to the ASM block, or removing the block altogether.".to_string(), ], }, + DuplicatedStorageKey { first_field, first_field_full_name, first_field_key_is_compiler_generated, second_field, second_field_full_name, second_field_key_is_compiler_generated, key, experimental_storage_domains } => Diagnostic { + reason: Some(Reason::new(code(1), "Two storage fields have the same storage key".to_string())), + issue: Issue::warning( + source_engine, + first_field.span(), + format!("\"{first_field_full_name}\" has the same storage key as \"{second_field_full_name}\"."), + ), + hints: vec![ + Hint::info( + source_engine, + second_field.span(), + format!("\"{second_field_full_name}\" is declared here."), + ), + ], + help: vec![ + if *first_field_key_is_compiler_generated || *second_field_key_is_compiler_generated { + format!("The key of \"{}\" is generated by the compiler using the following formula:", + if *first_field_key_is_compiler_generated { + first_field_full_name + } else { + second_field_full_name + } + ) + } else { + "Both keys are explicitly defined by using the `in` keyword.".to_string() + }, + if *first_field_key_is_compiler_generated || *second_field_key_is_compiler_generated { + if *experimental_storage_domains { + format!("{}sha256((0u8, \"{}\"))", + Indent::Single, + if *first_field_key_is_compiler_generated { + first_field_full_name + } else { + second_field_full_name + } + ) + } else { + format!("{}sha256(\"{}\")", + Indent::Single, + if *first_field_key_is_compiler_generated { + first_field_full_name + } else { + second_field_full_name + } + ) + } + } else { + Diagnostic::help_none() + }, + format!("The common key is: {key}.") + ], + }, _ => Diagnostic { // TODO: Temporary we use self here to achieve backward compatibility. // In general, self must not be used and will not be used once we diff --git a/sway-features/src/lib.rs b/sway-features/src/lib.rs index 55d50920891..fdff644741a 100644 --- a/sway-features/src/lib.rs +++ b/sway-features/src/lib.rs @@ -131,6 +131,8 @@ impl ExperimentalFeatures { features! { new_encoding = true, "https://github.com/FuelLabs/sway/issues/5727", + storage_domains = false, + "https://github.com/FuelLabs/sway/issues/6701", } #[derive(Clone, Debug, Default, Parser)] @@ -228,6 +230,7 @@ mod tests { let mut features = ExperimentalFeatures { new_encoding: false, + ..Default::default() }; std::env::set_var("FORC_EXPERIMENTAL", "new_encoding"); diff --git a/sway-ir/tests/tests.rs b/sway-ir/tests/tests.rs index 743b3523977..5e6ccaeaa8f 100644 --- a/sway-ir/tests/tests.rs +++ b/sway-ir/tests/tests.rs @@ -29,6 +29,8 @@ fn run_tests bool>(sub_dir: &str, opt_fn: F) { let experimental = ExperimentalFeatures { new_encoding: false, + // TODO: Properly support experimental features in IR tests. + ..Default::default() }; let mut ir = sway_ir::parser::parse(&input, &source_engine, experimental).unwrap_or_else( diff --git a/sway-lib-std/src/storage/storage_map.sw b/sway-lib-std/src/storage/storage_map.sw index 360ed95ade3..4d7aca969ae 100644 --- a/sway-lib-std/src/storage/storage_map.sw +++ b/sway-lib-std/src/storage/storage_map.sw @@ -6,6 +6,22 @@ use ::result::Result; use ::storage::storage_api::*; use ::storage::storage_key::*; +/// The storage domain value of the [StorageMap]. +/// +/// Storage slots of elements contained within a [StorageMap] +/// are calculated based on developers' or users' input (the key). +/// +/// To ensure that pre-images used to calculate storage slots can never +/// be the same as a pre-image of a compiler generated key of a storage +/// field, we prefix the pre-images with a single byte that denotes +/// the storage map domain. +/// +/// The domain prefix for the [StorageMap] is 1u8. +/// +/// For detailed elaboration see: https://github.com/FuelLabs/sway/issues/6317 +#[cfg(experimental_storage_domains = true)] +const STORAGE_MAP_DOMAIN: u8 = 1; + /// Errors pertaining to the `StorageMap` struct. pub enum StorageMapError { /// Indicates that a value already exists for the key. @@ -51,7 +67,7 @@ where where K: Hash, { - let key = sha256((key, self.field_id())); + let key = self.get_slot_key(key); write::(key, 0, value); } @@ -85,7 +101,7 @@ where where K: Hash, { - let key = sha256((key, self.field_id())); + let key = self.get_slot_key(key); StorageKey::::new(key, 0, key) } @@ -124,7 +140,7 @@ where where K: Hash, { - let key = sha256((key, self.field_id())); + let key = self.get_slot_key(key); clear::(key, 0) } @@ -175,7 +191,7 @@ where where K: Hash, { - let key = sha256((key, self.field_id())); + let key = self.get_slot_key(key); let val = read::(key, 0); @@ -189,4 +205,14 @@ where } } } + + #[cfg(experimental_storage_domains = false)] + fn get_slot_key(self, key: K) -> b256 { + sha256((key, self.field_id())) + } + + #[cfg(experimental_storage_domains = true)] + fn get_slot_key(self, key: K) -> b256 { + sha256((STORAGE_MAP_DOMAIN, key, self.field_id())) + } } diff --git a/sway-utils/src/constants.rs b/sway-utils/src/constants.rs index 00214945ed5..c0f8b6938a9 100644 --- a/sway-utils/src/constants.rs +++ b/sway-utils/src/constants.rs @@ -7,7 +7,8 @@ pub const USER_FORC_DIRECTORY: &str = ".forc"; pub const SRC_DIR: &str = "src"; pub const DEFAULT_NODE_URL: &str = "http://127.0.0.1:4000"; pub const LANGUAGE_NAME: &str = "Sway"; -pub const STORAGE_DOMAIN: &str = "storage"; +pub const STORAGE_DOMAIN: [u8; 1] = [0u8]; +pub const STORAGE_TOP_LEVEL_NAMESPACE: &str = "storage"; pub const STORAGE_NAMESPACE_SEPARATOR: &str = "::"; pub const STORAGE_FIELD_SEPARATOR: &str = "."; pub const STRUCT_FIELD_SEPARATOR: &str = "."; diff --git a/test/src/e2e_vm_tests/harness.rs b/test/src/e2e_vm_tests/harness.rs index 164d442e7bf..31dbcda4b48 100644 --- a/test/src/e2e_vm_tests/harness.rs +++ b/test/src/e2e_vm_tests/harness.rs @@ -398,22 +398,28 @@ pub(crate) fn test_json_abi( } if fs::metadata(oracle_path.clone()).is_err() { - bail!("JSON ABI oracle file does not exist for this test."); + bail!( + "JSON ABI oracle file does not exist for this test\nExpected oracle path: {}", + &oracle_path + ); } if fs::metadata(output_path.clone()).is_err() { - bail!("JSON ABI output file does not exist for this test."); + bail!( + "JSON ABI output file does not exist for this test\nExpected output path: {}", + &output_path + ); } - let oracle_contents = - fs::read_to_string(&oracle_path).expect("Something went wrong reading the file."); - let output_contents = - fs::read_to_string(&output_path).expect("Something went wrong reading the file."); + let oracle_contents = fs::read_to_string(&oracle_path) + .expect("Something went wrong reading the JSON ABI oracle file."); + let output_contents = fs::read_to_string(&output_path) + .expect("Something went wrong reading the JSON ABI output file."); if oracle_contents != output_contents { - println!("Mismatched ABI JSON output [{oracle_path}] versus [{output_path}]",); - println!( - "{}", + bail!( + "Mismatched ABI JSON output.\nOracle path: {}\nOutput path: {}\n{}", + oracle_path, + output_path, prettydiff::diff_lines(&oracle_contents, &output_contents) ); - bail!("Mismatched ABI JSON output."); } Ok(()) } @@ -435,29 +441,47 @@ fn emit_json_abi(file_name: &str, built_package: &BuiltPackage) -> Result<()> { Ok(()) } -pub(crate) fn test_json_storage_slots(file_name: &str, built_package: &BuiltPackage) -> Result<()> { +pub(crate) fn test_json_storage_slots( + file_name: &str, + built_package: &BuiltPackage, + suffix: &Option, +) -> Result<()> { emit_json_storage_slots(file_name, built_package)?; let manifest_dir = env!("CARGO_MANIFEST_DIR"); let oracle_path = format!( - "{}/src/e2e_vm_tests/test_programs/{}/{}", - manifest_dir, file_name, "json_storage_slots_oracle.json" + "{}/src/e2e_vm_tests/test_programs/{}/json_storage_slots_oracle.{}json", + manifest_dir, + file_name, + suffix + .as_ref() + .unwrap() + .strip_prefix("test") + .unwrap() + .strip_suffix("toml") + .unwrap() + .trim_start_matches('.') ); let output_path = format!( "{}/src/e2e_vm_tests/test_programs/{}/{}", manifest_dir, file_name, "json_storage_slots_output.json" ); if fs::metadata(oracle_path.clone()).is_err() { - bail!("JSON storage slots oracle file does not exist for this test."); + bail!("JSON storage slots oracle file does not exist for this test.\nExpected oracle path: {}", &oracle_path); } if fs::metadata(output_path.clone()).is_err() { - bail!("JSON storage slots output file does not exist for this test."); + bail!("JSON storage slots output file does not exist for this test.\nExpected output path: {}", &output_path); } - let oracle_contents = - fs::read_to_string(oracle_path).expect("Something went wrong reading the file."); - let output_contents = - fs::read_to_string(output_path).expect("Something went wrong reading the file."); + let oracle_contents = fs::read_to_string(oracle_path.clone()) + .expect("Something went wrong reading the JSON storage slots oracle file."); + let output_contents = fs::read_to_string(output_path.clone()) + .expect("Something went wrong reading the JSON storage slots output file."); if oracle_contents != output_contents { - bail!("Mismatched storage slots JSON output."); + bail!( + "Mismatched storage slots JSON output.\nOracle path: {}\nOutput path: {}\n{}", + oracle_path, + output_path, + prettydiff::diff_lines(&oracle_contents, &output_contents) + ); } Ok(()) } diff --git a/test/src/e2e_vm_tests/mod.rs b/test/src/e2e_vm_tests/mod.rs index 62dc360fea1..725056b9ac7 100644 --- a/test/src/e2e_vm_tests/mod.rs +++ b/test/src/e2e_vm_tests/mod.rs @@ -515,7 +515,7 @@ impl TestContext { if validate_storage_slots { for (name, built_pkg) in &compiled_pkgs { let (result, out) = run_and_capture_output(|| async { - harness::test_json_storage_slots(name, built_pkg) + harness::test_json_storage_slots(name, built_pkg, &suffix) }) .await; result?; @@ -602,7 +602,15 @@ impl TestContext { ))); } } - _ => todo!(), + TestResult::ReturnData(_) => { + todo!("Test result `ReturnData` is currently not implemented.") + } + TestResult::Return(_) => { + todo!("Test result `Return` is currently not implemented.") + } + TestResult::Revert(_) => { + todo!("Test result `Revert` is currently not implemented.") + } }, Receipt::ReturnData { data, .. } => match expected_result.unwrap() { TestResult::ReturnData(v) => { @@ -612,7 +620,15 @@ impl TestContext { ))); } } - _ => todo!(), + TestResult::Result(_) => { + todo!("Test result `Result` is currently not implemented.") + } + TestResult::Return(_) => { + todo!("Test result `Return` is currently not implemented.") + } + TestResult::Revert(_) => { + todo!("Test result `Revert` is currently not implemented.") + } }, _ => {} }; diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/stdout.snap index fee2b903ecd..84c0fa58caf 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_fail/invalid_cfg_arg/stdout.snap @@ -11,7 +11,7 @@ warning | 1 | predicate; 2 | #[cfg(c)] a - | --- Unexpected attribute value: "c" for attribute: "cfg" expected value "target" or "program_type" or "experimental_new_encoding" + | --- Unexpected attribute value: "c" for attribute: "cfg" expected value "target" or "program_type" or "experimental_new_encoding" or "experimental_storage_domains" | ____ diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/storage_invalid_storage_key_type/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_fail/storage_invalid_storage_key_type/Forc.lock new file mode 100644 index 00000000000..6024e958c64 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/storage_invalid_storage_key_type/Forc.lock @@ -0,0 +1,8 @@ +[[package]] +name = "core" +source = "path+from-root-C0C563B172E50A8D" + +[[package]] +name = "storage_invalid_storage_key_type" +source = "member" +dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/storage_invalid_storage_key_type/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/storage_invalid_storage_key_type/Forc.toml new file mode 100644 index 00000000000..18a5527966d --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/storage_invalid_storage_key_type/Forc.toml @@ -0,0 +1,9 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "storage_invalid_storage_key_type" +implicit-std = false + +[dependencies] +core = { path = "../../../../../../sway-lib-core" } diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/storage_invalid_storage_key_type/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/storage_invalid_storage_key_type/src/main.sw new file mode 100644 index 00000000000..18a4f599f52 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/storage_invalid_storage_key_type/src/main.sw @@ -0,0 +1,9 @@ +contract; + +fn get_u256() -> u256 { + 0x0u256 +} + +storage { + field in get_u256(): u64 = 0, +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/storage_invalid_storage_key_type/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/storage_invalid_storage_key_type/test.toml new file mode 100644 index 00000000000..150a184e449 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/storage_invalid_storage_key_type/test.toml @@ -0,0 +1,17 @@ +category = "fail" + +#check: $()error +#check: $()field in get_u256(): u64 = 0, +#nextln: $()Mismatched types. +#nextln: $()expected: b256 +#nextln: $()found: u256. +#nextln: $()Function return type does not match up with local type annotation. + +#check: $()error +#check: $()field in get_u256(): u64 = 0, +#nextln: $()Mismatched types. +#nextln: $()expected: b256 +#nextln: $()found: u256. +#nextln: $()Storage keys must have type "b256". + +#check: $()2 errors. \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/duplicated_storage_keys/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/duplicated_storage_keys/src/main.sw index 54c8ccf3246..2bfa29631e6 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/duplicated_storage_keys/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/duplicated_storage_keys/src/main.sw @@ -2,12 +2,24 @@ contract; storage { f1:u64 = 1, + #[cfg(experimental_storage_domains = true)] + f2 in 0xcecf0a910789de762c699a85a66835df1662df633238cbb25804b7f78640747b: u64 = 2, + #[cfg(experimental_storage_domains = false)] f2 in 0x36389d1013642dcb070193fc48b0316e9dfdfef1860096dc5957e3eb44430b83: u64 = 2, ns1 { f3 in 0x5f4c20ce4bd128e5393a4c2b82007dac795fa0006d01acf8db4c42632bc680ca: u64 = 2, }, ns2 { f4 in 0x5f4c20ce4bd128e5393a4c2b82007dac795fa0006d01acf8db4c42632bc680ca: u64 = 2, - } + }, + ns3 { + #[cfg(experimental_storage_domains = true)] + f5 in 0x41e70e0fdfa49becc40cbfd5c057ab0540e8844f3d737fa3b1ab21a564b48069: u64 = 3, + #[cfg(experimental_storage_domains = false)] + f5 in 0xa49ebab6739a90f7658bbbdc2ed139942bd0b7be2e89aa8d90a953c45bf7a211: u64 = 3, + }, + ns4 { + f6: u64 = 4, + }, } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/duplicated_storage_keys/test.storage_domains.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/duplicated_storage_keys/test.storage_domains.toml new file mode 100644 index 00000000000..4e181f7e13d --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/duplicated_storage_keys/test.storage_domains.toml @@ -0,0 +1,30 @@ +category = "compile" +experimental = { storage_domains = true } + +# check: $()Two storage fields have the same storage key +# check: $()f1:u64 = 1, +# nextln: $()"storage.f1" has the same storage key as "storage.f2". +# check: $()f2 in 0xcecf0a910789de762c699a85a66835df1662df633238cbb25804b7f78640747b: u64 = 2, +# nextln: $()"storage.f2" is declared here. +# check: $()The key of "storage.f1" is generated by the compiler using the following formula: +# nextln: $()sha256((0u8, "storage.f1")) +# nextln: $()The common key is: 0xcecf0a910789de762c699a85a66835df1662df633238cbb25804b7f78640747b. + +# check: $()Two storage fields have the same storage key +# check: $()f3 in 0x5f4c20ce4bd128e5393a4c2b82007dac795fa0006d01acf8db4c42632bc680ca: u64 = 2, +# nextln: $()"storage::ns1.f3" has the same storage key as "storage::ns2.f4". +# check: $()f4 in 0x5f4c20ce4bd128e5393a4c2b82007dac795fa0006d01acf8db4c42632bc680ca: u64 = 2, +# nextln: $()"storage::ns2.f4" is declared here. +# check: $()Both keys are explicitly defined by using the `in` keyword. +# nextln: $()The common key is: 0x5f4c20ce4bd128e5393a4c2b82007dac795fa0006d01acf8db4c42632bc680ca. + +# check: $()Two storage fields have the same storage key +# check: $()f5 in 0x41e70e0fdfa49becc40cbfd5c057ab0540e8844f3d737fa3b1ab21a564b48069: u64 = 3, +# nextln: $()"storage::ns3.f5" has the same storage key as "storage::ns4.f6". +# check: $()f6: u64 = 4, +# nextln: $()"storage::ns4.f6" is declared here. +# check: $()The key of "storage::ns4.f6" is generated by the compiler using the following formula: +# nextln: $()sha256((0u8, "storage::ns4.f6")) +# nextln: $()The common key is: 0x41e70e0fdfa49becc40cbfd5c057ab0540e8844f3d737fa3b1ab21a564b48069. + +expected_warnings = 9 diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/duplicated_storage_keys/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/duplicated_storage_keys/test.toml index 8e5e7a86ef3..30c36d8b5f8 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/duplicated_storage_keys/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/duplicated_storage_keys/test.toml @@ -1,13 +1,29 @@ category = "compile" -# check: $()Two storage fields are using the same storage key. -# nextln: $()First field: storage.f1 -# nextln: $()Second field: storage.f2 -# nextln: $()Key: 36389D1013642DCB070193FC48B0316E9DFDFEF1860096DC5957E3EB44430B83 +# check: $()Two storage fields have the same storage key +# check: $()f1:u64 = 1, +# nextln: $()"storage.f1" has the same storage key as "storage.f2". +# check: $()f2 in 0x36389d1013642dcb070193fc48b0316e9dfdfef1860096dc5957e3eb44430b83: u64 = 2, +# nextln: $()"storage.f2" is declared here. +# check: $()The key of "storage.f1" is generated by the compiler using the following formula: +# nextln: $()sha256("storage.f1") +# nextln: $()The common key is: 0x36389d1013642dcb070193fc48b0316e9dfdfef1860096dc5957e3eb44430b83. -# check: $()Two storage fields are using the same storage key. -# nextln: $()First field: storage::ns1.f3 -# nextln: $()Second field: storage::ns2.f4 -# nextln: $()Key: 5F4C20CE4BD128E5393A4C2B82007DAC795FA0006D01ACF8DB4C42632BC680CA +# check: $()Two storage fields have the same storage key +# check: $()f3 in 0x5f4c20ce4bd128e5393a4c2b82007dac795fa0006d01acf8db4c42632bc680ca: u64 = 2, +# nextln: $()"storage::ns1.f3" has the same storage key as "storage::ns2.f4". +# check: $()f4 in 0x5f4c20ce4bd128e5393a4c2b82007dac795fa0006d01acf8db4c42632bc680ca: u64 = 2, +# nextln: $()"storage::ns2.f4" is declared here. +# check: $()Both keys are explicitly defined by using the `in` keyword. +# nextln: $()The common key is: 0x5f4c20ce4bd128e5393a4c2b82007dac795fa0006d01acf8db4c42632bc680ca. -expected_warnings = 6 +# check: $()Two storage fields have the same storage key +# check: $()f5 in 0xa49ebab6739a90f7658bbbdc2ed139942bd0b7be2e89aa8d90a953c45bf7a211: u64 = 3, +# nextln: $()"storage::ns3.f5" has the same storage key as "storage::ns4.f6". +# check: $()f6: u64 = 4, +# nextln: $()"storage::ns4.f6" is declared here. +# check: $()The key of "storage::ns4.f6" is generated by the compiler using the following formula: +# nextln: $()sha256("storage::ns4.f6") +# nextln: $()The common key is: 0xa49ebab6739a90f7658bbbdc2ed139942bd0b7be2e89aa8d90a953c45bf7a211. + +expected_warnings = 9 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 1ed97f22e9d..d7218234e92 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 = 0xb48002b23e2861d62237348199ff111e310f5dd10298a01562e3a4d41cb6aae6; // AUTO-CONTRACT-ID ../../test_contracts/basic_storage --release +const CONTRACT_ID = 0x27857d650234acd05b5fa9a9bc34abf76fa66d2e6ce8c8b24416805b75005bd0; // 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_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 af5bdc4cd47..06673118a96 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 = 0x434f5f10c3270134e51a1963f610286466e448c1c6109e4f20502939c7a3d429; // AUTO-CONTRACT-ID ../../test_contracts/storage_enum_contract --release +const CONTRACT_ID = 0x47084a8c1eb453b655842e1b3067ee1f0d9081052bd74ac606efa6ae9a56d901; // 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/storage_slot_key_calculation/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/storage_slot_key_calculation/Forc.lock new file mode 100644 index 00000000000..fe96407a20f --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/storage_slot_key_calculation/Forc.lock @@ -0,0 +1,13 @@ +[[package]] +name = "core" +source = "path+from-root-90F1067CD9AC8A94" + +[[package]] +name = "std" +source = "path+from-root-90F1067CD9AC8A94" +dependencies = ["core"] + +[[package]] +name = "storage_slot_key_calculation" +source = "member" +dependencies = ["std"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/storage_slot_key_calculation/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/storage_slot_key_calculation/Forc.toml new file mode 100644 index 00000000000..cb479a470ea --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/storage_slot_key_calculation/Forc.toml @@ -0,0 +1,8 @@ +[project] +name = "storage_slot_key_calculation" +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" + +[dependencies] +std = { path = "../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/storage_slot_key_calculation/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/storage_slot_key_calculation/src/main.sw new file mode 100644 index 00000000000..a4810dff242 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/storage_slot_key_calculation/src/main.sw @@ -0,0 +1,53 @@ +contract; + +use std::hash::*; + +storage { + a: u8 = 0, + b: u8 = 0, + ns1 { + a: u8 = 0, + b: u8 = 0, + }, + ns2 { + ns3 { + a: u8 = 0, + b: u8 = 0, + }, + }, +} + +abi TestStorageKeyCalculation { + #[storage(read)] + fn test_storage_key_calculation(); +} + +impl TestStorageKeyCalculation for Contract { + #[cfg(experimental_storage_domains = false)] + #[storage(read)] + fn test_storage_key_calculation() { + assert_eq(storage.a.slot(), sha256("storage.a")); + assert_eq(storage.b.slot(), sha256("storage.b")); + assert_eq(storage::ns1.a.slot(), sha256("storage::ns1.a")); + assert_eq(storage::ns1.b.slot(), sha256("storage::ns1.b")); + assert_eq(storage::ns2::ns3.a.slot(), sha256("storage::ns2::ns3.a")); + assert_eq(storage::ns2::ns3.b.slot(), sha256("storage::ns2::ns3.b")); + } + + #[cfg(experimental_storage_domains = true)] + #[storage(read)] + fn test_storage_key_calculation() { + assert_eq(storage.a.slot(), sha256((0u8, "storage.a"))); + assert_eq(storage.b.slot(), sha256((0u8, "storage.b"))); + assert_eq(storage::ns1.a.slot(), sha256((0u8, "storage::ns1.a"))); + assert_eq(storage::ns1.b.slot(), sha256((0u8, "storage::ns1.b"))); + assert_eq(storage::ns2::ns3.a.slot(), sha256((0u8, "storage::ns2::ns3.a"))); + assert_eq(storage::ns2::ns3.b.slot(), sha256((0u8, "storage::ns2::ns3.b"))); + } +} + +#[test] +fn test() { + let caller = abi(TestStorageKeyCalculation, CONTRACT_ID); + caller.test_storage_key_calculation(); +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/storage_slot_key_calculation/test.storage_domains.toml b/test/src/e2e_vm_tests/test_programs/should_pass/storage_slot_key_calculation/test.storage_domains.toml new file mode 100644 index 00000000000..0890b8a8510 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/storage_slot_key_calculation/test.storage_domains.toml @@ -0,0 +1 @@ +experimental = { storage_domains = true } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/storage_slot_key_calculation/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/storage_slot_key_calculation/test.toml new file mode 100644 index 00000000000..c82484373af --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/storage_slot_key_calculation/test.toml @@ -0,0 +1,2 @@ +category = "unit_tests_pass" +expected_warnings = 1 diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/basic_storage/json_abi_oracle.storage_domains.json b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/basic_storage/json_abi_oracle.storage_domains.json new file mode 100644 index 00000000000..2f821ed58f1 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/basic_storage/json_abi_oracle.storage_domains.json @@ -0,0 +1,297 @@ +{ + "concreteTypes": [ + { + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "type": "()" + }, + { + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "type": "b256" + }, + { + "concreteTypeId": "d852149004cc9ec0bbe7dc4e37bffea1d41469b759512b6136f2e865a4c06e7d", + "metadataTypeId": 0, + "type": "enum std::option::Option", + "typeArguments": [ + "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + ] + }, + { + "concreteTypeId": "6906df92e2e485dde893b7d719d621b8910422e7c468f99caa5920e6ac19d9c6", + "metadataTypeId": 3, + "type": "struct basic_storage_abi::Quad" + }, + { + "concreteTypeId": "7880d311d30802b48bd6a100a31adb5af17f94bff12daee556d4f02c1ac5b2ff", + "metadataTypeId": 5, + "type": "struct std::vec::Vec", + "typeArguments": [ + "6906df92e2e485dde893b7d719d621b8910422e7c468f99caa5920e6ac19d9c6" + ] + }, + { + "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", + "type": "u256" + }, + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "type": "u64" + }, + { + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "type": "u8" + } + ], + "configurables": [], + "encodingVersion": "1", + "functions": [ + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "name": "storage_key" + } + ], + "name": "get_u64", + "output": "d852149004cc9ec0bbe7dc4e37bffea1d41469b759512b6136f2e865a4c06e7d" + }, + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "name": "key" + }, + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "name": "slots" + } + ], + "name": "intrinsic_load_quad", + "output": "7880d311d30802b48bd6a100a31adb5af17f94bff12daee556d4f02c1ac5b2ff" + }, + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "name": "key" + } + ], + "name": "intrinsic_load_word", + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "name": "key" + }, + { + "concreteTypeId": "7880d311d30802b48bd6a100a31adb5af17f94bff12daee556d4f02c1ac5b2ff", + "name": "values" + } + ], + "name": "intrinsic_store_quad", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "name": "key" + }, + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "name": "value" + } + ], + "name": "intrinsic_store_word", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "name": "key" + }, + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "name": "value" + } + ], + "name": "store_u64", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": [ + { + "arguments": [ + "read", + "write" + ], + "name": "storage" + } + ], + "inputs": [], + "name": "test_storage_exhaustive", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ], + "loggedTypes": [ + { + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "logId": "14454674236531057292" + }, + { + "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", + "logId": "1970142151624111756" + }, + { + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "logId": "8961848586872524460" + }, + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "logId": "1515152261580153489" + } + ], + "messagesTypes": [], + "metadataTypes": [ + { + "components": [ + { + "name": "None", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "Some", + "typeId": 1 + } + ], + "metadataTypeId": 0, + "type": "enum std::option::Option", + "typeParameters": [ + 1 + ] + }, + { + "metadataTypeId": 1, + "type": "generic T" + }, + { + "metadataTypeId": 2, + "type": "raw untyped ptr" + }, + { + "components": [ + { + "name": "v1", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "v2", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "v3", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "v4", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "metadataTypeId": 3, + "type": "struct basic_storage_abi::Quad" + }, + { + "components": [ + { + "name": "ptr", + "typeId": 2 + }, + { + "name": "cap", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "metadataTypeId": 4, + "type": "struct std::vec::RawVec", + "typeParameters": [ + 1 + ] + }, + { + "components": [ + { + "name": "buf", + "typeArguments": [ + { + "name": "", + "typeId": 1 + } + ], + "typeId": 4 + }, + { + "name": "len", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "metadataTypeId": 5, + "type": "struct std::vec::Vec", + "typeParameters": [ + 1 + ] + } + ], + "programType": "contract", + "specVersion": "1" +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/basic_storage/json_storage_slots_oracle.storage_domains.json b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/basic_storage/json_storage_slots_oracle.storage_domains.json new file mode 100644 index 00000000000..8c0169567bb --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/basic_storage/json_storage_slots_oracle.storage_domains.json @@ -0,0 +1,58 @@ +[ + { + "key": "040f131e97eaba9c2d25f5c1d6ea9489ce530940dd87d486f8cd9c7ff5360f6c", + "value": "6161616161000000000000000000000000000000000000000000000000000000" + }, + { + "key": "077f64b0ca598a020551265c0faf95f8e860b45700f27c06af3640a123818b17", + "value": "6161000000000000000000000000000000000000000000000000000000000000" + }, + { + "key": "2b46310c8d886cf7d9e4339837ecc696ecfaf2c431e56e725c552b92b11c3bc8", + "value": "0000000000000000000000000000000000000000000000000000000001234567" + }, + { + "key": "30226b031f925fbb2a1ad161ce31b798a684c6f52ed49cf84e244d324eceaf58", + "value": "6161616100000000000000000000000000000000000000000000000000000000" + }, + { + "key": "42e97a774f87c61347e7283755a043a5a896d37e801045e8f5ce538b6d1ce8c8", + "value": "0000000000000000000000000000000000000000000000000000000001234567" + }, + { + "key": "78dabd24c80fc40f05bae92654874f2f77bd13ef803fd55ccf014ff5849cdfd0", + "value": "6161616161610000000000000000000000000000000000000000000000000000" + }, + { + "key": "848a0a618b9c374a4b1b47c59ef2f0a01f5c42bb5e805ffd669412ce283b992a", + "value": "6161616161616161000000000000000000000000000000000000000000000000" + }, + { + "key": "84e44dc0900861559343f0fc02dc0d92f7e87872a50e730a85740b701b162863", + "value": "6161616161616100000000000000000000000000000000000000000000000000" + }, + { + "key": "933a534d4af4c376b0b569e8d8a2c62e635e26f403e124cb91d9c42e83d54373", + "value": "0100000000000000000000000000000000000000000000000000000000000000" + }, + { + "key": "976540acfef542cb328d6679def3e281cdb1a5bbaca7d9e59a30aa74f3952d90", + "value": "6100000000000000000000000000000000000000000000000000000000000000" + }, + { + "key": "9d3f8eb1f2d99b97a2fd6fa68fe7e5a9c5b6734739f8dd84f2ae3da221206a80", + "value": "0000000000000002000000000000000000000000000000000000000000000000" + }, + { + "key": "a42ed3ecc6aaf8d594f165e6c60cdaf172d59436167556f954e6559036736ceb", + "value": "6161610000000000000000000000000000000000000000000000000000000000" + }, + { + "key": "d33763008c92b260fc4381d53aa5976de2b5f991798799fa5edf300bb4a40e02", + "value": "6161616161616161616100000000000000000000000000000000000000000000" + }, + { + "key": "f8fde9e56bb5ab545fdfe17edabb876e6f4cd1b3296d92b266d4acb9ca0b5f79", + "value": "6161616161616161610000000000000000000000000000000000000000000000" + } +] \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/basic_storage/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/basic_storage/src/main.sw index 532709bfed7..251577caf5b 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/basic_storage/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/basic_storage/src/main.sw @@ -296,8 +296,6 @@ fn test_storage() { assert_eq(storage::ns1::ns2.c1.read(), NS1_NS2_C1); assert_eq(storage.c1.slot(), C1KEY); - assert_eq(storage.const_b256.slot(), sha256("storage.const_b256")); - assert_eq(storage::ns1::ns2.c1.slot(), sha256("storage::ns1::ns2.c1")); } // If these comparisons are done inline just above then it blows out the register allocator due to diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/basic_storage/test.storage_domains.toml b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/basic_storage/test.storage_domains.toml new file mode 100644 index 00000000000..0890b8a8510 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/basic_storage/test.storage_domains.toml @@ -0,0 +1 @@ +experimental = { storage_domains = true } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/basic_storage/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/basic_storage/test.toml index 8bce24f6a24..c1349fc15dc 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/basic_storage/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/basic_storage/test.toml @@ -1,4 +1,4 @@ category = "compile" validate_abi = true validate_storage_slots = true -expected_warnings = 3 +expected_warnings = 2 # TODO-DCA: Set to zero once https://github.com/FuelLabs/sway/issues/5921 is fixed. diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/increment_contract/json_abi_oracle.storage_domains.json b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/increment_contract/json_abi_oracle.storage_domains.json new file mode 100644 index 00000000000..edd98a1f3d1 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/increment_contract/json_abi_oracle.storage_domains.json @@ -0,0 +1,102 @@ +{ + "concreteTypes": [ + { + "concreteTypeId": "d852149004cc9ec0bbe7dc4e37bffea1d41469b759512b6136f2e865a4c06e7d", + "metadataTypeId": 1, + "type": "enum std::option::Option", + "typeArguments": [ + "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + ] + }, + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "type": "u64" + } + ], + "configurables": [], + "encodingVersion": "1", + "functions": [ + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [], + "name": "get", + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "attributes": [ + { + "arguments": [ + "read", + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "name": "increment_by" + } + ], + "name": "increment", + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "attributes": [ + { + "arguments": [ + "read", + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "d852149004cc9ec0bbe7dc4e37bffea1d41469b759512b6136f2e865a4c06e7d", + "name": "initial_value" + } + ], + "name": "increment_or_not", + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "loggedTypes": [], + "messagesTypes": [], + "metadataTypes": [ + { + "metadataTypeId": 0, + "type": "()" + }, + { + "components": [ + { + "name": "None", + "typeId": 0 + }, + { + "name": "Some", + "typeId": 2 + } + ], + "metadataTypeId": 1, + "type": "enum std::option::Option", + "typeParameters": [ + 2 + ] + }, + { + "metadataTypeId": 2, + "type": "generic T" + } + ], + "programType": "contract", + "specVersion": "1" +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/increment_contract/json_storage_slots_oracle.storage_domains.json b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/increment_contract/json_storage_slots_oracle.storage_domains.json new file mode 100644 index 00000000000..efa6132760a --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/increment_contract/json_storage_slots_oracle.storage_domains.json @@ -0,0 +1,6 @@ +[ + { + "key": "d810923c0d6cc6ed49622594d7368eb1e124753474e3ebd52a66c6c2ecb42642", + "value": "0000000000000000000000000000000000000000000000000000000000000000" + } +] \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/increment_contract/test.storage_domains.toml b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/increment_contract/test.storage_domains.toml new file mode 100644 index 00000000000..24be96bbf31 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/increment_contract/test.storage_domains.toml @@ -0,0 +1 @@ +experimental = { storage_domains = true } \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_access_contract/json_abi_oracle.storage_domains.json b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_access_contract/json_abi_oracle.storage_domains.json new file mode 100644 index 00000000000..9a1f9ebd31e --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_access_contract/json_abi_oracle.storage_domains.json @@ -0,0 +1,769 @@ +{ + "concreteTypes": [ + { + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "type": "()" + }, + { + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "type": "b256" + }, + { + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "type": "bool" + }, + { + "concreteTypeId": "35b24140807b67d1f1675de36775d5d6c62b04f3721f616a9adee739e24c9c15", + "metadataTypeId": 0, + "type": "enum storage_access_abi::E" + }, + { + "concreteTypeId": "893a66eb2f595d7e0cc15e2253da1b6e53fd634ad542b2f1a198a8ae3d8d92b2", + "type": "str[40]" + }, + { + "concreteTypeId": "427fd62288add8763eb5e0c4facf553d877489a3038b29a8a1045e9a853660f0", + "metadataTypeId": 1, + "type": "struct storage_access_abi::S" + }, + { + "concreteTypeId": "74df8abb4a65a07ec7420c0f167703fc6e26c9e43b8036ffacb89d399f13db73", + "metadataTypeId": 2, + "type": "struct storage_access_abi::T" + }, + { + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", + "type": "u16" + }, + { + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", + "type": "u32" + }, + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "type": "u64" + }, + { + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "type": "u8" + } + ], + "configurables": [], + "encodingVersion": "1", + "functions": [ + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [], + "name": "get_boolean", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [], + "name": "get_e", + "output": "35b24140807b67d1f1675de36775d5d6c62b04f3721f616a9adee739e24c9c15" + }, + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [], + "name": "get_e2", + "output": "35b24140807b67d1f1675de36775d5d6c62b04f3721f616a9adee739e24c9c15" + }, + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [], + "name": "get_int16", + "output": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + }, + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [], + "name": "get_int32", + "output": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [], + "name": "get_int8", + "output": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + }, + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [], + "name": "get_s", + "output": "427fd62288add8763eb5e0c4facf553d877489a3038b29a8a1045e9a853660f0" + }, + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [], + "name": "get_s_dot_t", + "output": "74df8abb4a65a07ec7420c0f167703fc6e26c9e43b8036ffacb89d399f13db73" + }, + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [], + "name": "get_s_dot_t_dot_boolean", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [], + "name": "get_s_dot_t_dot_int16", + "output": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + }, + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [], + "name": "get_s_dot_t_dot_int32", + "output": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [], + "name": "get_s_dot_t_dot_int8", + "output": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + }, + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [], + "name": "get_s_dot_t_dot_x", + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [], + "name": "get_s_dot_t_dot_y", + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [], + "name": "get_s_dot_t_dot_z", + "output": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [], + "name": "get_s_dot_x", + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [], + "name": "get_s_dot_y", + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [], + "name": "get_s_dot_z", + "output": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [], + "name": "get_string", + "output": "893a66eb2f595d7e0cc15e2253da1b6e53fd634ad542b2f1a198a8ae3d8d92b2" + }, + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [], + "name": "get_x", + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [], + "name": "get_y", + "output": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "name": "boolean" + } + ], + "name": "set_boolean", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "35b24140807b67d1f1675de36775d5d6c62b04f3721f616a9adee739e24c9c15", + "name": "e" + } + ], + "name": "set_e", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", + "name": "int16" + } + ], + "name": "set_int16", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", + "name": "int32" + } + ], + "name": "set_int32", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "name": "int8" + } + ], + "name": "set_int8", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "427fd62288add8763eb5e0c4facf553d877489a3038b29a8a1045e9a853660f0", + "name": "s" + } + ], + "name": "set_s", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "74df8abb4a65a07ec7420c0f167703fc6e26c9e43b8036ffacb89d399f13db73", + "name": "t" + } + ], + "name": "set_s_dot_t", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "name": "boolean" + } + ], + "name": "set_s_dot_t_dot_boolean", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", + "name": "int16" + } + ], + "name": "set_s_dot_t_dot_int16", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", + "name": "int32" + } + ], + "name": "set_s_dot_t_dot_int32", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "name": "int8" + } + ], + "name": "set_s_dot_t_dot_int8", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "name": "x" + } + ], + "name": "set_s_dot_t_dot_x", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "name": "y" + } + ], + "name": "set_s_dot_t_dot_y", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "name": "z" + } + ], + "name": "set_s_dot_t_dot_z", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "name": "x" + } + ], + "name": "set_s_dot_x", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "name": "y" + } + ], + "name": "set_s_dot_y", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "name": "z" + } + ], + "name": "set_s_dot_z", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "893a66eb2f595d7e0cc15e2253da1b6e53fd634ad542b2f1a198a8ae3d8d92b2", + "name": "string" + } + ], + "name": "set_string", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "name": "x" + } + ], + "name": "set_x", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "name": "y" + } + ], + "name": "set_y", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ], + "loggedTypes": [ + { + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "logId": "13213829929622723620" + } + ], + "messagesTypes": [], + "metadataTypes": [ + { + "components": [ + { + "name": "A", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "B", + "typeId": 2 + } + ], + "metadataTypeId": 0, + "type": "enum storage_access_abi::E" + }, + { + "components": [ + { + "name": "x", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "y", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "z", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "name": "t", + "typeId": 2 + } + ], + "metadataTypeId": 1, + "type": "struct storage_access_abi::S" + }, + { + "components": [ + { + "name": "x", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "y", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "z", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "name": "boolean", + "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "name": "int8", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + }, + { + "name": "int16", + "typeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + }, + { + "name": "int32", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "metadataTypeId": 2, + "type": "struct storage_access_abi::T" + } + ], + "programType": "contract", + "specVersion": "1" +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_access_contract/json_storage_slots_oracle.storage_domains.json b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_access_contract/json_storage_slots_oracle.storage_domains.json new file mode 100644 index 00000000000..ff1eae7956b --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_access_contract/json_storage_slots_oracle.storage_domains.json @@ -0,0 +1,74 @@ +[ + { + "key": "419b1120ea993203d7e223dfbe76184322453d6f8de946e827a8669102ab395b", + "value": "0000000000000040000000000000000000000000000000000000000000000000" + }, + { + "key": "4b06f7ce27bc88217a7c9d4300619d2900cef25ecb29a790ec869b02e4191275", + "value": "4141414141414141414141414141414141414141414141414141414141414141" + }, + { + "key": "4b06f7ce27bc88217a7c9d4300619d2900cef25ecb29a790ec869b02e4191276", + "value": "4141414141414141000000000000000000000000000000000000000000000000" + }, + { + "key": "7299da45c4430837636de04fb23f3343a80d88c1dc0455562b3066913f0d7745", + "value": "0000000000000020000000000000000000000000000000000000000000000000" + }, + { + "key": "865b6b6b53f4babe503029163d7076d649da88a10c4ed333d19c645d271f495c", + "value": "0000000000000010000000000000000000000000000000000000000000000000" + }, + { + "key": "8e06966f123f8d6e298f853c70d34036061474c4674b7960119ac4a08a557f0c", + "value": "0000000000000001000000000000000100000000000000020000000000000000" + }, + { + "key": "8e06966f123f8d6e298f853c70d34036061474c4674b7960119ac4a08a557f0d", + "value": "0000000000000000000000000000000000000000000000030100000000000000" + }, + { + "key": "8e06966f123f8d6e298f853c70d34036061474c4674b7960119ac4a08a557f0e", + "value": "0400000000000000000000000000000500000000000000060000000000000000" + }, + { + "key": "9538bea0a4c2601b6bd45782e4c10df5728427e310421d9a5d93f85a1f3704f2", + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "key": "9538bea0a4c2601b6bd45782e4c10df5728427e310421d9a5d93f85a1f3704f3", + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "key": "9538bea0a4c2601b6bd45782e4c10df5728427e310421d9a5d93f85a1f3704f4", + "value": "0000000000000000000000000000000000000000000003090000000000000000" + }, + { + "key": "ae10a55cca3f364be094340b109ccf393d12c2c07417ff2e719b1816ac793c86", + "value": "0000000000000001000000000000000200000000000000000000000000000000" + }, + { + "key": "ae10a55cca3f364be094340b109ccf393d12c2c07417ff2e719b1816ac793c87", + "value": "0000000000000000000000000000000300000000000000040000000000000005" + }, + { + "key": "ae10a55cca3f364be094340b109ccf393d12c2c07417ff2e719b1816ac793c88", + "value": "0000000000000000000000000000000000000000000000000000000000000006" + }, + { + "key": "ae10a55cca3f364be094340b109ccf393d12c2c07417ff2e719b1816ac793c89", + "value": "0100000000000000070000000000000000000000000000080000000000000009" + }, + { + "key": "d871d81721e9905a5cafe5b82dfde0ddb930f96a8e6deb44f92a8c9ce4d24ac1", + "value": "0800000000000000000000000000000000000000000000000000000000000000" + }, + { + "key": "e8aaf9a6b72b4eee2bcb2315773bc50e9166ff05c4221843637e25f0424a5dd5", + "value": "0100000000000000000000000000000000000000000000000000000000000000" + }, + { + "key": "eb390d9f85c8c849ff8aeb05c865ca66b37ba69a7bec8489b1c467f029b650af", + "value": "0101010101010101010101010101010101010101010101010101010101010101" + } +] \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_access_contract/test.storage_domains.toml b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_access_contract/test.storage_domains.toml new file mode 100644 index 00000000000..24be96bbf31 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_access_contract/test.storage_domains.toml @@ -0,0 +1 @@ +experimental = { storage_domains = true } \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_enum_contract/json_abi_oracle.storage_domains.json b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_enum_contract/json_abi_oracle.storage_domains.json new file mode 100644 index 00000000000..32bd4e374ca --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_enum_contract/json_abi_oracle.storage_domains.json @@ -0,0 +1,31 @@ +{ + "concreteTypes": [ + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "type": "u64" + } + ], + "configurables": [], + "encodingVersion": "1", + "functions": [ + { + "attributes": [ + { + "arguments": [ + "read", + "write" + ], + "name": "storage" + } + ], + "inputs": [], + "name": "read_write_enums", + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "loggedTypes": [], + "messagesTypes": [], + "metadataTypes": [], + "programType": "contract", + "specVersion": "1" +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_enum_contract/json_storage_slots_oracle.storage_domains.json b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_enum_contract/json_storage_slots_oracle.storage_domains.json new file mode 100644 index 00000000000..f2d1ca396cb --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_enum_contract/json_storage_slots_oracle.storage_domains.json @@ -0,0 +1,62 @@ +[ + { + "key": "12f9e955b5b2b5a00c0ebd1320f2cbd0e66c39396b3b3d7ff95c87f4b6e48c0d", + "value": "000000000000000000000000000000cd00000000000000000000000000000000" + }, + { + "key": "23e09d7a09a27d7d9c5c9d0f5191084c19a0a668c60b804a94e99234e6069c7b", + "value": "0000000000000001000000000000aa00000000000000bb00000000000000cc00" + }, + { + "key": "2e7251f5b28dbe052a7f5113d45f3cc2faccf7c955cbc0966089aa0d0059beab", + "value": "0000000000000001000000000000ab00000000000000bc00000000000000cd00" + }, + { + "key": "2e7251f5b28dbe052a7f5113d45f3cc2faccf7c955cbc0966089aa0d0059beac", + "value": "000000000000de00000000000000ef0000000000000000000000000000000000" + }, + { + "key": "2f02e964cd75fddf505a740d9daa11fef5f09b4d17058f893fc0f4e8b2244f53", + "value": "0000000000000000000000000000000100000000000000000000000000000000" + }, + { + "key": "50010301032c3383ef066fbb9ac7c25e3de42bdd5ccaec2d6e0bd26b6531bb0f", + "value": "0000000000000000000000000000000100000000000000000000000000000000" + }, + { + "key": "6b765908aa8ec7bc3a1d73cd252e40fb055de29fb0e9486a16e388cba9fa7c9f", + "value": "00000000000000000000000000000000000000000000000000000000000000ee" + }, + { + "key": "728df923e281e7cb9793c2c2d6419b735161b5e1b8d5ca2065569611418fc194", + "value": "000000000000000100000000000000cd00000000000000000000000000000000" + }, + { + "key": "7ddacb90e6ff09ed9aa4fde095854476123392aab8c73165cc65097b0a2a2578", + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "key": "7ddacb90e6ff09ed9aa4fde095854476123392aab8c73165cc65097b0a2a2579", + "value": "000000000000000000000000000000ff00000000000000000000000000000000" + }, + { + "key": "c20357da738934c36211a22c69d4c44bc7a3b500b07d9e7328c3f0a7c2c426c0", + "value": "0000000000000002000000000000000000000000000000000000000000000000" + }, + { + "key": "d60810fb854958d678015228bfbd5a23a3e1763c1ff90f6790f69fbb85b413c6", + "value": "000000000000000000000000000000ab00000000000000000000000000000000" + }, + { + "key": "d71ff2e9ac87ec91301ee89d18b1dc8991b79753f004ce0810661bd5bfa92bd2", + "value": "0000000000000001000000000000bb0000000000000000000000000000000000" + }, + { + "key": "d9149ae8e217ec10a045c9f83c5bc9d227285fe76b9bcdc8245e6a57a23d0229", + "value": "000000000000000000000000000000aa00000000000000000000000000000000" + }, + { + "key": "e7af73ebbf0ab36c9e30283a504e1326febe010a1b2d0deae9252af8302526a1", + "value": "0000000000000002000000000000000000000000000000000000000000000000" + } +] \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_enum_contract/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_enum_contract/src/main.sw index e604563d4e2..597bed643ce 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_enum_contract/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_enum_contract/src/main.sw @@ -117,10 +117,6 @@ fn check_s_u8_a(expected: u8) -> u8 { assert(i == expected); return i; }, - _ => { - assert(false); - return 99; - } } } @@ -132,10 +128,6 @@ fn check_s_u64_a(expected: u64) -> u64 { assert(i == expected); return i; }, - _ => { - assert(false); - return 9999; - } } } @@ -147,10 +139,6 @@ fn check_s_bool_a(expected: bool) -> u64 { assert(i == expected); return 171; }, - _ => { - assert(false); - return 9999; - } } } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_enum_contract/test.storage_domains.toml b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_enum_contract/test.storage_domains.toml new file mode 100644 index 00000000000..24be96bbf31 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_enum_contract/test.storage_domains.toml @@ -0,0 +1 @@ +experimental = { storage_domains = true } \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_namespace/json_abi_oracle.storage_domains.json b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_namespace/json_abi_oracle.storage_domains.json new file mode 100644 index 00000000000..a7b039e5eeb --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_namespace/json_abi_oracle.storage_domains.json @@ -0,0 +1,289 @@ +{ + "concreteTypes": [ + { + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "type": "()" + }, + { + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "type": "b256" + }, + { + "concreteTypeId": "d852149004cc9ec0bbe7dc4e37bffea1d41469b759512b6136f2e865a4c06e7d", + "metadataTypeId": 0, + "type": "enum std::option::Option", + "typeArguments": [ + "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + ] + }, + { + "concreteTypeId": "6906df92e2e485dde893b7d719d621b8910422e7c468f99caa5920e6ac19d9c6", + "metadataTypeId": 3, + "type": "struct basic_storage_abi::Quad" + }, + { + "concreteTypeId": "7880d311d30802b48bd6a100a31adb5af17f94bff12daee556d4f02c1ac5b2ff", + "metadataTypeId": 5, + "type": "struct std::vec::Vec", + "typeArguments": [ + "6906df92e2e485dde893b7d719d621b8910422e7c468f99caa5920e6ac19d9c6" + ] + }, + { + "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", + "type": "u256" + }, + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "type": "u64" + } + ], + "configurables": [], + "encodingVersion": "1", + "functions": [ + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "name": "storage_key" + } + ], + "name": "get_u64", + "output": "d852149004cc9ec0bbe7dc4e37bffea1d41469b759512b6136f2e865a4c06e7d" + }, + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "name": "key" + }, + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "name": "slots" + } + ], + "name": "intrinsic_load_quad", + "output": "7880d311d30802b48bd6a100a31adb5af17f94bff12daee556d4f02c1ac5b2ff" + }, + { + "attributes": [ + { + "arguments": [ + "read" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "name": "key" + } + ], + "name": "intrinsic_load_word", + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "name": "key" + }, + { + "concreteTypeId": "7880d311d30802b48bd6a100a31adb5af17f94bff12daee556d4f02c1ac5b2ff", + "name": "values" + } + ], + "name": "intrinsic_store_quad", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "name": "key" + }, + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "name": "value" + } + ], + "name": "intrinsic_store_word", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": [ + { + "arguments": [ + "write" + ], + "name": "storage" + } + ], + "inputs": [ + { + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "name": "key" + }, + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "name": "value" + } + ], + "name": "store_u64", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "attributes": [ + { + "arguments": [ + "read", + "write" + ], + "name": "storage" + } + ], + "inputs": [], + "name": "test_storage_exhaustive", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ], + "loggedTypes": [ + { + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "logId": "1515152261580153489" + }, + { + "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", + "logId": "1970142151624111756" + }, + { + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "logId": "8961848586872524460" + } + ], + "messagesTypes": [], + "metadataTypes": [ + { + "components": [ + { + "name": "None", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "Some", + "typeId": 1 + } + ], + "metadataTypeId": 0, + "type": "enum std::option::Option", + "typeParameters": [ + 1 + ] + }, + { + "metadataTypeId": 1, + "type": "generic T" + }, + { + "metadataTypeId": 2, + "type": "raw untyped ptr" + }, + { + "components": [ + { + "name": "v1", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "v2", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "v3", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "v4", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "metadataTypeId": 3, + "type": "struct basic_storage_abi::Quad" + }, + { + "components": [ + { + "name": "ptr", + "typeId": 2 + }, + { + "name": "cap", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "metadataTypeId": 4, + "type": "struct std::vec::RawVec", + "typeParameters": [ + 1 + ] + }, + { + "components": [ + { + "name": "buf", + "typeArguments": [ + { + "name": "", + "typeId": 1 + } + ], + "typeId": 4 + }, + { + "name": "len", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "metadataTypeId": 5, + "type": "struct std::vec::Vec", + "typeParameters": [ + 1 + ] + } + ], + "programType": "contract", + "specVersion": "1" +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_namespace/json_storage_slots_oracle.storage_domains.json b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_namespace/json_storage_slots_oracle.storage_domains.json new file mode 100644 index 00000000000..30e9e240f7c --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_namespace/json_storage_slots_oracle.storage_domains.json @@ -0,0 +1,54 @@ +[ + { + "key": "130875c838ab7f4f039a63d56d8173198d6edade9a61967c93b9d32d93547979", + "value": "6161000000000000000000000000000000000000000000000000000000000000" + }, + { + "key": "1997c0b14a3944421bc909d65cdb7f96023661790725e7a06d0bdf211002f9c0", + "value": "6161610000000000000000000000000000000000000000000000000000000000" + }, + { + "key": "1cb08489095e2318cabf34c2c00b0f2b78c151bf4e3caf2a1762778c1b79c052", + "value": "0000000000000001000000000000000000000000000000000000000000000000" + }, + { + "key": "35338f6734c20524ba70780eae61e4dc5398122eab4a3cad9509a3d3ddc1551b", + "value": "0000000000000000000000000000000000000000000000000000000001234567" + }, + { + "key": "55279c57558d3bb1938f803552769ed7dcb3efacd74d9a16cf71d0cfbaab6c0a", + "value": "6161616161616161616100000000000000000000000000000000000000000000" + }, + { + "key": "5d5895256cdf173ecc135c1a18de5133b00b36e5caae538407a883dd44cc0dac", + "value": "0000000000000000000000000000000000000000000000000000000001234567" + }, + { + "key": "5dbeb0e7fc4c2fa3b01b9873d2a4e23488fb486046b6074b4ae463b7bbacbe89", + "value": "6161616161000000000000000000000000000000000000000000000000000000" + }, + { + "key": "659790a8d5d87a599ab69d1a3e6f48ff00c850fb7d24ccd782b209a52e4be83c", + "value": "6161616161616100000000000000000000000000000000000000000000000000" + }, + { + "key": "7aac1eb5fdc9d977b39721c2ccddb3ae405eecac0d8570e3be2d70fe677db4bd", + "value": "6161616161616161610000000000000000000000000000000000000000000000" + }, + { + "key": "8449d22802f944884dd98b791627c4265f4303014d1975f3da48fde003d77936", + "value": "6161616161616161000000000000000000000000000000000000000000000000" + }, + { + "key": "c2f546e9b4a2a37895f7f563be4610aa580468ddd8ba5d3544513965d79eac8a", + "value": "6100000000000000000000000000000000000000000000000000000000000000" + }, + { + "key": "e1ba0adcc27d3a21cfe72cc296e282f1c4b9f6798f89ac4e4b8ac95e3ee16d81", + "value": "6161616161610000000000000000000000000000000000000000000000000000" + }, + { + "key": "fdcf008347ae968111d6837c46f05f1a9943e76f6998d51ee1220b4069709a51", + "value": "6161616100000000000000000000000000000000000000000000000000000000" + } +] \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_namespace/test.storage_domains.toml b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_namespace/test.storage_domains.toml new file mode 100644 index 00000000000..24be96bbf31 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_namespace/test.storage_domains.toml @@ -0,0 +1 @@ +experimental = { storage_domains = true } \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_namespace/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_namespace/test.toml index 94671fb72d4..a235275de20 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_namespace/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_namespace/test.toml @@ -1,4 +1,4 @@ category = "compile" validate_abi = true validate_storage_slots = true -expected_warnings = 1 +expected_warnings = 1 # TODO-DCA: Set to zero once https://github.com/FuelLabs/sway/issues/5921 is fixed. diff --git a/test/src/ir_generation/mod.rs b/test/src/ir_generation/mod.rs index 8313845fe39..6969ef1c689 100644 --- a/test/src/ir_generation/mod.rs +++ b/test/src/ir_generation/mod.rs @@ -223,7 +223,9 @@ pub(super) async fn run( tracing::info!("Testing {} ...", test_file_name.bold()); let experimental = ExperimentalFeatures { - new_encoding: false, // IR tests still need encoding v1 off + new_encoding: false, // IR tests still need encoding v1 off. + // TODO: Properly support experimental features in IR tests. + ..Default::default() }; // Compile to AST. We need to provide a faux build config otherwise the IR will have From 2b6fd7a53567581ca6e641110f9257ecd2fab173 Mon Sep 17 00:00:00 2001 From: jjcnn <38888011+jjcnn@users.noreply.github.com> Date: Fri, 15 Nov 2024 05:59:45 +0100 Subject: [PATCH 114/115] Fix module visibility check (#6685) ## Description Fixes #6673. The module visibility check has been broken for some time. In some cases, like the one described in #6673, this has resulted in modules being mistakenly regarded as inaccessible, even though they ought to be accessible. In other cases, private modules were mistakenly regarded as accessible. For examples see the updated tests in the PR. The check has now been fixed, and all tests have been updated accordingly. This bugfix can be regarded as a breaking change, because some modules that were deemed accessible before may now be deemed inaccessible and will require the addition of a `pub` keyword in front of the module declaration. ## 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. --------- Co-authored-by: Joshua Batty Co-authored-by: IGI-111 --- examples/enums/src/main.sw | 2 +- .../src/semantic_analysis/namespace/root.rs | 41 +++++++++++++------ .../language/reexport/aliases/src/main.sw | 24 +++++------ .../src/main.sw | 6 +-- .../src/main.sw | 24 +++++------ .../reexport/simple_glob_import/src/main.sw | 8 ++-- .../reexport/simple_item_import/src/main.sw | 10 +++-- .../should_pass/dca/unused_enum/src/main.sw | 2 +- .../should_pass/dca/unused_trait/src/main.sw | 2 +- .../language/generic_traits/src/main.sw | 4 +- .../import_method_from_other_file/src/main.sw | 2 +- .../src/main.sw | 2 +- .../match_expressions_constants/src/main.sw | 2 +- .../language/module_dep/src/lib.sw | 4 +- .../language/module_dep_multiple/src/lib.sw | 4 +- .../language/reexport/aliases/src/main.sw | 20 ++++----- .../src/main.sw | 24 +++++------ .../reexport/reexport_paths/src/main.sw | 20 ++++----- .../src/main.sw | 24 +++++------ .../reexport/simple_glob_import/src/main.sw | 8 ++-- .../reexport/simple_item_import/src/main.sw | 8 ++-- .../language/reexport/visibility/src/main.sw | 12 +++--- .../language/use_absolute_path/src/main.sw | 2 +- .../should_pass/stdlib/option/src/main.sw | 2 +- .../should_pass/stdlib/result/src/main.sw | 2 +- .../test_contracts/return_struct/src/main.sw | 2 +- 26 files changed, 140 insertions(+), 121 deletions(-) diff --git a/examples/enums/src/main.sw b/examples/enums/src/main.sw index b6804891143..87dbdf428cb 100644 --- a/examples/enums/src/main.sw +++ b/examples/enums/src/main.sw @@ -2,6 +2,6 @@ library; mod basic_enum; mod enum_of_structs; -mod enum_of_enums; +pub mod enum_of_enums; mod enums_avoid; mod enums_preferred; diff --git a/sway-core/src/semantic_analysis/namespace/root.rs b/sway-core/src/semantic_analysis/namespace/root.rs index 7d4e22b7265..086d91b31aa 100644 --- a/sway-core/src/semantic_analysis/namespace/root.rs +++ b/sway-core/src/semantic_analysis/namespace/root.rs @@ -683,6 +683,10 @@ impl Root { Ok(()) } + /// Check that all accessed modules in the src path are visible from the dst path. + /// If src and dst have a common ancestor module that is private, this privacy modifier is + /// ignored for visibility purposes, since src and dst are both behind that private visibility + /// modifier. Additionally, items in a private module are visible to its immediate parent. fn check_module_privacy( &self, handler: &Handler, @@ -690,20 +694,33 @@ impl Root { src: &ModulePath, dst: &ModulePath, ) -> Result<(), ErrorEmitted> { - // you are always allowed to access your ancestor's symbols - if !is_ancestor(src, dst) { - // we don't check the first prefix because direct children are always accessible - for prefix in iter_prefixes(src).skip(1) { - let module = self.module.lookup_submodule(handler, engines, prefix)?; - if module.visibility().is_private() { - let prefix_last = prefix[prefix.len() - 1].clone(); - handler.emit_err(CompileError::ImportPrivateModule { - span: prefix_last.span(), - name: prefix_last, - }); - } + // Calculate the number of src prefixes whose privacy is ignored. + let mut ignored_prefixes = 0; + + // Ignore visibility of common ancestors + ignored_prefixes += src + .iter() + .zip(dst) + .position(|(src_id, dst_id)| src_id != dst_id) + .unwrap_or(dst.len()); + + // Ignore visibility of direct submodules of the destination module + if dst.len() == ignored_prefixes { + ignored_prefixes += 1; + } + + // Check visibility of remaining submodules in the source path + for prefix in iter_prefixes(src).skip(ignored_prefixes) { + let module = self.module.lookup_submodule(handler, engines, prefix)?; + if module.visibility().is_private() { + let prefix_last = prefix[prefix.len() - 1].clone(); + handler.emit_err(CompileError::ImportPrivateModule { + span: prefix_last.span(), + name: prefix_last, + }); } } + Ok(()) } diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/aliases/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/aliases/src/main.sw index d84157a1bce..a8597cf626a 100755 --- a/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/aliases/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/aliases/src/main.sw @@ -1,17 +1,17 @@ script; -mod items_1; -mod lib_1; // Aliased item reexports of items_1 -mod items_2; -mod lib_2; // Aliased item reexports of items_2 -mod items_3; -mod lib_3; // Aliased item reexports of items_3 -mod items_4; -mod lib_4_1; // Aliased item reexports of items_4 -mod lib_4_2; // Aliased item reexports of lib_4_1 -mod items_5; -mod lib_5_1; // Aliased trait reexports from items_5 -mod lib_5_2; // Aliased trait reexports from items_5 +pub mod items_1; +pub mod lib_1; // Aliased item reexports of items_1 +pub mod items_2; +pub mod lib_2; // Aliased item reexports of items_2 +pub mod items_3; +pub mod lib_3; // Aliased item reexports of items_3 +pub mod items_4; +pub mod lib_4_1; // Aliased item reexports of items_4 +pub mod lib_4_2; // Aliased item reexports of lib_4_1 +pub mod items_5; +pub mod lib_5_1; // Aliased trait reexports from items_5 +pub mod lib_5_2; // Aliased trait reexports from items_5 mod tests; // All tests diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/multiple_imports_of_same_reexport/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/multiple_imports_of_same_reexport/src/main.sw index c4f06aaf84f..29853e98b33 100755 --- a/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/multiple_imports_of_same_reexport/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/multiple_imports_of_same_reexport/src/main.sw @@ -1,8 +1,8 @@ script; -mod items_1; -mod lib_1_1; // Item reexports of items_1 -mod lib_1_2; // Item reexports of items_1 +pub mod items_1; +pub mod lib_1_1; // Item reexports of items_1 +pub mod lib_1_2; // Item reexports of items_1 mod tests; // All tests diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/shadowing_in_reexporting_module/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/shadowing_in_reexporting_module/src/main.sw index a2961173628..c0290b47faf 100755 --- a/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/shadowing_in_reexporting_module/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/shadowing_in_reexporting_module/src/main.sw @@ -1,17 +1,17 @@ script; -mod items_1; -mod lib_1; // Item reexports of items_1 -mod items_2_1; -mod items_2_2; -mod lib_2; // Item reexports of items_2_1 and items_2_2 -mod items_3_1; -mod lib_3; // Item reexports of items_3_1 and items_3_2 -mod items_4_1; -mod items_4_2; -mod items_4_3; -mod items_4_4; -mod lib_4; // Item reexports of items_4_1 and items_4_2 +pub mod items_1; +pub mod lib_1; // Item reexports of items_1 +pub mod items_2_1; +pub mod items_2_2; +pub mod lib_2; // Item reexports of items_2_1 and items_2_2 +pub mod items_3_1; +pub mod lib_3; // Item reexports of items_3_1 and items_3_2 +pub mod items_4_1; +pub mod items_4_2; +pub mod items_4_3; +pub mod items_4_4; +pub mod lib_4; // Item reexports of items_4_1 and items_4_2 mod tests; // All tests diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/simple_glob_import/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/simple_glob_import/src/main.sw index 57262307323..fe1ea19f9c1 100755 --- a/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/simple_glob_import/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/simple_glob_import/src/main.sw @@ -1,9 +1,9 @@ script; -mod items_1; -mod lib_1; // Item reexports of items_1 -mod items_2; -mod lib_2; // Item reexports of items_1 +pub mod items_1; +pub mod lib_1; // Item reexports of items_1 +pub mod items_2; +pub mod lib_2; // Item reexports of items_1 mod tests; // All tests diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/simple_item_import/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/simple_item_import/src/main.sw index 57262307323..8856faf59f6 100755 --- a/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/simple_item_import/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/simple_item_import/src/main.sw @@ -1,9 +1,11 @@ script; -mod items_1; -mod lib_1; // Item reexports of items_1 -mod items_2; -mod lib_2; // Item reexports of items_1 +pub mod items_1; +pub mod lib_1; // Item reexports of items_1 +pub mod items_2; +pub mod lib_2; // Item reexports of items_2 +pub mod items_3; +pub mod lib_3; // Item reexports of items_3 mod tests; // All tests diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/dca/unused_enum/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/dca/unused_enum/src/main.sw index ef39fb605a9..5fc24d795cf 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/dca/unused_enum/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/dca/unused_enum/src/main.sw @@ -1,6 +1,6 @@ script; -mod r#enum; +pub mod r#enum; mod utils; fn main() { diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/dca/unused_trait/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/dca/unused_trait/src/main.sw index 2607dbb987a..7a95e67d0a5 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/dca/unused_trait/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/dca/unused_trait/src/main.sw @@ -1,6 +1,6 @@ script; -mod r#trait; +pub mod r#trait; mod utils; use r#trait::Trait; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_traits/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_traits/src/main.sw index 3e5e72a76e3..f050a4cc0fc 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_traits/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_traits/src/main.sw @@ -4,9 +4,9 @@ script; // but until then, multiple methods with the same name is undefined behavior. // https://doc.rust-lang.org/rust-by-example/trait/disambiguating.html -mod my_double; +pub mod my_double; mod my_point; -mod my_triple; +pub mod my_triple; use my_point::MyPoint; use my_triple::MyTriple; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/import_method_from_other_file/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/import_method_from_other_file/src/main.sw index 136515fc5c3..1f0fbad59be 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/import_method_from_other_file/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/import_method_from_other_file/src/main.sw @@ -1,7 +1,7 @@ script; mod context; -mod asset; +pub mod asset; mod utils; use context::Context; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/import_with_different_callpaths/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/import_with_different_callpaths/src/main.sw index 29e6fe78ddf..d672a617d81 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/import_with_different_callpaths/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/import_with_different_callpaths/src/main.sw @@ -1,6 +1,6 @@ script; -mod data_structures; +pub mod data_structures; mod eq_impls; use eq_impls::*; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_constants/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_constants/src/main.sw index ffa92ace5e7..df1535977a6 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_constants/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_constants/src/main.sw @@ -1,6 +1,6 @@ script; -mod lib; +pub mod lib; mod top_level; mod in_structs; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/module_dep/src/lib.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/module_dep/src/lib.sw index e59f07dba62..94d40f22f5b 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/module_dep/src/lib.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/module_dep/src/lib.sw @@ -1,7 +1,7 @@ library; -mod a; -mod b; +pub mod a; +pub mod b; fn main() -> u32 { 1 diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/module_dep_multiple/src/lib.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/module_dep_multiple/src/lib.sw index 06ceb2f6e8b..db23337b474 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/module_dep_multiple/src/lib.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/module_dep_multiple/src/lib.sw @@ -1,8 +1,8 @@ library; mod c; -mod a; -mod b; +pub mod a; +pub mod b; fn main() -> u32 { 1 diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/aliases/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/aliases/src/main.sw index 18a842fa725..b1a1ee9b298 100755 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/aliases/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/aliases/src/main.sw @@ -1,15 +1,15 @@ script; -mod items_1; -mod lib_1; // Aliased item reexports of items_1 -mod items_2; -mod lib_2; // Aliased item reexports of items_2 -mod items_3; -mod lib_3_1; // Aliased item reexports of items_3 -mod lib_3_2; // Aliased item reexports of lib_3_1 -mod items_4; -mod lib_4_1; // Aliased item reexports of items_4 -mod lib_4_2; // Aliased item reexports of items_4 with different aliases +pub mod items_1; +pub mod lib_1; // Aliased item reexports of items_1 +pub mod items_2; +pub mod lib_2; // Aliased item reexports of items_2 +pub mod items_3; +pub mod lib_3_1; // Aliased item reexports of items_3 +pub mod lib_3_2; // Aliased item reexports of lib_3_1 +pub mod items_4; +pub mod lib_4_1; // Aliased item reexports of items_4 +pub mod lib_4_2; // Aliased item reexports of items_4 with different aliases mod tests; // All tests diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/multiple_imports_of_same_reexport/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/multiple_imports_of_same_reexport/src/main.sw index 4ae46fbab15..01cd29bb68c 100755 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/multiple_imports_of_same_reexport/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/multiple_imports_of_same_reexport/src/main.sw @@ -1,17 +1,17 @@ script; -mod items_1; -mod lib_1_1; // Item reexports of items_1 -mod lib_1_2; // Item reexports of items_1 -mod items_2; -mod lib_2_1; // Star reexports of items_2 -mod lib_2_2; // Star reexports of items_2 -mod items_3; -mod lib_3_1; // Star reexports of items_3 -mod lib_3_2; // Item reexports of items_3 -mod items_4; -mod lib_4_1; // Item reexports of items_4 -mod lib_4_2; // Star reexports of items_4 +pub mod items_1; +pub mod lib_1_1; // Item reexports of items_1 +pub mod lib_1_2; // Item reexports of items_1 +pub mod items_2; +pub mod lib_2_1; // Star reexports of items_2 +pub mod lib_2_2; // Star reexports of items_2 +pub mod items_3; +pub mod lib_3_1; // Star reexports of items_3 +pub mod lib_3_2; // Item reexports of items_3 +pub mod items_4; +pub mod lib_4_1; // Item reexports of items_4 +pub mod lib_4_2; // Star reexports of items_4 mod tests; // All tests diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/reexport_paths/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/reexport_paths/src/main.sw index 84a4dffa3df..738e0d7b893 100755 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/reexport_paths/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/reexport_paths/src/main.sw @@ -1,15 +1,15 @@ script; -mod items_1; -mod lib_1_1; // Reexports of items_1 -mod lib_1_2; // Reexports of lib_1_1 -mod lib_2; // Reexports of std::hash::Hasher, which is not part of the std prelude -mod lib_3_1; // Reexports of std::hash::Hash, which is not part of the std prelude -mod lib_3_2; // Reexports of std::hash::Hash, which is not part of the std prelude -mod lib_4; // Reexport of std::registers::global_gas -mod lib_5; // Reexport of core::codec::* -//mod lib_6_1; // Reexports of std::address::Address from the std prelude -mod lib_6_2; // Reexports of std::address::Address directly from std::address +pub mod items_1; +pub mod lib_1_1; // Reexports of items_1 +pub mod lib_1_2; // Reexports of lib_1_1 +pub mod lib_2; // Reexports of std::hash::Hasher, which is not part of the std prelude +pub mod lib_3_1; // Reexports of std::hash::Hash, which is not part of the std prelude +pub mod lib_3_2; // Reexports of std::hash::Hash, which is not part of the std prelude +pub mod lib_4; // Reexport of std::registers::global_gas +pub mod lib_5; // Reexport of core::codec::* +//pub mod lib_6_1; // Reexports of std::address::Address from the std prelude +pub mod lib_6_2; // Reexports of std::address::Address directly from std::address mod tests; // All tests diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/shadowing_in_reexporting_module/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/shadowing_in_reexporting_module/src/main.sw index a2961173628..c0290b47faf 100755 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/shadowing_in_reexporting_module/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/shadowing_in_reexporting_module/src/main.sw @@ -1,17 +1,17 @@ script; -mod items_1; -mod lib_1; // Item reexports of items_1 -mod items_2_1; -mod items_2_2; -mod lib_2; // Item reexports of items_2_1 and items_2_2 -mod items_3_1; -mod lib_3; // Item reexports of items_3_1 and items_3_2 -mod items_4_1; -mod items_4_2; -mod items_4_3; -mod items_4_4; -mod lib_4; // Item reexports of items_4_1 and items_4_2 +pub mod items_1; +pub mod lib_1; // Item reexports of items_1 +pub mod items_2_1; +pub mod items_2_2; +pub mod lib_2; // Item reexports of items_2_1 and items_2_2 +pub mod items_3_1; +pub mod lib_3; // Item reexports of items_3_1 and items_3_2 +pub mod items_4_1; +pub mod items_4_2; +pub mod items_4_3; +pub mod items_4_4; +pub mod lib_4; // Item reexports of items_4_1 and items_4_2 mod tests; // All tests diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/simple_glob_import/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/simple_glob_import/src/main.sw index 57262307323..fe1ea19f9c1 100755 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/simple_glob_import/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/simple_glob_import/src/main.sw @@ -1,9 +1,9 @@ script; -mod items_1; -mod lib_1; // Item reexports of items_1 -mod items_2; -mod lib_2; // Item reexports of items_1 +pub mod items_1; +pub mod lib_1; // Item reexports of items_1 +pub mod items_2; +pub mod lib_2; // Item reexports of items_1 mod tests; // All tests diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/simple_item_import/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/simple_item_import/src/main.sw index 0b3777176d7..6470ef09668 100755 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/simple_item_import/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/simple_item_import/src/main.sw @@ -1,9 +1,9 @@ script; -mod items_1; -mod lib_1; // Item reexports of items_1 -mod items_2; -mod lib_2; // Item reexports of items_2 +pub mod items_1; +pub mod lib_1; // Item reexports of items_1 +pub mod items_2; +pub mod lib_2; // Item reexports of items_2 mod tests; // All tests diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/visibility/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/visibility/src/main.sw index 078a2114541..55d7e81f033 100755 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/visibility/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/reexport/visibility/src/main.sw @@ -1,11 +1,11 @@ script; -mod items_1; -mod lib_1_1; // Item reexports of items_1 -mod lib_1_2; // Item imports without reexport of items_1 -mod items_2; -mod lib_2_1; // Item imports without reexport of items_1 -mod lib_2_2; // Item reexports of items_1 +pub mod items_1; +pub mod lib_1_1; // Item reexports of items_1 +pub mod lib_1_2; // Item imports without reexport of items_1 +pub mod items_2; +pub mod lib_2_1; // Item imports without reexport of items_1 +pub mod lib_2_2; // Item reexports of items_1 mod tests; // All tests diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/use_absolute_path/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/use_absolute_path/src/main.sw index ce2c888d964..4dd52fdef97 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/use_absolute_path/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/use_absolute_path/src/main.sw @@ -1,6 +1,6 @@ script; -mod r#trait; +pub mod r#trait; mod foo; use ::foo::*; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/option/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/option/src/main.sw index f37ed2f5bff..ea66b079683 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/option/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/option/src/main.sw @@ -1,6 +1,6 @@ script; -mod data_structures; +pub mod data_structures; mod tests; use tests::*; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/result/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/result/src/main.sw index f37ed2f5bff..ea66b079683 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/result/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/result/src/main.sw @@ -1,6 +1,6 @@ script; -mod data_structures; +pub mod data_structures; mod tests; use tests::*; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/return_struct/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/return_struct/src/main.sw index 1dd7e0293ea..92e93915701 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/return_struct/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/return_struct/src/main.sw @@ -1,6 +1,6 @@ contract; -mod data_structures; +pub mod data_structures; mod interface; use interface::MyContract; From 1dfca80d7cc7bba9aa936b9dfbab3dbf8c3bb760 Mon Sep 17 00:00:00 2001 From: Cameron Carstens Date: Fri, 15 Nov 2024 13:17:02 +0700 Subject: [PATCH 115/115] Make `OrdEq` trait public (#6723) ## Description An internal contributor noted that the `OrdEq` trait was private. Although it could be used if implemented on the `impl` statement directly, this has been made public to allow for importing through the `use` statement. ## 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. --------- Co-authored-by: Joshua Batty Co-authored-by: IGI-111 --- .../src/tests/expects/impl_trait/mod.rs | 205 +++++++++--------- sway-lib-core/src/ops.sw | 2 +- 2 files changed, 104 insertions(+), 103 deletions(-) diff --git a/forc-plugins/forc-doc/src/tests/expects/impl_trait/mod.rs b/forc-plugins/forc-doc/src/tests/expects/impl_trait/mod.rs index d68364e7e4f..602b66f49d7 100644 --- a/forc-plugins/forc-doc/src/tests/expects/impl_trait/mod.rs +++ b/forc-plugins/forc-doc/src/tests/expects/impl_trait/mod.rs @@ -36,131 +36,132 @@ fn test_impl_traits_default() { assert_search_js( &doc_path, &expect![[r#" - var SEARCH_INDEX={"core":[{"html_filename":"trait.AsRawSlice.html","module_info":["core","raw_slice"],"name":"AsRawSlice","preview":"Trait to return a type as a raw_slice.\n","type_name":"trait"},{"html_filename":"fn.from_str_array.html","module_info":["core","str"],"name":"from_str_array","preview":"","type_name":"function"},{"html_filename":"trait.Add.html","module_info":["core","ops"],"name":"Add","preview":"Trait for the addition of two values.\n","type_name":"trait"},{"html_filename":"trait.Subtract.html","module_info":["core","ops"],"name":"Subtract","preview":"Trait for the subtraction of two values.\n","type_name":"trait"},{"html_filename":"trait.Multiply.html","module_info":["core","ops"],"name":"Multiply","preview":"Trait for the multiplication of two values.\n","type_name":"trait"},{"html_filename":"trait.Divide.html","module_info":["core","ops"],"name":"Divide","preview":"Trait for the division of two values.\n","type_name":"trait"},{"html_filename":"trait.Mod.html","module_info":["core","ops"],"name":"Mod","preview":"Trait for the modulo of two values.\n","type_name":"trait"},{"html_filename":"trait.Not.html","module_info":["core","ops"],"name":"Not","preview":"Trait to invert a type.\n","type_name":"trait"},{"html_filename":"trait.Eq.html","module_info":["core","ops"],"name":"Eq","preview":"Trait to evaluate if two types are equal.\n","type_name":"trait"},{"html_filename":"trait.Ord.html","module_info":["core","ops"],"name":"Ord","preview":"Trait to evaluate if one value is greater or less than another of the same type.\n","type_name":"trait"},{"html_filename":"trait.BitwiseAnd.html","module_info":["core","ops"],"name":"BitwiseAnd","preview":"Trait to bitwise AND two values of the same type.\n","type_name":"trait"},{"html_filename":"trait.BitwiseOr.html","module_info":["core","ops"],"name":"BitwiseOr","preview":"Trait to bitwise OR two values of the same type.\n","type_name":"trait"},{"html_filename":"trait.BitwiseXor.html","module_info":["core","ops"],"name":"BitwiseXor","preview":"Trait to bitwise XOR two values of the same type.\n","type_name":"trait"},{"html_filename":"trait.Shift.html","module_info":["core","ops"],"name":"Shift","preview":"Trait to bit shift a value.\n","type_name":"trait"},{"html_filename":"trait.TotalOrd.html","module_info":["core","ops"],"name":"TotalOrd","preview":"Trait to compare values of the same type.\n","type_name":"trait"},{"html_filename":"fn.ok_str_eq.html","module_info":["core","ops"],"name":"ok_str_eq","preview":"","type_name":"function"},{"html_filename":"struct.StorageKey.html","module_info":["core","storage"],"name":"StorageKey","preview":"Describes a location in storage.\n","type_name":"struct"},{"html_filename":"struct.Buffer.html","module_info":["core","codec"],"name":"Buffer","preview":"","type_name":"struct"},{"html_filename":"struct.BufferReader.html","module_info":["core","codec"],"name":"BufferReader","preview":"","type_name":"struct"},{"html_filename":"trait.AbiDecode.html","module_info":["core","codec"],"name":"AbiDecode","preview":"","type_name":"trait"},{"html_filename":"trait.AbiEncode.html","module_info":["core","codec"],"name":"AbiEncode","preview":"","type_name":"trait"},{"html_filename":"fn.encode.html","module_info":["core","codec"],"name":"encode","preview":"","type_name":"function"},{"html_filename":"fn.abi_decode.html","module_info":["core","codec"],"name":"abi_decode","preview":"","type_name":"function"},{"html_filename":"fn.abi_decode_in_place.html","module_info":["core","codec"],"name":"abi_decode_in_place","preview":"","type_name":"function"},{"html_filename":"fn.contract_call.html","module_info":["core","codec"],"name":"contract_call","preview":"","type_name":"function"},{"html_filename":"fn.decode_script_data.html","module_info":["core","codec"],"name":"decode_script_data","preview":"","type_name":"function"},{"html_filename":"fn.decode_predicate_data.html","module_info":["core","codec"],"name":"decode_predicate_data","preview":"","type_name":"function"},{"html_filename":"fn.decode_predicate_data_by_index.html","module_info":["core","codec"],"name":"decode_predicate_data_by_index","preview":"","type_name":"function"},{"html_filename":"fn.decode_first_param.html","module_info":["core","codec"],"name":"decode_first_param","preview":"","type_name":"function"},{"html_filename":"fn.decode_second_param.html","module_info":["core","codec"],"name":"decode_second_param","preview":"","type_name":"function"},{"html_filename":"primitive.u256.html","module_info":["core"],"name":"u256","preview":"256-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.u64.html","module_info":["core"],"name":"u64","preview":"64-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.u32.html","module_info":["core"],"name":"u32","preview":"32-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.u16.html","module_info":["core"],"name":"u16","preview":"16-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.u8.html","module_info":["core"],"name":"u8","preview":"8-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.b256.html","module_info":["core"],"name":"b256","preview":"256 bits (32 bytes), i.e. a hash","type_name":"primitive"},{"html_filename":"primitive.str.html","module_info":["core"],"name":"str","preview":"string slice","type_name":"primitive"},{"html_filename":"primitive.bool.html","module_info":["core"],"name":"bool","preview":"Boolean true or false","type_name":"primitive"},{"html_filename":"primitive.str[0].html","module_info":["core"],"name":"str[0]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[1].html","module_info":["core"],"name":"str[1]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[2].html","module_info":["core"],"name":"str[2]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[3].html","module_info":["core"],"name":"str[3]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[4].html","module_info":["core"],"name":"str[4]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[5].html","module_info":["core"],"name":"str[5]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[6].html","module_info":["core"],"name":"str[6]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[7].html","module_info":["core"],"name":"str[7]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[8].html","module_info":["core"],"name":"str[8]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[9].html","module_info":["core"],"name":"str[9]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[10].html","module_info":["core"],"name":"str[10]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[11].html","module_info":["core"],"name":"str[11]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[12].html","module_info":["core"],"name":"str[12]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[13].html","module_info":["core"],"name":"str[13]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[14].html","module_info":["core"],"name":"str[14]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[15].html","module_info":["core"],"name":"str[15]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[16].html","module_info":["core"],"name":"str[16]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[17].html","module_info":["core"],"name":"str[17]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[18].html","module_info":["core"],"name":"str[18]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[19].html","module_info":["core"],"name":"str[19]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[20].html","module_info":["core"],"name":"str[20]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[21].html","module_info":["core"],"name":"str[21]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[22].html","module_info":["core"],"name":"str[22]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[23].html","module_info":["core"],"name":"str[23]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[24].html","module_info":["core"],"name":"str[24]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[25].html","module_info":["core"],"name":"str[25]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[26].html","module_info":["core"],"name":"str[26]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[27].html","module_info":["core"],"name":"str[27]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[28].html","module_info":["core"],"name":"str[28]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[29].html","module_info":["core"],"name":"str[29]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[30].html","module_info":["core"],"name":"str[30]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[31].html","module_info":["core"],"name":"str[31]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[32].html","module_info":["core"],"name":"str[32]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[33].html","module_info":["core"],"name":"str[33]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[34].html","module_info":["core"],"name":"str[34]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[35].html","module_info":["core"],"name":"str[35]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[36].html","module_info":["core"],"name":"str[36]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[37].html","module_info":["core"],"name":"str[37]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[38].html","module_info":["core"],"name":"str[38]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[39].html","module_info":["core"],"name":"str[39]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[40].html","module_info":["core"],"name":"str[40]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[41].html","module_info":["core"],"name":"str[41]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[42].html","module_info":["core"],"name":"str[42]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[43].html","module_info":["core"],"name":"str[43]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[44].html","module_info":["core"],"name":"str[44]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[45].html","module_info":["core"],"name":"str[45]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[46].html","module_info":["core"],"name":"str[46]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[47].html","module_info":["core"],"name":"str[47]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[48].html","module_info":["core"],"name":"str[48]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[49].html","module_info":["core"],"name":"str[49]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[50].html","module_info":["core"],"name":"str[50]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[51].html","module_info":["core"],"name":"str[51]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[52].html","module_info":["core"],"name":"str[52]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[53].html","module_info":["core"],"name":"str[53]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[54].html","module_info":["core"],"name":"str[54]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[55].html","module_info":["core"],"name":"str[55]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[56].html","module_info":["core"],"name":"str[56]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[57].html","module_info":["core"],"name":"str[57]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[58].html","module_info":["core"],"name":"str[58]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[59].html","module_info":["core"],"name":"str[59]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[60].html","module_info":["core"],"name":"str[60]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[61].html","module_info":["core"],"name":"str[61]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[62].html","module_info":["core"],"name":"str[62]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[63].html","module_info":["core"],"name":"str[63]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[64].html","module_info":["core"],"name":"str[64]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"index.html","module_info":["core"],"name":"core","preview":"","type_name":"module"},{"html_filename":"index.html","module_info":["core","codec"],"name":"codec","preview":"","type_name":"module"},{"html_filename":"index.html","module_info":["core","ops"],"name":"ops","preview":"","type_name":"module"},{"html_filename":"index.html","module_info":["core","raw_slice"],"name":"raw_slice","preview":"","type_name":"module"},{"html_filename":"index.html","module_info":["core","storage"],"name":"storage","preview":"","type_name":"module"},{"html_filename":"index.html","module_info":["core","str"],"name":"str","preview":"","type_name":"module"}],"impl_traits":[{"html_filename":"trait.Foo.html","module_info":["impl_traits","foo"],"name":"Foo","preview":"","type_name":"trait"},{"html_filename":"trait.Baz.html","module_info":["impl_traits","foo"],"name":"Baz","preview":"","type_name":"trait"},{"html_filename":"struct.Bar.html","module_info":["impl_traits","bar"],"name":"Bar","preview":"","type_name":"struct"},{"html_filename":"index.html","module_info":["impl_traits","bar"],"name":"bar","preview":"","type_name":"module"},{"html_filename":"index.html","module_info":["impl_traits","foo"],"name":"foo","preview":"","type_name":"module"}]}; + var SEARCH_INDEX={"core":[{"html_filename":"trait.AsRawSlice.html","module_info":["core","raw_slice"],"name":"AsRawSlice","preview":"Trait to return a type as a raw_slice.\n","type_name":"trait"},{"html_filename":"fn.from_str_array.html","module_info":["core","str"],"name":"from_str_array","preview":"","type_name":"function"},{"html_filename":"trait.Add.html","module_info":["core","ops"],"name":"Add","preview":"Trait for the addition of two values.\n","type_name":"trait"},{"html_filename":"trait.Subtract.html","module_info":["core","ops"],"name":"Subtract","preview":"Trait for the subtraction of two values.\n","type_name":"trait"},{"html_filename":"trait.Multiply.html","module_info":["core","ops"],"name":"Multiply","preview":"Trait for the multiplication of two values.\n","type_name":"trait"},{"html_filename":"trait.Divide.html","module_info":["core","ops"],"name":"Divide","preview":"Trait for the division of two values.\n","type_name":"trait"},{"html_filename":"trait.Mod.html","module_info":["core","ops"],"name":"Mod","preview":"Trait for the modulo of two values.\n","type_name":"trait"},{"html_filename":"trait.Not.html","module_info":["core","ops"],"name":"Not","preview":"Trait to invert a type.\n","type_name":"trait"},{"html_filename":"trait.Eq.html","module_info":["core","ops"],"name":"Eq","preview":"Trait to evaluate if two types are equal.\n","type_name":"trait"},{"html_filename":"trait.Ord.html","module_info":["core","ops"],"name":"Ord","preview":"Trait to evaluate if one value is greater or less than another of the same type.\n","type_name":"trait"},{"html_filename":"trait.BitwiseAnd.html","module_info":["core","ops"],"name":"BitwiseAnd","preview":"Trait to bitwise AND two values of the same type.\n","type_name":"trait"},{"html_filename":"trait.BitwiseOr.html","module_info":["core","ops"],"name":"BitwiseOr","preview":"Trait to bitwise OR two values of the same type.\n","type_name":"trait"},{"html_filename":"trait.BitwiseXor.html","module_info":["core","ops"],"name":"BitwiseXor","preview":"Trait to bitwise XOR two values of the same type.\n","type_name":"trait"},{"html_filename":"trait.OrdEq.html","module_info":["core","ops"],"name":"OrdEq","preview":"Trait to evaluate if one value is greater than or equal, or less than or equal to another of the same type.","type_name":"trait"},{"html_filename":"trait.Shift.html","module_info":["core","ops"],"name":"Shift","preview":"Trait to bit shift a value.\n","type_name":"trait"},{"html_filename":"trait.TotalOrd.html","module_info":["core","ops"],"name":"TotalOrd","preview":"Trait to compare values of the same type.\n","type_name":"trait"},{"html_filename":"fn.ok_str_eq.html","module_info":["core","ops"],"name":"ok_str_eq","preview":"","type_name":"function"},{"html_filename":"struct.StorageKey.html","module_info":["core","storage"],"name":"StorageKey","preview":"Describes a location in storage.\n","type_name":"struct"},{"html_filename":"struct.Buffer.html","module_info":["core","codec"],"name":"Buffer","preview":"","type_name":"struct"},{"html_filename":"struct.BufferReader.html","module_info":["core","codec"],"name":"BufferReader","preview":"","type_name":"struct"},{"html_filename":"trait.AbiDecode.html","module_info":["core","codec"],"name":"AbiDecode","preview":"","type_name":"trait"},{"html_filename":"trait.AbiEncode.html","module_info":["core","codec"],"name":"AbiEncode","preview":"","type_name":"trait"},{"html_filename":"fn.encode.html","module_info":["core","codec"],"name":"encode","preview":"","type_name":"function"},{"html_filename":"fn.abi_decode.html","module_info":["core","codec"],"name":"abi_decode","preview":"","type_name":"function"},{"html_filename":"fn.abi_decode_in_place.html","module_info":["core","codec"],"name":"abi_decode_in_place","preview":"","type_name":"function"},{"html_filename":"fn.contract_call.html","module_info":["core","codec"],"name":"contract_call","preview":"","type_name":"function"},{"html_filename":"fn.decode_script_data.html","module_info":["core","codec"],"name":"decode_script_data","preview":"","type_name":"function"},{"html_filename":"fn.decode_predicate_data.html","module_info":["core","codec"],"name":"decode_predicate_data","preview":"","type_name":"function"},{"html_filename":"fn.decode_predicate_data_by_index.html","module_info":["core","codec"],"name":"decode_predicate_data_by_index","preview":"","type_name":"function"},{"html_filename":"fn.decode_first_param.html","module_info":["core","codec"],"name":"decode_first_param","preview":"","type_name":"function"},{"html_filename":"fn.decode_second_param.html","module_info":["core","codec"],"name":"decode_second_param","preview":"","type_name":"function"},{"html_filename":"primitive.u256.html","module_info":["core"],"name":"u256","preview":"256-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.u64.html","module_info":["core"],"name":"u64","preview":"64-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.u32.html","module_info":["core"],"name":"u32","preview":"32-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.u16.html","module_info":["core"],"name":"u16","preview":"16-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.u8.html","module_info":["core"],"name":"u8","preview":"8-bit unsigned integer","type_name":"primitive"},{"html_filename":"primitive.b256.html","module_info":["core"],"name":"b256","preview":"256 bits (32 bytes), i.e. a hash","type_name":"primitive"},{"html_filename":"primitive.str.html","module_info":["core"],"name":"str","preview":"string slice","type_name":"primitive"},{"html_filename":"primitive.bool.html","module_info":["core"],"name":"bool","preview":"Boolean true or false","type_name":"primitive"},{"html_filename":"primitive.str[0].html","module_info":["core"],"name":"str[0]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[1].html","module_info":["core"],"name":"str[1]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[2].html","module_info":["core"],"name":"str[2]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[3].html","module_info":["core"],"name":"str[3]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[4].html","module_info":["core"],"name":"str[4]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[5].html","module_info":["core"],"name":"str[5]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[6].html","module_info":["core"],"name":"str[6]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[7].html","module_info":["core"],"name":"str[7]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[8].html","module_info":["core"],"name":"str[8]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[9].html","module_info":["core"],"name":"str[9]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[10].html","module_info":["core"],"name":"str[10]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[11].html","module_info":["core"],"name":"str[11]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[12].html","module_info":["core"],"name":"str[12]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[13].html","module_info":["core"],"name":"str[13]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[14].html","module_info":["core"],"name":"str[14]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[15].html","module_info":["core"],"name":"str[15]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[16].html","module_info":["core"],"name":"str[16]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[17].html","module_info":["core"],"name":"str[17]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[18].html","module_info":["core"],"name":"str[18]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[19].html","module_info":["core"],"name":"str[19]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[20].html","module_info":["core"],"name":"str[20]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[21].html","module_info":["core"],"name":"str[21]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[22].html","module_info":["core"],"name":"str[22]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[23].html","module_info":["core"],"name":"str[23]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[24].html","module_info":["core"],"name":"str[24]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[25].html","module_info":["core"],"name":"str[25]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[26].html","module_info":["core"],"name":"str[26]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[27].html","module_info":["core"],"name":"str[27]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[28].html","module_info":["core"],"name":"str[28]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[29].html","module_info":["core"],"name":"str[29]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[30].html","module_info":["core"],"name":"str[30]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[31].html","module_info":["core"],"name":"str[31]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[32].html","module_info":["core"],"name":"str[32]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[33].html","module_info":["core"],"name":"str[33]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[34].html","module_info":["core"],"name":"str[34]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[35].html","module_info":["core"],"name":"str[35]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[36].html","module_info":["core"],"name":"str[36]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[37].html","module_info":["core"],"name":"str[37]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[38].html","module_info":["core"],"name":"str[38]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[39].html","module_info":["core"],"name":"str[39]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[40].html","module_info":["core"],"name":"str[40]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[41].html","module_info":["core"],"name":"str[41]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[42].html","module_info":["core"],"name":"str[42]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[43].html","module_info":["core"],"name":"str[43]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[44].html","module_info":["core"],"name":"str[44]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[45].html","module_info":["core"],"name":"str[45]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[46].html","module_info":["core"],"name":"str[46]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[47].html","module_info":["core"],"name":"str[47]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[48].html","module_info":["core"],"name":"str[48]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[49].html","module_info":["core"],"name":"str[49]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[50].html","module_info":["core"],"name":"str[50]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[51].html","module_info":["core"],"name":"str[51]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[52].html","module_info":["core"],"name":"str[52]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[53].html","module_info":["core"],"name":"str[53]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[54].html","module_info":["core"],"name":"str[54]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[55].html","module_info":["core"],"name":"str[55]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[56].html","module_info":["core"],"name":"str[56]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[57].html","module_info":["core"],"name":"str[57]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[58].html","module_info":["core"],"name":"str[58]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[59].html","module_info":["core"],"name":"str[59]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[60].html","module_info":["core"],"name":"str[60]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[61].html","module_info":["core"],"name":"str[61]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[62].html","module_info":["core"],"name":"str[62]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[63].html","module_info":["core"],"name":"str[63]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"primitive.str[64].html","module_info":["core"],"name":"str[64]","preview":"fixed-length string","type_name":"primitive"},{"html_filename":"index.html","module_info":["core"],"name":"core","preview":"","type_name":"module"},{"html_filename":"index.html","module_info":["core","codec"],"name":"codec","preview":"","type_name":"module"},{"html_filename":"index.html","module_info":["core","ops"],"name":"ops","preview":"","type_name":"module"},{"html_filename":"index.html","module_info":["core","raw_slice"],"name":"raw_slice","preview":"","type_name":"module"},{"html_filename":"index.html","module_info":["core","storage"],"name":"storage","preview":"","type_name":"module"},{"html_filename":"index.html","module_info":["core","str"],"name":"str","preview":"","type_name":"module"}],"impl_traits":[{"html_filename":"trait.Foo.html","module_info":["impl_traits","foo"],"name":"Foo","preview":"","type_name":"trait"},{"html_filename":"trait.Baz.html","module_info":["impl_traits","foo"],"name":"Baz","preview":"","type_name":"trait"},{"html_filename":"struct.Bar.html","module_info":["impl_traits","bar"],"name":"Bar","preview":"","type_name":"struct"},{"html_filename":"index.html","module_info":["impl_traits","bar"],"name":"bar","preview":"","type_name":"module"},{"html_filename":"index.html","module_info":["impl_traits","foo"],"name":"foo","preview":"","type_name":"module"}]}; "object"==typeof exports&&"undefined"!=typeof module&&(module.exports=SEARCH_INDEX);"#]], ); assert_file_tree( doc_dir_name, project_name, vec![ - "core/primitive.str[26].html", - "core/primitive.str[54].html", - "core/primitive.u256.html", - "core/primitive.str[2].html", - "core/primitive.u8.html", + "core/ops/trait.TotalOrd.html", + "core/ops/trait.Mod.html", + "impl_traits/bar/index.html", + "impl_traits/all.html", "core/primitive.str[17].html", - "core/primitive.str[49].html", + "core/primitive.str[51].html", + "core/codec/fn.abi_decode.html", + "core/codec/struct.Buffer.html", + "core/codec/trait.AbiDecode.html", + "core/ops/trait.Divide.html", + "core/codec/fn.abi_decode_in_place.html", "core/primitive.str[34].html", - "core/primitive.str[46].html", - "core/primitive.str[15].html", - "core/primitive.str[21].html", - "core/primitive.str.html", - "core/primitive.str[24].html", - "core/primitive.str[38].html", - "core/primitive.str[47].html", - "core/primitive.str[31].html", - "core/primitive.bool.html", - "core/primitive.str[14].html", - "core/primitive.str[48].html", - "core/primitive.str[1].html", - "core/primitive.str[42].html", - "core/primitive.str[6].html", - "core/primitive.b256.html", - "core/primitive.str[5].html", - "core/primitive.str[43].html", + "core/codec/fn.decode_first_param.html", + "core/primitive.str[20].html", "core/primitive.str[4].html", - "core/primitive.str[19].html", - "core/primitive.str[25].html", - "core/primitive.str[57].html", - "core/primitive.str[56].html", + "core/primitive.str[42].html", "core/primitive.str[10].html", - "core/primitive.str[44].html", + "core/ops/trait.Subtract.html", + "core/primitive.str[28].html", + "core/primitive.u8.html", + "core/primitive.u256.html", + "core/str/fn.from_str_array.html", + "core/primitive.str[62].html", + "core/primitive.str[64].html", + "core/codec/trait.AbiEncode.html", + "core/primitive.str[8].html", + "core/primitive.str[43].html", + "core/codec/fn.decode_predicate_data_by_index.html", "core/primitive.str[37].html", - "core/primitive.str[0].html", - "core/primitive.str[53].html", - "core/primitive.str[59].html", - "core/primitive.str[22].html", - "core/primitive.str[33].html", - "core/primitive.str[27].html", - "core/primitive.str[13].html", + "core/primitive.b256.html", + "core/ops/trait.Eq.html", + "core/storage/index.html", + "core/primitive.str[58].html", + "core/primitive.str[44].html", + "core/raw_slice/index.html", "core/primitive.u16.html", - "core/primitive.str[3].html", "core/primitive.str[35].html", - "core/primitive.str[7].html", - "core/primitive.str[51].html", - "core/primitive.str[40].html", - "core/primitive.str[28].html", - "core/primitive.str[41].html", - "core/primitive.str[58].html", - "core/primitive.str[45].html", - "core/primitive.str[62].html", - "core/primitive.str[63].html", "core/primitive.str[60].html", - "core/primitive.str[50].html", - "core/primitive.str[55].html", - "core/primitive.str[8].html", - "core/primitive.str[32].html", - "core/primitive.str[23].html", - "core/primitive.str[30].html", - "core/primitive.str[61].html", - "core/primitive.str[18].html", - "core/primitive.u32.html", - "core/primitive.str[64].html", + "core/primitive.str[59].html", "core/primitive.str[39].html", - "core/primitive.str[29].html", - "core/primitive.str[11].html", - "core/primitive.str[20].html", - "core/primitive.str[9].html", - "core/primitive.str[12].html", + "core/primitive.str[49].html", + "core/primitive.str[40].html", + "core/index.html", + "search.js", + "core/ops/trait.OrdEq.html", + "core/primitive.bool.html", + "impl_traits/foo/trait.Baz.html", + "core/primitive.str.html", + "core/primitive.str[13].html", "core/primitive.u64.html", "core/primitive.str[16].html", - "core/primitive.str[36].html", - "core/primitive.str[52].html", - "core/all.html", - "core/codec/fn.abi_decode.html", - "core/codec/fn.abi_decode_in_place.html", - "core/codec/fn.contract_call.html", - "core/codec/fn.decode_predicate_data.html", - "core/codec/fn.decode_predicate_data_by_index.html", - "core/codec/fn.decode_first_param.html", - "core/codec/fn.decode_script_data.html", - "core/codec/fn.decode_second_param.html", - "core/codec/fn.encode.html", "core/codec/index.html", - "core/codec/struct.Buffer.html", - "core/codec/struct.BufferReader.html", - "core/codec/trait.AbiDecode.html", - "core/codec/trait.AbiEncode.html", - "core/index.html", - "core/ops/fn.ok_str_eq.html", + "core/primitive.str[47].html", + "core/primitive.str[57].html", + "core/ops/trait.Not.html", + "core/primitive.str[50].html", + "core/raw_slice/trait.AsRawSlice.html", + "core/primitive.str[24].html", + "core/primitive.str[56].html", "core/ops/index.html", - "core/ops/trait.Add.html", + "core/primitive.str[3].html", + "core/primitive.str[36].html", + "core/primitive.str[27].html", + "core/codec/fn.decode_script_data.html", + "impl_traits/index.html", + "core/primitive.str[12].html", + "impl_traits/foo/trait.Foo.html", + "core/primitive.str[15].html", + "core/primitive.str[29].html", + "core/primitive.str[22].html", "core/ops/trait.BitwiseAnd.html", - "core/ops/trait.BitwiseOr.html", - "core/ops/trait.BitwiseXor.html", - "core/ops/trait.Divide.html", - "core/ops/trait.Eq.html", - "core/ops/trait.Mod.html", - "core/ops/trait.Multiply.html", - "core/ops/trait.Not.html", + "core/all.html", + "core/primitive.str[11].html", "core/ops/trait.Ord.html", - "core/ops/trait.Shift.html", - "core/ops/trait.Subtract.html", - "core/ops/trait.TotalOrd.html", - "core/raw_slice/index.html", - "core/raw_slice/trait.AsRawSlice.html", - "core/storage/index.html", - "core/storage/struct.StorageKey.html", - "core/str/fn.from_str_array.html", "core/str/index.html", - "impl_traits/all.html", - "impl_traits/bar/index.html", - "impl_traits/bar/struct.Bar.html", + "core/primitive.str[31].html", "impl_traits/foo/index.html", - "impl_traits/foo/trait.Baz.html", - "impl_traits/foo/trait.Foo.html", - "impl_traits/index.html", - "search.js", + "core/primitive.str[55].html", + "core/primitive.str[38].html", + "core/codec/struct.BufferReader.html", + "core/primitive.str[54].html", + "core/primitive.str[53].html", + "core/primitive.str[19].html", + "core/storage/struct.StorageKey.html", + "core/primitive.str[25].html", + "core/primitive.str[30].html", + "core/codec/fn.encode.html", + "core/primitive.str[26].html", + "core/primitive.str[41].html", + "core/codec/fn.decode_second_param.html", + "core/primitive.u32.html", + "core/ops/fn.ok_str_eq.html", + "core/primitive.str[1].html", + "core/primitive.str[18].html", + "core/primitive.str[33].html", + "core/primitive.str[0].html", + "core/codec/fn.decode_predicate_data.html", + "core/primitive.str[9].html", + "core/ops/trait.Shift.html", + "core/ops/trait.Multiply.html", + "core/primitive.str[32].html", + "core/primitive.str[46].html", + "core/primitive.str[7].html", + "core/primitive.str[14].html", + "core/ops/trait.Add.html", + "core/primitive.str[23].html", + "core/primitive.str[52].html", + "core/primitive.str[48].html", + "core/primitive.str[2].html", + "core/primitive.str[5].html", + "impl_traits/bar/struct.Bar.html", + "core/primitive.str[63].html", + "core/primitive.str[21].html", + "core/codec/fn.contract_call.html", + "core/ops/trait.BitwiseXor.html", + "core/primitive.str[61].html", + "core/primitive.str[45].html", + "core/ops/trait.BitwiseOr.html", + "core/primitive.str[6].html", ], ); } diff --git a/sway-lib-core/src/ops.sw b/sway-lib-core/src/ops.sw index 371bbff5382..c49147bccae 100644 --- a/sway-lib-core/src/ops.sw +++ b/sway-lib-core/src/ops.sw @@ -995,7 +995,7 @@ impl BitwiseXor for u8 { } /// Trait to evaluate if one value is greater than or equal, or less than or equal to another of the same type. -trait OrdEq: Ord + Eq { +pub trait OrdEq: Ord + Eq { } { /// Evaluates if one value of the same type is greater or equal to than another. ///