diff --git a/prism_compile.c b/prism_compile.c index bb3d91ffde..1828984baa 100644 --- a/prism_compile.c +++ b/prism_compile.c @@ -3994,9 +3994,11 @@ pm_compile_defined_expr0(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_l return; } case PM_CALL_NODE: { +#define BLOCK_P(cast) ((cast)->block != NULL && PM_NODE_TYPE_P((cast)->block, PM_BLOCK_NODE)) + const pm_call_node_t *cast = ((const pm_call_node_t *) node); - if (cast->block != NULL && PM_NODE_TYPE_P(cast->block, PM_BLOCK_NODE)) { + if (BLOCK_P(cast)) { dtype = DEFINED_EXPR; break; } @@ -4016,7 +4018,7 @@ pm_compile_defined_expr0(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_l if (cast->receiver) { pm_compile_defined_expr0(iseq, cast->receiver, node_location, ret, popped, scope_node, true, lfinish, true); - if (PM_NODE_TYPE_P(cast->receiver, PM_CALL_NODE)) { + if (PM_NODE_TYPE_P(cast->receiver, PM_CALL_NODE) && !BLOCK_P((const pm_call_node_t *) cast->receiver)) { PUSH_INSNL(ret, location, branchunless, lfinish[2]); const pm_call_node_t *receiver = (const pm_call_node_t *) cast->receiver; @@ -4038,6 +4040,8 @@ pm_compile_defined_expr0(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_l } return; + +#undef BLOCK_P } case PM_YIELD_NODE: PUSH_INSN(ret, location, putnil); diff --git a/test/ruby/test_compile_prism.rb b/test/ruby/test_compile_prism.rb index 043d5d8c0e..4a18040d63 100644 --- a/test/ruby/test_compile_prism.rb +++ b/test/ruby/test_compile_prism.rb @@ -207,6 +207,9 @@ module Prism assert_prism_eval("defined?(a(itself))") assert_prism_eval("defined?(itself(itself))") + # method chain with a block on the inside + assert_prism_eval("defined?(itself { 1 }.itself)") + # Method chain on a constant assert_prism_eval(<<~RUBY) class PrismDefinedNode