ruby-formatter / rufo

The Ruby Formatter
MIT License
894 stars 56 forks source link

Single splat in case context causes crash: `to_ary': undefined method `[]' for nil #325

Closed jbarber closed 1 week ago

jbarber commented 1 month ago
bundle exec rufo --version

Reproduction case:

class Foo
  def self.[](*args)= true
end

data = "a"
case "baz"
in Foo[*data] # This splat is what causes the crash
  puts "foo"
else
  puts "bar"
end

Backtrace:

You've found a bug!
It happened while trying to format the file test.rb
Please report it to https://github.com/ruby-formatter/rufo/issues with code that triggers it
bundler: failed to load command: rufo (/home/jbarber/.asdf/installs/ruby/3.3.3/bin/rufo)
/home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/formatter.rb:4014:in `to_ary': undefined method `[]' for nil (NoMethodError)

    node[0].is_a?(Symbol) ? [node] : node
        ^^^
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/formatter.rb:1768:in `visit_comma_separated_list'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/formatter.rb:3159:in `visit_constant_pattern'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/formatter.rb:3087:in `visit_array_pattern'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/formatter.rb:478:in `visit'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/formatter.rb:2979:in `block in visit_when'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/formatter.rb:3678:in `indent'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/formatter.rb:2968:in `visit_when'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/formatter.rb:389:in `visit'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/formatter.rb:2943:in `visit_case'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/formatter.rb:387:in `visit'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/formatter.rb:517:in `block (2 levels) in visit_exps'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/formatter.rb:3994:in `push_node'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/formatter.rb:516:in `block in visit_exps'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/formatter.rb:495:in `each'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/formatter.rb:495:in `each_with_index'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/formatter.rb:495:in `visit_exps'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/formatter.rb:202:in `visit'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/formatter.rb:178:in `format'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/command.rb:146:in `format'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/command.rb:107:in `format_file'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/command.rb:85:in `block in format_args'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/command.rb:78:in `each'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/command.rb:78:in `format_args'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/command.rb:40:in `run'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/lib/rufo/command.rb:12:in `run'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/rufo-0.18.0/exe/rufo:4:in `<top (required)>'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/bin/rufo:25:in `load'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/bin/rufo:25:in `<top (required)>'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/bundler-2.5.14/lib/bundler/cli/exec.rb:58:in `load'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/bundler-2.5.14/lib/bundler/cli/exec.rb:58:in `kernel_load'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/bundler-2.5.14/lib/bundler/cli/exec.rb:23:in `run'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/bundler-2.5.14/lib/bundler/cli.rb:455:in `exec'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/bundler-2.5.14/lib/bundler/vendor/thor/lib/thor/command.rb:28:in `run'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/bundler-2.5.14/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/bundler-2.5.14/lib/bundler/vendor/thor/lib/thor.rb:527:in `dispatch'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/bundler-2.5.14/lib/bundler/cli.rb:35:in `dispatch'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/bundler-2.5.14/lib/bundler/vendor/thor/lib/thor/base.rb:584:in `start'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/bundler-2.5.14/lib/bundler/cli.rb:29:in `start'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/bundler-2.5.14/exe/bundle:28:in `block in <top (required)>'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/bundler-2.5.14/lib/bundler/friendly_errors.rb:117:in `with_friendly_errors'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/lib/ruby/gems/3.3.0/gems/bundler-2.5.14/exe/bundle:20:in `<top (required)>'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/bin/bundle:25:in `load'
    from /home/jbarber/.asdf/installs/ruby/3.3.3/bin/bundle:25:in `<main>'
jbarber commented 1 month ago

I came across this because we use Dry::Monad and we're checking for Success / Failure in the case statement conditions.

kzkn commented 1 week ago

@jbarber Hi :smiley: Thanks for the report. I've pushed a fix for the issue to master branch. Please give it try.

jbarber commented 6 days ago

Thanks @kzkn - unfortunately I don't have access to the original code anymore - so can't test it upstream, but if the change fixed the repoduction - then I'm pretty sure it'll work.

Thanks!