diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index cf3c24d19..f041a2c99 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -3974,7 +3974,13 @@ codegen_if(codegen_scope *s, node *varnode, int val) mrb_sym sym_nil_p = MRB_SYM_Q(nil); if (call_n->method_name == sym_nil_p && callargs_empty(call_n->args)) { nil_p = TRUE; - codegen(s, call_n->receiver, VAL); + if (call_n->receiver) { + codegen(s, call_n->receiver, VAL); + } + else { + /* implicit receiver: bare `nil?` means `self.nil?` */ + gen_load_op1(s, OP_LOADSELF, VAL); + } } } diff --git a/test/t/codegen.rb b/test/t/codegen.rb index c4e031bd3..1e4d37559 100644 --- a/test/t/codegen.rb +++ b/test/t/codegen.rb @@ -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