diff --git a/src/sugar.jl b/src/sugar.jl index ede4527a..57077229 100644 --- a/src/sugar.jl +++ b/src/sugar.jl @@ -166,6 +166,20 @@ function lower_index(collection::Symbol, index, dim) end function parse_obj_optics(ex) + dollar_exprs = foldtree([], ex) do exs, x + x isa Expr && x.head == :$ ? + push!(exs, only(x.args)) : + exs + end + if !isempty(dollar_exprs) + length(dollar_exprs) == 1 || error("Only a single dollar-expression is supported") + # obj is the only dollar-expression: + obj = esc(only(dollar_exprs)) + # parse expr with an underscore instead of the dollar-expression: + _, optics = parse_obj_optics(postwalk(x -> x isa Expr && x.head == :$ ? :_ : x, ex)) + return obj, optics + end + if @capture(ex, (front_ |> back_)) obj, frontoptic = parse_obj_optics(front) backoptic = try diff --git a/test/test_core.jl b/test/test_core.jl index 5ecc3db4..6e36f3af 100644 --- a/test/test_core.jl +++ b/test/test_core.jl @@ -136,6 +136,21 @@ end @test [@set(t[1] = 10), @set(t[2] *= 2)] == [(10, 2), (1, 4)] end +@testset "explicit target" begin + x = [1, 2, 3] + x_orig = x + @test (@set $(x)[2] = 100) == [1, 100, 3] + @test (@set $(x[2]) = 100) == 100 + @test (@set $(x)[2] + 2 = 100) == [1, 98, 3] # impossible without $ + @test (@set $(x[2]) + 2 = 100) == 98 # impossible without $ + @test x_orig === x == [1, 2, 3] + + @test (@reset $(x[2]) = 100) == 100 + @test x_orig === x == [1, 100, 3] + @test (@reset $(x)[2] = 200) == [1, 200, 3] + @test x_orig !== x == [1, 200, 3] +end + struct UserDefinedLens end