Skip to content

store the value of a captured variable, not its box - #171

Open
singhharsh1708 wants to merge 1 commit into
JuliaDynamics:masterfrom
singhharsh1708:unbox-captured-slots
Open

singhharsh1708 wants to merge 1 commit into
JuliaDynamics:masterfrom
singhharsh1708:unbox-captured-slots

Conversation

@singhharsh1708

@singhharsh1708 singhharsh1708 commented Sep 9, 2026 •

Copy link
Copy Markdown

Fixes #134.

The issue has it the other way round: the slot is not given the un-boxed type, it is given Core.Box. A variable an inner function captures and reassigns is a Core.Box in the body get_slots infers from, while the transformed body assigns the value itself, so the conversion fails. The state machine field is the storage, so the box is redundant, and such a slot is now Any. Both the declared bound and the type the generated constructor instantiates need it, since they are computed separately.

Both @test_broken pass now, and the closure example from the issue is covered too. test_main goes from 44 passing and 2 broken to 47 passing, on 1.10, 1.11 and 1.12.

Numbered 1.0.9 now that 1.0.8 shipped with #174; #168 also claims 1.0.9, so whichever lands second renumbers.

A variable that an inner function captures and reassigns is a `Core.Box` in the body that slot
types are inferred from, so the state machine field was typed `Core.Box` while the transformed
body assigns the value itself, and the assignment failed to convert.

The field is the storage, so the box is not needed. Infer such a slot as `Any` instead, in the
declared bound and in the type the generated constructor instantiates.

Fixes JuliaDynamics#134. The two `@test_broken` for it now pass, and the closure example from the issue is
covered as well.
@github-actions

Copy link
Copy Markdown

Benchmark Results (Julia v1)

