soutaro / rbs-inline

Inline RBS type declaration
MIT License
165 stars 6 forks source link

Incorrect RBS definitions for methods with block parameters #41

Closed euglena1215 closed 3 weeks ago

euglena1215 commented 1 month ago

Description

Incorrect RBS definitions are generated for methods with block parameters, causing errors during static type checking with steep check.

Steps to Reproduce

  1. Create a Ruby file test.rb with the following content:
# rbs_inline: enabled

class Foo
  def foo(&block)
    block.call
  end
end
  1. Run rbs-inline on the file. The generated RBS file will be:
# Generated from test.rb with RBS::Inline

class Foo
  def foo: () ?{ (?) -> untyped } -> untyped
end
  1. Run steep check on the generated RBS file. The following error is encountered:
test.rb:4:2: [error] UnexpectedError: undefined method `required_positionals' for an instance of RBS::Types::UntypedFunction(NoMethodError)
│ 1. /Users/teppei/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/steep-1.6.0/lib/steep/ast/types/factory.rb:229:in `params'
│ 2. /Users/teppei/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/steep-1.6.0/lib/steep/ast/types/factory.rb:276:in `block in method_type'
│ 3. <internal:kernel>:148:in `yield_self'
│ 4. /Users/teppei/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/steep-1.6.0/lib/steep/ast/types/factory.rb:272:in `method_type'
│ 5. /Users/teppei/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/steep-1.6.0/lib/steep/type_construction.rb:157:in `block (2 levels) in for_new_method'
│ 6. /Users/teppei/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/steep-1.6.0/lib/steep/type_construction.rb:157:in `map'
│ 7. /Users/teppei/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/steep-1.6.0/lib/steep/type_construction.rb:157:in `block in for_new_method'
│ 8. <internal:kernel>:148:in `yield_self'
│ 9. /Users/teppei/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/steep-1.6.0/lib/steep/type_construction.rb:155:in `for_new_method'
│ 10. /Users/teppei/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/steep-1.6.0/lib/steep/type_construction.rb:278:in `with_method_constr'
│ 11. /Users/teppei/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/steep-1.6.0/lib/steep/type_construction.rb:942:in `block (2 levels) in synthesize'
│ 12. <internal:kernel>:148:in `yield_self'
│ 13. /Users/teppei/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/steep-1.6.0/lib/steep/type_construction.rb:937:in `block in synthesize'
│ 14. /Users/teppei/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/activesupport-7.1.3.3/lib/active_support/tagged_logging.rb:135:in `block in tagged'
│ 15. /Users/teppei/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/activesupport-7.1.3.3/lib/active_support/tagged_logging.rb:39:in `tagged'
│   (32 more backtrace)
│
│ Diagnostic ID: Ruby::UnexpectedError
│
└   def foo(&block)
    ~~~~~~~~~~~~~~~

Expected Behavior

RBS definitions for methods with block parameters should be correct. For example:

class Foo 
  def foo: () ?{ (*untyped, **untyped) -> untyped } -> untyped
end

Actual Behavior

The generated RBS file for methods with block parameters is incorrect, leading to errors during type checking.

Environment

soutaro commented 1 month ago

Oops, the new (?) -> void syntax is introduced in RBS 3.5 and Steep 1.7, both of them is pre-released yet. Update your Gemfile or equivalent to allow installing the pre-released versions.

gem "steep", "~> 1.7.0.dev", require: false

rbs-inline gem declares a dependency to rbs-3.5, but it doesn't have to steep.

euglena1215 commented 1 month ago

Thank you for your comment!

I have confirmed that (?) -> untyped works with steep-1.7.0.dev.

I don't think users will notice that rbs-inline is a dependency of steep-1.7.0.dev or later, so I think I'll add that dependency to the gemspec.

soutaro commented 3 weeks ago

Closing this because rbs-3.5 and steep-1.7 are released now, and the dependencies are updated.