Skip to content

Fix RLC unsoundness with explicit @MustCallUnknown annotation#6994

Open
kelloggm wants to merge 33 commits into
typetools:masterfrom
kelloggm:6990
Open

Fix RLC unsoundness with explicit @MustCallUnknown annotation#6994
kelloggm wants to merge 33 commits into
typetools:masterfrom
kelloggm:6990

Conversation

@kelloggm

Copy link
Copy Markdown
Contributor

fixes #6990

@kelloggm kelloggm requested a review from mernst March 20, 2025 16:24
mernst
mernst previously approved these changes Mar 20, 2025

@mernst mernst left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks!

@mernst mernst enabled auto-merge (squash) March 20, 2025 16:29
@kelloggm

Copy link
Copy Markdown
Contributor Author

@mernst I think you should review this again to make sure that the new @MustCall annotations in the Initialization checker are ok.

Also, this change could introduce user-facing behavior in the form of new warnings (as shown by the need to add those annotations). Does that warrant a changelog entry? If so, I don't mind adding one.

@mernst

mernst commented Mar 25, 2025

Copy link
Copy Markdown
Member

@kelloggm CI is not passing. Could you fix that? Then I will review.

@mernst

mernst commented Jul 18, 2025

Copy link
Copy Markdown
Member

@kelloggm Ping.

@mernst mernst requested a review from Copilot July 18, 2025 14:35

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull Request Overview

This pull request fixes an RLC (Resource Leak Checker) unsoundness issue by adding explicit @MustCallUnknown annotations to prevent incorrect behavior when handling owning parameters with unknown must-call obligations.

  • Adds proper error detection for @Owning parameters with @MustCallUnknown annotations
  • Improves must-call type resolution by using hierarchy-aware annotation lookup
  • Adds type annotations to initialization classes to ensure proper type checking

Reviewed Changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
DropOwning.java New test case demonstrating the fix for issue #6990 with expected error
CrashForTempVar.java Adds suppression annotation to focus testing on crash detection
MustCallConsistencyAnalyzer.java Updates annotation lookup logic and fixes typo in comment
InitializationTransfer.java Adds @MustCall type annotations to class declaration
InitializationStore.java Adds @MustCall type annotations and improves class documentation

@coderabbitai

coderabbitai Bot commented Mar 3, 2026

Copy link
Copy Markdown
Contributor

PR changed again? Review this PR in Change Stack to compare snapshots and stay oriented.

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

Run ID: a23ab4fb-e3c6-4e23-bb4a-3198f1663332

📥 Commits

Reviewing files that changed from the base of the PR and between 9e19901 and cdd7e3e.

📒 Files selected for processing (1)
  • annotation-file-utilities/src/main/java/org/checkerframework/afu/annotator/Main.java

📝 Walkthrough

Walkthrough

Tightens @MustCall generic bounds for initialization and collection types; changes MustCallConsistencyAnalyzer#getMustCallValue to resolve stored @MustCall via the qualifier-hierarchy; adds targeted @SuppressWarnings("resourceleak:required.method.not.known") annotations in annotation-file-utilities and RegexUtil; and adds/updates resource-leak diagnostic messages. No runtime control-flow logic was changed.

Possibly related PRs

🚥 Pre-merge checks | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning PR introduces @MustCall annotations on generic type parameters in initialization/visitor classes and adds resourceleak message handling, but reviewers conclude this creates >150 false positives requiring extensive user annotations, making it an unacceptable fix for issue #6990. Reconsider the approach to fixing RLC unsoundness. The current solution of adding @MustCall to generic bounds causes unacceptable annotation burden. Explore alternative fixes such as modifying generic defaulting rules or other mechanisms that don't require widespread user-visible changes.
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.

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

✨ 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 and usage tips.

@mernst mernst self-assigned this Apr 22, 2026

@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 the current code and only fix it if needed.

