Skip to content

Prism.find can return the wrong node on older Ruby versions #4066

@eregon

Description

@eregon

Quoting from https://bugs.ruby-lang.org/issues/21795#note-13:


I thought more about node_id and I found at least one case where it is problematic with different versions of Prism.
The problem is the node_id from the bytecode is computed by the builtin Prism parser used by prism_compile.c, while the usage of e.g. Prism.find might use a more recent Prism.
Here is a reproduction showing the problem:

if false
  # A code snippet which generates a different number of nodes on Prism 1.2.0 and 1.9.0
  case 1
  in 2
    A.print message:
  in 3
    A.print message:
  end
end

def a
end

def b
end

require "prism"
p Prism.find(method(:b))

ruby master is fine:

$ ruby -v find_check.rb
ruby 4.1.0dev (2026-03-27T16:16:27Z revert-source_loca.. f510d4103e) +PRISM [x86_64-linux]
@ DefNode (location: (14,0)-(15,3))
├── flags: newline
├── name: :b

But on Ruby 3.4.5 it's broken:

# Use latest prism, there is no prism release with Prism.find yet:
$ cd prism
$ bundle exec rake compile
$ bundle exec ruby find_check.rb 
@ DefNode (location: (11,0)-(12,3))
├── flags: newline
├── name: :a

This returns method a and not b!

And if I change p Prism.find(method(:b)) to p Prism.find(method(:a)),
then ruby-master is correct, but 3.4.5 returns an IfNode.

IOW, 3.4.5 returns the wrong node


I think a good fix for now would be to remove the RubyVM-based implementation of Node.find.
And use start/end offset (or line+column) when that becomes available.

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