Skip to content

Commit 398152b

Browse files
committed
Raise void value expression in begin clauses
In some cases Prism was either not raising an appropriate `void value expression` error, or raising that error when the syntax is considered valid. To fix this Prism needs to check whether we have other clauses on the `begin` rather than just returning `cast->statements`. * If the `cast->statements` are null and the `cast->ensure_clause` is not null, set the code to `cast->ensure_clause` * else * If there is a `cast->rescue_clause` * Check if `cast->statements` are null and `cast->rescue_clause->statements` are null, and return `NULL` * Check if there is an `else_clause`, and set the node to `cast->else_clause`. * Otherwise return `cast->statements` as the node * return `cast->statements` as the node See tests for test cases. Note I took these directly from CRuby so if desired I can delete them since the test will now pass. This only fixes one test in the `test_parse` file, taking failures from 14 to 13. This fixes `TestParse#test_void_value_in_rhs` and is related to issue #2791.
1 parent a05813d commit 398152b

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

src/prism.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,6 +1183,31 @@ pm_check_value_expression(pm_node_t *node) {
11831183
return NULL;
11841184
case PM_BEGIN_NODE: {
11851185
pm_begin_node_t *cast = (pm_begin_node_t *) node;
1186+
1187+
if (cast->statements == NULL && cast->ensure_clause != NULL) {
1188+
node = (pm_node_t *) cast->ensure_clause;
1189+
}
1190+
else {
1191+
if (cast->rescue_clause != NULL) {
1192+
if (cast->rescue_clause->statements == NULL) {
1193+
return NULL;
1194+
}
1195+
else if (cast->else_clause != NULL) {
1196+
node = (pm_node_t *) cast->else_clause;
1197+
}
1198+
else {
1199+
node = (pm_node_t *) cast->statements;
1200+
}
1201+
}
1202+
else {
1203+
node = (pm_node_t *) cast->statements;
1204+
}
1205+
}
1206+
1207+
break;
1208+
}
1209+
case PM_ENSURE_NODE: {
1210+
pm_ensure_node_t *cast = (pm_ensure_node_t *) node;
11861211
node = (pm_node_t *) cast->statements;
11871212
break;
11881213
}

test/prism/errors_test.rb

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1630,6 +1630,41 @@ class << (return)
16301630
]
16311631
end
16321632

1633+
def test_void_value_expression_in_begin_statement
1634+
source = <<~RUBY
1635+
x = return 1
1636+
x = return, 1
1637+
x = 1, return
1638+
x, y = return
1639+
x = begin return ensure end
1640+
x = begin ensure return end
1641+
x = begin return ensure return end
1642+
x = begin return; rescue; return end
1643+
x = begin return; rescue; return; else return end
1644+
x = begin; return; rescue; retry; end
1645+
RUBY
1646+
1647+
message = 'unexpected void value expression'
1648+
assert_errors expression(source), source, [
1649+
[message, 4..12],
1650+
[message, 17..23],
1651+
[message, 34..40],
1652+
[message, 48..54],
1653+
[message, 65..71],
1654+
[message, 100..106],
1655+
[message, 121..127],
1656+
[message, 156..162],
1657+
[message, 222..228],
1658+
[message, 244..250],
1659+
]
1660+
1661+
refute_error_messages("x = begin return; rescue; end")
1662+
refute_error_messages("x = begin return; rescue; return; else end")
1663+
refute_error_messages("x = begin; rescue; retry; end")
1664+
refute_error_messages("x = begin 1; rescue; retry; ensure; end")
1665+
refute_error_messages("x = begin 1; rescue; return; end")
1666+
end
1667+
16331668
def test_void_value_expression_in_def
16341669
source = <<~RUBY
16351670
def (return).x

0 commit comments

Comments
 (0)