Inline comments:
In
`@checker/src/main/java/org/checkerframework/checker/initialization/InitializationTransfer.java`:
- Around line 59-62: The generic type V in InitializationTransfer is bound as
CFAbstractValue<V> but InitializationStore is parameterized with `@MustCall`({})
V, causing an annotated type-argument mismatch; change V's bound to
CFAbstractValue<@MustCall({}) V> so the value type annotation matches
InitializationStore's value parameter (update the type parameter declaration on
class InitializationTransfer accordingly, keeping T and S as-is and preserving
references to InitializationStore and `@MustCall`).
🪄 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: 65fb28ac-d3eb-4c99-8f99-9320be6dabc6

📥 Commits

Reviewing files that changed from the base of the PR and between 43deefc and 4558806.

📒 Files selected for processing (7)
  • annotation-file-utilities/src/main/java/org/checkerframework/afu/annotator/Main.java
  • annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/io/ASTPath.java
  • annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/coll/LinkedHashKeyedSet.java
  • annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/coll/VivifyingMap.java
  • checker/src/main/java/org/checkerframework/checker/initialization/InitializationStore.java
  • checker/src/main/java/org/checkerframework/checker/initialization/InitializationTransfer.java
  • checker/src/main/java/org/checkerframework/checker/resourceleak/MustCallConsistencyAnalyzer.java

@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)
checker/src/main/java/org/checkerframework/checker/initialization/InitializationTransfer.java (1)

60-60: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Align V's bound with InitializationStore.

Line 63 passes @MustCall({}) V to InitializationStore, but line 60 binds V as CFAbstractValue<V> instead of CFAbstractValue<@MustCall({}) V>. This creates a type-argument mismatch with InitializationStore's declaration (see context snippet), which expects the value bound to be CFAbstractValue<@MustCall({}) V>.

Proposed fix
 public class InitializationTransfer<
-        V extends CFAbstractValue<V>,
+        V extends CFAbstractValue<`@MustCall`({}) V>,
         T extends InitializationTransfer<V, T, S>,
         S extends InitializationStore<`@MustCall`({}) V, `@MustCall`({}) S>>
🤖 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
`@checker/src/main/java/org/checkerframework/checker/initialization/InitializationTransfer.java`
at line 60, The generic type parameter V on InitializationTransfer is bounded
incorrectly: change the bound from CFAbstractValue<V> to
CFAbstractValue<`@MustCall`({}) V> so it matches the expected type used when
constructing/using InitializationStore; update the class declaration's type
parameter (InitializationTransfer<... V ...>) to use
CFAbstractValue<`@MustCall`({}) V> and any related declarations that reference V
to preserve the `@MustCall` annotation so InitializationStore's type-argument
constraints align with CFAbstractValue<`@MustCall`({}) V>.
🤖 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
`@checker/src/main/java/org/checkerframework/checker/initialization/InitializationTransfer.java`:
- Line 60: The generic type parameter V on InitializationTransfer is bounded
incorrectly: change the bound from CFAbstractValue<V> to
CFAbstractValue<`@MustCall`({}) V> so it matches the expected type used when
constructing/using InitializationStore; update the class declaration's type
parameter (InitializationTransfer<... V ...>) to use
CFAbstractValue<`@MustCall`({}) V> and any related declarations that reference V
to preserve the `@MustCall` annotation so InitializationStore's type-argument
constraints align with CFAbstractValue<`@MustCall`({}) V>.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: b0b83557-a0fa-4255-8fa7-32accdb89c43

📥 Commits

Reviewing files that changed from the base of the PR and between 4558806 and 8a5e10b.

📒 Files selected for processing (3)
  • annotation-file-utilities/src/main/java/org/checkerframework/afu/annotator/Main.java
  • checker/src/main/java/org/checkerframework/checker/initialization/InitializationTransfer.java
  • checker/src/main/java/org/checkerframework/checker/resourceleak/MustCallConsistencyAnalyzer.java

