Skip to content

Stop one unparseable type from aborting the whole typecheck run - #1263

Open
apiology wants to merge 4 commits into
castwide:masterfrom
apiology:fix-1259-typecheck-crash
Open

Stop one unparseable type from aborting the whole typecheck run#1263
apiology wants to merge 4 commits into
castwide:masterfrom
apiology:fix-1259-typecheck-crash

Conversation

@apiology

@apiology apiology commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Problem: solargraph typecheck can die partway through with a backtrace, leaving the rest of the workspace unchecked.

$ solargraph typecheck --level strong
lib/a.rb:12: Unresolved call to bar
.../complex_type/unique_type.rb:54:in `parse': Bad hash type: name=Hash, substring=<String, nil, Enumerable<Integer>> - must have exactly two parameters (Solargraph::ComplexTypeError)
	from .../thor/command.rb:28:in `run'
	from .../thor/base.rb:585:in `start'

No summary line, no problem count, and every file after the failing one goes unvisited — one bad type annotation costs the entire run.

Solution: TypeChecker#call_problems now rescues each call site's inference and reports the failure as a Problem scoped to that call, and Hash types always render as {K => V}, which — unlike <K, V> — can represent ComplexTypes as keys and/or values.

🤖 Generated with Claude Code

https://claude.ai/code/session_01RALWyFBErKxFodRMRzLnBu

…or boundary

Two issues found while reviewing PR castwide#1259:

- ComplexType::TypeMethods#generate_substring_from's Hash fallback
  branch unconditionally emitted the 2-parameter `<K, V>` notation, even
  when key_types/subtypes held more than one type (from a comma-separated
  union on either side of a Hash{} literal, or from generics
  substitution rebuilding a Hash-named type with parameters_type out of
  sync with its key_types/subtypes). Reparsing the resulting 3+-parameter
  string raised Solargraph::ComplexTypeError, and since ApiMap#get_method_stack
  reparses a receiver type's rooted_tag unguarded, this could crash
  method resolution for that receiver. Now falls back to the `{K => V}`
  notation, which reparses correctly regardless of how many types are on
  either side.

- TypeChecker#call_problems ran chain.infer (and argument_problems_for)
  for every call node in a file with no rescue around it, so any
  exception raised while inferring a single call's type aborted
  TypeChecker#problems entirely, silently losing every diagnostic for
  the rest of the file. Each call site's inference is now wrapped in a
  rescue that logs the error and reports it as a Problem scoped to that
  call, so one bad call site degrades to one reported problem instead of
  killing the whole run.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H7Hb7H69hfyzgHJqFiEjgQ
@apiology
apiology force-pushed the fix-1259-typecheck-crash branch from 6dab664 to c3cc59d Compare August 5, 2026 13:56
@apiology
apiology marked this pull request as ready for review August 5, 2026 14:22
apiology added a commit to apiology/solargraph that referenced this pull request Aug 5, 2026
@apiology
apiology marked this pull request as draft August 31, 2026 17:29
Vince's pending review on PR 1263 flagged four comments as too long
or as changelogging (narrating a regression's discovery instead of
stating a still-true fact). Shorten the rescue comment in
type_checker.rb to one line, and drop or shrink the PR-comment-URL
narration in the two new complex_type_spec.rb examples and the new
type_checker_spec.rb example, since the it descriptions already say
what each test covers.

Two other comments on the same PR (type_methods.rb:201 and :206) ask
whether generate_substring_from should always use {K=>V} notation
instead of branching on <K,V> vs {K=>V} -- a design question, not a
style fix, left for Vince to decide.
The <K, V> form has room for exactly one type on each side, so a
union in either position produced a tag that failed to reparse.
Rather than choosing between the two notations at render time,
always emit {K => V}, which holds a comma-separated list on either
side. Hash<K, V> is still accepted as input; only the generated tag
changes.

This collapses the branch into the existing hash_parameters? case.
fixed_parameters? moves ahead of it so Hash(A, B) still renders as a
tuple.

The two round-trip specs now assert that reparsing the generated tag
yields the same tag, rather than only that it does not raise.
@apiology apiology changed the title Fix Hash<K,V> tag round-trip crash and TypeChecker call-inference error boundary Stop one unparseable type from aborting the whole typecheck run Sep 5, 2026
@apiology
apiology marked this pull request as ready for review September 5, 2026 14:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant