mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-compiler: fix bare nil? in if/unless to use self as receiver
The if/unless nil? optimization called codegen() on the call node's receiver, but a bare `nil?` is parsed as an FCALL whose receiver is NULL. codegen(NULL) emits OP_LOADNIL, so the JMPNIL was testing the literal nil instead of self, making `if nil?` always behave as `if nil.nil?` (always true) and `unless nil?` always skip its body. Load self when the receiver is implicit. Fixes #6874. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -194,3 +194,29 @@ assert('register window of calls (#3783)') do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assert('bare `nil?` in if/unless uses self as receiver (#6874)') do
|
||||
klass = Class.new do
|
||||
def unless_form
|
||||
reached = false
|
||||
unless nil?
|
||||
reached = true
|
||||
end
|
||||
reached
|
||||
end
|
||||
|
||||
def if_form
|
||||
if nil?
|
||||
:yes
|
||||
else
|
||||
:no
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assert_true klass.new.unless_form
|
||||
assert_equal :no, klass.new.if_form
|
||||
# Sanity: explicit literal nil receiver still optimized correctly.
|
||||
result = if nil.nil? then :yes else :no end
|
||||
assert_equal :yes, result
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user