Trivial fns allowing control if a type is trivially encoded/decoded
Description
Continuation of https://github.com/FuelLabs/sway/pull/7488.
This PR introduces the option for each type to control its own is_trivial.
Primitive data types have direct implementation (only decoding bool is false, as we need to guarantee its value is zero or one).
Structs, tuples, arrays etc... are trivial if their runtime representation and "inner types" allow for trivial encoding or decoding.
Enums are more complicated as we need to control that the enum tag is valid; they are not trivial.
String arrays are not trivially encoded/decoded for backwards compatibility with "encoding v0" that needs padding in some cases.
Some tests are showing a small regression (6 gas), which comes from the introduced "if" not being optimised away. I want to solve this in another PR, where the "if" condition will come from a const, and IR generation will guarantee that only one branch will ever be emitted.
Snapshot "echo"
Small QOL of snapshot was introduced with the "echo" command. It just prints the message directly, wrapping on 80 chars. The idea is to explain what the snapshot is trying to test.
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
- [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*orNew Featurelabels where relevant. - [x] I have done my best to ensure that my PR adheres to the Fuel Labs Code Review Standards.
- [ ] I have requested a review from the relevant team or maintainers.
[!NOTE] Add per-type trivial encode/decode flags and use raw_ptr fast paths in ABI (encode/decode) with supporting changes to codec, String/Vec, and tests.
- std/codec:
- Introduce
AbiEncode::is_encode_trivialandAbiDecode::is_decode_trivial; add helpersis_encode_trivial/is_decode_trivial.- Switch
encode/abi_decodeto branch on triviality; adddecode_from_raw_ptrand raw-ptr-baseddecode_*helpers.- Make
BufferReaderparameter accessors returnraw_ptr; minor refactors to use raw ptr copies.- Implement triviality for primitives, arrays/tuples (conditional),
str[strN]non-trivial, enums non-trivial.- std/string & std/vec: implement trivial encode/decode markers (non-trivial) and adapt codec impls.
- Tests/fixtures:
- Update snapshots (IR/ASM/bytecode/gas), JSON ABI offsets, contract/predicate IDs, and logging expectations to match new encoding paths.
Written by Cursor Bugbot for commit dddd944aba55150be64f0749bf4977ece3e1bb3c. This will update automatically on new commits. Configure here.
CodSpeed Performance Report
Merging #7501 will degrade performances by 12.57%
Comparing xunilrj/trivial-fns-codec-traits (9f6ed6e) with master (b4fa78d)
Summary
❌ 1 regression
✅ 24 untouched
:warning: Please fix the performance issues or acknowledge them on CodSpeed.
Benchmarks breakdown
| Benchmark | BASE |
HEAD |
Change | |
|---|---|---|---|---|
| ❌ | compile |
4.7 s | 5.3 s | -12.57% |
-13.24% compile time regression is a bit unfortunate. Any way we can get this number down a bit?
Bytecode e2e
| Improvements | Regressions | |
|---|---|---|
| Count | 106 | 37 |
| Average | 18.99% | -23.49% |
| Median | 13.27% | -6.36% |
| Max | 47.47% | -525.00% |
| Min | 0.61% | -0.52% |
Gas Usage e2e
| Improvements | Regressions | |
|---|---|---|
| Count | 40 | 19 |
| Average | 8.10% | -18.67% |
| Median | 5.77% | -2.89% |
| Max | 36.80% | -262.26% |
| Min | 0.04% | -0.21% |
Gas Usage In Langauge Tests
| Improvements | Regressions | |
|---|---|---|
| Count | 6 | 19 |
| Average | 1.41% | -1.94% |
| Median | 0.65% | -0.12% |
| Max | 3.64% | -13.59% |
| Min | 0.03% | -0.01% |
PR Summary
Introduce per-type trivial encode/decode flags in ABI, update implementations and snapshots (including new snapshot echo), and refresh contract IDs/tooling.
-
ABI/Encoding:
- Add per-type
AbiEncode/AbiDecodehooks:is_encode_trivial()andis_decode_trivial(); wire into primitives and composites (structs/tuples/arrays use inner/truntime checks; enums non-trivial; strings/Vecs non-trivial for v0 compat). - Implement non-trivial encode for
String,Vec<T>, and several test newtypes (raw ptr, custom error).
- Add per-type
-
Tests/Snapshots:
- Update IR/ASM, gas counts, and ABI JSON (offsets/log metadata) to reflect triviality and logging changes.
- Add unit-type enum logging; adjust various snapshots (array/tuple/const_generics/panic/logging/etc.).
- Add
echocommand to snapshot harness (80-char wrapped) for inline test descriptions.
-
Tooling/Misc:
- Update contract IDs across require-deployment tests; fix
update-contract-ids.shto pass path toforc contract-id.
- Update contract IDs across require-deployment tests; fix
Written by Cursor Bugbot for commit 9f6ed6ede3d19990ba02b0eabf8ad669e4ae96ad. This will update automatically on new commits. Configure here.
:+1:
gas usage e2e
| Improvements | Regressions | |
|---|---|---|
| Count | — | — |
| Average | — | — |
| Median | — | — |
| Max | — | — |
| Min | — | — |
gas usage in lang
| Improvements | Regressions | |
|---|---|---|
| Count | 17 | 34 |
| Average | 0.62% | -3.09% |
| Median | 0.03% | -1.82% |
| Max | 3.64% | -18.32% |
| Min | 0.01% | -0.01% |
Worst offender now are string arrays. Which are not trivially encoded/decoded anymore, because that layout issue that we have.