Skip to content

Propagate nullness facts for CastToNonNullMethod - #1630

Open
Shankar-v27 wants to merge 3 commits into
uber:masterfrom
Shankar-v27:fix-cast-to-nonnull-propagation
Open

Propagate nullness facts for CastToNonNullMethod#1630
Shankar-v27 wants to merge 3 commits into
uber:masterfrom
Shankar-v27:fix-cast-to-nonnull-propagation

Conversation

@Shankar-v27

@Shankar-v27 Shankar-v27 commented Jul 16, 2026

Copy link
Copy Markdown

Fixes #1628.

Summary

Objects.requireNonNull(...) propagates non-null facts during dataflow analysis because it is guaranteed to throw when passed null. Arbitrary methods configured via -XepOpt:NullAway:CastToNonNullMethod do not necessarily have that guarantee, so propagating non-null facts by default would be unsound.

This PR introduces a new opt-in configuration option:

-XepOpt:NullAway:CastToNonNullMethodFailsOnNull=true

When enabled, configured CastToNonNullMethods are treated as fail-fast during dataflow analysis and propagate non-null facts similarly to Objects.requireNonNull(...). The default behavior remains unchanged, preserving backward compatibility and soundness.

Changes

  • Add the CastToNonNullMethodFailsOnNull configuration option.
  • Enable downstream non-null propagation for configured CastToNonNullMethods only when the option is enabled.
  • Preserve the existing behavior for failIfNullParameters and the default CastToNonNullMethod behavior.
  • Add regression tests covering:
    • default behavior,
    • explicit false,
    • explicit true,
    • unchanged Objects.requireNonNull(...) behavior.

Validation

  • Added regression tests covering the new configuration option.
  • Ran :nullaway:test.
  • Ran spotlessCheck.

AI Usage

AI assistance was used during the development of this contribution to:

  • understand the existing NullAway architecture and relevant code paths,
  • discuss implementation approaches based on maintainer feedback,
  • review and refine the implementation,
  • help improve regression tests and this PR description.

I personally implemented, reviewed, and validated all code changes. I inspected the relevant source files, made the implementation decisions, ran the project's test suite locally, and verified the final behavior. I understand the implementation and can explain the reasoning behind each change.

Summary by CodeRabbit

  • New Features
    • Added a new configuration/CLI option to control whether castToNonNull(...) is treated as throwing on null inputs.
  • Bug Fixes
    • Improved nullability propagation for library-mode "cast-to-non-null" behavior, expanding the set of arguments treated as guaranteed and ensuring downstream dereference diagnostics match the configured semantics.
  • Tests
    • Added coverage for default behavior, explicit false, and enabled true cases, plus verification that Objects.requireNonNull(...) behavior remains unchanged.

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

LibraryModelsHandler now conditionally merges fail-if-null and cast-to-non-null argument positions, including the configured single-parameter method, when applying unconditional NONNULL updates. Configuration and CLI support expose this behavior, while CoreTests covers default, disabled, enabled, and Objects.requireNonNull propagation cases.

Possibly related PRs

  • uber/NullAway#1409: Updates library-model definitions for methods participating in cast-to-non-null behavior.

Suggested reviewers: msridhar

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.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
Linked Issues check ✅ Passed The changes implement the requested CastToNonNullMethod downstream non-null propagation and add regression tests.
Out of Scope Changes check ✅ Passed The config and test updates are directly supporting the CastToNonNullMethod propagation fix and stay in scope.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: propagating nullness facts for CastToNonNullMethod.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@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

