Skip to content

Add test for @SuppressWarnings and @AnnotatedFor interaction and refine SourceChecker logic#1699

Open
aosen-xiong wants to merge 7 commits into
eisop:masterfrom
aosen-xiong:fix-annotatedfor-warning
Open

Add test for @SuppressWarnings and @AnnotatedFor interaction and refine SourceChecker logic#1699
aosen-xiong wants to merge 7 commits into
eisop:masterfrom
aosen-xiong:fix-annotatedfor-warning

Conversation

@aosen-xiong
Copy link
Copy Markdown
Collaborator

Fix @SuppressWarnings on an enclosing element being ignored when an inner element carries @AnnotatedFor.

The early return was redundant: the loop's natural termination already produces false when no matching @SuppressWarnings is found. Removing it lets the walk continue past @AnnotatedFor-annotated elements to enclosing scopes.

Copilot AI review requested due to automatic review settings May 5, 2026 02:31
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes warning suppression behavior in SourceChecker so an enclosing @SuppressWarnings still applies when an inner declaration is marked @AnnotatedFor. It also adds regression tests in both framework-level subtyping tests and nullness conservative-default tests.

Changes:

  • Removed the redundant early return in SourceChecker.shouldSuppressWarnings(Element, String) so suppression lookup continues through enclosing elements.
  • Added a subtyping regression test covering class-level @SuppressWarnings with a method-level @AnnotatedFor.
  • Added a nullness regression test covering the same interaction for nullness checking.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
framework/tests/conservative-defaults/annotatedfor/AnnotatedForTest.java Adds a regression case proving outer @SuppressWarnings("subtyping") overrides inner @AnnotatedFor("subtyping").
framework/src/main/java/org/checkerframework/framework/source/SourceChecker.java Removes the early exit that prevented suppression lookup from reaching enclosing scopes.
checker/tests/nulless-conservative-defaults/annotatedfornullness/AnnotatedForNullness.java Adds a nullness regression case for the same suppression/@AnnotatedFor interaction.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Collaborator

@thisisalexandercook thisisalexandercook left a comment

Choose a reason for hiding this comment

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

Great catch! It may be worth noting that #1331 also removes this check as part of its broader refactor, but this bug is independent and makes sense as its own PR.

Comment thread framework/tests/conservative-defaults/annotatedfor/AnnotatedForTest.java Outdated
Co-authored-by: Alex Cook <43047600+thisisalexandercook@users.noreply.github.com>
@aosen-xiong
Copy link
Copy Markdown
Collaborator Author

Great catch! It may be worth noting that #1331 also removes this check as part of its broader refactor, but this bug is independent and makes sense as its own PR.

Thanks! Yes, that's the point of having this PR.

Copy link
Copy Markdown
Member

@wmdietl wmdietl left a comment

Choose a reason for hiding this comment

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

Thanks for looking into this!
Also, please go through the javadoc and manual and see where this behavior is described.

return true;
}
}
if (isAnnotatedForThisCheckerOrUpstreamChecker(elt)) {
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.

The public boolean shouldSuppressWarnings(TreePath path, String errKey) overload still has this logic in it, twice.
Should that version continue to check for this condition?

I would expect that we need to find two things:

  1. what is the nearest SuppressWarnings?
  2. what is the nearest AnnotatedFor or UnannotatedFor?

Once we found an AnnotatedFor or UnannotatedFor, we can stop looking for the other as well, but we do need to continue looking for a SuppressWarnings, and the other way around.

Can you look through the other overload and write a test case that triggers that version?

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.

The public boolean shouldSuppressWarnings(TreePath path, String errKey) overload still has this logic in it, twice.

Updated. The TreePath overload no longer returns immediately when it sees an applicable @AnnotatedFor.

I would expect that we need to find two things:

  1. what is the nearest SuppressWarnings?
  2. what is the nearest AnnotatedFor or UnannotatedFor?

The new logic does that by tracking whether an applicable @AnnotatedFor was found, while continuing to walk enclosing declarations for a matching @SuppressWarnings. If it finds a matching suppression, it returns true; if it found @AnnotatedFor but no suppression, it returns false.

Also, please go through the javadoc and manual and see where this behavior is described.

I updated the relevant manual sections to state that diagnostics in an @AnnotatedFor scope can still be suppressed by an in-scope @SuppressWarnings.

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.

4 participants