Skip to content

Commit

Permalink
[ruby/prism] Fix a diagnostic incompatibility
Browse files Browse the repository at this point in the history
This PR fixes a diagnostic incompatibility when using no anonymous keyword rest parameter:

```ruby
foo(**)
```

Note, although the actual update applies only to the `foo(**)` case, for reference,
`foo(*)` and `foo(&) are also mentioned below.

## Ruby (Expected)

```console
$ ruby -cve 'foo(*)'
ruby 3.3.0 (2023-12-25 revision ruby/prism@5124f9ac75) [x86_64-darwin22]
-e:1: no anonymous rest parameter
-e: compile error (SyntaxError)

$ ruby -cve 'foo(**)'
ruby 3.3.0 (2023-12-25 revision ruby/prism@5124f9ac75) [x86_64-darwin22]
-e:1: no anonymous keyword rest parameter
-e: compile error (SyntaxError)

$ ruby -cve 'foo(&)'
ruby 3.3.0 (2023-12-25 revision ruby/prism@5124f9ac75) [x86_64-darwin22]
-e:1: no anonymous block parameter
-e: compile error (SyntaxError)
```

## Prism (Actual)

Before:

```console
$ bundle exec ruby -Ilib -rprism -wve 'p Prism.parse("foo(*)").errors'
ruby 3.3.0 (2023-12-25 revision ruby/prism@5124f9ac75) [x86_64-darwin22]
[#<Prism::ParseError @type=:argument_no_forwarding_star @message="unexpected `*` when the parent method is not forwarding"
@location=#<Prism::Location @start_offset=4 @Length=1 start_line=1> @Level=:fatal>]

$ bundle exec ruby -Ilib -rprism -wve 'p Prism.parse("foo(**)").errors'
ruby 3.3.0 (2023-12-25 revision ruby/prism@5124f9ac75) [x86_64-darwin22]
[#<Prism::ParseError @type=:expect_expression_after_splat_hash @message="expected an expression after `**` in a hash"
@location=#<Prism::Location @start_offset=4 @Length=2 start_line=1> @Level=:fatal>]

$ bundle exec ruby -Ilib -rprism -wve 'p Prism.parse("foo(&)").errors'
ruby 3.3.0 (2023-12-25 revision ruby/prism@5124f9ac75) [x86_64-darwin22]
[#<Prism::ParseError @type=:argument_no_forwarding_amp @message="unexpected `&` when the parent method is not forwarding"
@location=#<Prism::Location @start_offset=4 @Length=1 start_line=1> @Level=:fatal>]
```

After:

```console
$ bundle exec ruby -Ilib -rprism -wve 'p Prism.parse("foo(*)").errors'
ruby 3.3.0 (2023-12-25 revision ruby/prism@5124f9ac75) [x86_64-darwin22]
[#<Prism::ParseError @type=:argument_no_forwarding_star @message="unexpected `*` when the parent method is not forwarding"
@location=#<Prism::Location @start_offset=4 @Length=1 start_line=1> @Level=:fatal>]

$ bundle exec ruby -Ilib -rprism -wve 'p Prism.parse("foo(**)").errors'
ruby 3.3.0 (2023-12-25 revision ruby/prism@5124f9ac75) [x86_64-darwin22]
[#<Prism::ParseError @type=:argument_no_forwarding_star_star @message="unexpected `**` when the parent method is not forwarding"
@location=#<Prism::Location @start_offset=4 @Length=2 start_line=1> @Level=:fatal>]

$ bundle exec ruby -Ilib -rprism -wve 'p Prism.parse("foo(&)").errors'
ruby 3.3.0 (2023-12-25 revision ruby/prism@5124f9ac75) [x86_64-darwin22]
[#<Prism::ParseError @type=:argument_no_forwarding_amp @message="unexpected `&` when the parent method is not forwarding"
@location=#<Prism::Location @start_offset=4 @Length=1 start_line=1> @Level=:fatal>]
```

ruby/prism@633c9d9fd4
  • Loading branch information
koic authored and matzbot committed Mar 19, 2024
1 parent 72a613b commit 0a10702
Show file tree
Hide file tree
Showing 4 changed files with 5 additions and 1 deletion.
2 changes: 2 additions & 0 deletions lib/prism/translation/parser.rb
Expand Up @@ -135,6 +135,8 @@ def error_diagnostic(error, offset_cache)
Diagnostic.new(:error, :no_anonymous_blockarg, {}, diagnostic_location, [])
when :argument_no_forwarding_star
Diagnostic.new(:error, :no_anonymous_restarg, {}, diagnostic_location, [])
when :argument_no_forwarding_star_star
Diagnostic.new(:error, :no_anonymous_kwrestarg, {}, diagnostic_location, [])
when :begin_lonely_else
location = location.copy(length: 4)
diagnostic_location = build_range(location, offset_cache)
Expand Down
1 change: 1 addition & 0 deletions prism/config.yml
Expand Up @@ -15,6 +15,7 @@ errors:
- ARGUMENT_NO_FORWARDING_AMP
- ARGUMENT_NO_FORWARDING_ELLIPSES
- ARGUMENT_NO_FORWARDING_STAR
- ARGUMENT_NO_FORWARDING_STAR_STAR
- ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT
- ARGUMENT_SPLAT_AFTER_SPLAT
- ARGUMENT_TERM_PAREN
Expand Down
2 changes: 1 addition & 1 deletion prism/prism.c
Expand Up @@ -6818,7 +6818,7 @@ pm_parser_scope_forwarding_all_check(pm_parser_t *parser, const pm_token_t * tok

static inline void
pm_parser_scope_forwarding_keywords_check(pm_parser_t *parser, const pm_token_t * token) {
pm_parser_scope_forwarding_param_check(parser, token, PM_SCOPE_PARAMETERS_FORWARDING_KEYWORDS, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH);
pm_parser_scope_forwarding_param_check(parser, token, PM_SCOPE_PARAMETERS_FORWARDING_KEYWORDS, PM_ERR_ARGUMENT_NO_FORWARDING_STAR_STAR);
}

/**
Expand Down
1 change: 1 addition & 0 deletions prism/templates/src/diagnostic.c.erb
Expand Up @@ -97,6 +97,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
[PM_ERR_ARGUMENT_NO_FORWARDING_AMP] = { "unexpected `&` when the parent method is not forwarding", PM_ERROR_LEVEL_FATAL },
[PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES] = { "unexpected `...` when the parent method is not forwarding", PM_ERROR_LEVEL_FATAL },
[PM_ERR_ARGUMENT_NO_FORWARDING_STAR] = { "unexpected `*` when the parent method is not forwarding", PM_ERROR_LEVEL_FATAL },
[PM_ERR_ARGUMENT_NO_FORWARDING_STAR_STAR] = { "unexpected `**` when the parent method is not forwarding", PM_ERROR_LEVEL_FATAL },
[PM_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT] = { "unexpected `*` splat argument after a `**` keyword splat argument", PM_ERROR_LEVEL_FATAL },
[PM_ERR_ARGUMENT_SPLAT_AFTER_SPLAT] = { "unexpected `*` splat argument after a `*` splat argument", PM_ERROR_LEVEL_FATAL },
[PM_ERR_ARGUMENT_TERM_PAREN] = { "expected a `)` to close the arguments", PM_ERROR_LEVEL_FATAL },
Expand Down

0 comments on commit 0a10702

Please sign in to comment.