Skip to content

Commit 2095c1e

Browse files
authored
Merge pull request #156 from torfjelde/tor/use-gensym-in-setmacro
Use gensym for `lens` variable in `setmacro`
2 parents 2d3c9f7 + 6546c49 commit 2095c1e

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

src/sugar.jl

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,19 +183,20 @@ function setmacro(lenstransform, ex::Expr; overwrite::Bool=false)
183183
@assert length(ex.args) == 2
184184
ref, val = ex.args
185185
obj, lens = parse_obj_lens(ref)
186+
lenssym = gensym(:lens)
186187
dst = overwrite ? obj : gensym("_")
187188
val = esc(val)
188189
ret = if ex.head == :(=)
189190
quote
190-
lens = ($lenstransform)($lens)
191-
$dst = $set($obj, lens, $val)
191+
$lenssym = ($lenstransform)($lens)
192+
$dst = $set($obj, $lenssym, $val)
192193
end
193194
else
194195
op = get_update_op(ex.head)
195196
f = :($_UpdateOp($op,$val))
196197
quote
197-
lens = ($lenstransform)($lens)
198-
$dst = $modify($f, $obj, lens)
198+
$lenssym = ($lenstransform)($lens)
199+
$dst = $modify($f, $obj, $lenssym)
199200
end
200201
end
201202
ret

test/test_setmacro.jl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,31 @@ using StaticNumbers
4646
@test m3 === @SMatrix[1 0; 0 0]
4747
end
4848

49+
function test_all_inferrable(f, argtypes)
50+
typed = first(code_typed(f, argtypes))
51+
code = typed.first
52+
@test all(T -> !(T isa UnionAll || T === Any), code.slottypes)
53+
end
54+
55+
# Example of macro that caused inference issues before.
56+
macro test_macro(expr)
57+
quote
58+
function f($(esc(:x)))
59+
$(Setfield.setmacro(identity, expr, overwrite=true))
60+
$(Setfield.setmacro(identity, expr, overwrite=true))
61+
$(Setfield.setmacro(identity, expr, overwrite=true))
62+
$(Setfield.setmacro(identity, expr, overwrite=true))
63+
$(Setfield.setmacro(identity, expr, overwrite=true))
64+
return $(esc(:x))
65+
end
66+
end
67+
end
68+
69+
@testset "setmacro multiple usage" begin
70+
let f = @test_macro(x[end] = 1)
71+
test_all_inferrable(f, (Vector{Float64}, ))
72+
end
73+
end
74+
4975
end#module
5076

0 commit comments

Comments
 (0)