Project

General

Profile

Bug #17534

Pattern-matching is broken with find pattern

Added by zverok (Victor Shepelev) about 2 months ago. Updated about 1 month ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:102061]

Description

The minimal reproduction code:

case [1, 2, 3]
in y
  puts "branch1"
in [*, x, *]
  puts "branch2"
else
  puts "branch3"
end

This outputs long "raw disasm" sequence, and then

---------------------
break_pm.rb:6: argument stack underflow (-1)
break_pm.rb: compile error (SyntaxError)
$ ruby -v
ruby 3.1.0dev (2021-01-13T09:12:49Z master 6f6dfdcc68) [x86_64-linux]

Updated by palkan (Vladimir Dementyev) about 2 months ago

zverok (Victor Shepelev) wrote:

The minimal reproduction code:

case [1, 2, 3]
in y
  puts "branch1"
in [*, x, *]
  puts "branch2"
else
  puts "branch3"
end

This outputs long "raw disasm" sequence, and then

---------------------
break_pm.rb:6: argument stack underflow (-1)
break_pm.rb: compile error (SyntaxError)
$ ruby -v
ruby 3.1.0dev (2021-01-13T09:12:49Z master 6f6dfdcc68) [x86_64-linux]

That could be related to https://github.com/ruby/ruby/pull/3104.
I'll take a look.

Updated by palkan (Vladimir Dementyev) about 2 months ago

palkan (Vladimir Dementyev) wrote in #note-1:

That could be related to https://github.com/ruby/ruby/pull/3104.
I'll take a look.

Hm, nope. Reproduced in the older revision (d6c9c014e2). Investigating further.

Updated by palkan (Vladimir Dementyev) about 2 months ago

So, what I found: the bug is caused by iseq_peephole_optimize and find patterns iseq incompatibility; remove_unreachable_chunk doesn't remove while_begin, next_loop and other find_pattern specific labels, but removes general pattern matching instructions (including stack allocation for "local" variables). (Disabling remove_unreachable_chunk fixes this).

Possibly, that happens due to the labels cycle (while_begin -> next_loop -> while_begin); though I'm not really familiar with the peephole optimization. /cc nobu (Nobuyoshi Nakada) ko1 (Koichi Sasada)

Updated by palkan (Vladimir Dementyev) about 2 months ago

As a quick fix I propose marking patterns as unremoveable: https://github.com/ruby/ruby/pull/4094

Updated by ktsj (Kazuki Tsujimoto) about 1 month ago

  • Backport changed from 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN to 2.5: DONTNEED, 2.6: DONTNEED, 2.7: DONTNEED, 3.0: REQUIRED
  • Status changed from Open to Closed

palkan (Vladimir Dementyev):
Thanks to fix!

naruse (Yui NARUSE):
Could you backport 1b89b99941548fdb65305dd9a412082e7fdba45a to 3.0?

Updated by naruse (Yui NARUSE) about 1 month ago

  • Backport changed from 2.5: DONTNEED, 2.6: DONTNEED, 2.7: DONTNEED, 3.0: REQUIRED to 2.5: DONTNEED, 2.6: DONTNEED, 2.7: DONTNEED, 3.0: DONE

ruby_3_0 2dc39e2fd45aacd5fcd33ed80f602bd6f2ddb504 merged revision(s) 1b89b99941548fdb65305dd9a412082e7fdba45a.

Also available in: Atom PDF