Conversation
A `self.class == other.class` guard (or `self.class.eql?(other.class)`) guarantees other has the same runtime class as self. Since self is an instance of the enclosing method's declared type, other is too -- narrowing other to that declared type is a sound upper bound, the same tradeoff #process_isa already documents for is_a?. FlowSensitiveTyping had no path to this fact: it never received the enclosing closure at all, so it could not resolve self's declared type. Threading closure through (already the shape #process_isa's sibling would need for a class-scope check) and adding #process_class_eq covers the guard in both an && chain and a return-unless-style guard. This clears all 9 `@sg-ignore flow sensitive typing should support .class == .class` / `needs to handle self.class == other.class` markers already present on master's own eql?/== methods (unique_type.rb, type_methods.rb, equality.rb, api_map.rb), confirmed via full-workspace `solargraph typecheck --level strong`: message set is byte-identical to the pre-fix baseline (531 problems) once the markers are removed, so nothing regresses.
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: This PR was written by Claude Code on behalf of @apiology.
Problem: A common
#==/#eql?idiom checksself.class == other.classbefore comparing fields, but flow-sensitive typing does not narrowotherfrom that check, so every field comparison after it fails atstrong.otherstays declaredObjecteven though the guard proves it shares self's runtime class.Solution:
self.class == other.classguaranteesother's runtime class equalsself's, and that runtime class is always a subtype of the enclosing method's declared instance type — so narrowingotherto that declared type is a sound upper bound, the same tradeoff#process_isadocuments foris_a?.FlowSensitiveTypingnever received the enclosing closure, so it could not resolveself's type; this threads it through and adds#process_class_eq, covering both an&&chain and areturn false unlessguard. Skipped for class methods, whoseself.classis always::Class.Clears all 9
@sg-ignoremarkers on this repo's own#==/#eql?methods, confirmed by a byte-identical full-workspace typecheck problem set once the markers are removed.