Bug #17105
closedA single `return` can return to two different places in a proc inside a lambda inside a method
Description
A single return in the source code might return to 2 different lexical places.
That seems wrong to me, as AFAIK all other control flow language constructs always jump to a single place.
def m(call_proc)
r = -> {
# This single return in the source might exit the lambda or the method!
proc = Proc.new { return :return }
if call_proc
proc.call
:after_in_lambda
else
proc
end
}.call # returns here if call_proc
if call_proc
[:after_in_method, r]
else
r.call
:never_reached
end
end
p m(true) # => [:after_in_method, :return]
p m(false) # :return
We're trying to figure out the semantics of return inside a proc in
https://github.com/oracle/truffleruby/issues/1488#issuecomment-669185675
and this behavior doesn't seem to make much sense.
@headius (Charles Nutter) also seems to agree:
I would consider that behavior to be incorrect; once the proc has escaped from the lambda, its return target is no longer valid. It should not return to a different place.
https://github.com/jruby/jruby/issues/6350#issuecomment-669603740
So:
- is this behavior intentional? or is it a bug?
- what are actually the semantics of
returninside a proc?
The semantics seem incredibly complicated to a point developers have no idea where return actually goes.
Also it must get even more complicated if one defines a lambda method as the block in lambda { return } is then non-deterministically a proc or lambda.