Skip to content

Account for annotations in extends / implements when computing view as supertype#1266

Merged
msridhar merged 11 commits into
masterfrom
issue-1252
Sep 1, 2025
Merged

Account for annotations in extends / implements when computing view as supertype#1266
msridhar merged 11 commits into
masterfrom
issue-1252

Conversation

@msridhar

@msridhar msridhar commented Aug 29, 2025

Copy link
Copy Markdown
Collaborator

Fixes #1252

In JDK 21 and earlier, the Types.asSuper method did not account for annotations present in extends / implements clauses. So, here we wrap calls to asSuper in extra logic to re-introduce these annotations. We already introduced the logic to fix the same issue with Types.memberType.

This fix also (unexpectedly) addresses an issue in another test which was misdiagnosed as #1022. #1022 indicated annotations were missing in cast types in earlier JDKs, but this was incorrect (that issue should be closed). In fact, the bug observed there (in test intersectionTypeInvalidAssign) was in fact the asSuper bug fixed here. We misdiagnosed the problem partly because in some JDK version after JDK 21, Types.asSuper started behaving differently and preserving annotations in extends / implements clauses.

As a related cleanup, delete the unused InferGenericMethodSubstitutionViaAssignmentContextVisitor class.

Summary by CodeRabbit

  • New Features

    • Config-aware supertype resolution and a utility that preserves explicit nullability on generic type parameters.
    • Public API to compute nullness annotations along inheritance paths.
  • Bug Fixes

    • Better generic/interface inheritance handling so nullable bounds are respected when passing subtype instances to supertype-typed parameters.
  • Tests

    • Added an interface-inheritance test and simplified generics tests by removing Java-version conditionals.
  • Chores

    • Updated visitors to use config and removed an unused inference visitor class.

@coderabbitai

coderabbitai Bot commented Aug 29, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Threads Config into generics nullability logic, replaces direct Types.asSuper(...) calls with TypeSubstitutionUtils.asSuper(..., config), adds utilities to restore explicit nullability on type-variable substitutions, exposes APIs to compute type-var annotations along inheritance, removes an obsolete inference visitor, and updates/adds tests.

Changes

Cohort / File(s) Summary
Config-aware asSuper adoption
nullaway/src/main/java/com/uber/nullaway/generics/CheckIdenticalNullabilityVisitor.java, nullaway/src/main/java/com/uber/nullaway/generics/ConstraintSolverImpl.java
Wire Config into visitor/constructor and replace types.asSuper(...) with TypeSubstitutionUtils.asSuper(types, ..., (Symbol.ClassSymbol) ..., config); use the returned supertype (e.g., rhsTypeAsSuper) for subsequent logic.
Type substitution utility
nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.java
Add public static @Nullable Type asSuper(Types types, Type subtype, Symbol.ClassSymbol superTypeSymbol, Config config) that delegates to types.asSuper(...), computes annotations on type variables from the subtype, and restores explicit nullability annotations on the resulting supertype.
Inheritance/path utilities (API addition)
nullaway/src/main/java/com/uber/nullaway/generics/ClassDeclarationNullnessAnnotUtils.java
Add getAnnotsOnTypeVarsFromSubtypes(DeclaredType, Symbol.ClassSymbol, Types, Config) and an inheritancePath overload targeting a ClassSymbol; refactor method-based path logic to use the new overload.
Generics wiring
nullaway/src/main/java/com/uber/nullaway/generics/GenericsChecks.java
Pass config when constructing CheckIdenticalNullabilityVisitor (constructor signature updated).
Removed obsolete visitor
nullaway/src/main/java/com/uber/nullaway/generics/InferGenericMethodSubstitutionViaAssignmentContextVisitor.java
Delete the entire class file that previously inferred generic method substitutions via assignment context.
Tests
nullaway/src/test/java/com/uber/nullaway/jspecify/GenericInheritanceTests.java, nullaway/src/test/java/com/uber/nullaway/jspecify/GenericsTests.java
Add interfaceInheritance() test; simplify intersectionTypeInvalidAssign() by removing JDK-version branching and consolidating test input.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant GC as GenericsChecks
  participant CIV as CheckIdenticalNullabilityVisitor
  participant TSU as TypeSubstitutionUtils
  participant CDU as ClassDeclarationNullnessAnnotUtils
  participant JT as Javac Types

  GC->>CIV: new CheckIdenticalNullabilityVisitor(state,this,config)
  CIV->>TSU: asSuper(types, rhsType, lhsClassSym, config)
  TSU->>JT: types.asSuper(subtype, superTypeSymbol)
  JT-->>TSU: asSuperResult or null
  alt asSuperResult non-null
    TSU->>CDU: getAnnotsOnTypeVarsFromSubtypes(subtype, superTypeSymbol, types, config)
    CDU-->>TSU: annotsMap
    TSU-->>CIV: restoredSupertype (asSuperResult with explicit nullability)
  else asSuperResult null/raw
    TSU-->>CIV: null/raw (no restoration)
  end
  CIV-->>GC: continue checks using restoredSupertype
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • lazaroclapp
  • yuxincs

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled
  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 2737b76 and 9f7a833.

📒 Files selected for processing (1)
  • nullaway/src/main/java/com/uber/nullaway/generics/CheckIdenticalNullabilityVisitor.java (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • nullaway/src/main/java/com/uber/nullaway/generics/CheckIdenticalNullabilityVisitor.java
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: JDK 17 on windows-latest with Error Prone 2.41.0
  • GitHub Check: JDK 17 on ubuntu-latest with Error Prone 2.41.0
  • GitHub Check: Build caffeine with snapshot
  • GitHub Check: JDK 11 on ubuntu-latest with Error Prone 2.14.0
  • GitHub Check: JDK 17 on ubuntu-latest with Error Prone 2.14.0
  • GitHub Check: Build spring-framework with snapshot
  • GitHub Check: JDK 11 on ubuntu-latest with Error Prone 2.31.0
  • GitHub Check: JDK 17 on macos-latest with Error Prone 2.41.0
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch issue-1252

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@codecov

codecov Bot commented Aug 29, 2025

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.55%. Comparing base (e2b65aa) to head (9f7a833).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff              @@
##             master    #1266      +/-   ##
============================================
+ Coverage     88.12%   88.55%   +0.43%     
- Complexity     2426     2431       +5     
============================================
  Files            92       91       -1     
  Lines          8033     8013      -20     
  Branches       1600     1598       -2     
============================================
+ Hits           7079     7096      +17     
+ Misses          494      458      -36     
+ Partials        460      459       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 (2)
nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.java (1)

206-211: Avoid unsafe cast from AnnotationMirror to Attribute.TypeCompound

This cast can CCE if the value isn’t a type-use annotation (rare but possible). Guard it.

-      Attribute.TypeCompound typeArgAnnot =
-          (Attribute.TypeCompound) annotsOnTypeVarsFromSubtypes.get(other.tsym);
-      if (typeArgAnnot != null) {
-        return typeWithAnnot(t, typeArgAnnot);
-      }
+      AnnotationMirror maybeAnnot = annotsOnTypeVarsFromSubtypes.get(other.tsym);
+      if (maybeAnnot instanceof Attribute.TypeCompound) {
+        return typeWithAnnot(t, (Attribute.TypeCompound) maybeAnnot);
+      }
nullaway/src/main/java/com/uber/nullaway/generics/CheckIdenticalNullabilityVisitor.java (1)

82-83: Compare enclosing types after aligning RHS base: use rhsTypeAsSuper

Using rhsType.getEnclosingType() can mismatch when RHS base was adjusted via asSuper.

-    return lhsType.getEnclosingType().accept(this, rhsType.getEnclosingType());
+    return lhsType.getEnclosingType().accept(this, rhsTypeAsSuper.getEnclosingType());
🧹 Nitpick comments (1)
nullaway/src/test/java/com/uber/nullaway/jspecify/GenericsTests.java (1)

1984-2008: Add order-variant of intersection type to harden coverage

Intersection types are unordered semantically, but parser/LUB differences can surface. Consider also testing (Serializable & A<...>) to guard against order-sensitive regressions.

Apply this diff to extend the test body:

   static void test1(Object o) {
     var x = (A<String> & Serializable) o;
     // BUG: Diagnostic contains: Cannot assign from type B to type A<String> & Serializable
     x = new B();
     // ok
     x = new C();
+    var y = (Serializable & A<String>) o;
+    // BUG: Diagnostic contains: Cannot assign from type B to type Serializable & A<String>
+    y = new B();
+    // ok
+    y = new C();
   }
   static void test2(Object o) {
     var x = (A<@Nullable String> & Serializable) o;
     x = new B();
     // BUG: Diagnostic contains: Cannot assign from type C to type A<@Nullable String> & Serializable
     x = new C();
+    var y = (Serializable & A<@Nullable String>) o;
+    y = new B();
+    // BUG: Diagnostic contains: Cannot assign from type C to type Serializable & A<@Nullable String>
+    y = new C();
   }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between cf02218 and 308d1d3.

📒 Files selected for processing (8)
  • nullaway/src/main/java/com/uber/nullaway/generics/CheckIdenticalNullabilityVisitor.java (3 hunks)
  • nullaway/src/main/java/com/uber/nullaway/generics/ClassDeclarationNullnessAnnotUtils.java (2 hunks)
  • nullaway/src/main/java/com/uber/nullaway/generics/ConstraintSolverImpl.java (1 hunks)
  • nullaway/src/main/java/com/uber/nullaway/generics/GenericsChecks.java (1 hunks)
  • nullaway/src/main/java/com/uber/nullaway/generics/InferGenericMethodSubstitutionViaAssignmentContextVisitor.java (1 hunks)
  • nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.java (1 hunks)
  • nullaway/src/test/java/com/uber/nullaway/jspecify/GenericInheritanceTests.java (1 hunks)
  • nullaway/src/test/java/com/uber/nullaway/jspecify/GenericsTests.java (2 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: msridhar
PR: uber/NullAway#1248
File: nullaway/src/main/java/com/uber/nullaway/generics/GenericsChecks.java:847-857
Timestamp: 2025-08-28T04:54:20.922Z
Learning: In NullAway's GenericsChecks.java, NewClassTree support for explicit type argument substitution requires more extensive changes beyond just modifying the conditional in compareGenericTypeParameterNullabilityForCall. The maintainers prefer to handle NewClassTree support in a separate follow-up rather than expanding the scope of PRs focused on specific issues like super constructor calls.
📚 Learning: 2025-08-28T04:54:20.922Z
Learnt from: msridhar
PR: uber/NullAway#1248
File: nullaway/src/main/java/com/uber/nullaway/generics/GenericsChecks.java:847-857
Timestamp: 2025-08-28T04:54:20.922Z
Learning: In NullAway's GenericsChecks.java, NewClassTree support for explicit type argument substitution requires more extensive changes beyond just modifying the conditional in compareGenericTypeParameterNullabilityForCall. The maintainers prefer to handle NewClassTree support in a separate follow-up rather than expanding the scope of PRs focused on specific issues like super constructor calls.

Applied to files:

  • nullaway/src/main/java/com/uber/nullaway/generics/InferGenericMethodSubstitutionViaAssignmentContextVisitor.java
  • nullaway/src/main/java/com/uber/nullaway/generics/ConstraintSolverImpl.java
  • nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.java
  • nullaway/src/test/java/com/uber/nullaway/jspecify/GenericsTests.java
  • nullaway/src/main/java/com/uber/nullaway/generics/CheckIdenticalNullabilityVisitor.java
  • nullaway/src/main/java/com/uber/nullaway/generics/GenericsChecks.java
  • nullaway/src/test/java/com/uber/nullaway/jspecify/GenericInheritanceTests.java
  • nullaway/src/main/java/com/uber/nullaway/generics/ClassDeclarationNullnessAnnotUtils.java
📚 Learning: 2025-08-14T18:50:06.159Z
Learnt from: msridhar
PR: uber/NullAway#1245
File: guava-recent-unit-tests/src/test/java/com/uber/nullaway/guava/NullAwayGuavaParametricNullnessTests.java:101-102
Timestamp: 2025-08-14T18:50:06.159Z
Learning: In NullAway JSpecify tests, when JDK version requirements exist due to bytecode annotation reading capabilities, prefer failing tests over skipping them on unsupported versions to ensure CI catches regressions and enforces proper JDK version usage for developers.

Applied to files:

  • nullaway/src/test/java/com/uber/nullaway/jspecify/GenericsTests.java
  • nullaway/src/test/java/com/uber/nullaway/jspecify/GenericInheritanceTests.java
🧬 Code graph analysis (3)
nullaway/src/main/java/com/uber/nullaway/generics/InferGenericMethodSubstitutionViaAssignmentContextVisitor.java (1)
nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.java (1)
  • TypeSubstitutionUtils (22-287)
nullaway/src/main/java/com/uber/nullaway/generics/ConstraintSolverImpl.java (1)
nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.java (1)
  • TypeSubstitutionUtils (22-287)
nullaway/src/main/java/com/uber/nullaway/generics/CheckIdenticalNullabilityVisitor.java (1)
nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.java (1)
  • TypeSubstitutionUtils (22-287)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: JDK 17 on windows-latest with Error Prone 2.41.0
🔇 Additional comments (12)
nullaway/src/test/java/com/uber/nullaway/jspecify/GenericsTests.java (1)

1984-2008: Unified intersection-type test across JDKs — LGTM

Consolidation to a single expectation looks correct and matches the PR intent.

nullaway/src/main/java/com/uber/nullaway/generics/ConstraintSolverImpl.java (2)

103-105: Switch to TypeSubstitutionUtils.asSuper preserves nullability — LGTM

This will restore explicit nullability from extends/implements in the supertype view and aligns with the PR’s goal.


103-105: No remaining direct Types.asSuper calls
All .asSuper invocations now use the TypeSubstitutionUtils.asSuper wrapper; no further migration needed.

nullaway/src/main/java/com/uber/nullaway/generics/InferGenericMethodSubstitutionViaAssignmentContextVisitor.java (1)

34-36: Use of TypeSubstitutionUtils.asSuper here is correct

Keeps assignment-context inference consistent with annotation restoration.

nullaway/src/main/java/com/uber/nullaway/generics/GenericsChecks.java (2)

717-717: Pass Config into CheckIdenticalNullabilityVisitor — LGTM

Constructor threading of Config is appropriate given downstream asSuper/memberType usage.


717-717: All instantiations of CheckIdenticalNullabilityVisitor use the updated (state, this, config) signature; no mixed constructors remain.

nullaway/src/test/java/com/uber/nullaway/jspecify/GenericInheritanceTests.java (1)

235-253: New interfaceInheritance test exercises extends-annotation restoration — LGTM

Covers the reported Sub extends Base<@nullable T> scenario and validates the fix.

nullaway/src/main/java/com/uber/nullaway/generics/CheckIdenticalNullabilityVisitor.java (2)

43-44: Switch to TypeSubstitutionUtils.asSuper preserves nullability. LGTM


21-26: All call sites include the Config parameter Verified via ripgrep that the lone invocation in GenericsChecks.java uses all three arguments—no further updates needed.

nullaway/src/main/java/com/uber/nullaway/generics/ClassDeclarationNullnessAnnotUtils.java (3)

48-66: New API for supertype-based annotation mapping. LGTM


106-107: Delegation to class-based path helper. LGTM


119-133: Path construction logic looks correct and immutable. LGTM

@msridhar msridhar marked this pull request as draft August 29, 2025 05:36
@msridhar

Copy link
Copy Markdown
Collaborator Author

I've confirmed the Spring error on CI is valid:

/tmp/spring-framework/spring-beans/src/main/java/org/springframework/beans/factory/aot/DefaultBeanRegistrationCodeFragments.java:75: error: [NullAway] Cannot assign from type SingletonSupplier<InstantiationDescriptor> to type Supplier<InstantiationDescriptor> due to mismatched nullability of type parameters

This is because SingletonSupplier<T> extends Supplier<@Nullable T> (here). Once again, I can't submit a PR to fix this with the current release because of inference limitations in 0.12.9.

Though the error is valid, it's also incomprehensible; the type parameters look the same! Let me think about if we can do something better.

@msridhar

Copy link
Copy Markdown
Collaborator Author

Though the error is valid, it's also incomprehensible; the type parameters look the same! Let me think about if we can do something better.

I've decided this is a bit involved and should be fixed in a follow up; filed #1268.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.java (1)

24-52: Config-aware asSuper wrapper looks correct and addresses JDK<=21 behavior

Good: narrowed param to Symbol.ClassSymbol, mirrors memberType(...) restoration path, and uses unsubstituted superTypeSymbol.asType() as template. This also resolves the earlier review about unsafe casts.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled
  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 308d1d3 and 93de291.

📒 Files selected for processing (7)
  • nullaway/src/main/java/com/uber/nullaway/generics/CheckIdenticalNullabilityVisitor.java (4 hunks)
  • nullaway/src/main/java/com/uber/nullaway/generics/ClassDeclarationNullnessAnnotUtils.java (2 hunks)
  • nullaway/src/main/java/com/uber/nullaway/generics/ConstraintSolverImpl.java (1 hunks)
  • nullaway/src/main/java/com/uber/nullaway/generics/GenericsChecks.java (1 hunks)
  • nullaway/src/main/java/com/uber/nullaway/generics/InferGenericMethodSubstitutionViaAssignmentContextVisitor.java (2 hunks)
  • nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.java (1 hunks)
  • nullaway/src/test/java/com/uber/nullaway/jspecify/GenericsTests.java (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • nullaway/src/main/java/com/uber/nullaway/generics/ConstraintSolverImpl.java
  • nullaway/src/main/java/com/uber/nullaway/generics/GenericsChecks.java
  • nullaway/src/test/java/com/uber/nullaway/jspecify/GenericsTests.java
  • nullaway/src/main/java/com/uber/nullaway/generics/ClassDeclarationNullnessAnnotUtils.java
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: msridhar
PR: uber/NullAway#1248
File: nullaway/src/main/java/com/uber/nullaway/generics/GenericsChecks.java:847-857
Timestamp: 2025-08-28T04:54:20.922Z
Learning: In NullAway's GenericsChecks.java, NewClassTree support for explicit type argument substitution requires more extensive changes beyond just modifying the conditional in compareGenericTypeParameterNullabilityForCall. The maintainers prefer to handle NewClassTree support in a separate follow-up rather than expanding the scope of PRs focused on specific issues like super constructor calls.
📚 Learning: 2025-08-28T04:54:20.922Z
Learnt from: msridhar
PR: uber/NullAway#1248
File: nullaway/src/main/java/com/uber/nullaway/generics/GenericsChecks.java:847-857
Timestamp: 2025-08-28T04:54:20.922Z
Learning: In NullAway's GenericsChecks.java, NewClassTree support for explicit type argument substitution requires more extensive changes beyond just modifying the conditional in compareGenericTypeParameterNullabilityForCall. The maintainers prefer to handle NewClassTree support in a separate follow-up rather than expanding the scope of PRs focused on specific issues like super constructor calls.

Applied to files:

  • nullaway/src/main/java/com/uber/nullaway/generics/InferGenericMethodSubstitutionViaAssignmentContextVisitor.java
  • nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.java
🧬 Code graph analysis (2)
nullaway/src/main/java/com/uber/nullaway/generics/CheckIdenticalNullabilityVisitor.java (1)
nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.java (1)
  • TypeSubstitutionUtils (22-287)
nullaway/src/main/java/com/uber/nullaway/generics/InferGenericMethodSubstitutionViaAssignmentContextVisitor.java (1)
nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.java (1)
  • TypeSubstitutionUtils (22-287)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: JDK 11 on ubuntu-latest with Error Prone 2.31.0
  • GitHub Check: JDK 17 on macos-latest with Error Prone 2.41.0
  • GitHub Check: JDK 17 on ubuntu-latest with Error Prone 2.14.0
  • GitHub Check: JDK 17 on ubuntu-latest with Error Prone 2.41.0
  • GitHub Check: JDK 17 on windows-latest with Error Prone 2.41.0
  • GitHub Check: JDK 11 on ubuntu-latest with Error Prone 2.14.0
  • GitHub Check: Build spring-framework with snapshot
  • GitHub Check: Build caffeine with snapshot
🔇 Additional comments (1)
nullaway/src/main/java/com/uber/nullaway/generics/CheckIdenticalNullabilityVisitor.java (1)

22-27: LGTM: thread Config and use TypeSubstitutionUtils.asSuper

Constructor change and call site updates are consistent; cast to ClassSymbol is safe here since lhsType is a Type.ClassType. Enclosing-type comparison now correctly uses the super-view.

Also applies to: 44-46, 85-85

@lazaroclapp lazaroclapp left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I have one minor question, but either way it LGTM.

// should also match. When there is no enclosing type, getEnclosingType() returns a NoType
// object, which gets handled by the fallback visitType() method
return lhsType.getEnclosingType().accept(this, rhsType.getEnclosingType());
return lhsType.getEnclosingType().accept(this, rhsTypeAsSuper.getEnclosingType());

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Was this working before? What's the change in semantics between using rhsType vs rhsTypeAsSuper here to get the enclosing type? (Just curious)

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.

This is a very good question and I went down a bit of a rabbit hole trying to figure it out :-) The change was suggested by Code Rabbit and seemed harmless, but as I dug more I couldn't construct a test where it actually mattered. If we just use rhsType, then when comparing enclosing types, we should recursively call asSuper() and everything should work out. I undid the change but added a comment to this effect.

While I was digging into this I found #1274 and typetools/checker-framework#7239 🙂

@msridhar msridhar enabled auto-merge (squash) September 1, 2025 22:18
@msridhar msridhar merged commit 39fed3d into master Sep 1, 2025
12 of 14 checks passed
@msridhar msridhar deleted the issue-1252 branch September 1, 2025 22:26
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.

Nullability of generics ignored for extended interfaces

2 participants