whitequark / parser

A Ruby parser.
Other
1.57k stars 197 forks source link

+ ruby{33,34}.y: allow blocks inherit anonymous args. #1010

Closed iliabylich closed 2 months ago

iliabylich commented 2 months ago

This commit tracks upstream commit ruby/ruby@596db9c.

Closes https://github.com/whitequark/parser/issues/963.

Unfortunately there are 0 tests for anonymous <PARAM> parameter is also used within block error message in the ruby/ruby repo.

A small script to verify this behaviour ```sh set -x $RUN 'def b(&) ->(&) {c(&)} end' $RUN 'def b(*) ->(*) {c(*)} end' $RUN 'def b(a, *) ->(*) {c(1, *)} end' $RUN 'def b(*) ->(a, *) {c(*)} end' $RUN 'def b(**) ->(**) {c(**)} end' $RUN 'def b(k:, **) ->(**) {c(k: 1, **)} end' $RUN 'def b(**) ->(k:, **) {c(**)} end' echo $RUN 'def b(&) ->(&) {c()} end' $RUN 'def b(*) ->(*) {c()} end' $RUN 'def b(**) ->(**) {c()} end' echo $RUN 'def b(&) ->() {c(&)} end' $RUN 'def b(*) ->() {c(*)} end' $RUN 'def b(a, *) ->() {c(1, *)} end' $RUN 'def b(*) ->(a) {c(*)} end' $RUN 'def b(**) ->() {c(**)} end' $RUN 'def b(k:, **) ->() {c(k: 1, **)} end' $RUN 'def b(**) ->(k:) {c(**)} end' ```

Ruby 3.3.0 (only inputs in the 2nd group are valid):

Details ``` + ruby -cve 'def b(&) ->(&) {c(&)} end' ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23] -e:1: anonymous block parameter is also used within block -e: compile error (SyntaxError) + ruby -cve 'def b(*) ->(*) {c(*)} end' ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23] -e:1: anonymous rest parameter is also used within block -e: compile error (SyntaxError) + ruby -cve 'def b(a, *) ->(*) {c(1, *)} end' ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23] -e:1: anonymous rest parameter is also used within block -e: compile error (SyntaxError) + ruby -cve 'def b(*) ->(a, *) {c(*)} end' ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23] -e:1: anonymous rest parameter is also used within block -e: compile error (SyntaxError) + ruby -cve 'def b(**) ->(**) {c(**)} end' ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23] -e:1: anonymous keyword rest parameter is also used within block -e: compile error (SyntaxError) + ruby -cve 'def b(k:, **) ->(**) {c(k: 1, **)} end' ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23] -e:1: anonymous keyword rest parameter is also used within block -e: compile error (SyntaxError) + ruby -cve 'def b(**) ->(k:, **) {c(**)} end' ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23] -e:1: anonymous keyword rest parameter is also used within block -e: compile error (SyntaxError) + echo + ruby -cve 'def b(&) ->(&) {c()} end' ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23] Syntax OK + ruby -cve 'def b(*) ->(*) {c()} end' ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23] Syntax OK + ruby -cve 'def b(**) ->(**) {c()} end' ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23] Syntax OK + echo + ruby -cve 'def b(&) ->() {c(&)} end' ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23] -e:1: anonymous block parameter is also used within block -e: compile error (SyntaxError) + ruby -cve 'def b(*) ->() {c(*)} end' ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23] -e:1: anonymous rest parameter is also used within block -e: compile error (SyntaxError) + ruby -cve 'def b(a, *) ->() {c(1, *)} end' ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23] -e:1: anonymous rest parameter is also used within block -e: compile error (SyntaxError) + ruby -cve 'def b(*) ->(a) {c(*)} end' ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23] -e:1: anonymous rest parameter is also used within block -e: compile error (SyntaxError) + ruby -cve 'def b(**) ->() {c(**)} end' ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23] -e:1: anonymous keyword rest parameter is also used within block -e: compile error (SyntaxError) + ruby -cve 'def b(k:, **) ->() {c(k: 1, **)} end' ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23] -e:1: anonymous keyword rest parameter is also used within block -e: compile error (SyntaxError) + ruby -cve 'def b(**) ->(k:) {c(**)} end' ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23] -e:1: anonymous keyword rest parameter is also used within block -e: compile error (SyntaxError) ```

