-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
topdown/eval: fix 'every' term plugging on save #4775
topdown/eval: fix 'every' term plugging on save #4775
Conversation
1d22b5c
to
9cd21f7
Compare
ast/compile_test.go
Outdated
every y in [2] { | ||
y in output | ||
} | ||
}`), |
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 think we should be able to reorder this properly: If comp = [ 1 | true ]
is would come after object.get(...)
, we'd be fine.
Right now, when checking the output vars of the call, we get nothing because the call is unsafe. However, we also fly through the checks required to add the object.get
call to the reordered body, so we'd be getting the same ordering back. However, with the every
call, we'll get an error: output
is unsafe, because it's never removed from the unsafe
set, since it's never part of the output vars of the reordered
body.
Previously missing plugging could cause unsafe variables in the PE output. Now, all terms in the 'every' body should be plugged properly. The approach taken here is to plug them all, and then fix the key and val var names of the copied every expression. Those vars are fresh after the compiler is done with the expression, so plugging them should never have any effect outside of the rename. Signed-off-by: Stephan Renatus <[email protected]>
49b8960
to
91cde1a
Compare
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.
Since we're saving the body of every
without PE-ing it we need to namespace the variables to avoid conflicts w/ vars from any the callers. Nice find!
for i := range every.Body { | ||
switch t := every.Body[i].Terms.(type) { | ||
case *ast.Term: | ||
every.Body[i].Terms = e.e.bindings.Plug(t) | ||
every.Body[i].Terms = e.e.bindings.PlugNamespaced(t, e.e.caller.bindings) | ||
case []*ast.Term: | ||
for j := range t { | ||
t[j] = e.e.bindings.Plug(t[j]) | ||
for j := 1; j < len(t); j++ { // don't plug operator, t[0] | ||
t[j] = e.e.bindings.PlugNamespaced(t[j], e.e.caller.bindings) | ||
} | ||
} | ||
} |
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.
Unrelated to these changes, but it looks like we're only dealing with single terms and calls here. What happens if the body contains an ast.Every
? Is there some rewriting that I'm not aware of?
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.
Good find. Probably an oversight. I'll look into it later.
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.
Previously missing plugging could cause unsafe variables in the
PE output.
Now, all terms in the 'every' body should be plugged properly.
The approach taken here is to plug them all, and then fix the
key and val var names of the copied every expression. Those vars
are fresh after the compiler is done with the expression, so
plugging them should never have any effect outside of the rename.
Fixes the first part of #4766