-
Notifications
You must be signed in to change notification settings - Fork 428
Fix interaction between @NotOnlyInitialized and @UnderInitialization #7426
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Fix interaction between @NotOnlyInitialized and @UnderInitialization #7426
Conversation
📝 WalkthroughWalkthroughThis pull request modifies the initialization type checking logic in the Checker Framework. The primary change updates Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this 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
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
checker/src/main/java/org/checkerframework/checker/initialization/InitializationAnnotatedTypeFactory.java(1 hunks)checker/tests/nullness/InitializationNotOnlyInitialized.java(1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: mernst
Repo: typetools/checker-framework PR: 7354
File: annotation-file-utilities/tests/LocalMultipleManyMethodsShifted.java:14-14
Timestamp: 2025-11-02T02:18:00.536Z
Learning: In the Checker Framework repository, when doing refactoring PRs (such as preferring isEmpty() over size() comparisons), test files should not be changed. Tests should remain stable to preserve their exact patterns for annotation processing and bytecode verification purposes.
📚 Learning: 2025-10-22T20:41:01.112Z
Learnt from: kelloggm
Repo: typetools/checker-framework PR: 7166
File: checker/src/main/java/org/checkerframework/checker/collectionownership/CollectionOwnershipAnnotatedTypeFactory.java:128-136
Timestamp: 2025-10-22T20:41:01.112Z
Learning: In checker/src/main/java/org/checkerframework/checker/collectionownership/CollectionOwnershipAnnotatedTypeFactory.java, prefer instance fields over static state for analysis caches (e.g., maps keyed by Tree/Block). There is at most one ATF per running checker, so static mutable fields are discouraged.
Applied to files:
checker/src/main/java/org/checkerframework/checker/initialization/InitializationAnnotatedTypeFactory.java
🔇 Additional comments (1)
checker/src/main/java/org/checkerframework/checker/initialization/InitializationAnnotatedTypeFactory.java (1)
515-523: The code change appears correct for the stated PR objective.The call to
getUninitializedInvariantFields(store, path, false, Collections.emptyList()).isEmpty()correctly checks whether all invariant fields are initialized in the given store without applying any receiver annotation filters. This aligns with the PR goal to rely solely on invariant-field initialization. No evidence suggests this parameter choice is problematic.
| // @test | ||
| // @summary Reproduce incorrect interaction between @NotOnlyInitialized and @UnderInitialization | ||
| // @compile | ||
| import org.checkerframework.checker.initialization.qual.*; | ||
| import org.checkerframework.checker.nullness.qual.*; | ||
|
|
||
| class Parent { | ||
| @NonNull String parentField; | ||
|
|
||
| Parent() { | ||
| parentField = "parent"; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test appears incomplete and doesn't validate the fix.
Based on issue #7373 and the PR objectives, the test should demonstrate:
- A class with both
@NotOnlyInitializedand@NonNullfields - A private method that should be callable on
this - A constructor that assigns both fields, then calls the private method
- Verification that the method call succeeds without producing the spurious
method.invocationerror
The current test only defines a parent class with a single @NonNull field and doesn't exercise the interaction between @NotOnlyInitialized and @UnderInitialization.
🔎 Suggested test expansion
class Parent {
@NonNull String parentField;
+ @NotOnlyInitialized Object notOnlyInitField;
Parent() {
parentField = "parent";
+ notOnlyInitField = new Object();
+ helperMethod(); // This should not produce an error after the fix
+ }
+
+ private void helperMethod() {
+ // Method that requires @UnderInitialization(Parent) or better
}
}🤖 Prompt for AI Agents
In checker/tests/nullness/InitializationNotOnlyInitialized.java around lines 1
to 13, the test is incomplete: it only defines a Parent with a @NonNull field
but does not exercise the interaction between @NotOnlyInitialized and
@UnderInitialization or verify that a private method call in a constructor after
initializing fields does not produce a spurious method.invocation error. Update
the file to add a subclass that declares a @NotOnlyInitialized @NonNull field, a
second @NonNull field, a private method that uses those fields, and a
constructor that assigns both fields and then calls the private method (ensuring
the constructor parameter is annotated @UnderInitialization(ClassName.class) if
needed); the test should compile without errors to confirm the method call is
allowed. Ensure the new code is included in the test harness so the compile run
will fail if the spurious method.invocation error reappears.
|
The failures in These failures are unrelated to this PR’s changes; all checker, inference, I believe this is an environment-related docs issue in CI rather than a |
Fixes #7373
This PR fixes an incorrect interaction between @NotOnlyInitialized and
@UnderInitialization that caused a spurious method.invocation error.
The initialization refinement now relies solely on invariant-field
initialization, which matches the Checker Framework documentation.
Testing: