Skip to content

Fix crash cause by type inference treats java type as covariant when on the qualifier should be.#7707

Merged
smillst merged 13 commits into
typetools:masterfrom
smillst:issue7676
May 11, 2026
Merged

Fix crash cause by type inference treats java type as covariant when on the qualifier should be.#7707
smillst merged 13 commits into
typetools:masterfrom
smillst:issue7676

Conversation

@smillst
Copy link
Copy Markdown
Member

@smillst smillst commented May 6, 2026

This pull request cause new false positives for classes that use @Covariant. (Optional and Class are the most used one in the JDK.)
Fixes #7676, Fixes #7695, and Fixes #7699.

@smillst smillst assigned mernst and unassigned mernst May 6, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 6, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3867ba7b-6827-4454-81cc-7f8ccaa5b787

📥 Commits

Reviewing files that changed from the base of the PR and between 31cd695 and 2f95718.

📒 Files selected for processing (5)
  • checker/tests/nullness/java8/Issue1098.java
  • checker/tests/nullness/java8/Issue1098NoJdk.java
  • framework/src/main/java/org/checkerframework/framework/type/DefaultTypeHierarchy.java
  • framework/src/main/java/org/checkerframework/framework/util/typeinference8/constraint/Typing.java
  • framework/tests/all-systems/Issue7699.java

📝 Walkthrough

Walkthrough

