Skip to content

RSpec/LeadingSubject crashes under TargetRubyVersion: 3.4 with prism #2145

@Drowze

Description

@Drowze

Steps to reproduce the problem

Given foo_spec.rb:

RSpec.describe "Test" do
  subject { "foo" }
  it
end

Given .rubocop.yml:

AllCops:
  TargetRubyVersion: 3.4
plugins:
  - rubocop-rspec

Running rubocop:

rubocop -d --cache false --only RSpec/LeadingSubject foo_spec.rb

Expected behavior

I expect no unhandled crashes.

Actual behavior

A crash on leading_subject.rb.
(NOTE: the crash does NOT happen if I set ParserEngine to parser_whitequark, so it's likely an issue related to some difference between Parser and Prism)

Some relevant lines of the output:

An error occurred while RSpec/LeadingSubject cop was inspecting /Users/Drowze/workspace/ruby-scripts/rubocop_lsp_bug/foo_spec.rb:2:2.
/Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-rspec-3.8.0/lib/rubocop/cop/rspec/leading_subject.rb:67:in 'RuboCop::Cop::RSpec::LeadingSubject#parent': undefined method 'body' for nil (NoMethodError)

          node.each_ancestor(:block).first.body
                                          ^^^^^
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-rspec-3.8.0/lib/rubocop/cop/rspec/leading_subject.rb:59:in 'RuboCop::Cop::RSpec::LeadingSubject#offending_node'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-rspec-3.8.0/lib/rubocop/cop/rspec/leading_subject.rb:50:in 'RuboCop::Cop::RSpec::LeadingSubject#check_previous_nodes'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-rspec-3.8.0/lib/rubocop/cop/rspec/leading_subject.rb:44:in 'RuboCop::Cop::RSpec::LeadingSubject#on_block'
Full output (click to expand)
Scanning /Users/Drowze/workspace/ruby-scripts/rubocop_lsp_bug/foo_spec.rb
An error occurred while RSpec/LeadingSubject cop was inspecting /Users/Drowze/workspace/ruby-scripts/rubocop_lsp_bug/foo_spec.rb:2:2.
/Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-rspec-3.8.0/lib/rubocop/cop/rspec/leading_subject.rb:67:in 'RuboCop::Cop::RSpec::LeadingSubject#parent': undefined method 'body' for nil (NoMethodError)

          node.each_ancestor(:block).first.body
                                          ^^^^^
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-rspec-3.8.0/lib/rubocop/cop/rspec/leading_subject.rb:59:in 'RuboCop::Cop::RSpec::LeadingSubject#offending_node'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-rspec-3.8.0/lib/rubocop/cop/rspec/leading_subject.rb:50:in 'RuboCop::Cop::RSpec::LeadingSubject#check_previous_nodes'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-rspec-3.8.0/lib/rubocop/cop/rspec/leading_subject.rb:44:in 'RuboCop::Cop::RSpec::LeadingSubject#on_block'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/cop/commissioner.rb:107:in 'Kernel#public_send'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/cop/commissioner.rb:107:in 'block (2 levels) in RuboCop::Cop::Commissioner#trigger_responding_cops'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/cop/commissioner.rb:171:in 'RuboCop::Cop::Commissioner#with_cop_error_handling'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/cop/commissioner.rb:106:in 'block in RuboCop::Cop::Commissioner#trigger_responding_cops'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/cop/commissioner.rb:105:in 'Array#each'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/cop/commissioner.rb:105:in 'RuboCop::Cop::Commissioner#trigger_responding_cops'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/cop/commissioner.rb:69:in 'RuboCop::Cop::Commissioner#on_block'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-ast-1.48.0/lib/rubocop/ast/traversal.rb:147:in 'block in RuboCop::AST::Traversal#on_dstr'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-ast-1.48.0/lib/rubocop/ast/traversal.rb:147:in 'Array#each'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-ast-1.48.0/lib/rubocop/ast/traversal.rb:147:in 'RuboCop::AST::Traversal#on_dstr'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/cop/commissioner.rb:71:in 'RuboCop::Cop::Commissioner#on_begin'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-ast-1.48.0/lib/rubocop/ast/traversal.rb:169:in 'RuboCop::AST::Traversal#on_itblock'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/cop/commissioner.rb:71:in 'RuboCop::Cop::Commissioner#on_itblock'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-ast-1.48.0/lib/rubocop/ast/traversal.rb:20:in 'RuboCop::AST::Traversal#walk'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/cop/commissioner.rb:87:in 'RuboCop::Cop::Commissioner#investigate'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/cop/team.rb:174:in 'RuboCop::Cop::Team#investigate_partial'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/cop/team.rb:108:in 'RuboCop::Cop::Team#investigate'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/runner.rb:350:in 'block in RuboCop::Runner#inspect_file'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/runner.rb:349:in 'Array#each'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/runner.rb:349:in 'Enumerable#flat_map'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/runner.rb:349:in 'RuboCop::Runner#inspect_file'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/runner.rb:291:in 'block in RuboCop::Runner#do_inspection_loop'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/runner.rb:326:in 'block in RuboCop::Runner#iterate_until_no_changes'
        from <internal:kernel>:168:in 'Kernel#loop'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/runner.rb:319:in 'RuboCop::Runner#iterate_until_no_changes'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/runner.rb:287:in 'RuboCop::Runner#do_inspection_loop'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/runner.rb:167:in 'block in RuboCop::Runner#file_offenses'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/runner.rb:192:in 'RuboCop::Runner#file_offense_cache'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/runner.rb:166:in 'RuboCop::Runner#file_offenses'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/runner.rb:154:in 'RuboCop::Runner#process_file'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/runner.rb:135:in 'block in RuboCop::Runner#each_inspected_file'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/runner.rb:134:in 'Array#each'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/runner.rb:134:in 'Enumerable#reduce'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/runner.rb:134:in 'RuboCop::Runner#each_inspected_file'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/runner.rb:120:in 'RuboCop::Runner#inspect_files'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/runner.rb:73:in 'RuboCop::Runner#run'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/cli/command/execute_runner.rb:26:in 'block in RuboCop::CLI::Command::ExecuteRunner#execute_runner'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/cli/command/execute_runner.rb:52:in 'RuboCop::CLI::Command::ExecuteRunner#with_redirect'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/cli/command/execute_runner.rb:25:in 'RuboCop::CLI::Command::ExecuteRunner#execute_runner'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/cli/command/execute_runner.rb:17:in 'RuboCop::CLI::Command::ExecuteRunner#run'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/cli/command.rb:11:in 'RuboCop::CLI::Command.run'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/cli/environment.rb:18:in 'RuboCop::CLI::Environment#run'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/cli.rb:128:in 'RuboCop::CLI#run_command'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/cli.rb:135:in 'RuboCop::CLI#execute_runners'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/cli.rb:54:in 'block in RuboCop::CLI#run'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/cli.rb:87:in 'RuboCop::CLI#profile_if_needed'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/lib/rubocop/cli.rb:45:in 'RuboCop::CLI#run'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/lib/ruby/gems/3.4.0/gems/rubocop-1.81.7/exe/rubocop:15:in '<top (required)>'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/bin/rubocop:25:in 'Kernel#load'
        from /Users/Drowze/.local/share/mise/installs/ruby/3.4.7/bin/rubocop:25:in '<main>'
.

1 file inspected, no offenses detected

1 error occurred:
An error occurred while RSpec/LeadingSubject cop was inspecting /Users/Drowze/workspace/ruby-scripts/rubocop_lsp_bug/foo_spec.rb:2:2.
configuration from /Users/Drowze/workspace/ruby-scripts/rubocop_lsp_bug/.rubocop.yml
Errors are usually caused by RuboCop bugs.
Please, update to the latest RuboCop version if not already in use, and report a bug if the issue still occurs on this version.
https://github.com/rubocop/rubocop/issues

Mention the following information in the issue report:
1.81.7 (using Parser 3.3.10.0, rubocop-ast 1.48.0, analyzing as Ruby 2.7, running on ruby 3.4.7) [arm64-darwin24]
Finished in 0.11606499998015352 seconds

RuboCop RSpec version

$ rubocop -V
1.81.7 (using Parser 3.3.10.0, Prism 1.6.0, rubocop-ast 1.48.0, analyzing as Ruby 3.4, running on ruby 3.4.7) [arm64-darwin24]
  - rubocop-rspec 3.8.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions