aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreileencodes <eileencodes@gmail.com>2024-05-13 17:10:22 -0400
committergit <svn-admin@ruby-lang.org>2024-05-23 19:30:03 +0000
commitc96b5791efd7d14c7387adea9c6c252d7ecbb231 (patch)
treee75b890bb2868f24f8be5456cb7070fd7421188c
parent49fcd33e136ee2fe8720183b63a41bb6ef8d615c (diff)
downloadruby-c96b5791efd7d14c7387adea9c6c252d7ecbb231.tar.gz
[ruby/prism] 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. https://github.com/ruby/prism/commit/398152b412
-rw-r--r--prism/prism.c25
-rw-r--r--test/prism/errors_test.rb35
2 files changed, 60 insertions, 0 deletions
diff --git a/prism/prism.c b/prism/prism.c
index 5499ce4764..6d0dd6b66f 100644
--- a/prism/prism.c
+++ b/prism/prism.c
@@ -1183,6 +1183,31 @@ pm_check_value_expression(pm_node_t *node) {
return NULL;
case PM_BEGIN_NODE: {
pm_begin_node_t *cast = (pm_begin_node_t *) node;
+
+ if (cast->statements == NULL && cast->ensure_clause != NULL) {
+ node = (pm_node_t *) cast->ensure_clause;
+ }
+ else {
+ if (cast->rescue_clause != NULL) {
+ if (cast->rescue_clause->statements == NULL) {
+ return NULL;
+ }
+ else if (cast->else_clause != NULL) {
+ node = (pm_node_t *) cast->else_clause;
+ }
+ else {
+ node = (pm_node_t *) cast->statements;
+ }
+ }
+ else {
+ node = (pm_node_t *) cast->statements;
+ }
+ }
+
+ break;
+ }
+ case PM_ENSURE_NODE: {
+ pm_ensure_node_t *cast = (pm_ensure_node_t *) node;
node = (pm_node_t *) cast->statements;
break;
}
diff --git a/test/prism/errors_test.rb b/test/prism/errors_test.rb
index 50417e476e..5f4acb0120 100644
--- a/test/prism/errors_test.rb
+++ b/test/prism/errors_test.rb
@@ -1630,6 +1630,41 @@ module Prism
]
end
+ def test_void_value_expression_in_begin_statement
+ source = <<~RUBY
+ x = return 1
+ x = return, 1
+ x = 1, return
+ x, y = return
+ x = begin return ensure end
+ x = begin ensure return end
+ x = begin return ensure return end
+ x = begin return; rescue; return end
+ x = begin return; rescue; return; else return end
+ x = begin; return; rescue; retry; end
+ RUBY
+
+ message = 'unexpected void value expression'
+ assert_errors expression(source), source, [
+ [message, 4..12],
+ [message, 17..23],
+ [message, 34..40],
+ [message, 48..54],
+ [message, 65..71],
+ [message, 100..106],
+ [message, 121..127],
+ [message, 156..162],
+ [message, 222..228],
+ [message, 244..250],
+ ]
+
+ refute_error_messages("x = begin return; rescue; end")
+ refute_error_messages("x = begin return; rescue; return; else end")
+ refute_error_messages("x = begin; rescue; retry; end")
+ refute_error_messages("x = begin 1; rescue; retry; ensure; end")
+ refute_error_messages("x = begin 1; rescue; return; end")
+ end
+
def test_void_value_expression_in_def
source = <<~RUBY
def (return).x