summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYusuke Endoh <mame@ruby-lang.org>2025-06-13 12:44:08 +0900
committergit <svn-admin@ruby-lang.org>2025-07-16 15:48:09 +0000
commit4cf85fe2140d0522f924ab57c850b2f03b967390 (patch)
tree2de07a6f650ac4a560cb148171e1aaca9f477d44
parent830ab2c5b5ea58d1f29cb5e9b3864626b9dc8592 (diff)
[ruby/prism] Reject `true && not true`
A command-call-like `not true` must be rejected after `&&` and `||`. https://bugs.ruby-lang.org/issues/21337 https://github.com/ruby/prism/commit/0513cf22ad
-rw-r--r--prism/config.yml1
-rw-r--r--prism/prism.c5
-rw-r--r--prism/templates/src/diagnostic.c.erb1
-rw-r--r--test/prism/errors/command_calls_31.txt12
4 files changed, 19 insertions, 0 deletions
diff --git a/prism/config.yml b/prism/config.yml
index cb154500b3..8002fff706 100644
--- a/prism/config.yml
+++ b/prism/config.yml
@@ -101,6 +101,7 @@ errors:
- EXPECT_FOR_DELIMITER
- EXPECT_IDENT_REQ_PARAMETER
- EXPECT_IN_DELIMITER
+ - EXPECT_LPAREN_AFTER_NOT
- EXPECT_LPAREN_REQ_PARAMETER
- EXPECT_MESSAGE
- EXPECT_RBRACKET
diff --git a/prism/prism.c b/prism/prism.c
index ffe874fe08..02fbc65825 100644
--- a/prism/prism.c
+++ b/prism/prism.c
@@ -19775,6 +19775,11 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
pm_arguments_t arguments = { 0 };
pm_node_t *receiver = NULL;
+ if (!accepts_command_call && !match1(parser, PM_TOKEN_PARENTHESIS_LEFT)) {
+ pm_parser_err_current(parser, PM_ERR_EXPECT_LPAREN_AFTER_NOT);
+ return (pm_node_t *) pm_missing_node_create(parser, parser->current.start, parser->current.end);
+ }
+
accept1(parser, PM_TOKEN_NEWLINE);
if (accept1(parser, PM_TOKEN_PARENTHESIS_LEFT)) {
diff --git a/prism/templates/src/diagnostic.c.erb b/prism/templates/src/diagnostic.c.erb
index ce98dc5acd..389b1dc484 100644
--- a/prism/templates/src/diagnostic.c.erb
+++ b/prism/templates/src/diagnostic.c.erb
@@ -184,6 +184,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
[PM_ERR_EXPECT_FOR_DELIMITER] = { "unexpected %s; expected a 'do', newline, or ';' after the 'for' loop collection", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_EXPECT_IDENT_REQ_PARAMETER] = { "expected an identifier for the required parameter", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_EXPECT_IN_DELIMITER] = { "expected a delimiter after the patterns of an `in` clause", PM_ERROR_LEVEL_SYNTAX },
+ [PM_ERR_EXPECT_LPAREN_AFTER_NOT] = { "expected a `(` after `not`", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_EXPECT_LPAREN_REQ_PARAMETER] = { "expected a `(` to start a required parameter", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_EXPECT_MESSAGE] = { "unexpected %s; expecting a message to send to the receiver", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_EXPECT_RBRACKET] = { "expected a matching `]`", PM_ERROR_LEVEL_SYNTAX },
diff --git a/test/prism/errors/command_calls_31.txt b/test/prism/errors/command_calls_31.txt
new file mode 100644
index 0000000000..72d5fc588f
--- /dev/null
+++ b/test/prism/errors/command_calls_31.txt
@@ -0,0 +1,12 @@
+true && not true
+ ^~~~ expected a `(` after `not`
+ ^~~~ unexpected 'true', expecting end-of-input
+
+true || not true
+ ^~~~ expected a `(` after `not`
+ ^~~~ unexpected 'true', expecting end-of-input
+
+true && not (true)
+ ^ expected a `(` after `not`
+ ^ unexpected '(', expecting end-of-input
+