Skip to content

Commit 4439c3d

Browse files
Stevengreclaude
andcommitted
fix(rt): handle closure aggregate and non-tuple tuple-arg fallback
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>
1 parent 7aa0a7c commit 4439c3d

3 files changed

Lines changed: 24 additions & 0 deletions

File tree

kmir/src/kmir/kdist/mir-semantics/kmir.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,12 @@ Therefore a heuristics is used here:
610610
=> #setLocalValue(place(local(IDX), .ProjectionElems), #incrementRef(VAL)) ~> #setTupleArgs(IDX +Int 1, REST)
611611
...
612612
</k>
613+
614+
// Fallback for closure-call paths where the argument is not wrapped as a tuple.
615+
rule <k> #setTupleArgs(IDX, VAL:Value)
616+
=> #setLocalValue(place(local(IDX), .ProjectionElems), #incrementRef(VAL))
617+
...
618+
</k> [owise]
613619
```
614620

615621

kmir/src/kmir/kdist/mir-semantics/rt/data.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,12 @@ Literal arrays are also built using this RValue.
10511051
...
10521052
</k>
10531053
1054+
rule <k> ARGS:List ~> #mkAggregate(aggregateKindClosure(_CLOSUREDEF, _GENERICARGS))
1055+
=>
1056+
Aggregate(variantIdx(0), ARGS)
1057+
...
1058+
</k>
1059+
10541060
10551061
// #readOperands accumulates a list of `TypedLocal` values from operands
10561062
syntax KItem ::= #readOperands ( Operands )
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
fn apply<F: FnOnce(u8) -> u8>(f: F, v: u8) -> u8 {
2+
f(v)
3+
}
4+
5+
fn main() {
6+
let _ = repro();
7+
}
8+
9+
fn repro() -> u8 {
10+
let f = |x: u8| x + 1;
11+
apply(f, 41u8)
12+
}

0 commit comments

Comments
 (0)