-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Fix at-views for setindex expression #59403
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
I don't believe this is quite right. I think the intended expansion of |
8fd1ffd
to
70e4a6a
Compare
70e4a6a
to
ee3f203
Compare
Updated. Should also work for other flavors of assignments now I kept the way |
I'm pretty sure the normal julia> @macroexpand @views x[a:b] = c
:(x[a:b] = c) It seems that julia> @macroexpand @views x[a:b] += c
:(let var"#2#a" = x, var"#1#i1" = a:b
var"#2#a"[var"#1#i1"] = (Base.maybeview)(var"#2#a", var"#1#i1") + c
end)
julia> @macroexpand @views x[a:b] .+= c
:(let var"#4#a" = x, var"#3#i1" = a:b
var"#4#a"[var"#3#i1"] .= (Base.maybeview)(var"#4#a", var"#3#i1") .+ c
end) That said, I wasn't perfectly happy with simply ignoring these cases as in the previous implementation because it's inconsistent with the function name. Also, the previous one didn't handle other flavors of assignments correctly and handling those does require the lowering style that you suggested. |
@@ -46,77 +121,7 @@ function replace_ref_begin_end_!(__module__::Module, ex, withex, in_quote_contex | |||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, this error has also always been incorrect, if the intent of this function is to predict lowering. Lowering does not consider this to be invalid, and simply skips the replacement when withex === nothing
:
julia> var"begin" = var"end" = 3
3
for i = eachindex(ex.args) | ||
if i == 1 | ||
# we'll deal with the ref expression later | ||
continue | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems an odd way to deal with a binary operator being to loop from 1 to 2 skipping 1
for i = eachindex(ex.args) | |
if i == 1 | |
# we'll deal with the ref expression later | |
continue | |
end | |
let i = 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was going to handle only args[2]
here. However, the code below treated it as if there could be more than 2 argument for this expression
Line 272 in cbea8cf
mapany(e -> esc(_views(e)), ex.args[2:end])...))), Base) |
@@ -132,6 +137,18 @@ function replace_ref_begin_end_!(__module__::Module, ex, withex, in_quote_contex | |||
escs -= 1 | |||
elseif ex.head === :meta || ex.head === :inert | |||
return ex, used_withex | |||
elseif !in_quote_context && last(string(ex.head)) == '=' && Meta.isexpr(ex.args[1], :ref) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
elseif !in_quote_context && last(string(ex.head)) == '=' && Meta.isexpr(ex.args[1], :ref) | |
elseif !in_quote_context && last(string(ex.head)) == '=' && Meta.isexpr(Meta.unescape(ex.args[1]), :ref) |
# we'll deal with the ref expression later | ||
continue | ||
end | ||
ex.args[i], used = replace_ref_begin_end_!(__module__, ex.args[i], withex, in_quote_context, escs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ex.args[i], used = replace_ref_begin_end_!(__module__, ex.args[i], withex, in_quote_context, escs) | |
rhs, used = reescape(replace_ref_begin_end_!(__module__, unescape(ex.args[i]), withex, in_quote_context, escs) | |
ex.args[i] = reescape(rhs, ex.args[i]) | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume the first reescape should not be there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, why should the escape/unescape be done on this argument? This should just be a generic handling of the an expression just like the first argument of the :ref expression and exactly the same as the fallback case below. I assume replace_ref_begin_end_!
is handling the escaping part correctly, else many more places would need to be fixed.
I could see though, that the first argument (the LHS) needs to be handled manually since we need to see through escape to figure out if the LHS of an assignment operator is an Expr(:ref)
. The implementation of @views
below doesn't seem to handle this either though, and should probably be fixed at the same time,
julia> macro views_wrapper(lhs, rhs)
quote
@views $(esc(lhs)) += $(esc(rhs))
end
end
@views_wrapper (macro with 1 method)
julia> @macroexpand @views_wrapper x[a:b] 1
quote
#= REPL[3]:3 =#
(Base.maybeview)(x, a:b) += 1
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And another issue seems to be that this function also straight up ignore escape expressions in general (unless they appears in hygienic-scope
expressions). Shouldn't that logic only apply if the "begin"/"end" is escaped compared to the ref expression?
Basically, I feel like esc(:(x[begin:end]))
should be processed whereas :(x[$(esc(:(var"begin":var"end")))])
shouldn't.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, lots of code handles esc
wrong. Including lowering, which considers begin
/end
to ignore scope (as we currently emulate here)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right now x[esc(begin:end)]
is being lowered to x[begin:end]
. Would this be considered a bug in the long term or is it the job of this function to lift the begin/end out of the argument of ref?
Fix #59383