eclipse-jdt / eclipse-jdt/eclipse.jdt.core
support @SafeVarargs and @SuppressWarnings("varargs") as correct suppression of varargs warnings
- Dominant language
- Java
- Stars
- 237
- Forks
- 195
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 47
Description
Summarizing the discussion from [java warning: Varargs method could cause heap pollution from non-reifiable varargs parameter](https://stackoverflow.com/questions/28914088/java-warning-varargs-method-could-cause-heap-pollution-from-non-reifiable-varar), there are two varargs-related warning suppression annotations: 1) `@SafeVarargs`, which suppresses a warning related to to possible heap pollution from from varargs in a method's _contract_ (signature); and 2) `@SuppressWarnings("varargs")`, which suppresses a similar varargs warning related to usage _within_ the method.
Unfortunately **Eclipse does not recognize `@SuppressWarnings("varargs")`**, and forces us to use `@SuppressWarnings("unchecked")` instead; moreover when `@SuppressWarnings("unchecked")` is used, Eclipse produces a warning if we additionally use `@SafeVarargs` (saying that `@SuppressWarnings("unchecked")` is redundant), which is ironic seeing that the JDK itself uses `@SafeVarargs` in methods such as `java.util.Collections.addAll(…)`. In fact support for `@SuppressWarnings("varargs")` was requested in [Eclipse Bug 349669](https://bugs.eclipse.org/bugs/show_bug.cgi?id=349669) and [Eclipse Bug 344783](https://bugs.eclipse.org/bugs/show_bug.cgi?id=344783). (It appears the latter was opened over 10 years ago, is almost identical to this present request, with the same conclusion of this present ticket, and has an unknown status as it was marked "bulk move out of 4.8", and its status is unknown.)
Let me back up and start with an example, as I discussed in [correct way to avoid varargs "method could cause heap pollution from non-reifiable varargs parameter iterators" in Eclipse](https://stackoverflow.com/questions/73955058/correct-way-to-avoid-varargs-method-could-cause-heap-pollution-from-non-reifiab).
```java
public static HashSet createHashSet(final E... elements) {
final HashSet hashSet = new HashSet(elements.length);
java.util.Collections.addAll(hashSet, elements);
return hashSet;
}
```
If I'm compiling with Java 17 using `-Xlint:all`, I get the following warning for the method signature:
> `Varargs method could cause heap pollution from non-reifiable varargs parameter iterators`
Eclipse 2022-09 suggests using `@SafeVarargs`. And indeed Java's own `java.util.Collections.addAll(…)` itself uses `@SafeVarargs`! Yet when I add it to the method signature, `javac` gives me the same warning, only further down in the `java.util.Collections.addAll(…)` line.
The answers to [java warning: Varargs method could cause heap pollution from non-reifiable varargs parameter](https://stackoverflow.com/questions/28914088/java-warning-varargs-method-could-cause-heap-pollution-from-non-reifiable-varar) explain that there is a distinction between suppressing the warning for the method's contract and suppressing it for usage in the message body, suggesting to additionally use `@SuppressWarnings("varargs")` on the method for IntelliJ. And indeed when I use both `@SafeVarargs` and `@SuppressWarnings("varargs")` together, the lint warning goes away with `javac`. However Eclipse says this annotation value `"varargs"` is unsupported. So I have just traded one warning in `javac` for one in Eclipse. That is the crux of the issue.
Eclipse also suggests using `@SuppressWarnings("unchecked")`. If I add _only_ `@SuppressWarnings("unchecked")` to the method, then the warning goes away both in Eclipse and in `javac` with linting! So Eclipse seems to imply that a single `@SuppressWarnings("unchecked")` is the way to go.
But I don't think it's the way to go because:
* The JDK itself uses `@SafeVarargs` with methods like `java.util.Collections.addAll(…)`, and if I use the Eclipse suggestion of `@SuppressWarnings("unchecked")`, Eclipse says that `@SuppressWarnings("unchecked")` is redundant (i.e. Eclipse wants me to remove `@SafeVarargs`).
* IntelliJ, if I read [java warning: Varargs method could cause heap pollution from non-reifiable varargs parameter](https://stackoverflow.com/questions/28914088/java-warning-varargs-method-could-cause-heap-pollution-from-non-reifiable-varar) correctly, seems to accept `@SafeVarargs` with `@SuppressWarnings("varargs")`.
* `@SuppressWarnings("unchecked")` seems rather broad; isn't that older approach, before `@SafeVarargs` was introduced (if my memory serves me)?
In short, I just want a way to prevent the Java 17 `javac` varargs warnings on a case-by-case basis in a way that is compatible not only with `javac` with linting, but also with other IDEs such as IntelliJ. If `@SuppressWarnings("unchecked")` is the appropriate annotation to use, then close this ticket as invalid. But from the references I've mentioned, along with the JDK's own usage, it would seem that a combination of `@SuppressWarnings("varargs")` for the signature and `@SuppressWarnings("varargs")` for the implementation are the latest and most appropriate annotations here.
Contributor guide
Assessment
This issue has not been assessed yet.