"invalid assignment location" on function call returning view

I get an error trying to assign to the view result of a function call directly, but not when assigning to that same view after saving it in a variable. I can’t figure out why.

@generated function view_slice_last(arr::Array{T,D}, dx) where {T,D}
    initial_colons = [:(:) for i in 1:(D-1)]
    quote
        @view arr[$(initial_colons...),dx]
    end
end

example = rand(5,4,3)

view_slice_last(example, 2) .*= 0.0       # ERROR: LoadError: Invalid assignment location "view_slice_last(example,2)

saved_view = view_slice_last(example,2)
saved_view .*= 0.0        # works fine!

(also if anyone has a better way to do what I did with the generated function please do tell – I imagine there must be something but I couldn’t find anything else)

EDIT this answer is incorrect

Use ()s, eg

(view_slice_last(example, 2)) .*= 0.0

And for an alternative, consider something like

function view_slice_last2(arr::AbstractArray{T,N}, dx) where {T,N}
    view(arr, ntuple(_ -> Colon(), N - 1)..., dx)
end

The Julia 1.2-pre compiler appears to figure everything out nicely, I didn’t test earlier ones.

This doesn’t seem to work, at least in 1.1. Same error.

Great suggestion! The 1.1 compiler figures it out just fine, too.

You are right, I was thinking of something else. I am not aware of a way that would lower that expression, without an interim variable like you worked around it.

This was fixed in 1.2:

https://github.com/JuliaLang/julia/issues/31295

3 Likes