Fix evaluation order issue in f(**h, &h.delete(key))
Previously, this would delete the key in h before keyword splatting h. This goes against how ruby handles f(*a, &a.pop) and similar expressions.
Fix this by having the compiler check whether the block pass expression is safe. If it is not safe, then dup the keyword splatted hash before evaluating the block pass expression.
Fix evaluation order issue in f(**h, &h.delete(key))
Previously, this would delete the key in
hbefore keywordsplatting
h. This goes against how ruby handlesf(*a, &a.pop)and similar expressions.
Fix this by having the compiler check whether the block pass
expression is safe. If it is not safe, then dup the keyword
splatted hash before evaluating the block pass expression.
For expression:
h=nil; f(**h, &h.delete(:key))VM instructions before:
VM instructions after:
This is the same as 07d3bf4832532ae7446c9a6924d79aed60a7a9a5, except that
it removes unnecessary hash allocations when using the prism compiler.
Fixes [Bug #20640]