Ruby 3.3.1 (the 2nd and the 3rd groups are valid):

Details ``` + ruby -cve 'def b(&) ->(&) {c(&)} end' ruby 3.3.1 (2024-04-23 revision c56cd86388) [arm64-darwin23] -e:1: anonymous block parameter is also used within block -e: compile error (SyntaxError) + ruby -cve 'def b(*) ->(*) {c(*)} end' ruby 3.3.1 (2024-04-23 revision c56cd86388) [arm64-darwin23] -e:1: anonymous rest parameter is also used within block -e: compile error (SyntaxError) + ruby -cve 'def b(a, *) ->(*) {c(1, *)} end' ruby 3.3.1 (2024-04-23 revision c56cd86388) [arm64-darwin23] -e:1: anonymous rest parameter is also used within block -e: compile error (SyntaxError) + ruby -cve 'def b(*) ->(a, *) {c(*)} end' ruby 3.3.1 (2024-04-23 revision c56cd86388) [arm64-darwin23] -e:1: anonymous rest parameter is also used within block -e: compile error (SyntaxError) + ruby -cve 'def b(**) ->(**) {c(**)} end' ruby 3.3.1 (2024-04-23 revision c56cd86388) [arm64-darwin23] -e:1: anonymous keyword rest parameter is also used within block -e: compile error (SyntaxError) + ruby -cve 'def b(k:, **) ->(**) {c(k: 1, **)} end' ruby 3.3.1 (2024-04-23 revision c56cd86388) [arm64-darwin23] -e:1: anonymous keyword rest parameter is also used within block -e: compile error (SyntaxError) + ruby -cve 'def b(**) ->(k:, **) {c(**)} end' ruby 3.3.1 (2024-04-23 revision c56cd86388) [arm64-darwin23] -e:1: anonymous keyword rest parameter is also used within block -e: compile error (SyntaxError) + echo + ruby -cve 'def b(&) ->(&) {c()} end' ruby 3.3.1 (2024-04-23 revision c56cd86388) [arm64-darwin23] Syntax OK + ruby -cve 'def b(*) ->(*) {c()} end' ruby 3.3.1 (2024-04-23 revision c56cd86388) [arm64-darwin23] Syntax OK + ruby -cve 'def b(**) ->(**) {c()} end' ruby 3.3.1 (2024-04-23 revision c56cd86388) [arm64-darwin23] Syntax OK + echo + ruby -cve 'def b(&) ->() {c(&)} end' ruby 3.3.1 (2024-04-23 revision c56cd86388) [arm64-darwin23] Syntax OK + ruby -cve 'def b(*) ->() {c(*)} end' ruby 3.3.1 (2024-04-23 revision c56cd86388) [arm64-darwin23] Syntax OK + ruby -cve 'def b(a, *) ->() {c(1, *)} end' ruby 3.3.1 (2024-04-23 revision c56cd86388) [arm64-darwin23] Syntax OK + ruby -cve 'def b(*) ->(a) {c(*)} end' ruby 3.3.1 (2024-04-23 revision c56cd86388) [arm64-darwin23] Syntax OK + ruby -cve 'def b(**) ->() {c(**)} end' ruby 3.3.1 (2024-04-23 revision c56cd86388) [arm64-darwin23] Syntax OK + ruby -cve 'def b(k:, **) ->() {c(k: 1, **)} end' ruby 3.3.1 (2024-04-23 revision c56cd86388) [arm64-darwin23] Syntax OK + ruby -cve 'def b(**) ->(k:) {c(**)} end' ruby 3.3.1 (2024-04-23 revision c56cd86388) [arm64-darwin23] Syntax OK ```

This patch (mirrors 3.3.1, thus also groups 2 and 3 are valid):

