Skip to content

Run inference for generic method calls nested inside receivers#1571

Merged
msridhar merged 7 commits into
masterfrom
nested-receiver-inference
May 16, 2026
Merged

Run inference for generic method calls nested inside receivers#1571
msridhar merged 7 commits into
masterfrom
nested-receiver-inference

Conversation

@msridhar
Copy link
Copy Markdown
Collaborator

@msridhar msridhar commented May 9, 2026

Discovered this issue while investigating #1500. When computing the type of an invocation, we may need to run inference for a generic method call nested within its receiver in order to compute its proper type.

This change exposed a couple of other issues, which are fixed in PRs stack on top of this one. The integration test failures are expected.

Summary by CodeRabbit

  • Bug Fixes

    • Improved null-safety analysis for chained generic method calls by using the actual call receiver context when resolving invoked method types, yielding more accurate nullability results in complex generic scenarios and reducing false positives/negatives.
  • Tests

    • Added a unit test validating nested chained receiver behavior to exercise generic type inference and guard against regressions.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 9, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

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: af734192-2ebc-49c2-b6ac-11d4d402a428

📥 Commits

Reviewing files that changed from the base of the PR and between d293b16 and 4431838.

📒 Files selected for processing (2)
  • nullaway/src/main/java/com/uber/nullaway/generics/GenericsChecks.java
  • nullaway/src/test/java/com/uber/nullaway/jspecify/GenericMethodTests.java

Walkthrough

This PR changes GenericsChecks.getTreeType so MethodInvocationTree uses the call's enclosing/receiver type to recompute the invoked method's MethodType (via getEnclosingTypeForCallExpression and TypeSubstitutionUtils.memberType) before calling handler.onOverrideMethodType, instead of always using symbol.type.asMethodType(). It also adds a nestedReceivers() test exercising chained generic receiver inference under @NullMarked.

Possibly related PRs

  • uber/NullAway#1293: Adjusts GenericsChecks to compute enclosing/member method types and adds GenericMethodTests for chained receivers.
  • uber/NullAway#1248: Modifies GenericsChecks to derive enclosing/member method types rather than using raw symbol types.
  • uber/NullAway#1286: Updates invoked method type computation/substitution in GenericsChecks using call/assignment context.

Suggested labels

jspecify

Suggested reviewers

  • lazaroclapp
  • yuxincs
🚥 Pre-merge checks | ✅ 4 | ❌ 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 (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: running inference for generic method calls nested inside receivers.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch nested-receiver-inference

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.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 9, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.41%. Comparing base (070840c) to head (4431838).

Additional details and impacted files
@@            Coverage Diff            @@
##             master    #1571   +/-   ##
=========================================
  Coverage     88.40%   88.41%           
- Complexity     2881     2882    +1     
=========================================
  Files           103      103           
  Lines          9637     9644    +7     
  Branches       1940     1941    +1     
=========================================
+ Hits           8520     8527    +7     
  Misses          535      535           
  Partials        582      582           

☔ 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.

@msridhar msridhar force-pushed the nested-receiver-inference branch from ca80da3 to d293b16 Compare May 15, 2026 23:36
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 `@nullaway/src/test/java/com/uber/nullaway/jspecify/GenericMethodTests.java`:
- Around line 1656-1657: Remove the unused import "java.util.Objects" from the
test source string in GenericMethodTests.java so the test code no longer
contains an unused import; locate the multi-line test string where the import
appears (the block containing 'import java.util.Objects;') and delete that
import line so the string only includes actually used imports.
🪄 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: 593692d6-c504-4bd6-80a0-10c1499a442e

📥 Commits

Reviewing files that changed from the base of the PR and between ca80da3 and d293b16.

📒 Files selected for processing (2)
  • nullaway/src/main/java/com/uber/nullaway/generics/GenericsChecks.java
  • nullaway/src/test/java/com/uber/nullaway/jspecify/GenericMethodTests.java

Comment thread nullaway/src/test/java/com/uber/nullaway/jspecify/GenericMethodTests.java Outdated
Copy link
Copy Markdown
Collaborator

@lazaroclapp lazaroclapp left a comment

Choose a reason for hiding this comment

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

Some nits, but overall LGTM!

static Foo<@Nullable String> FOO2 =
Foo.of(new Foo<@Nullable String>())
.or(new Foo<@Nullable String>())
.or(new Foo<@Nullable String>());
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.

A bit surprised we don't have an example here reporting an issue (e.g. where one of the .or(...) methods is passing an incompatible type. We have a few true negative cases, but not the true positive, right?

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.

Good point, will add a true positive test

// for method invocations and field reads, there may be annotations on type variables in
// the return / field type that need to be restored
if (tree instanceof MethodInvocationTree invocationTree) {
// for a call to an instance method, we may need to run inference on a nested call
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.

Is nested call here just meaning a chained method call as the receiver? Or are there more complex cases? I know is in the test, but a brief example here would be great :)

@msridhar msridhar enabled auto-merge (squash) May 16, 2026 23:08
@msridhar msridhar merged commit cd0428a into master May 16, 2026
11 of 14 checks passed
@msridhar msridhar deleted the nested-receiver-inference branch May 16, 2026 23:21
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.

2 participants