steep icon indicating copy to clipboard operation
steep copied to clipboard

Symbol#to_proc passed as an optional block argument causes a warning "Cannot pass a value of type `::Proc` as a block-pass-argument"

Open trinistr opened this issue 1 year ago • 2 comments

This issue seems to be similar to #709 and #652, but slightly different. This is a pretty annoying problem when using Rubocop as it prefers Symbol#to_proc over blocks.

> steep --version
1.7.1

Consider following code:

module Test
  def pass
    yield 1
  end

  def with_block
    pass { -_1 }
  end

  def with_to_proc
    pass(&:-@)
  end

  def with_proc
    pass(&->(v) { -v } )
  end
end

with following signatures:

module Test
  def pass: () ?{ (Integer value) -> Integer } -> Integer

  def with_block: () -> Integer
  def with_to_proc: () -> Integer
  def with_proc: () -> Integer
end

Only the &:-@ construct is getting a warning:

lib/test.rb:11:9: [warning] Cannot pass a value of type `::Proc` as a block-pass-argument of type `(^(::Integer) -> ::Integer | nil)`
│   ::Proc <: (^(::Integer) -> ::Integer | nil)
│     ::Proc <: ^(::Integer) -> ::Integer
│
│ Diagnostic ID: Ruby::BlockTypeMismatch
│
└     pass(&:-@)
           ~~~~

However, changing the block to be non-optional suddenly gets rid of the warning:

def pass: () { (Integer value) -> Integer } -> Integer

It seems that the case of just passing a #to_proc value is handled, but optionality of the block causes something to break.

trinistr avatar Aug 16 '24 19:08 trinistr