Details ``` + bin/ruby-parse --33 -e 'def b(&) ->(&) {c(&)} end' (fragment:0):1:19: error: anonymous block parameter is also used within block (fragment:0):1: def b(&) ->(&) {c(&)} end (fragment:0):1: ^ + bin/ruby-parse --33 -e 'def b(*) ->(*) {c(*)} end' (fragment:0):1:19: error: anonymous rest parameter is also used within block (fragment:0):1: def b(*) ->(*) {c(*)} end (fragment:0):1: ^ + bin/ruby-parse --33 -e 'def b(a, *) ->(*) {c(1, *)} end' (fragment:0):1:25: error: anonymous rest parameter is also used within block (fragment:0):1: def b(a, *) ->(*) {c(1, *)} end (fragment:0):1: ^ + bin/ruby-parse --33 -e 'def b(*) ->(a, *) {c(*)} end' (fragment:0):1:22: error: anonymous rest parameter is also used within block (fragment:0):1: def b(*) ->(a, *) {c(*)} end (fragment:0):1: ^ + bin/ruby-parse --33 -e 'def b(**) ->(**) {c(**)} end' (fragment:0):1:21: error: anonymous keyword rest parameter is also used within block (fragment:0):1: def b(**) ->(**) {c(**)} end (fragment:0):1: ^~ + bin/ruby-parse --33 -e 'def b(k:, **) ->(**) {c(k: 1, **)} end' (fragment:0):1:31: error: anonymous keyword rest parameter is also used within block (fragment:0):1: def b(k:, **) ->(**) {c(k: 1, **)} end (fragment:0):1: ^~ + bin/ruby-parse --33 -e 'def b(**) ->(k:, **) {c(**)} end' (fragment:0):1:25: error: anonymous keyword rest parameter is also used within block (fragment:0):1: def b(**) ->(k:, **) {c(**)} end (fragment:0):1: ^~ + echo + bin/ruby-parse --33 -e 'def b(&) ->(&) {c()} end' (def :b (args (blockarg nil)) (block (lambda) (args (blockarg nil)) (send nil :c))) + bin/ruby-parse --33 -e 'def b(*) ->(*) {c()} end' (def :b (args (restarg)) (block (lambda) (args (restarg)) (send nil :c))) + bin/ruby-parse --33 -e 'def b(**) ->(**) {c()} end' (def :b (args (kwrestarg)) (block (lambda) (args (kwrestarg)) (send nil :c))) + echo + bin/ruby-parse --33 -e 'def b(&) ->() {c(&)} end' (def :b (args (blockarg nil)) (block (lambda) (args) (send nil :c (block-pass nil)))) + bin/ruby-parse --33 -e 'def b(*) ->() {c(*)} end' (def :b (args (restarg)) (block (lambda) (args) (send nil :c (forwarded-restarg)))) + bin/ruby-parse --33 -e 'def b(a, *) ->() {c(1, *)} end' (def :b (args (arg :a) (restarg)) (block (lambda) (args) (send nil :c (int 1) (forwarded-restarg)))) + bin/ruby-parse --33 -e 'def b(*) ->(a) {c(*)} end' (def :b (args (restarg)) (block (lambda) (args (arg :a)) (send nil :c (forwarded-restarg)))) + bin/ruby-parse --33 -e 'def b(**) ->() {c(**)} end' (def :b (args (kwrestarg)) (block (lambda) (args) (send nil :c (kwargs (forwarded-kwrestarg))))) + bin/ruby-parse --33 -e 'def b(k:, **) ->() {c(k: 1, **)} end' (def :b (args (kwarg :k) (kwrestarg)) (block (lambda) (args) (send nil :c (kwargs (pair (sym :k) (int 1)) (forwarded-kwrestarg))))) + bin/ruby-parse --33 -e 'def b(**) ->(k:) {c(**)} end' (def :b (args (kwrestarg)) (block (lambda) (args (kwarg :k)) (send nil :c (kwargs (forwarded-kwrestarg))))) ```