Latest Results
Implement dynamic storage based `StorageVec` (#7614)
## Description
This PR is an additional step in implementing #7560. It implements
`StorageVec<V>` for dynamic storage.
Additionally the PR:
- adds comprehensive test coverage for `StorageVec` in the form of
in-language tests. Existing SDK harness tests are deleted in favor of
new in-language tests. This is aligned with the agreed strategy to
migrate SDK harness tests to in-language tests.
- closes #6040 by properly documenting the semantics of zero-sized types
in relation to storage. Every `StorageVec<V>` methods that does not work
with zero-sized types, which are assumed to be nested storage types, is
now documented for limitations.
- fixes #7618 by accepting non-aligned types of any size in `store_vec`
and `load_vec` and padding them accordingly.
- fixes existing issue of over-allocating memory and having larger
amount of slot writes than needed in the quads-based implementation of
`store_vec`.
- consistently add reverts to all existing `StorageVec<V>` methods in
the quads-based implementation that cannot be used with nested storage
types. For more details see Breaking Changes below.
When running in-language tests using `forc test` on the whole workspace
two blocking issues occur:
- #7612
- #7613
Workarounds for those issues are commented in code and linked to the
issues.
Additional in-language tests for other storage types will be added in a
separate PR.
## Breaking Changes
Existing `StorageVec<V>` methods in the quads-based implementation that
cannot be used with nested storage types, e.g., `swap` now consistently
reverts if `V` is a nested storage type.
Previously, those methods:
- sometimes always reverted,
- sometimes reverted in specific paths,
- sometimes executed with undefined behavior.
Consistently reverting can be a breaking change if some existing code
called these methods and they were not reverting. Note that such calls
represent invalid usage of the storage API (although it was up to now
not clearly documented as such) and reverting will actually point to
bugs in existing callers code.
## 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. Disable initialization of dynamic storage fields larger than 32 bytes (#7622)
## Description
This PR disables emitting of `storage_slots.json` entries for `storage`
declaration fields whose size is larger than 32 bytes, when compiled
with `dynamic_storage` enabled.
This is a temporary solution for the currently missing possibility to
create transactions that can initial dynamic storage. In a follow up PR
we will:
- make initialization of `storage` fields optional,
- provide explicit compiler error if a dynamic storage field larger than
32 bytes is initialized.
This temporary solution of initializing fields <=32 bytes works because
initializing dynamic storage fields using the current transaction
creation where 32-byte slots are accepted is compatible with dynamic
storage read from those fields.
Additionally, the PR:
- removes validating storage slots from E2E tests where there were no
`storage` declaration at all. Instead, it adds a single, dedicated
`storage_slots_json_generation_empty_storage` test for testing
generation of empty storage slots JSON files.
- adds support for different `json_storage_slot_oracle` files for
different experimental features and build profiles. Note that this
functionality was already supported for `json_abi_oracle` files.
- adds `--storage-only` CI argument for filtering only E2E tests that
validate storage slot JSON
- closes #7609 by validating ABI and storage slot JSON files in
"unit_tests_pass" tests, and by deleting all remaining legacy
`json_abi_oracle_flat*.json` files.
## 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. Fix tuple codec helpers to avoid LSP stack overflows (#7611)
## Summary
I reproduced an LSP crash where opening and incrementally editing
`fuel-o2-exports/contracts/order-book/src/main.sw` could abort the
server and leave stale semantic highlighting behind in the client.
Daniel pointed out that the generated tuple helpers in `std::codec` are
emitted as one large left-associative `&&` chain. This change fixes the
root recursion pressure there instead of carrying the LSP stack-size
workaround.
The generator change is in `sway-lib-std/generate.sh`, and the
regenerated output is checked in at `sway-lib-std/src/codec.sw`. The
snapshot updates are included because the generated helper shape changes
source spans, IR local numbering, bytecode size, and a few gas values in
the affected e2e snapshot outputs.
## Root cause
The LSP crash was a stack overflow while processing generated
`std::codec` tuple code. The tuple triviality helpers were emitted as
deeply left-associated `&&` expressions, e.g. one expression chaining
checks across all tuple elements.
Because `&&` is left-associative, that produces a deeply left-leaning
AST. Recursive compiler and LSP passes then consume one stack frame per
node while lowering, traversing, or building semantic-token state. On
the `fuel-o2-exports` order-book repro, that was enough to bring down
the language server and leave stale semantic highlighting in the editor.
The earlier LSP stack-size mitigation kept the process alive by giving
those recursive paths more stack. Daniel's suggestion fixes the
source-level shape that was creating the stack pressure in the first
place.
## Why this mitigates it
The tuple helpers now use:
```sway
let r = __runtime_mem_id::<Self>() == __encoding_mem_id::<Self>();
let r = r && is_encode_trivial::<A>();
let r = r && is_encode_trivial::<B>();
r
```
instead of one large chained expression.
That keeps each expression shallow, so compiler and LSP recursion does
not scale with the full tuple arity in a single left-deep AST. The
language server no longer needs the stack-size workaround for this
repro.
## Validation
- regenerated `sway-lib-std/src/codec.sw` from
`sway-lib-std/generate.sh`
- verified regeneration produced no extra generated-file diff beyond the
checked-in `codec.sw`
- verified no generated left-deep tuple triviality chains remain
- `RUSTUP_TOOLCHAIN=1.93.0 cargo build -p forc-lsp --release`
- tested in an isolated VS Code session using the rebuilt
`target/release/forc-lsp`
- opened `fuel-o2-exports/contracts/order-book/src/main.sw`
- exercised the original edit/semantic-highlighting path
- observed `225` `textDocument/didChange` notifications and `11`
`textDocument/semanticTokens/range` requests
- no panic, stack overflow, abort, server exit, or stale-highlighting
failure reproduced
- updated the affected e2e `stdout.snap` files after CI snapshot drift
- `RUSTUP_TOOLCHAIN=1.93.0 cargo run --locked --release --bin test --
--locked --kind snapshot` Latest Branches
-15%
ironcev/optimize-vec-encoding-decoding 0%
+17%
ironcev/const-generic-array-not-an-indexable-type © 2026 CodSpeed Technology