From: "kddnewton (Kevin Newton) via ruby-core" Date: 2026-10-16T01:15:57+00:00 Subject: [ruby-core:127136] [Ruby Bug#22448] Jump value with a command call with a method call chained Issue #22448 has been reported by kddnewton (Kevin Newton). ---------------------------------------- Bug #22448: Jump value with a command call with a method call chained https://bugs.ruby-lang.org/issues/22448 * Author: kddnewton (Kevin Newton) * Status: Open * Backport: 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- This is a little bit odd, found this while fuzzing Prism. Right now, parse.y raises a void value expression error for a method call on a parenthesized jump, as in: ```ruby def m; (return foo 1 do end).bar; end ``` but if you get rid of the parentheses it says it's good to go, and compiles unreachable code: ``` $ ruby --parser=parse.y --dump=insns -e 'def m; return foo 1 do end.bar; end' == disasm: #@-e:1 (1,0)-(1,35)> 0000 definemethod :m, m ( 1)[Li] 0003 putobject :m 0005 leave == disasm: # 0000 putself ( 1)[LiCa] 0001 putobject_INT2FIX_1_ 0002 send , block in m 0005 leave [Re] 0006 putnil 0007 opt_send_without_block 0009 leave [Re] == disasm: # 0000 putnil ( 1)[Bc] 0001 leave [Br] ``` The parse tree actually attaches the block to the return itself. The same thing happens with break and next, with ., &. and ::, and with arguments on the chained call: ``` $ ruby --parser=parse.y -ce 'loop { break foo 1 do end.bar }' # Syntax OK $ ruby --parser=parse.y -ce 'loop { next foo 1 do end.bar }' # Syntax OK $ ruby --parser=parse.y -ce 'def m; return foo 1 do end&.bar; end' # Syntax OK $ ruby --parser=parse.y -ce 'def m; return foo 1 do end::bar; end' # Syntax OK $ ruby --parser=parse.y -ce 'def m; return foo 1 do end.bar 2; end' # Syntax OK $ ruby --parser=parse.y -ce 'loop { (break foo do end).bar }' # void value expression ``` I think all of these should be void value expressions since they're just compiling dead code. For context, Prism has been parsing those chains within the jump, so they get called before their result is thrown, which is inconsistent. So we could also just do that in parse.y instead. I'm fine with either solution. -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/