🤖 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/main/java/com/uber/nullaway/handlers/LibraryModelsHandler.java`:
- Around line 406-408: Update setUnconditionalArgumentNullness to retrieve
config.getCastToNonNullMethod() first and use short-circuit checks before
constructing the qualifiedName string. Only concatenate
ASTHelpers.enclosingClass(callee) with callee.getSimpleName() when the
configured cast-to-non-null method is present and the one-parameter condition
can match, preserving the existing isCliCastToNonNull behavior.
🪄 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: 826ea860-36b5-4be7-aa26-9fffb322e12c

📥 Commits

Reviewing files that changed from the base of the PR and between 77726c5 and d1297f1.

📒 Files selected for processing (2)
  • nullaway/src/main/java/com/uber/nullaway/handlers/LibraryModelsHandler.java
  • nullaway/src/test/java/com/uber/nullaway/CoreTests.java

Comment thread nullaway/src/main/java/com/uber/nullaway/handlers/LibraryModelsHandler.java Outdated
@Shankar-v27
Shankar-v27 force-pushed the fix-cast-to-nonnull-propagation branch from d1297f1 to fcfb69f Compare July 16, 2026 06:30

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

♻️ Duplicate comments (1)
nullaway/src/main/java/com/uber/nullaway/handlers/LibraryModelsHandler.java (1)

406-408: 🧹 Nitpick | 🔵 Trivial

Avoid unconditional string allocations on the hot path.

Because setUnconditionalArgumentNullness is called on every method invocation, computing the qualifiedName via string concatenation unconditionally creates unnecessary allocation overhead during compilation.

You can avoid this overhead for the vast majority of cases (especially when the CLI property isn't configured) by extracting config.getCastToNonNullMethod() and leveraging short-circuit evaluation.

⚡ Proposed performance optimization
-    String qualifiedName = ASTHelpers.enclosingClass(callee) + "." + callee.getSimpleName();
-    boolean isCliCastToNonNull =
-        qualifiedName.equals(config.getCastToNonNullMethod()) && callee.getParameters().size() == 1;
+    String cliCastToNonNull = config.getCastToNonNullMethod();
+    boolean isCliCastToNonNull =
+        cliCastToNonNull != null
+            && callee.getParameters().size() == 1
+            && cliCastToNonNull.equals(
+                ASTHelpers.enclosingClass(callee) + "." + callee.getSimpleName());
🤖 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 `@nullaway/src/main/java/com/uber/nullaway/handlers/LibraryModelsHandler.java`
around lines 406 - 408, Update setUnconditionalArgumentNullness to retrieve
config.getCastToNonNullMethod() first and use short-circuit checks before
constructing the qualified method name. Only concatenate
ASTHelpers.enclosingClass(callee) with callee.getSimpleName() when the
configured cast-to-non-null method is present and the parameter-count condition
can still match, preserving the existing isCliCastToNonNull behavior.
🤖 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.

Duplicate comments:
In `@nullaway/src/main/java/com/uber/nullaway/handlers/LibraryModelsHandler.java`:
- Around line 406-408: Update setUnconditionalArgumentNullness to retrieve
config.getCastToNonNullMethod() first and use short-circuit checks before
constructing the qualified method name. Only concatenate
ASTHelpers.enclosingClass(callee) with callee.getSimpleName() when the
configured cast-to-non-null method is present and the parameter-count condition
can still match, preserving the existing isCliCastToNonNull behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 93acfbfd-6b5d-44f1-b58c-cd534a1992bf

📥 Commits

Reviewing files that changed from the base of the PR and between d1297f1 and fcfb69f.

📒 Files selected for processing (2)
  • nullaway/src/main/java/com/uber/nullaway/handlers/LibraryModelsHandler.java
  • nullaway/src/test/java/com/uber/nullaway/CoreTests.java

@msridhar

Copy link
Copy Markdown
Collaborator

@Shankar-v27 please see our new policy on AI usage https://github.com/uber/NullAway/blob/master/CONTRIBUTING.md#ai-usage Does this PR adhere to the policy? Please update the description if needed.

@Shankar-v27

Copy link
Copy Markdown
Author

@Shankar-v27 please see our new policy on AI usage https://github.com/uber/NullAway/blob/master/CONTRIBUTING.md#ai-usage Does this PR adhere to the policy? Please update the description if needed.

I have updated the PR description to include the AI usage disclosure and to reflect the final implementation. Could you please take another look when you have a chance? Thank you!

@Shankar-v27

Copy link
Copy Markdown
Author

Hi @msridhar, I updated the PR description to comply with the new AI usage policy and verified the implementation and tests. When you have some time, could you please take another look? I'd appreciate any further feedback. Thank you!

@msridhar

msridhar commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

I think the general approach here is reasonable. But, I'm still not sure it's worth the additional complexity to add this feature. Also, we have some higher-priority features / issues to deal with right now. So, I'm going to hold off on fully reviewing and merging this. Sorry for the delay @Shankar-v27

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Downcasting (CastToNonNullMethod) does NOT propagate to the other occurrences of the same expression

2 participants