Skip to content

Enable inference failure warnings in experimental mode, and fix related bug in library models - #1649

Merged
msridhar merged 9 commits into
masterfrom
inf-failure-warnings-in-experimental-mode
Jul 26, 2026
Merged

Enable inference failure warnings in experimental mode, and fix related bug in library models#1649
msridhar merged 9 commits into
masterfrom
inf-failure-warnings-in-experimental-mode

Conversation

@msridhar

@msridhar msridhar commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator

See #1551

For now, we only enable inference failure warnings in experimental mode, so we can further fix bugs before enabling by default.

We also enable these warnings for all JSpecify mode tests (and remove test helper methods that enabled them explicitly) and for building NullAway itself. This exposed a bug in our use of library models: in LibraryModelsHandler.onOverrideMethodType, we were not adding top-level @Nullable annotations on parameters captured by the LibraryModels.explicitlyNullableParameters() method. We fix that issue here, and also disallow representation of such annotations as a nested annotation with an empty path, to avoid confusion and redundancy. Eventually we may want to settle on a single mechanism for expressing top-level or nested parameter annotations, but that is for a future cleanup / PR.

The PR may look large, but most changes relate to renaming makeHelperWithInferenceFailureWarning to just makeHelper.

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Enhanced JSpecify support to apply top-level @Nullable to method parameter types using library models.
    • Added a dedicated JSpecify experimental compiler option and streamlined experimental-mode arguments.
  • Bug Fixes

    • Enforced that nested annotation type paths are non-empty (empty paths now rejected).
    • Adjusted JSpecify experimental defaults so generic inference warning behavior is enabled by default.
    • Removed an invalid nested-annotation entry from test library models.
  • Tests

    • Updated JSpecify test harnesses to simplify compiler flags and added an Optional wildcard regression case.
    • Added unit coverage for empty vs non-empty type paths.

@msridhar

msridhar commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator Author

@codecov

codecov Bot commented Jul 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.50000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.04%. Comparing base (347410a) to head (5da04a1).

Files with missing lines Patch % Lines
...m/uber/nullaway/libmodel/NestedAnnotationInfo.java 50.00% 1 Missing and 1 partial ⚠️
...m/uber/nullaway/handlers/LibraryModelsHandler.java 92.30% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master    #1649      +/-   ##
============================================
- Coverage     88.06%   88.04%   -0.02%     
- Complexity     3070     3074       +4     
============================================
  Files           105      105              
  Lines         10342    10351       +9     
  Branches       2091     2095       +4     
============================================
+ Hits           9108     9114       +6     
- Misses          581      582       +1     
- Partials        653      655       +2     

☔ View full report in Codecov by Harness.
📢 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 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

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 Plus

Run ID: fa8423d9-2271-4867-a23c-4298e545ac45

📥 Commits

Reviewing files that changed from the base of the PR and between 34713b1 and e77d75e.

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

Walkthrough

JSpecify mode now enables the experimental compiler option and inference-failure warnings by default. NestedAnnotationInfo rejects empty type paths. LibraryModelsHandler applies top-level nullable annotations to explicitly nullable JSpecify parameters before nested annotations. The obsolete Box#orElse(T) model entry was removed, and JSpecify tests use simplified helper configurations with wildcard Optional.orElse(null) coverage.

Possibly related PRs

Suggested labels: jspecify

Suggested reviewers: codingkiddo, yuxincs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.52% 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 accurately captures the two main changes: enabling inference-failure warnings in experimental mode and fixing the library-model bug.
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.
✨ 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 inf-failure-warnings-in-experimental-mode

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.

