typetools / typetools/checker-framework
-AwarnUnneededSuppressions leads to unsuppressable warning from Nullness Checker, when using a compound declaration
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 1.1k
- Forks
- 440
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 134
Description
Compile the below file with:
javac -g Issue2586.java -processor nullness -ArequirePrefixInWarningSuppressions -AwarnUnneededSuppressions
There is an error that is not possible to be suppressed. That is, suppressing it leads to an unsuppressable warning.
Methods m1 and m2 show this behavior: both with and without a @SuppressWarnings, the Nullness Checker issues a warning.
There are two ways to rewrite the code to avoid the error:
* by using manifest literals instead of a constant variable (m3), or
* by splitting the compound variable declaration into two declaranions (m5)
Here is the code:
// Compile this file with:
// javac -g Isuse2586.java -processor nullness -ArequirePrefixInWarningSuppressions -AwarnUnneededSuppressions
import java.util.HashMap;
import java.util.Map;
import org.checkerframework.checker.nullness.qual.EnsuresKeyForIf;
import org.checkerframework.checker.nullness.qual.KeyFor;
import org.checkerframework.dataflow.qual.Pure;
public class Issue2586 {
void m1(Aux aux1, Aux aux2) {
if (aux1.hasValue(Aux.MINIMUM_VALUE) && aux2.hasValue(Aux.MINIMUM_VALUE)) {
// error: [keyfor:argument.type.incompatible] incompatible types in argument.
int minA = aux1.getInt(Aux.MINIMUM_VALUE),
minB = aux2.getInt(Aux.MINIMUM_VALUE);
}
}
void m2(Aux aux1, Aux aux2) {
if (aux1.hasValue(Aux.MINIMUM_VALUE) && aux2.hasValue(Aux.MINIMUM_VALUE)) {
// warning: [nullness:unneeded.suppression] warning suppression "keyfor:argument.type.incompatible" is not used by NullnessChecker
@SuppressWarnings("keyfor:argument.type.incompatible")
int minA = aux1.getInt(Aux.MINIMUM_VALUE),
minB = aux2.getInt(Aux.MINIMUM_VALUE);
}
}
void m3(Aux aux1, Aux aux2) {
if (aux1.hasValue("minvalue") && aux2.hasValue("minvalue")) {
@SuppressWarnings("keyfor:argument.type.incompatible")
int minA = aux1.getInt("minvalue"),
minB = aux2.getInt("minvalue");
}
}
void m5(Aux aux1, Aux aux2) {
if (aux1.hasValue(Aux.MINIMUM_VALUE) && aux2.hasValue(Aux.MINIMUM_VALUE)) {
int minA = aux1.getInt(Aux.MINIMUM_VALUE);
@SuppressWarnings("keyfor:argument.type.incompatible")
int minB = aux2.getInt(Aux.MINIMUM_VALUE);
}
}
}
class Aux {
public Map<String, String> map = new HashMap<>();
public static final String MINIMUM_VALUE = "minvalue";
@Pure
@EnsuresKeyForIf(result = true, expression = "#1", map = "map")
public boolean hasValue(String key) {
return map.containsKey(key);
}
@Pure
public int getInt(@KeyFor("this.map") String key) {
return 22;
}
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the Issue2586.java reproducer and compile it using the javac command in the report, focusing on the Nullness Checker handling of the compound declarations in m1 and m2. The issue is resolved when the keyfor suppression can suppress the reported incompatibility without producing an unneeded-suppression warning, while the m3 and m5 variants continue to behave consistently.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100