Skip to content

fix(rt): closure aggregate + #setTupleArgs fallback#952

Draft
Stevengre wants to merge 2 commits intomasterfrom
jh/fix-closure-aggregate-tuple-arg
Draft

fix(rt): closure aggregate + #setTupleArgs fallback#952
Stevengre wants to merge 2 commits intomasterfrom
jh/fix-closure-aggregate-tuple-arg

Conversation

@Stevengre
Copy link
Contributor

@Stevengre Stevengre commented Feb 28, 2026

Summary

Add a reduction rule for aggregateKindClosure and an [owise] fallback for #setTupleArgs when the argument is a plain Value (not wrapped in a tuple Aggregate).

  • Add aggregateKindClosure rule: ARGS:List ~> #mkAggregate(aggregateKindClosure(...)) => Aggregate(variantIdx(0), ARGS)
  • Add #setTupleArgs(IDX, VAL:Value) [owise] fallback for single-value arguments
  • Add closure-no-capture.rs regression test

Context

MIR represents closure construction via Rvalue::Aggregate(AggregateKind::Closure(...)). The K semantics had rules for aggregateKindTuple and aggregateKindAdt but no rule for aggregateKindClosure, leaving the term stuck after collecting operands into a List.

Additionally, when a closure is called with a single argument, the Rust calling convention passes it as a plain Value rather than wrapping it in a tuple Aggregate. The existing #setTupleArgs rules only matched Aggregate(variantIdx(0), ...) or List — 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:

Leaf <k>:
  ListItem(...) ~> #mkAggregate(aggregateKindClosure(...))
  -- no matching rule, term is 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.rs gets stuck at #mkAggregate(aggregateKindClosure(...))

With fix (GREEN):

test_prove_rs[closure-no-capture] PASSED

Test plan

  • test_prove_rs[closure-no-capture]
  • make test-integration regression

Stevengre and others added 2 commits February 28, 2026 10:11
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant