Skip to content

Filtered DSL generation misses lazy signatures hidden by prepend #2710

Description

@KaanOzkan

Related to #2705, but caused by the reverse ordering. Here the wrapper is already prepended while the original method's sig remains unevaluated, causing filtered generation to miss a signature that full generation finds.

tapioca dsl Foo can generate an untyped RBI while tapioca dsl generates a typed RBI when an already-loaded prepended method hides an unevaluated sig.

For example:

require "sorbet-runtime"

module Wrapper
  def call(*args)
    super
  end
end

class Foo
  extend T::Sig

  sig { params(value: String).returns(String) }
  def call(value)
    value
  end

  prepend Wrapper
end

method = Foo.instance_method(:call)

method.owner
# => Wrapper

T::Utils.signature_for_method(method)
# => nil

T::Utils.run_all_sig_blocks

T::Utils.signature_for_method(method)
# => signature with (String) -> String

Filtered DSL generation does not call T::Utils.run_all_sig_blocks, so a DSL compiler inspecting Foo.instance_method(:call) sees the wrapper's parameters and no signature:

sig { params(args: T.untyped).returns(T.untyped) }
def call(*args); end

Unfiltered generation evaluates all pending signatures first, allowing Sorbet Runtime to associate the signature with the currently resolved wrapper:

sig { params(value: String).returns(String) }
def call(value); end

Both commands should generate the typed definition.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions