mirror of
https://github.com/ruby/ruby.git
synced 2025-09-15 16:44:01 +02:00
Fix retry
in nested rescue
blocks
Restore `rescue`-context from the outer context. `retry` targets the next outer block except for between `rescue` and `else` or `ensure`, otherwise, if there is no enclosing block, it should be syntax error.
This commit is contained in:
parent
5a376f0f71
commit
eaa0fbf9b9
2 changed files with 44 additions and 10 deletions
33
parse.y
33
parse.y
|
@ -1571,6 +1571,12 @@ static NODE *allow_block_exit(struct parser_params *p);
|
||||||
static void restore_block_exit(struct parser_params *p, NODE *exits);
|
static void restore_block_exit(struct parser_params *p, NODE *exits);
|
||||||
static void clear_block_exit(struct parser_params *p, bool error);
|
static void clear_block_exit(struct parser_params *p, bool error);
|
||||||
|
|
||||||
|
static void
|
||||||
|
next_rescue_context(struct lex_context *next, const struct lex_context *outer, enum rescue_context def)
|
||||||
|
{
|
||||||
|
next->in_rescue = outer->in_rescue == after_rescue ? after_rescue : def;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
restore_defun(struct parser_params *p, NODE *name)
|
restore_defun(struct parser_params *p, NODE *name)
|
||||||
{
|
{
|
||||||
|
@ -2116,29 +2122,37 @@ begin_block : block_open top_compstmt '}'
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
bodystmt : compstmt
|
bodystmt : compstmt[body]
|
||||||
|
lex_ctxt[ctxt]
|
||||||
opt_rescue
|
opt_rescue
|
||||||
k_else
|
k_else
|
||||||
{
|
{
|
||||||
if (!$2) yyerror1(&@3, "else without rescue is useless");
|
if (!$opt_rescue) yyerror1(&@k_else, "else without rescue is useless");
|
||||||
p->ctxt.in_rescue = after_else;
|
next_rescue_context(&p->ctxt, &$ctxt, after_else);
|
||||||
|
}
|
||||||
|
compstmt[elsebody]
|
||||||
|
{
|
||||||
|
next_rescue_context(&p->ctxt, &$ctxt, after_ensure);
|
||||||
}
|
}
|
||||||
compstmt
|
|
||||||
opt_ensure
|
opt_ensure
|
||||||
{
|
{
|
||||||
/*%%%*/
|
/*%%%*/
|
||||||
$$ = new_bodystmt(p, $1, $2, $5, $6, &@$);
|
$$ = new_bodystmt(p, $body, $opt_rescue, $elsebody, $opt_ensure, &@$);
|
||||||
/*% %*/
|
/*% %*/
|
||||||
/*% ripper: bodystmt!($1, $2, $5, $6) %*/
|
/*% ripper: bodystmt!($body, $opt_rescue, $elsebody, $opt_ensure) %*/
|
||||||
}
|
}
|
||||||
| compstmt
|
| compstmt[body]
|
||||||
|
lex_ctxt[ctxt]
|
||||||
opt_rescue
|
opt_rescue
|
||||||
|
{
|
||||||
|
next_rescue_context(&p->ctxt, &$ctxt, after_ensure);
|
||||||
|
}
|
||||||
opt_ensure
|
opt_ensure
|
||||||
{
|
{
|
||||||
/*%%%*/
|
/*%%%*/
|
||||||
$$ = new_bodystmt(p, $1, $2, 0, $3, &@$);
|
$$ = new_bodystmt(p, $body, $opt_rescue, 0, $opt_ensure, &@$);
|
||||||
/*% %*/
|
/*% %*/
|
||||||
/*% ripper: bodystmt!($1, $2, Qnil, $3) %*/
|
/*% ripper: bodystmt!($body, $opt_rescue, Qnil, $opt_ensure) %*/
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -4242,7 +4256,6 @@ k_ensure : keyword_ensure
|
||||||
{
|
{
|
||||||
token_info_warn(p, "ensure", p->token_info, 1, &@$);
|
token_info_warn(p, "ensure", p->token_info, 1, &@$);
|
||||||
$$ = p->ctxt;
|
$$ = p->ctxt;
|
||||||
p->ctxt.in_rescue = after_ensure;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -283,6 +283,27 @@ class TestAst < Test::Unit::TestCase
|
||||||
assert_parse("begin rescue; ensure; defined? retry; end")
|
assert_parse("begin rescue; ensure; defined? retry; end")
|
||||||
assert_parse("END {defined? retry}")
|
assert_parse("END {defined? retry}")
|
||||||
assert_parse("begin rescue; END {defined? retry}; end")
|
assert_parse("begin rescue; END {defined? retry}; end")
|
||||||
|
|
||||||
|
assert_parse("#{<<-"begin;"}\n#{<<-'end;'}")
|
||||||
|
begin;
|
||||||
|
def foo
|
||||||
|
begin
|
||||||
|
yield
|
||||||
|
rescue StandardError => e
|
||||||
|
begin
|
||||||
|
puts "hi"
|
||||||
|
retry
|
||||||
|
rescue
|
||||||
|
retry unless e
|
||||||
|
raise e
|
||||||
|
else
|
||||||
|
retry
|
||||||
|
ensure
|
||||||
|
retry
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end;
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_invalid_yield
|
def test_invalid_yield
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue