@views throws an error in combination with a struct

I am not sure if this is a bug or just not allowed syntax for some reason. The @views macro throws an error under seemingly narrow circumstances as shown in the last line of the example below:

struct Foo{T}
    a::Vector{T}
end

n = 10
x = Foo(ones(n))
y = ones(n)
z = ones(n)

# These things all work
#-----------------------
#@views is fine on the LHS without 'end'
@views x.a[2:n] .= y[2:n]

#@views is fine on the RHS with 'end'
@views w = x.a[2:end] .+ x.a[2:end]

#@views works on non-structs either way
@views y[2:n]   = z[2:n]
@views y[2:end] = z[2:end]

#@views works with a struct like this
@views x.a[2:n] .= y[2:n]
@views x.a[2:end] .= y[2:end]

# This does not work
#------------------------
@views x.a[2:end] .+= y[2:end]

The final line above gives me ERROR: syntax: invalid let syntax. If this is expected behaviour, what distinguishes the final line from those preceding?

I see this error in both v1.7 and 1.5.

Edit : Opened as issue 44356. I marked the the post by @goerch as the solution to this because the use of multiple @view macros seems a good workaround.

2 Likes

This seems to work

(@view x.a[2:end]) .+= (@view y[2:end])

I’d call it an omission(bug). Macro programming is hard. Would suspect .+= isn’t recognized…

Edit: Hm. Seems to be more complicated, because

v1 = [1]
v2 = [2]
@views v1[begin:end] .+= v2[begin:end]

works. So parser precedence again(had this one time before…)?

1 Like

The issue here is that lowering seems to have problems with let-blocks on the left-hand side of .+= expressions:

julia> let a=[0]; a end .+= 1
ERROR: syntax: invalid let syntax around REPL[5]:1
Stacktrace:
 [1] top-level scope
   @ REPL[5]:1

I don’t see why this shouldn’t work, could you open an issue?

2 Likes

Ah, I understand: I should have simply @macroexpand-ed this.

Thank you. I have opened an issue with a link back to the discussion here.

1 Like