@msridhar
msridhar marked this pull request as draft July 24, 2026 02:53
@msridhar
msridhar force-pushed the add-jspecify-experimental branch from 2191a1c to faaed55 Compare July 24, 2026 04:02
@msridhar
msridhar force-pushed the inf-failure-warnings-in-experimental-mode branch from 035a576 to 5aa2bd9 Compare July 24, 2026 04:02
@msridhar
msridhar force-pushed the add-jspecify-experimental branch from faaed55 to 4276a87 Compare July 24, 2026 04:28
@msridhar
msridhar force-pushed the inf-failure-warnings-in-experimental-mode branch from 5aa2bd9 to ad563fd Compare July 24, 2026 04:28
@msridhar
msridhar force-pushed the add-jspecify-experimental branch from 4276a87 to e39330a Compare July 24, 2026 14:31
Base automatically changed from add-jspecify-experimental to master July 24, 2026 16:48
@msridhar
msridhar force-pushed the inf-failure-warnings-in-experimental-mode branch 2 times, most recently from 6864b90 to a7b561f Compare July 24, 2026 17:44
@msridhar
msridhar force-pushed the inf-failure-warnings-in-experimental-mode branch from a7b561f to c2ca171 Compare July 24, 2026 20:25
@msridhar msridhar changed the title Enable inference failure warnings in experimental mode and for unit tests Enable inference failure warnings, and fix related bug in library models Jul 24, 2026
@msridhar msridhar changed the title Enable inference failure warnings, and fix related bug in library models Enable inference failure warnings in experimental mode, and fix related bug in library models Jul 25, 2026
@msridhar
msridhar marked this pull request as ready for review July 25, 2026 00:27
@msridhar
msridhar requested a review from lazaroclapp July 25, 2026 00:27

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

A few questions below:

}

/** Updates method types based on nested annotation information from library models. */
/** Updates method types based on top-level parameter and nested annotation library models. */

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.

Wonder if expanding this comment to note how this is specifically for matching type parameters / generics eventually is worth it. I was a bit confused about why we would discard explicitlyNullableParameters when that is not necessarily related to JSpecify / handling type parameters. But, it turns out this handler method is only ever used inside nullaway/src/main/java/com/uber/nullaway/generics/*, because that's the only place where we care if the method type was overriden.

Actually, given that, do we want to have this check for isJSpecifyMode() or just rely on the callers to know why they are asking about the method type? Am I missing something that happens without the config.isJSpecifyMode() check?

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'm happy to update the comment to indicate that this is currently only relevant for generics in JSpecify mode, and to check for isJSpecifyMode() inside the body and fail if it's off.

In the (distant?) future where JSpecify mode is the default, and maybe we don't want to support anything else, there is a lot of code that could be cleaned up...

if (explicitlyNullableParameters.contains(index)) {
updatedArgType = applyTopLevelNullableAnnotation(updatedArgType, state);
}
if (!annotationsForArg.isEmpty()) {

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.

If we don't guard on config.isJSpecifyMode() for the explicitlyNullableParameters case, and we are considering potential future callers outside com.uber.nullaway.generics, then we probably want to check that config flag here instead.

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've now asserted at the top of this method that we're in JSpecify mode

*/
public record NestedAnnotationInfo(Annotation annotation, ImmutableList<TypePathEntry> typePath) {

public NestedAnnotationInfo {

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.

Remind me why we have the duplication between this and library-model/library-model-generator/src/main/java/com/uber/nullaway/libmodel/NestedAnnotationInfo.java ...

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.

Yeah 😐 It's to avoid a dependence from the library model generation code on NullAway and vice versa. I didn't want NullAway to depend on library model code via a separate artifact that needs to be shipped to Maven Central, etc. Making the lib model generation code depend on NullAway led to all kinds of Gradle unhappiness, if I recall correctly.

Anyway, I've forgotten all the details but we should fix this, and I've opened #1657 on that

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.

Ok @lazaroclapp FYI this is fixed in #1659

@msridhar
msridhar enabled auto-merge (squash) July 26, 2026 20:24
@msridhar
msridhar merged commit 1767334 into master Jul 26, 2026
13 of 14 checks passed
@msridhar
msridhar deleted the inf-failure-warnings-in-experimental-mode branch July 26, 2026 20:41
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