Rebind block self from RBS block self types - #1335
Draft
apiology wants to merge 1 commit into
Draft
Conversation
RBS records a block self rebinding as { () [self: Foo] -> void }, but
the conversion built the block Pin::Signature without reading
RBS::Types::Block#self_type, and Pin::Block#maybe_rebind consulted only
a YARD @yieldreceiver tag. Every RBS-declared block binding was dropped:
ActiveRecord::Base.after_commit is declared ?{ () [self: instance] ->
untyped } and still left instance methods unresolved inside its block.
Signature now carries the binding as self_type, and maybe_rebind falls
back to it when no @yieldreceiver tag is present. Putting it on the
signature rather than synthesizing a tag keeps the pin cache and the
rendered documentation free of tags no author wrote, and leaves the
precedence explicit: CoreFills states several core bindings more
precisely than RBS does, and those keep winning.
Three RBS forms are deliberately not converted. RBS self means the
receiver unchanged, which no Solargraph tag expresses -- it translates
to self, and self_to_type reduces Class<Foo> to Foo, which is right for
RBS instance and wrong here; converting it broke Module#class_eval
rebinding. A type variable cannot name a namespace. An untyped self type
carries nothing.
Per-overload bindings collapse to the first signature, matching how
Pin::Method#block already exposes signatures.first.block for block
parameter types.
RbsTranslator.to_complex_type declared @PARAM type
[RBS::Types::Bases::Base], which only the Bases::* members satisfy --
Union, Optional, ClassInstance and Literal do not descend from it, so
every call site was reported as passing a wrong argument type. The tag
now names RBS::Types::t, the alias the rbs gem declares for every type
node, which Solargraph expands: passing a String still errors with the
full union spelled out, so the check is satisfied rather than skipped.
That takes to_complex_type argument-type errors from 12 to 1, the
survivor being a call site genuinely outside the union.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Claude:
Problem: Calling an instance method inside an
after_commitblockis reported as unresolved, even though activerecord's RBS declares the
block's
selfto be the model instance.Every RBS block binding is affected, not just this one:
{ () [self: Foo] -> void }is dropped during conversion, so today onlya YARD
@yieldreceivertag can rebind a block.Solution:
Pin::Signaturenow carries the RBS block self type, andPin::Block#maybe_rebindfalls back to it when no@yieldreceivertagapplies.