whitequark / parser

A Ruby parser.
Other
1.59k stars 199 forks source link

Inconsistent AST generation with semicolon before `rescue` #1040

Closed koic closed 2 months ago

koic commented 2 months ago

There is an incompatibility with the AST parsing in the Parser gem.

Without a semicolon before rescue:

$ ruby-parse -e "foo do next unless bar rescue StandardError; end"
(block
  (send nil :foo)
  (args)
  (rescue
    (if
      (send nil :bar) nil
      (next))
    (resbody nil nil
      (const nil :StandardError)) nil))

With a semicolon before rescue:

$ ruby-parse -e "foo do next unless bar; rescue StandardError; end"
(block
  (send nil :foo)
  (args)
  (rescue
    (if
      (send nil :bar) nil
      (next))
    (resbody
      (array
        (const nil :StandardError)) nil nil) nil))

Expected

I expect both examples to generate the same AST as the one without a semicolon before rescue.

Actual

An unexpected array node is generated in the example with a semicolon before rescue.

iliabylich commented 2 months ago

Haven't checked it yet, but looks like in the first example it's a post-rescue (like in foo rescue bar) while in the other the delimiter makes it a begin; rescue; end thing. The former can't have a list of errors, the latter can, thus there's an array node.

foo do next unless (bar rescue StandardError); end

# vs

foo do
  next unless bar;
rescue StandardError;
end
koic commented 2 months ago

Ah, it was my misunderstanding. Thank you for the detailed explanation!