lowering: accept a destructuring element parameter in the fold-loop pass - #90
Merged
Conversation
A folder that names its element by destructuring (`fun m (p, l) -> Map.add p l m`) was rejected by the in-place fold pass and fell back to `_pf_fold`, which copies the accumulator every step and goes quadratic. Only the accumulator parameter is substituted by name; the element parameter is the loop target, so any irrefutable pattern works there. `PyStmt::For` now takes a `PyForTarget` (a name or a nested tuple of names), so a tuple element emits Python's own `for (p, l) in steps:` header. Any other irrefutable shape binds a temp and unpacks on the first body line via the existing `unpack_into_as`. The pattern's bound names feed the P8 collision check as body binders. The accumulator parameter keeps its rules.
simontreanor
added a commit
that referenced
this pull request
Aug 30, 2026
…after #90, #91 and #93 Resolves the overlap between the lookup peephole (#93) and the Option/Result ladder (#94): both hooks run in the match lowering, lookup first since it needs no Option at all; the two new list helpers return the _None_ singleton; tests whose scrutinee both passes rewrote now expect the combined output.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The in-place fold pass (
DESIGN.md§5.1) rejected any folder whose element parameter was a pattern rather than a name, soList.fold (fun m (p, l) -> Map.add p l m) Map.empty stepsfell back to_pf_fold(a fresh copy per step) and went quadratic, while thefst/sndspelling of the same folder was linear.Only the accumulator parameter is substituted by name; the element parameter is just the loop target. This PR accepts any irrefutable element pattern:
PyStmt::Fornow carries aPyForTarget(a name or a nested tuple of names), so a tuple element emits Python's own header:for (p, l) in steps:/for (a, (b, c)) in xs:/for (p, _) in steps:.unpack_into_as(the same machinery a destructuringdefparameter uses). Not reachable from the parser today, which admits only names, wildcards and tuples as parameters, but the emit path is covered by a unit test.let clash p = … List.fold (fun m (p, l) -> …)still falls back.params[0]) keeps its existing name-only rule;PYFUN_NO_FOLD_OPTand the rejected path are byte-identical.Top-level and block-local named folders (
let add m (p, l) = …) get the same treatment, and it composes with the tuple accumulator.Tests
tests/compile.rs: lambda, top-level named, block-local named, nested tuple, wildcard, tuple-accumulator composition, the P8 clash fallback, a destructuring accumulator still falling back, and an e2e check that the destructuring andfst/sndspellings both take the loop path and agree.src/lowering/fold_loop.rs: unit tests forloop_target.cargo test,cargo clippy --all-targets,cargo fmt --checkall clean.Closes #85