[ruby-core:122086] [Ruby Bug#21337] Using `not` on the RHS of a logical operator becomes valid syntax with Prism

Issue #21337 has been reported by koic (Koichi ITO). ---------------------------------------- Bug #21337: Using `not` on the RHS of a logical operator becomes valid syntax with Prism https://bugs.ruby-lang.org/issues/21337 * Author: koic (Koichi ITO) * Status: Open * ruby -v: ruby 3.4.3 (2025-04-14 revision d0b7e5b6a0) +PRISM [x86_64-darwin24] * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- The following syntax behavior differs between Ruby 3.3 (parse.y by default) and Ruby 3.4 (Prism by default). ```ruby if true && not true; end ``` ## Expected In Ruby 3.3 and earlier, the following code results in a syntax error. The default parser is `parse.y`. ```console $ ruby -vce 'if true && not true; end' ruby 3.3.8 (2025-04-09 revision b200bad6cd) [x86_64-darwin24] -e:1: syntax error, unexpected `true', expecting '(' if true && not true; end ruby: compile error (SyntaxError) ``` The key point is that `not` is used on the right-hand side of a logical operator. ## Actual When the default parser is switched to Prism, it is accepted as valid syntax with Ruby 3.4+ (Prism by default): ```console $ ruby -vce 'if true && not true; end' ruby 3.4.3 (2025-04-14 revision d0b7e5b6a0) +PRISM [x86_64-darwin24] Syntax OK $ ruby -vce 'if true && not true; end' ruby 3.5.0dev (2025-05-13T02:05:19Z master 9b8c846bdf) +PRISM [x86_64-darwin24] Syntax OK ``` Specifying parse.y causes a syntax error, as before 3.3 (parse.y by default): ```console $ ruby -vce 'if true && not true; end' ruby 3.3.8 (2025-04-09 revision b200bad6cd) [x86_64-darwin24] -e:1: syntax error, unexpected `true', expecting '(' if true && not true; end ruby: compile error (SyntaxError) $ ruby --parser=parse.y -vce 'if true && not true; end' ruby 3.5.0dev (2025-05-13T02:05:19Z master 9b8c846bdf) [x86_64-darwin24] -e:1: syntax error, unexpected 'true', expecting '(' if true && not true; end ruby: compile error (SyntaxError) ``` The behavior seen in the parse.y producing a syntax error might be probably the expected one. Any case, it is likely that users would not expect such a discrepancy between parsers. This issue was noticed in the context of the following RuboCop issue: https://github.com/rubocop/rubocop/issues/14177 -- https://bugs.ruby-lang.org/

Issue #21337 has been updated by byroot (Jean Boussier). Assignee set to prism ---------------------------------------- Bug #21337: Using `not` on the RHS of a logical operator becomes valid syntax with Prism https://bugs.ruby-lang.org/issues/21337#change-113243 * Author: koic (Koichi ITO) * Status: Open * Assignee: prism * ruby -v: ruby 3.4.3 (2025-04-14 revision d0b7e5b6a0) +PRISM [x86_64-darwin24] * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- The following syntax behavior differs between Ruby 3.3 (parse.y by default) and Ruby 3.4 (Prism by default). ```ruby if true && not true; end ``` ## Expected In Ruby 3.3 and earlier, the following code results in a syntax error. The default parser is `parse.y`. ```console $ ruby -vce 'if true && not true; end' ruby 3.3.8 (2025-04-09 revision b200bad6cd) [x86_64-darwin24] -e:1: syntax error, unexpected `true', expecting '(' if true && not true; end ruby: compile error (SyntaxError) ``` The key point is that `not` is used on the right-hand side of a logical operator. ## Actual When the default parser is switched to Prism, it is accepted as valid syntax with Ruby 3.4+ (Prism by default): ```console $ ruby -vce 'if true && not true; end' ruby 3.4.3 (2025-04-14 revision d0b7e5b6a0) +PRISM [x86_64-darwin24] Syntax OK $ ruby -vce 'if true && not true; end' ruby 3.5.0dev (2025-05-13T02:05:19Z master 9b8c846bdf) +PRISM [x86_64-darwin24] Syntax OK ``` Specifying parse.y causes a syntax error, as before 3.3 (parse.y by default): ```console $ ruby -vce 'if true && not true; end' ruby 3.3.8 (2025-04-09 revision b200bad6cd) [x86_64-darwin24] -e:1: syntax error, unexpected `true', expecting '(' if true && not true; end ruby: compile error (SyntaxError) $ ruby --parser=parse.y -vce 'if true && not true; end' ruby 3.5.0dev (2025-05-13T02:05:19Z master 9b8c846bdf) [x86_64-darwin24] -e:1: syntax error, unexpected 'true', expecting '(' if true && not true; end ruby: compile error (SyntaxError) ``` The behavior seen in the parse.y producing a syntax error might be probably the expected one. Any case, it is likely that users would not expect such a discrepancy between parsers. This issue was noticed in the context of the following RuboCop issue: https://github.com/rubocop/rubocop/issues/14177 -- https://bugs.ruby-lang.org/

Issue #21337 has been updated by Dan0042 (Daniel DeLorme). I prefer the behavior of Prism here. Intuitively, `true && not true` seems like it should be valid just like `true and not true` ---------------------------------------- Bug #21337: Using `not` on the RHS of a logical operator becomes valid syntax with Prism https://bugs.ruby-lang.org/issues/21337#change-113373 * Author: koic (Koichi ITO) * Status: Open * Assignee: prism * ruby -v: ruby 3.4.3 (2025-04-14 revision d0b7e5b6a0) +PRISM [x86_64-darwin24] * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- The following syntax behavior differs between Ruby 3.3 (parse.y by default) and Ruby 3.4 (Prism by default). ```ruby if true && not true; end ``` ## Expected In Ruby 3.3 and earlier, the following code results in a syntax error. The default parser is `parse.y`. ```console $ ruby -vce 'if true && not true; end' ruby 3.3.8 (2025-04-09 revision b200bad6cd) [x86_64-darwin24] -e:1: syntax error, unexpected `true', expecting '(' if true && not true; end ruby: compile error (SyntaxError) ``` The key point is that `not` is used on the right-hand side of a logical operator. ## Actual When the default parser is switched to Prism, it is accepted as valid syntax with Ruby 3.4+ (Prism by default): ```console $ ruby -vce 'if true && not true; end' ruby 3.4.3 (2025-04-14 revision d0b7e5b6a0) +PRISM [x86_64-darwin24] Syntax OK $ ruby -vce 'if true && not true; end' ruby 3.5.0dev (2025-05-13T02:05:19Z master 9b8c846bdf) +PRISM [x86_64-darwin24] Syntax OK ``` Specifying parse.y causes a syntax error, as before 3.3 (parse.y by default): ```console $ ruby -vce 'if true && not true; end' ruby 3.3.8 (2025-04-09 revision b200bad6cd) [x86_64-darwin24] -e:1: syntax error, unexpected `true', expecting '(' if true && not true; end ruby: compile error (SyntaxError) $ ruby --parser=parse.y -vce 'if true && not true; end' ruby 3.5.0dev (2025-05-13T02:05:19Z master 9b8c846bdf) [x86_64-darwin24] -e:1: syntax error, unexpected 'true', expecting '(' if true && not true; end ruby: compile error (SyntaxError) ``` The behavior seen in the parse.y producing a syntax error might be probably the expected one. Any case, it is likely that users would not expect such a discrepancy between parsers. This issue was noticed in the context of the following RuboCop issue: https://github.com/rubocop/rubocop/issues/14177 -- https://bugs.ruby-lang.org/

Issue #21337 has been updated by matz (Yukihiro Matsumoto). I am against this prism behavior. It introduces ambiguity for `not a && b` (might be `not (a && b)` or `(not a) && b`). I don't think we can have formal definition of this `not` behavior. Matz. ---------------------------------------- Bug #21337: Using `not` on the RHS of a logical operator becomes valid syntax with Prism https://bugs.ruby-lang.org/issues/21337#change-113619 * Author: koic (Koichi ITO) * Status: Assigned * Assignee: prism * ruby -v: ruby 3.4.3 (2025-04-14 revision d0b7e5b6a0) +PRISM [x86_64-darwin24] * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- The following syntax behavior differs between Ruby 3.3 (parse.y by default) and Ruby 3.4 (Prism by default). ```ruby if true && not true; end ``` ## Expected In Ruby 3.3 and earlier, the following code results in a syntax error. The default parser is `parse.y`. ```console $ ruby -vce 'if true && not true; end' ruby 3.3.8 (2025-04-09 revision b200bad6cd) [x86_64-darwin24] -e:1: syntax error, unexpected `true', expecting '(' if true && not true; end ruby: compile error (SyntaxError) ``` The key point is that `not` is used on the right-hand side of a logical operator. ## Actual When the default parser is switched to Prism, it is accepted as valid syntax with Ruby 3.4+ (Prism by default): ```console $ ruby -vce 'if true && not true; end' ruby 3.4.3 (2025-04-14 revision d0b7e5b6a0) +PRISM [x86_64-darwin24] Syntax OK $ ruby -vce 'if true && not true; end' ruby 3.5.0dev (2025-05-13T02:05:19Z master 9b8c846bdf) +PRISM [x86_64-darwin24] Syntax OK ``` Specifying parse.y causes a syntax error, as before 3.3 (parse.y by default): ```console $ ruby -vce 'if true && not true; end' ruby 3.3.8 (2025-04-09 revision b200bad6cd) [x86_64-darwin24] -e:1: syntax error, unexpected `true', expecting '(' if true && not true; end ruby: compile error (SyntaxError) $ ruby --parser=parse.y -vce 'if true && not true; end' ruby 3.5.0dev (2025-05-13T02:05:19Z master 9b8c846bdf) [x86_64-darwin24] -e:1: syntax error, unexpected 'true', expecting '(' if true && not true; end ruby: compile error (SyntaxError) ``` The behavior seen in the parse.y producing a syntax error might be probably the expected one. Any case, it is likely that users would not expect such a discrepancy between parsers. This issue was noticed in the context of the following RuboCop issue: https://github.com/rubocop/rubocop/issues/14177 -- https://bugs.ruby-lang.org/

Issue #21337 has been updated by mame (Yusuke Endoh). `p(not 1)` is also allowed in Ruby 3.4, but this should also be prohibited, @matz said. @kddnewton @tenderlovemaking @eileencodes Can you fix this issue soon? We need to backport to 3.4 to stop Ruby 3.4 users writing such code. ---------------------------------------- Bug #21337: Using `not` on the RHS of a logical operator becomes valid syntax with Prism https://bugs.ruby-lang.org/issues/21337#change-113631 * Author: koic (Koichi ITO) * Status: Assigned * Assignee: prism * ruby -v: ruby 3.4.3 (2025-04-14 revision d0b7e5b6a0) +PRISM [x86_64-darwin24] * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- The following syntax behavior differs between Ruby 3.3 (parse.y by default) and Ruby 3.4 (Prism by default). ```ruby if true && not true; end ``` ## Expected In Ruby 3.3 and earlier, the following code results in a syntax error. The default parser is `parse.y`. ```console $ ruby -vce 'if true && not true; end' ruby 3.3.8 (2025-04-09 revision b200bad6cd) [x86_64-darwin24] -e:1: syntax error, unexpected `true', expecting '(' if true && not true; end ruby: compile error (SyntaxError) ``` The key point is that `not` is used on the right-hand side of a logical operator. ## Actual When the default parser is switched to Prism, it is accepted as valid syntax with Ruby 3.4+ (Prism by default): ```console $ ruby -vce 'if true && not true; end' ruby 3.4.3 (2025-04-14 revision d0b7e5b6a0) +PRISM [x86_64-darwin24] Syntax OK $ ruby -vce 'if true && not true; end' ruby 3.5.0dev (2025-05-13T02:05:19Z master 9b8c846bdf) +PRISM [x86_64-darwin24] Syntax OK ``` Specifying parse.y causes a syntax error, as before 3.3 (parse.y by default): ```console $ ruby -vce 'if true && not true; end' ruby 3.3.8 (2025-04-09 revision b200bad6cd) [x86_64-darwin24] -e:1: syntax error, unexpected `true', expecting '(' if true && not true; end ruby: compile error (SyntaxError) $ ruby --parser=parse.y -vce 'if true && not true; end' ruby 3.5.0dev (2025-05-13T02:05:19Z master 9b8c846bdf) [x86_64-darwin24] -e:1: syntax error, unexpected 'true', expecting '(' if true && not true; end ruby: compile error (SyntaxError) ``` The behavior seen in the parse.y producing a syntax error might be probably the expected one. Any case, it is likely that users would not expect such a discrepancy between parsers. This issue was noticed in the context of the following RuboCop issue: https://github.com/rubocop/rubocop/issues/14177 -- https://bugs.ruby-lang.org/

Issue #21337 has been updated by tenderlovemaking (Aaron Patterson). Status changed from Assigned to Closed Backport changed from 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN to 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: REQUIRED I think this is fixed in 4cf85fe2140d0522f924ab57c850b2f03b967390 ---------------------------------------- Bug #21337: Using `not` on the RHS of a logical operator becomes valid syntax with Prism https://bugs.ruby-lang.org/issues/21337#change-114135 * Author: koic (Koichi ITO) * Status: Closed * Assignee: prism * ruby -v: ruby 3.4.3 (2025-04-14 revision d0b7e5b6a0) +PRISM [x86_64-darwin24] * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: REQUIRED ---------------------------------------- The following syntax behavior differs between Ruby 3.3 (parse.y by default) and Ruby 3.4 (Prism by default). ```ruby if true && not true; end ``` ## Expected In Ruby 3.3 and earlier, the following code results in a syntax error. The default parser is `parse.y`. ```console $ ruby -vce 'if true && not true; end' ruby 3.3.8 (2025-04-09 revision b200bad6cd) [x86_64-darwin24] -e:1: syntax error, unexpected `true', expecting '(' if true && not true; end ruby: compile error (SyntaxError) ``` The key point is that `not` is used on the right-hand side of a logical operator. ## Actual When the default parser is switched to Prism, it is accepted as valid syntax with Ruby 3.4+ (Prism by default): ```console $ ruby -vce 'if true && not true; end' ruby 3.4.3 (2025-04-14 revision d0b7e5b6a0) +PRISM [x86_64-darwin24] Syntax OK $ ruby -vce 'if true && not true; end' ruby 3.5.0dev (2025-05-13T02:05:19Z master 9b8c846bdf) +PRISM [x86_64-darwin24] Syntax OK ``` Specifying parse.y causes a syntax error, as before 3.3 (parse.y by default): ```console $ ruby -vce 'if true && not true; end' ruby 3.3.8 (2025-04-09 revision b200bad6cd) [x86_64-darwin24] -e:1: syntax error, unexpected `true', expecting '(' if true && not true; end ruby: compile error (SyntaxError) $ ruby --parser=parse.y -vce 'if true && not true; end' ruby 3.5.0dev (2025-05-13T02:05:19Z master 9b8c846bdf) [x86_64-darwin24] -e:1: syntax error, unexpected 'true', expecting '(' if true && not true; end ruby: compile error (SyntaxError) ``` The behavior seen in the parse.y producing a syntax error might be probably the expected one. Any case, it is likely that users would not expect such a discrepancy between parsers. This issue was noticed in the context of the following RuboCop issue: https://github.com/rubocop/rubocop/issues/14177 -- https://bugs.ruby-lang.org/
participants (6)
-
byroot (Jean Boussier)
-
Dan0042 (Daniel DeLorme)
-
koic (Koichi ITO)
-
mame (Yusuke Endoh)
-
matz (Yukihiro Matsumoto)
-
tenderlovemaking (Aaron Patterson)