1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Treat return in block in class/module as LocalJumpError (#2511)

return directly in class/module is an error, so return in
proc in class/module should also be an error.  I believe the
previous behavior was an unintentional oversight during the
addition of top-level return in 2.4.
This commit is contained in:
Jeremy Evans 2019-10-02 07:56:28 -07:00 committed by GitHub
parent 9759e3c9f0
commit ef697388be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
Notes: git 2019-10-02 23:56:57 +09:00
Merged-By: jeremyevans <code@jeremyevans.net>
3 changed files with 20 additions and 11 deletions

View file

@ -443,17 +443,18 @@ describe "The return keyword" do
end
describe "within a block within a class" do
it "is allowed" do
File.write(@filename, <<-END_OF_CODE)
class ReturnSpecs::A
ScratchPad << "before return"
1.times { return }
ScratchPad << "after return"
end
END_OF_CODE
ruby_version_is "2.7" do
it "is not allowed" do
File.write(@filename, <<-END_OF_CODE)
class ReturnSpecs::A
ScratchPad << "before return"
1.times { return }
ScratchPad << "after return"
end
END_OF_CODE
load @filename
ScratchPad.recorded.should == ["before return"]
-> { load @filename }.should raise_error(LocalJumpError)
end
end
end

View file

@ -1272,6 +1272,10 @@ eom
assert_warn(/argument of top-level return is ignored/) {eval("return 1")}
end
def test_return_in_proc_in_class
assert_in_out_err(['-e', 'class TestSyntax; proc{ return }.call; end'], "", [], /^-e:1:.*unexpected return \(LocalJumpError\)/)
end
def test_syntax_error_in_rescue
bug12613 = '[ruby-core:76531] [Bug #12613]'
assert_syntax_error("#{<<-"begin;"}\n#{<<-"end;"}", /Invalid retry/, bug12613)

View file

@ -1258,7 +1258,10 @@ vm_throw_start(const rb_execution_context_t *ec, rb_control_frame_t *const reg_c
switch (escape_cfp->iseq->body->type) {
case ISEQ_TYPE_TOP:
case ISEQ_TYPE_MAIN:
if (toplevel) goto valid_return;
if (toplevel) {
if (in_class_frame) goto unexpected_return;
goto valid_return;
}
break;
case ISEQ_TYPE_EVAL:
case ISEQ_TYPE_CLASS:
@ -1276,6 +1279,7 @@ vm_throw_start(const rb_execution_context_t *ec, rb_control_frame_t *const reg_c
escape_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(escape_cfp);
}
unexpected_return:;
rb_vm_localjump_error("unexpected return", throwobj, TAG_RETURN);
valid_return:;