Time benchmarks
master 456c7dd... master / 456c7dd...
hardcoded types/BigInt/Channels csize=0 0.106 ± 0.0078 ms 0.104 ± 0.0061 ms 1.01 ± 0.096
hardcoded types/BigInt/Channels csize=1 0.11 ± 0.0073 ms 0.107 ± 0.0059 ms 1.03 ± 0.089
hardcoded types/BigInt/Channels csize=100 17.7 ± 1.9 μs 19 ± 2.7 μs 0.932 ± 0.16
hardcoded types/BigInt/Channels csize=20 21.7 ± 1.3 μs 21.4 ± 0.58 μs 1.02 ± 0.065
hardcoded types/BigInt/Closure 4.4 ± 0.53 μs 4.1 ± 0.25 μs 1.07 ± 0.14
hardcoded types/BigInt/Closure optimized 3.18 ± 0.18 μs 3.12 ± 0.19 μs 1.02 ± 0.085
hardcoded types/BigInt/Closure statemachine 3.11 ± 0.25 μs 3.19 ± 0.88 μs 0.974 ± 0.28
hardcoded types/BigInt/Direct 3.42 ± 0.3 μs 3.06 ± 0.15 μs 1.12 ± 0.11
hardcoded types/BigInt/Iteration protocol 3.17 ± 0.21 μs 3.13 ± 0.22 μs 1.02 ± 0.097
hardcoded types/BigInt/ResumableFunctions 3.43 ± 0.16 μs 3.17 ± 0.15 μs 1.08 ± 0.073
hardcoded types/BigInt/Task scheduling 24.6 ± 2.1e+02 μs 26.1 ± 2.1e+02 μs 0.944 ± 11
hardcoded types/Int64/Channels csize=0 0.0997 ± 0.0057 ms 0.0994 ± 0.0058 ms 1 ± 0.082
hardcoded types/Int64/Channels csize=1 0.103 ± 0.0063 ms 0.103 ± 0.0072 ms 1 ± 0.093
hardcoded types/Int64/Channels csize=100 14.8 ± 1.7 μs 14.1 ± 1.7 μs 1.05 ± 0.18
hardcoded types/Int64/Channels csize=20 17.5 ± 0.42 μs 17.6 ± 0.78 μs 0.993 ± 0.05
hardcoded types/Int64/Closure 1.68 ± 0.13 μs 1.75 ± 0.3 μs 0.956 ± 0.18
hardcoded types/Int64/Closure optimized 0.046 ± 0.001 μs 0.05 ± 0.001 μs 0.92 ± 0.027
hardcoded types/Int64/Closure statemachine 0.047 ± 0.002 μs 0.046 ± 0.001 μs 1.02 ± 0.049
hardcoded types/Int64/Direct 0.045 ± 0.001 μs 0.044 ± 0.001 μs 1.02 ± 0.033
hardcoded types/Int64/Iteration protocol 0.046 ± 0.001 μs 0.065 ± 0.001 μs 0.708 ± 0.019
hardcoded types/Int64/ResumableFunctions 0.046 ± 0.001 μs 0.047 ± 0.001 μs 0.979 ± 0.03
hardcoded types/Int64/Task scheduling 23.1 ± 2.1e+02 μs 21.8 ± 2.2e+02 μs 1.06 ± 14
time_to_load 0.0318 ± 0.00053 s 0.0318 ± 0.0008 s 1 ± 0.03
Memory benchmarks
master 456c7dd... master / 456c7dd...
hardcoded types/BigInt/Channels csize=0 0.302 k allocs: 7.7 kB 0.302 k allocs: 7.7 kB 1
hardcoded types/BigInt/Channels csize=1 0.302 k allocs: 7.71 kB 0.302 k allocs: 7.71 kB 1
hardcoded types/BigInt/Channels csize=100 0.305 k allocs: 9.24 kB 0.305 k allocs: 9.24 kB 1
hardcoded types/BigInt/Channels csize=20 0.305 k allocs: 9.24 kB 0.305 k allocs: 9.24 kB 1
hardcoded types/BigInt/Closure 0.192 k allocs: 5.23 kB 0.192 k allocs: 5.23 kB 1
hardcoded types/BigInt/Closure optimized 0.19 k allocs: 5.2 kB 0.19 k allocs: 5.2 kB 1
hardcoded types/BigInt/Closure statemachine 0.19 k allocs: 5.2 kB 0.19 k allocs: 5.2 kB 1
hardcoded types/BigInt/Direct 0.188 k allocs: 5.14 kB 0.188 k allocs: 5.14 kB 1
hardcoded types/BigInt/Iteration protocol 0.19 k allocs: 5.2 kB 0.19 k allocs: 5.2 kB 1
hardcoded types/BigInt/ResumableFunctions 0.19 k allocs: 5.2 kB 0.19 k allocs: 5.2 kB 1
hardcoded types/BigInt/Task scheduling 0.197 k allocs: 5.85 kB 0.197 k allocs: 5.85 kB 1
hardcoded types/Int64/Channels csize=0 0.097 k allocs: 2.27 kB 0.097 k allocs: 2.27 kB 1
hardcoded types/Int64/Channels csize=1 19 allocs: 1.06 kB 19 allocs: 1.06 kB 1
hardcoded types/Int64/Channels csize=100 22 allocs: 2.59 kB 22 allocs: 2.59 kB 1
hardcoded types/Int64/Channels csize=20 22 allocs: 2.59 kB 22 allocs: 2.59 kB 1
hardcoded types/Int64/Closure 0.082 k allocs: 1.28 kB 0.082 k allocs: 1.28 kB 1
hardcoded types/Int64/Closure optimized 0 allocs: 0 B 0 allocs: 0 B
hardcoded types/Int64/Closure statemachine 0 allocs: 0 B 0 allocs: 0 B
hardcoded types/Int64/Direct 0 allocs: 0 B 0 allocs: 0 B
hardcoded types/Int64/Iteration protocol 0 allocs: 0 B 0 allocs: 0 B
hardcoded types/Int64/ResumableFunctions 0 allocs: 0 B 0 allocs: 0 B
hardcoded types/Int64/Task scheduling 0.085 k allocs: 1.88 kB 0.085 k allocs: 1.88 kB 1
time_to_load 0.201 k allocs: 11.8 kB 0.201 k allocs: 11.8 kB 1

This branch has not been deployed

No deployments
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.

Closure-boxed variables lead to type conversion errors

1 participant