@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
`@annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/SceneOps.java`:
- Around line 296-297: The Javadoc has a duplicated generic `@param` tag: it
documents both keys and values as `@param` <K>; update the second tag to `@param`
<V> to correctly document the method/type parameters K and V in SceneOps (where
the method/type declares <K, V>), ensuring the value type parameter is
documented as V rather than K.
🪄 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: 45bd2e18-19b2-466f-9e0f-712e76d638c0

📥 Commits

Reviewing files that changed from the base of the PR and between 8a5e10b and 182fcd6.

📒 Files selected for processing (3)
  • annotation-file-utilities/src/main/java/org/checkerframework/afu/annotator/Main.java
  • annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/SceneOps.java
  • annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/coll/VivifyingMap.java

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
annotation-file-utilities/src/main/java/org/checkerframework/afu/annotator/Main.java (1)

616-621: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Fix remaining Main.temporaryDebug references (field missing in Main.java).

annotation-file-utilities/.../Main.java no longer contains temporaryDebug, but there are still many Main.temporaryDebug usages (e.g., IndexFileSpecification.java:522, Insertion.java:209, TreeFinder.java multiple sites, Insertions.java multiple sites). Restore the field or update those call sites to the new debug flag so the build doesn’t fail.

🤖 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
`@annotation-file-utilities/src/main/java/org/checkerframework/afu/annotator/Main.java`
around lines 616 - 621, Several files still reference Main.temporaryDebug which
was removed; add back a compatible flag in Main or update all call sites to the
current debug mechanism. Either restore a public static boolean temporaryDebug =
false in Main (so IndexFileSpecification, Insertion, TreeFinder, Insertions
continue to compile), or replace each Main.temporaryDebug usage with the new
debug check (for example Main.dbug.isEnabled() or the project's canonical debug
flag) across the referenced classes (IndexFileSpecification, Insertion,
TreeFinder, Insertions) so the build no longer fails.
🤖 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.

Outside diff comments:
In
`@annotation-file-utilities/src/main/java/org/checkerframework/afu/annotator/Main.java`:
- Around line 616-621: Several files still reference Main.temporaryDebug which
was removed; add back a compatible flag in Main or update all call sites to the
current debug mechanism. Either restore a public static boolean temporaryDebug =
false in Main (so IndexFileSpecification, Insertion, TreeFinder, Insertions
continue to compile), or replace each Main.temporaryDebug usage with the new
debug check (for example Main.dbug.isEnabled() or the project's canonical debug
flag) across the referenced classes (IndexFileSpecification, Insertion,
TreeFinder, Insertions) so the build no longer fails.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: a98093c0-8d74-44c2-ab4e-d117e9050e31

📥 Commits

Reviewing files that changed from the base of the PR and between 182fcd6 and 7a74fd9.

📒 Files selected for processing (2)
  • annotation-file-utilities/src/main/java/org/checkerframework/afu/annotator/Main.java
  • annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/SceneOps.java

@kelloggm kelloggm disabled auto-merge June 2, 2026 19:14
@kelloggm

kelloggm commented Jun 2, 2026

Copy link
Copy Markdown
Contributor Author

@mernst this change triggers a huge number of false positive warnings that need to be resolved via a meaningless-seeming annotation (>150) in the Checker Framework itself, so I think we need to revisit it - is this really the right fix to prevent the false negative in #6990? It will be pretty disruptive for users of the RLC who have already annotated their programs.

In particular, the vast majority of the false positives are caused by this PR's interaction with the defaulting rules for generics. Consider the following example, from AnalysisResult.java:

  public static <V> String nodeValuesToString(Map<Node, @MustCall V> nodeValues) {
    if (nodeValues.isEmpty()) {
      return "{}";
    }
    StringJoiner result = new StringJoiner(String.format("%n    "));
    result.add("{");
    for (Map.Entry<Node, @MustCall V> entry : nodeValues.entrySet()) {
      Node key = entry.getKey();
      result.add(String.format("%s => %s", key.toStringDebug(), entry.getValue()));
    }
    result.add("}");
    return result.toString();
  }

