Bug #21661
openEndless method definition as a default value of block parameter is wrongly accepted in Prism
Description
These are syntax error in parse.y but not in Prism.
p do |a = def f = 1; b| end
p do |a = def f = 1| 2; b|c end # `|` inside block parameter
Normal assignment as a default value p do |a = b = 1| end is already syntax error.
        
          
          Updated by Earlopain (Earlopain _) 2 days ago
          
          
        
        
      
      It isn't specifically about block locals, p do |a = def f = 1, b| end is the same.
p do |a = def f = 1| 2; b|c end becomes p do |a = (def f = 1| 2); b|c end, so one block local b and method body of c. The same issue as the first example I believe.
That said, it looks inconsistent in parse.y: def foo(a = def f = 1, b); end and ->(a = def f = 1; b) {} is accepted. Why is it ok in method and lamba parameters but not in block parameters? I feel like it should be rejected in all these cases.
        
          
          Updated by tompng (tomoya ishida) 1 day ago
          
          
        
        
      
      Inside | | style block parameter, binary operators (example: 1+2, 1|2) are rejected because we need to reject ambiguous |.
On the right hand side of assignment and endless def, binary operators are allowed, unless we introduce a special state or something.
So def foo(a = b = 1+2); end, def foo(a = def f = 1+2); end, ->(a = b = 1+2){}, ->(a = def f = 1+2) {} are all consistently accepted, and consistently rejected when surrounded by {| |}.
Assignment in default value of method definition is already used. https://github.com/ruby/ruby/blob/11583f53b172ead33355330c1445964d5af47f46/array.rb#L129C3-L129C35
class Array
  def first n = unspecified = true
end
Also need to fix default value of keyword parameter proc { |a: def f = 1, **| }
        
          
          Updated by Earlopain (Earlopain _) about 18 hours ago
          
          
        
        
      
      I appreciate the explanation. I openend https://github.com/ruby/prism/pull/3702, it would be nice if you can check that the added tests match your expectation. Basically it is no endless method definition only between |...|, which is my understanding.