fix(rt): closure aggregate + #setTupleArgs fallback#952
Draft
fix(rt): closure aggregate + #setTupleArgs fallback#952
Conversation
Add a rule for `aggregateKindClosure` to construct closures as `Aggregate(variantIdx(0), ARGS)`, matching the existing tuple and ADT aggregate handling. Add an `[owise]` fallback to `#setTupleArgs` for `Value` arguments that are not wrapped in an `Aggregate` tuple. This handles closure-call paths where a single argument is passed directly. Test: `closure-no-capture.rs` — a non-capturing closure passed through a generic `FnOnce` call. Exercises the `#setTupleArgs` fallback for unwrapped single-value arguments. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.
Summary
Add a reduction rule for
aggregateKindClosureand an[owise]fallback for#setTupleArgswhen the argument is a plainValue(not wrapped in a tupleAggregate).aggregateKindClosurerule:ARGS:List ~> #mkAggregate(aggregateKindClosure(...)) => Aggregate(variantIdx(0), ARGS)#setTupleArgs(IDX, VAL:Value) [owise]fallback for single-value argumentsclosure-no-capture.rsregression testContext
MIR represents closure construction via
Rvalue::Aggregate(AggregateKind::Closure(...)). The K semantics had rules foraggregateKindTupleandaggregateKindAdtbut no rule foraggregateKindClosure, leaving the term stuck after collecting operands into aList.Additionally, when a closure is called with a single argument, the Rust calling convention passes it as a plain
Valuerather than wrapping it in a tupleAggregate. The existing#setTupleArgsrules only matchedAggregate(variantIdx(0), ...)orList— the[owise]fallback handles the unwrapped case.This matches miri's closure handling where closure aggregates are constructed the same way as struct aggregates, and single-element tuples are not wrapped.
Without this fix, any program constructing a closure gets stuck:
With this fix, closure construction reduces to
Aggregate(variantIdx(0), ARGS)and single-value tuple-arg dispatch works correctly.Proof evidence
Without fix (RED):
closure-no-capture.rsgets stuck at#mkAggregate(aggregateKindClosure(...))With fix (GREEN):
Test plan
test_prove_rs[closure-no-capture]make test-integrationregression