Stop reporting a duck type's own method as unresolved - #1280
Open
apiology wants to merge 2 commits into
Open
Conversation
apiology
marked this pull request as ready for review
August 11, 2026 17:15
apiology
added a commit
to apiology/solargraph
that referenced
this pull request
Aug 11, 2026
…d method Chain::Call#resolve converted duck-typed receivers to Object and searched Object's real method stack, so a call matching the duck type's own declared method (e.g. `# @PARAM thing [#read_body]` then `thing.read_body`) was reported as an unresolved call at strict typecheck level and above, even though ApiMap#get_complex_type_methods already handled this correctly for completion. Special-cases duck-type receivers to synthesize a matching Pin::DuckMethod, marked explicit: false so arity checking (which has no real signature to check against) is skipped. Fixes castwide#1257 Conflict in lib/solargraph/source/chain/call.rb: incoming's branch, based directly on castwide/master, special-cased duck types inline in Call#resolve via `binder.each_unique_type.map { ... }`, predating this branch's method_pins_for_binder/method_stack_pins refactor (which generically handles unions/intersections and dedups by path). Kept this branch's structure and moved the duck-type special case into method_stack_pins's single-UniqueType branch instead, so duck typing gets the same union/intersection handling as every other receiver type rather than a separate parallel code path. Verified: spec/type_checker/levels/alpha_spec.rb, spec/type_checker/levels/strict_spec.rb, spec/source/chain/call_spec.rb (141 examples, 0 failures, 10 pending), and a broader safety net - spec/type_checker, spec/source, spec/source_map/clip_spec.rb, spec/api_map_spec.rb, spec/api_map_method_spec.rb, spec/pin (880 examples, 1 failure, 29 pending). The 1 failure (spec/api_map_spec.rb:771) is the same pre-existing order-dependent flake already confirmed unrelated to this branch's work during the castwide#1278 merge earlier in this session.
apiology
added a commit
to apiology/solargraph
that referenced
this pull request
Aug 13, 2026
…er return type in Pin::Method#typify Pin::DuckMethod.new never sets closure:, so the unconditional closure.gates call crashed with NoMethodError on duck-typed method calls. Use the pin's own gates accessor (already nil-safe, equivalent to the inline closure&.gates || [''] this branch had) instead. typify_from_super also returned an ancestor pin's raw, unqualified return_type instead of calling pin.typify(api_map) on it, so a borrowed type would be qualified against the duck pin's own fabricated gates rather than the ancestor's real ones. Removes 12 @sg-ignore "Not enough arguments to Module#protected" comments across Chain::Call/Hash/If/Link/Literal/Or#equality_fields that this fix made unneeded - strong typecheck problem count back to 230, matching pre-merge baseline.
apiology
added a commit
to apiology/solargraph
that referenced
this pull request
Aug 13, 2026
apiology
marked this pull request as draft
August 31, 2026 20:36
apiology
added a commit
to apiology/solargraph
that referenced
this pull request
Sep 5, 2026
Brings castwide#1280 up to its current head. Seven of its eight commits are already here; the outstanding one is 66adce5, removing the dead TypeMethods#qualify. That method is the undercover node this PR owns, complex_type/type_methods.rb:248-258 at 0%. It closes by deletion rather than by coverage - nothing called it. Also carries a comment rewrite on UniqueType::BOT, naming which operations a wrong @rooted would actually break rather than leaving it general. No conflicts. 2200 examples, 0 failures, 45 pending.
apiology
force-pushed
the
fix-1257-duck-type-own-method
branch
from
September 6, 2026 02:40
684cc6e to
10ea7dd
Compare
apiology
marked this pull request as ready for review
September 6, 2026 03:47
Chain::Call#resolve converted a duck-typed receiver to Object and
searched Object's method stack, so a call to a method the duck type
itself declares was reported as an unresolved call at strict level and
above:
# @PARAM thing [#read_body]
def fetch(thing)
thing.read_body
end
# => Unresolved call to read_body on #read_body
ApiMap#get_complex_type_methods already handles this correctly for
completion, so the same call resolved for autocomplete while failing
typecheck.
Special-case a duck-type receiver whose name matches the called method
and synthesize a Pin::DuckMethod, mirroring get_complex_type_methods.
The pin is explicit: false so arity checking is skipped -- a duck type
declares that the method exists, not what signature it has, so checking
arity against it would turn "unresolved call" into a false "too many
arguments".
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1280 dispatches a duck call to Pin::DuckMethod for the first time. That pin has no closure, so typify_from_super walks nil and raises NoMethodError on any duck tag Object also answers, such as #to_s. It also synthesized a zero-arg signature, which no real call matches. Ported from #72, which carries the same two changes on the intersection branch. Neither references intersections.
apiology
force-pushed
the
fix-1257-duck-type-own-method
branch
from
September 8, 2026 21:32
800376d to
5d5f6f2
Compare
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.
Problem: A call to a method that a duck-typed parameter itself declares is reported as unresolved.
It fires at
strictand above on every duck-typed parameter, even thoughApiMap#get_complex_type_methodsalready resolves the same call correctly for completion.Solution:
Chain::Call#resolvesynthesizes aPin::DuckMethodwhen the receiver is a duck type naming the called method, mirroringget_complex_type_methods; the pin isexplicit: falseso arity checking is skipped, since a duck type declares that the method exists, not what signature it has.Fixes #1257
🤖 Generated with Claude Code