tapioca icon indicating copy to clipboard operation
tapioca copied to clipboard

Test against Rails 8

Open KaanOzkan opened this issue 11 months ago • 4 comments

Rails "current" CI tests against 7.1.5 because it's the version specified in the Gemfile.

We should bump this version and start requiring CI checks on Rails 8 as a result.

Also there's no more active support for Rails 7.0 and 7.1 so it might be time to remove 7.0 from the CI.

  • [ ] 7.2
  • [ ] 8.0 (current)
  • [ ] main

KaanOzkan avatar Jan 07 '25 14:01 KaanOzkan

Thank you for raising this @KaanOzkan! I'd like to raise that we seem to miss Rails 7.2 in CI as well. We just realised there's an issue with the signature auto-generated for ActiveSupport::Duration#to_f (see this line). Tapioca generates the following:

# source://activesupport//lib/active_support/duration.rb#224
def to_f(&_arg0); end

But looking at the implementation, it doesn't seem like #to_f really takes a block as input. I'm unsure where this is coming from, but it wasn't there in Rails 7.1.x

iMacTia avatar Jan 14 '25 17:01 iMacTia

@iMacTia Rails 7.2 changed how that delegation works. I think it's adding an & argument here. So tapioca looks correct to me. I assume Rails has a reason for generating with an explicit optional block argument but I don't have context.

KaanOzkan avatar Jan 14 '25 23:01 KaanOzkan

Looks like it's accidentally finding the delegation methods take a block argument, they cascade to either Integer or Float (the @value instance variable inside an ActiveSupport::Duration object), neither of which have a #to_f implementation that calls a passed block.

Ruby does allow you to pass blocks to any method, so I guess the type signature isn't wrong, but in this case passing blocks isn't expected, nor do any of the delegated methods invoke a passed block. The documentation for Integer#to_f, Float#to_f shows no blocks are expected to be passed too.

As someone who doesn't understand much of the internals of Tapioca, I can see why this would be generating the signature it is, but that is then at odds with the documentation for those APIs, because they don't take blocks but it's typed as taking a block.

We've worked around it with a shim in our app currently, but it sounds to me like Tapioca might want to special-case these Delegate.generate calls in Rails.

# sorbet/rbi/shims/active_support.rb
class ActiveSupport::Duration
  # …

  sig { params(_arg0: T.proc.void).returns(Float) }
  def to_f(&_arg0); end

  # …
end

caius avatar Jan 15 '25 14:01 caius