Latest Results
Remove cloning of parsed tree elements during type checking (#7667)
## Description
This PR removes excessive unnecessary cloning of parsed tree elements
(parsed declarations and expressions) during type checking.
Removing cloning further reduces compilation time of the `order-book`
contract **from ~4.3 to ~4.1 seconds**.
Here is the number of `clone()` calls (taken from the `order-book`
contract) for several parsed tree elements, _given just for the highest
levels of transformation_:
| Parsed element | Number of `clone()`s |
| ---------------------------- | -------------------: |
| AstNodeContent | 23778 |
| VariableDeclaration | 9321 |
| ImplSelfOrTrait | 1244 |
| ConstantDeclaration | 308 |
| StructDeclaration | 104 |
| EnumDeclaration | 48 |
| TraitDeclaration | 43 |
| AbiDeclaration | 27 |
| ConfigurableDeclaration | 22 |
Note that these is only the cloning at the highest level of
transformation from the parsed to typed tree. **Those cloned element or
their contained elements were later repeatedly cloned on lower steps,
especially parsed `Expression`s.**
When creating final typed tree elements, we still clone some parts of
their corresponding parsed tree elements. Those are mostly `Span`s,
`Attributes` (only `Arc` clone), and `Indent`s. Removing those clones
would require additional changes in the compiler architecture, and at
least for cheep clones like `Span`s and `Arc`s it wouldn't bring much.
E.g., see: #6602. The goal of this PR was to remove unnecessary
double-cloning of parsed elements, where the final (cheeper) clones
taken into typed tree were cloned from expensive parsed element clones.
Additionally, the PR:
- removes additional unnecessary `clone()` calls unrelated to cloning of
parsed declarations.
- changes `collect` for `Expression` to always bail out on first error.
This behavior was inconsistent for different `ExpressionKind`s. We might
consider doing it other way around continuing collections on errors, but
it must be consistent for all `ExpressionKind`s. (Note that only
`TyCodeBlock::collect` actually collects, and always returns `Ok`.)
## 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)
- [ ] 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. Latest Branches
+24%
ironcev/remove-cloning-of-parsed-declarations +25%
xunilrj/fix-opt-passes-convergence 0%
ironcev/add-decl-engine-stats-to-compiler-metrics © 2026 CodSpeed Technology