Skip to content

Handle Rawtype more gracefully#1438

Open
aosen-xiong wants to merge 15 commits into
eisop:masterfrom
aosen-xiong:eisop-792
Open

Handle Rawtype more gracefully#1438
aosen-xiong wants to merge 15 commits into
eisop:masterfrom
aosen-xiong:eisop-792

Conversation

@aosen-xiong

@aosen-xiong aosen-xiong commented Nov 9, 2025

Copy link
Copy Markdown
Collaborator

Fixes #792

Fixes a crash in propagation for wildcard type arguments of raw types.

When PropagationTypeAnnotator visits a raw declared type, it already fixes up the synthesized wildcard type arguments from the raw type’s declaration bounds. This PR avoids re-processing those raw-type wildcard arguments in visitWildcard, preventing the crash reported in eisop#792.

@aosen-xiong aosen-xiong marked this pull request as ready for review November 9, 2025 06:47
aosen-xiong added a commit to aosen-xiong/checker-framework that referenced this pull request Mar 4, 2026
Copilot AI review requested due to automatic review settings March 4, 2026 03:47

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a Checker Framework crash when PropagationTypeAnnotator encounters a wildcard related to a raw declared type (as reported in #792), and adds a regression test to prevent recurrence.

Changes:

  • Add a regression test (RawtypeCrash.java) that triggers the rawtype/wildcard scenario from the crash report.
  • Update PropagationTypeAnnotator#getTypeParameterElement to return null (instead of throwing) when the enclosing declared type is raw.
  • Record the fix in the changelog as closing eisop#792.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
framework/tests/viewpointtest/RawtypeCrash.java Adds a minimal test case that previously crashed the framework during type annotation propagation.
framework/src/main/java/org/checkerframework/framework/type/typeannotator/PropagationTypeAnnotator.java Avoids throwing BugInCF when attempting to map a wildcard to a type parameter in the presence of raw types.
docs/CHANGELOG.md Notes the issue as closed in the upcoming release notes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@aosen-xiong aosen-xiong requested a review from wmdietl March 4, 2026 06:53

@wmdietl wmdietl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking into fixing this!
Isn't the code at https://github.com/aosen-xiong/checker-framework/blob/08171af48258a6d3a543f0ba85932dabd712dbb6/framework/src/main/java/org/checkerframework/framework/type/typeannotator/PropagationTypeAnnotator.java#L91 supposed to fix up raw types?
Is this crash an indication that the fix-up over there isn't doing the right things?
Maybe that code should do something different for wildcards?

@wmdietl wmdietl assigned aosen-xiong and unassigned wmdietl Mar 23, 2026
@aosen-xiong

Copy link
Copy Markdown
Collaborator Author

Thanks for looking into fixing this! Isn't the code at https://github.com/aosen-xiong/checker-framework/blob/08171af48258a6d3a543f0ba85932dabd712dbb6/framework/src/main/java/org/checkerframework/framework/type/typeannotator/PropagationTypeAnnotator.java#L91 supposed to fix up raw types? Is this crash an indication that the fix-up over there isn't doing the right things? Maybe that code should do something different for wildcards?

Debugging the added test shows two visitWildcard iterations linked by scan(wildcard.getExtendsBound(), null).

Iteration 1 (non-raw wildcard)

wildcard: ? extends V (typeArgOfRawType=false)
upper/extends bound: another wildcard object (? extends @Top Object)
lower/super bound: @Bottom NullType (implicit lower bound for ? extends ...)
This is the wildcard stored in the parent type-arg list.

Iteration 2 (recursive, raw/synthesized wildcard)

reached from iteration 1 via scan(extendsBound)
wildcard: ? extends Object (typeArgOfRawType=true)
upper/extends bound: @Top Object
lower/super bound: @Bottom NullType

This is a different wildcard instance/symbol from iteration 1 (different wrapper and underlying wildcard).
Because iteration 2 uses a synthesized raw wildcard, but the parents field only contain the type for the first iteration.

@aosen-xiong

aosen-xiong commented Mar 23, 2026

Copy link
Copy Markdown
Collaborator Author

Btw, the fix up for raw types are completely skipped in this case because of this check.

if (!AnnotatedTypes.isTypeArgOfRawType(typeArgs.get(i))) {
    // Sometimes the framework infers a more precise type argument, so just use it.
    continue;
}

@aosen-xiong aosen-xiong requested a review from wmdietl March 23, 2026 20:19
@aosen-xiong aosen-xiong assigned wmdietl and unassigned aosen-xiong Mar 23, 2026
visitedNodes.put(wildcard, null);

// Raw wildcard args are already fixed up in visitDeclared.
// Recursive traversal through scan(wildcard.getExtendsBound(), ...) can

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what this comment is trying to say. The body of the then-block calls scan on both bounds of the wildcard. Is this intended? What is the problem with re-entering?
Is there any point in scanning these two bounds here? Will they ever propagate anything useful?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated the comment.

@wmdietl wmdietl assigned aosen-xiong and unassigned wmdietl Mar 24, 2026
@aosen-xiong aosen-xiong requested a review from wmdietl May 25, 2026 15:56
@aosen-xiong aosen-xiong removed their assignment May 25, 2026

@wmdietl wmdietl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@@ -0,0 +1,4 @@
public class RawtypeCrash<V> {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this problem specific to the viewpoint checker?
Would it be better to add to all-systems (possibly suppressing all warnings to just check for the crash)?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried Nullness, Interning, and Tainting checkers and did not see this BugInCF crash from RawtypeCrash there.

Do you think we should keep it in the viewpoint checker tests or move it all-systems?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the only checker that is breaking with this code is the Viewpoint Checker, maybe it needs a change? Why does no other type checker fail with this code? Doesn't that indicate that the VP Checker is doing something wrong?

In any case, isn't this another argument to move it to all-systems, to ensure that all type systems work with this code?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried adding all-systems to ViewpointTestCheckerTest. It exposes many additional viewpoint-checker failures/crashes, so enabling it wholesale is a follow-up task.

For this PR, I will keep the small duplicated viewpointtest/RawtypeCrash.java. The all-systems copy provides useful broad coverage, but by itself it does not exercise the viewpoint checker.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other failures are also discussed in #433.

@wmdietl wmdietl assigned aosen-xiong and unassigned wmdietl May 28, 2026
@aosen-xiong aosen-xiong requested a review from wmdietl May 30, 2026 22:09
@aosen-xiong aosen-xiong assigned wmdietl and unassigned aosen-xiong May 30, 2026
@wmdietl wmdietl assigned aosen-xiong and unassigned wmdietl Jun 8, 2026
@aosen-xiong aosen-xiong assigned wmdietl and unassigned aosen-xiong Jun 10, 2026
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.

Not a type argument crashes

3 participants