This PR changes Typing.reduceContained to always create TYPE_EQUALITY while preserving an isCovarTypeArg flag, short-circuits DefaultTypeHierarchy.visitTypeArgs for class underlying types, and adds/updates tests (CovariantError, Issue7676, Issue7695, Issue7699, Issue1098 variants, Issue1218) exercising Optional.flatMap, switch/ternary, covariance, and nullness suppression diagnostics.

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR addresses all three linked issues (#7676, #7695, #7699) with targeted changes to type inference and type hierarchy logic for covariant types.
Out of Scope Changes check ✅ Passed All code changes are directly related to fixing covariant type handling and type inference issues in the linked issues.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
framework/src/main/java/org/checkerframework/framework/util/typeinference8/constraint/Typing.java (1)

47-95: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

isCovarTypeArg is read but logically unused — should be final and either included in equals/hashCode or removed.

The field is assigned only in the constructor (line 94) and read at line 317 to propagate into chained constraints, but equals/hashCode (lines 467–490) ignore it. This means two Typing instances differing only by isCovarTypeArg are considered equal, causing silent dedup losses if both are added to a set. Since the field has no getter and plays no role in constraint reduction logic, it currently functions as dead code being carried through constraint chains.

If this is an intentional placeholder for the TODO at lines 310–316, document it explicitly; otherwise, decide whether to:

  • Include isCovarTypeArg in equals and hashCode, or
  • Remove the field until it has an actual consumer.

Also:

  • Make the field final (only assigned in the constructor).
  • Fix typo at line 315: "postives" → "positives".
♻️ Suggested local tightening
-  /** True if this constraint is for a covariant type argument. */
-  private boolean isCovarTypeArg;
+  /** True if this constraint is for a covariant type argument. */
+  private final boolean isCovarTypeArg;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@framework/src/main/java/org/checkerframework/framework/util/typeinference8/constraint/Typing.java`
around lines 47 - 95, The private field isCovarTypeArg is assigned only in the
Typing(Constraint, AbstractType, AbstractType, Kind, boolean) constructor but is
not final and is omitted from equals(Object) and hashCode(), causing logical
inequality errors or silent dedup; either make isCovarTypeArg final and include
it in Typing.equals and Typing.hashCode (so instances that differ only by this
flag are distinct), or drop the field entirely if unused; also correct the
"postives" typo to "positives" in the related comment. Ensure you update
references where chained constraints propagate isCovarTypeArg (so code uses the
chosen approach consistently).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@checker/tests/tainting/CovariantError.java`:
- Around line 11-15: Update the TODO in method use(CovariantError t) to track
this known false positive by adding a linked issue reference: change the
existing comment above the cls(this.getMyClass(), t) call to include the issue
number or URL (and optionally a short title) so future work on Typing.java
(covariant qualifier handling / equal Java types) can trace this regression;
ensure the comment mentions it's a known false positive and references the
tracker ID or link.

In
`@framework/src/main/java/org/checkerframework/framework/util/typeinference8/constraint/Typing.java`:
- Around line 310-317: Fix the typo "postives" → "positives" in the comment and
add a one-line clarifying note next to the Typing constructor call (the line
that returns new Typing(this, S, T, Kind.TYPE_EQUALITY, isCovarTypeArg)) stating
that although isCovarTypeArg is being forwarded here, reduceEquality() does not
branch on that flag today so the flag has no effect; reference the Typing
constructor, the isCovarTypeArg parameter, and reduceEquality() in the note so
future readers know covariance isn't honored downstream.

---

Outside diff comments:
In
`@framework/src/main/java/org/checkerframework/framework/util/typeinference8/constraint/Typing.java`:
- Around line 47-95: The private field isCovarTypeArg is assigned only in the
Typing(Constraint, AbstractType, AbstractType, Kind, boolean) constructor but is
not final and is omitted from equals(Object) and hashCode(), causing logical
inequality errors or silent dedup; either make isCovarTypeArg final and include
it in Typing.equals and Typing.hashCode (so instances that differ only by this
flag are distinct), or drop the field entirely if unused; also correct the
"postives" typo to "positives" in the related comment. Ensure you update
references where chained constraints propagate isCovarTypeArg (so code uses the
chosen approach consistently).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8415384b-514c-41a4-ac37-8a1f90aa4be1

📥 Commits

Reviewing files that changed from the base of the PR and between 3f56b4b and 8d9ce4b.

📒 Files selected for processing (7)
  • checker/tests/nullness/java8/Issue1098.java
  • checker/tests/nullness/java8/Issue1098NoJdk.java
  • checker/tests/tainting/CovariantError.java
  • framework/src/main/java/org/checkerframework/framework/util/typeinference8/constraint/Typing.java
  • framework/tests/all-systems/Issue7676.java
  • framework/tests/all-systems/Issue7695.java
  • framework/tests/all-systems/Issue7699.java

Comment thread checker/tests/tainting/CovariantError.java
@smillst smillst self-assigned this May 7, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@framework/src/main/java/org/checkerframework/framework/type/DefaultTypeHierarchy.java`:
- Around line 580-582: The early-return in DefaultTypeHierarchy that checks
TypesUtils.isClassType(subtype.getUnderlyingType()) wrongly skips type-argument
and raw-type logic for all declared class types; tighten this by either (A)
narrowing the guard to only java.lang.Class<X> (e.g., check the underlying
type’s symbol is java.lang.Class) so type-argument containment,
castedAsSuper(...) and the ignoreRawTypes && (subtypeRaw || supertypeRaw)
handling still run for other classes, or (B) if the broad bypass is intentional,
add a clear comment above the guard that references the root cause (e.g., the
AsSuperVisitor/JDK-8265255 issue) and explain why skipping castedAsSuper and
raw-type checks is safe; update DefaultTypeHierarchy around the isClassType
check and ensure castedAsSuper and ignoreRawTypes logic are not accidentally
bypassed for non-java.lang.Class types.

In `@framework/tests/all-systems/Issue7699.java`:
- Line 4: Fix the typo in the inline comment on the suppression annotation:
change the comment text in the line containing `@SuppressWarnings`("argument") //
TODO: This is a false postive. to read "false positive" instead of "false
postive" so the comment becomes // TODO: This is a false positive.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4a229799-822c-493d-9ae7-5141afa51eed

📥 Commits

Reviewing files that changed from the base of the PR and between 8d9ce4b and 2847100.

📒 Files selected for processing (3)
  • framework/src/main/java/org/checkerframework/framework/type/DefaultTypeHierarchy.java
  • framework/src/main/java/org/checkerframework/framework/util/typeinference8/constraint/Typing.java
  • framework/tests/all-systems/Issue7699.java

Comment thread framework/tests/all-systems/Issue7699.java Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@framework/tests/value/Issue1218.java`:
- Around line 127-130: The expected-error directives before the ForEnum test
cases are malformed with an extra closing bracket (`]]`); locate the two
directives that precede the `new ForEnum<>(MyEnum.A, MyEnum.B);` and `new
ForEnum<>(MyEnum.A, MyEnum.B, MyEnum.C);` lines and change `// :: error:
[type.arguments.not.inferred]]` to `// :: error: [type.arguments.not.inferred]`
so the diagnostic matcher can correctly recognize the expected errors.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4aa4982c-101f-4402-b095-846ed6dede04

📥 Commits

Reviewing files that changed from the base of the PR and between 2847100 and 2906b14.

📒 Files selected for processing (2)
  • framework/src/main/java/org/checkerframework/framework/type/DefaultTypeHierarchy.java
  • framework/tests/value/Issue1218.java

Comment thread framework/tests/value/Issue1218.java Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@framework/tests/h1h2checker/GetClassStubTest.java`:
- Around line 15-19: The TODO that silences the expected assignment errors for
Class<@H1Bot ? extends `@H1Bot` Object> fail1 and Class<@H1Bot ?> fail2 should be
linked to a tracking issue and the variable names updated to reflect known false
negatives; update the comment from a bare "TODO" to include the issue number
(e.g. TODO: ISSUE-1234) adjacent to the existing "// :: error: [assignment]"
marker and rename the variables (fail1, fail2) to explicit names like
knownFalseNegative1 and knownFalseNegative2 where the declarations use
i.getClass() so the test clearly records the exception as tracked and
intentional.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 907ae580-4767-47ee-903f-e19972f4cc78

📥 Commits

Reviewing files that changed from the base of the PR and between 2906b14 and 475985d.

📒 Files selected for processing (4)
  • framework/src/main/java/org/checkerframework/common/value/ValueQualifierHierarchy.java
  • framework/tests/all-systems/Issue7695.java
  • framework/tests/all-systems/Issue7699.java
  • framework/tests/h1h2checker/GetClassStubTest.java
💤 Files with no reviewable changes (1)
  • framework/src/main/java/org/checkerframework/common/value/ValueQualifierHierarchy.java

Comment thread framework/tests/h1h2checker/GetClassStubTest.java
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
mernst
mernst previously approved these changes May 8, 2026
Copy link
Copy Markdown
Member

@mernst mernst left a comment

Choose a reason for hiding this comment

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

LGTM

@smillst smillst merged commit 20307c4 into typetools:master May 11, 2026
37 checks passed
@smillst smillst deleted the issue7676 branch May 11, 2026 16:01
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.

Type argument inference crashed Type argument inference crashed AsSuperVisitor: type is not an erased subtype of supertype.

2 participants