Fixes #20010 Avoid crash on missing TASTy class references#25908
Draft
soronpo wants to merge 2 commits intoscala:mainfrom
Draft
Fixes #20010 Avoid crash on missing TASTy class references#25908soronpo wants to merge 2 commits intoscala:mainfrom
soronpo wants to merge 2 commits intoscala:mainfrom
Conversation
When a transitive dependency is missing from the classpath, the TASTy reader for a TYPEREF can produce a TypeRef whose symbol cannot be resolved. Downstream code in `computeBaseData` then hits an internal `non-class parent` assertion and crashes the compiler. Replace such unresolvable `TypeRef`s with a stub class symbol (similar to what Scala2Unpickler does), so the user sees a `BadSymbolicReference` error on first use instead of a compiler crash. The substitution is limited to references whose prefix is a package or a module, where member lookup is deterministic, to avoid converting transient lookup failures into spurious stubs during incremental completion. Adds an sbt scripted regression test (`sbt-test/tasty-compat/i20010`) that mirrors the original minimisation: three modules, `a`/`b`/`c`, where compiling `c` must not crash when `a` is absent from its classpath. https://claude.ai/code/session_01MmjynkrPu387FLVh175djG
The previous TreeUnpickler-based fix substituted a stub class symbol for any unresolvable cross-file `TypeRef` whose prefix is a package or module. That regressed `sbt-test/source-dependencies/missing-annot`: when a class on the classpath references annotation classes that are no longer reachable, the stub now eagerly throws a `BadSymbolicReference` error - even though the original behaviour was to silently tolerate missing annotations. Move the fix to its narrowest possible scope: the `non-class parent` assertion in `ClassDenotation.computeBaseData`. When the assertion would fire because a parent's `TypeRef` could not be resolved (`p.typeSymbol == NoSymbol`), report a `BadSymbolicReference`-style error with the position of the class that failed to resolve and continue. Annotation processing and other paths that legitimately tolerate missing references are unaffected. `computeBaseData` can be invoked multiple times for the same class (e.g. once via `derivesFrom` from `Namer.checkedParentType`, then again via `isValueClass` from `Checking.checkWellFormed`), so a per-denotation `reportedMissingParents` set deduplicates the diagnostic. Also handle the `MatchError` that fires when `computeMemberNames` encounters the same non-class parent: silently skip after the missing reference has already been reported. https://claude.ai/code/session_01MmjynkrPu387FLVh175djG
Contributor
Author
|
I'm just curious about the CI, but I will close this PR. It's gotten too large to be vibe-coded. |
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.
When a transitive dependency is missing from the classpath, the TASTy reader for a TYPEREF can produce a TypeRef whose symbol cannot be resolved. Downstream code in
computeBaseDatathen hits an internalnon-class parentassertion and crashes the compiler.Replace such unresolvable
TypeRefs with a stub class symbol (similar to what Scala2Unpickler does), so the user sees aBadSymbolicReferenceerror on first use instead of a compiler crash. The substitution is limited to references whose prefix is a package or a module, where member lookup is deterministic, to avoid converting transient lookup failures into spurious stubs during incremental completion.Adds an sbt scripted regression test (
sbt-test/tasty-compat/i20010) that mirrors the original minimisation: three modules,a/b/c, where compilingcmust not crash whenais absent from its classpath.Fixes #20010
How much have you relied on LLM-based tools in this contribution?
Extensively, but its a small fix.
How was the solution tested?
New automated tests (including the issue's reproducer, if applicable)