Before this change, neither of the two @MustCall annotations were necessary: V defaulted to @MustCallUnknown, which was "fine" (although technically unsound, for the same reason as the example in #6990 pointed out). With this change, an error is generated about the call to entry.getValue(), because its type is @MustCallUnknown V and it is dropped. The annotations fix this by changing the map to require that its entries have empty must-call sets.

There are a lot of similar examples throughout the Checker Framework, although the most sites affected by far are in "analysis" classes that have type parameters for their Value, Store, and Analysis types. Each one of these declarations needs to be modified from (e.g.) V extends CFValue<V> to V extends CFValue<@MustCall V>. This is a tedious and seemingly pointless process, and I'm not sure it's a good idea to force it on users.

One option would be to change the default bound on such types from top (i.e., @MustCallUnknown) to bottom (i.e., @MustCall). However, this would effectively forbid resource collections of any kind (because List<Socket> wouldn't be compatible with List<E>), which would probably interact poorly with the RLCC PR that @msridhar and @iamsanjaymalakar are working through right now. Maybe one of them has an idea about what the right decision here is? Or, maybe the RLCC changes will make this no longer a concern - I recall at some point Sascha discussed changing the defaulting rules for generics to support the collections changes, but I don't remember where we ended up landing on that.

@mernst

mernst commented Jun 2, 2026

Copy link
Copy Markdown
Member

@kelloggm Thanks for your analysis. I agree that this change requires an unacceptable number of annotations, for no gain. I don't have a suggestion, and I don't know whether generics defaulting rules would improve the situation.

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
annotation-file-utilities/src/main/java/org/checkerframework/afu/annotator/Main.java (1)

411-424: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Prevent infinite loop in AST parent traversal.

At Line 415 and Line 416, path is not advanced for VARIABLE/METHOD, so the loop can spin forever on the same node.

Proposed fix
             while (path != null) {
               Tree leaf = path.getLeaf();
               switch (leaf.getKind()) {
                 // TODO: Is this an infinite loop if leaf is a VARIABLE or METHOD?
-                case VARIABLE -> varTree = (JCTree.JCVariableDecl) leaf;
-                case METHOD -> {
-                  // This assignment is not used.
-                  // methTree = (JCTree.JCMethodDecl) leaf;
-                }
+                case VARIABLE -> {
+                  varTree = (JCTree.JCVariableDecl) leaf;
+                  path = path.getParentPath();
+                }
+                case METHOD -> path = path.getParentPath();
                 case ANNOTATION_TYPE, CLASS, ENUM, INTERFACE -> {
                   break loop;
                 }
                 default -> path = path.getParentPath();
               }
             }
🤖 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
`@annotation-file-utilities/src/main/java/org/checkerframework/afu/annotator/Main.java`
around lines 411 - 424, The while loop in Main.java that walks parent paths can
hang because in the VARIABLE and METHOD cases you don't advance path; modify the
switch handling for leaf kinds (VARIABLE / METHOD) so after setting varTree (and
assigning methTree if needed) you also set path = path.getParentPath() (or
otherwise advance the traversal) so the loop progresses; ensure the loop
label/behaviour (break loop) remains unchanged and remove or fix the
commented-out unused methTree assignment as appropriate.
🤖 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
`@checker/src/main/java/org/checkerframework/checker/resourceleak/MustCallConsistencyAnalyzer.java`:
- Around line 1510-1527: Update the comment in MustCallConsistencyAnalyzer.java
near the constructor-handling branch (the block that checks
TreeUtils.isConstructor(enclosingMethodTree)) to fix the typo: change the phrase
"owning file reassignment error" to "owning field reassignment error"; the
relevant symbols to locate the code are enclosingMethodTree,
enclosingClassElement, receiverTypeElement, lhsElement and the call to
ConstructorFirstWriteAnalysis.isFirstWriteToFieldInConstructor(node.getTree(),
lhsElement, enclosingMethodTree, cmAtf).

---

Outside diff comments:
In
`@annotation-file-utilities/src/main/java/org/checkerframework/afu/annotator/Main.java`:
- Around line 411-424: The while loop in Main.java that walks parent paths can
hang because in the VARIABLE and METHOD cases you don't advance path; modify the
switch handling for leaf kinds (VARIABLE / METHOD) so after setting varTree (and
assigning methTree if needed) you also set path = path.getParentPath() (or
otherwise advance the traversal) so the loop progresses; ensure the loop
label/behaviour (break loop) remains unchanged and remove or fix the
commented-out unused methTree assignment as appropriate.
🪄 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: fd5c53fe-e626-4bd4-b8d9-88e8094a9cb3

📥 Commits

Reviewing files that changed from the base of the PR and between 7429f78 and 9e19901.

📒 Files selected for processing (6)
  • annotation-file-utilities/src/main/java/org/checkerframework/afu/annotator/Main.java
  • annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/io/ASTPath.java
  • annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/SceneOps.java
  • annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/coll/LinkedHashKeyedSet.java
  • annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/coll/VivifyingMap.java
  • checker/src/main/java/org/checkerframework/checker/resourceleak/MustCallConsistencyAnalyzer.java

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

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
annotation-file-utilities/src/main/java/org/checkerframework/afu/annotator/Main.java (1)

411-424: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Prevent infinite loop in AST parent traversal.

At Line 415 and Line 416, path is not advanced for VARIABLE/METHOD, so the loop can spin forever on the same node.

Proposed fix
             while (path != null) {
               Tree leaf = path.getLeaf();
               switch (leaf.getKind()) {
                 // TODO: Is this an infinite loop if leaf is a VARIABLE or METHOD?
-                case VARIABLE -> varTree = (JCTree.JCVariableDecl) leaf;
-                case METHOD -> {
-                  // This assignment is not used.
-                  // methTree = (JCTree.JCMethodDecl) leaf;
-                }
+                case VARIABLE -> {
+                  varTree = (JCTree.JCVariableDecl) leaf;
+                  path = path.getParentPath();
+                }
+                case METHOD -> path = path.getParentPath();
                 case ANNOTATION_TYPE, CLASS, ENUM, INTERFACE -> {
                   break loop;
                 }
                 default -> path = path.getParentPath();
               }
             }
🤖 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
`@annotation-file-utilities/src/main/java/org/checkerframework/afu/annotator/Main.java`
around lines 411 - 424, The while loop in Main.java that walks parent paths can
hang because in the VARIABLE and METHOD cases you don't advance path; modify the
switch handling for leaf kinds (VARIABLE / METHOD) so after setting varTree (and
assigning methTree if needed) you also set path = path.getParentPath() (or
otherwise advance the traversal) so the loop progresses; ensure the loop
label/behaviour (break loop) remains unchanged and remove or fix the
commented-out unused methTree assignment as appropriate.
🤖 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
`@checker/src/main/java/org/checkerframework/checker/resourceleak/MustCallConsistencyAnalyzer.java`:
- Around line 1510-1527: Update the comment in MustCallConsistencyAnalyzer.java
near the constructor-handling branch (the block that checks
TreeUtils.isConstructor(enclosingMethodTree)) to fix the typo: change the phrase
"owning file reassignment error" to "owning field reassignment error"; the
relevant symbols to locate the code are enclosingMethodTree,
enclosingClassElement, receiverTypeElement, lhsElement and the call to
ConstructorFirstWriteAnalysis.isFirstWriteToFieldInConstructor(node.getTree(),
lhsElement, enclosingMethodTree, cmAtf).

---

Outside diff comments:
In
`@annotation-file-utilities/src/main/java/org/checkerframework/afu/annotator/Main.java`:
- Around line 411-424: The while loop in Main.java that walks parent paths can
hang because in the VARIABLE and METHOD cases you don't advance path; modify the
switch handling for leaf kinds (VARIABLE / METHOD) so after setting varTree (and
assigning methTree if needed) you also set path = path.getParentPath() (or
otherwise advance the traversal) so the loop progresses; ensure the loop
label/behaviour (break loop) remains unchanged and remove or fix the
commented-out unused methTree assignment as appropriate.
🪄 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: fd5c53fe-e626-4bd4-b8d9-88e8094a9cb3

📥 Commits

Reviewing files that changed from the base of the PR and between 7429f78 and 9e19901.

📒 Files selected for processing (6)
  • annotation-file-utilities/src/main/java/org/checkerframework/afu/annotator/Main.java
  • annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/io/ASTPath.java
  • annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/SceneOps.java
  • annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/coll/LinkedHashKeyedSet.java
  • annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/coll/VivifyingMap.java
  • checker/src/main/java/org/checkerframework/checker/resourceleak/MustCallConsistencyAnalyzer.java
🛑 Comments failed to post (1)
checker/src/main/java/org/checkerframework/checker/resourceleak/MustCallConsistencyAnalyzer.java (1)

1510-1527: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Verify ConstructorFirstWriteAnalysis class exists and has the expected method

# Search for the class definition
rg -n "class ConstructorFirstWriteAnalysis" --type java

# Search for the method signature
rg -n "isFirstWriteToFieldInConstructor" --type java -A 3

Repository: typetools/checker-framework

Length of output: 2030


Fix typo in comment

Line 1513: change “owning file reassignment error” to “owning field reassignment error”.

📝 Fix typo
-      // (If the field is not private, conservatively throw the owning file reassignment error.)
+      // (If the field is not private, conservatively throw the owning field reassignment error.)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    } else if (TreeUtils.isConstructor(enclosingMethodTree)) {
      // If this assignment is the first write to the private field in this constructor,
      // then do not throw non-final owning field reassignment error.
      // (If the field is not private, conservatively throw the owning field reassignment error.)
      ExecutableElement elementFromDeclaration =
          TreeUtils.elementFromDeclaration(enclosingMethodTree);
      `@SuppressWarnings`("nullness:dereference.of.nullable") // a constructor has an enclosing class
      Element enclosingClassElement = elementFromDeclaration.getEnclosingElement();
      Element receiverTypeElement = TypesUtils.getTypeElement(receiver.getType());
      if (Objects.equals(enclosingClassElement, receiverTypeElement)) {
        VariableElement lhsElement = lhs.getElement();
        if (lhsElement.getModifiers().contains(Modifier.PRIVATE)
            && ConstructorFirstWriteAnalysis.isFirstWriteToFieldInConstructor(
                node.getTree(), lhsElement, enclosingMethodTree, cmAtf)) {
          // Safe; first assignment in constructor.
          return;
        }
      }
🤖 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
`@checker/src/main/java/org/checkerframework/checker/resourceleak/MustCallConsistencyAnalyzer.java`
around lines 1510 - 1527, Update the comment in MustCallConsistencyAnalyzer.java
near the constructor-handling branch (the block that checks
TreeUtils.isConstructor(enclosingMethodTree)) to fix the typo: change the phrase
"owning file reassignment error" to "owning field reassignment error"; the
relevant symbols to locate the code are enclosingMethodTree,
enclosingClassElement, receiverTypeElement, lhsElement and the call to
ConstructorFirstWriteAnalysis.isFirstWriteToFieldInConstructor(node.getTree(),
lhsElement, enclosingMethodTree, cmAtf).

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.

RLC unsoundness at (pseudo?) assignments to @MustCallUnknown

3 participants