eclipse-jdt / eclipse-jdt/eclipse.jdt.core

ECJ accepts `==` comparison between `Class<? extends Set<?>>` and `Class<SequencedSet>` that javac rejects

Open
#4,729 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
237
Forks
195
Avg merge
1d 12h
Merged PRs (30d)
47

Description

I ran into an issue where JDK 25 is finding an error but Eclipse is not. I had an LLM generate the following description and test case.

### Summary

ECJ compiles code that uses `==` to compare `Class>` with `Class`, but javac rejects it with "incomparable types". ECJ should reject this code to maintain consistency with javac.

### Environment

- Eclipse Version: EE 2025-12 (4.38.0)
- Java Version: openjdk 25 2025-09-16 LTS
- OS: Windows

```
openjdk 25 2025-09-16 LTS
OpenJDK Runtime Environment Temurin-25+36 (build 25+36-LTS)
OpenJDK 64-Bit Server VM Temurin-25+36 (build 25+36-LTS, mixed mode, sharing)
```

### Steps to Reproduce

1. Create the following Java file:

```java
import java.util.Set;
import java.util.SequencedSet;

public class WildcardClassComparison {

static Class> getSetClass() {
return Set.class;
}

public static void main(String[] args) {
boolean isSequenced = getSetClass() == SequencedSet.class;
System.out.println("isSequenced: " + isSequenced);
}
}
```

2. Open in Eclipse—no compilation error is shown
3. Compile with javac: `javac WildcardClassComparison.java`

### Expected Behavior

ECJ should report a compilation error consistent with javac:

```
error: incomparable types: Class> and Class
boolean isSequenced = getSetClass() == SequencedSet.class;
^
```

### Actual Behavior

ECJ accepts the code without error.

### Analysis

The `==` operator requires operands to be comparable types. javac determines that `Class>` (with its nested wildcard and capture) is not comparable to `Class` because the capture represents an unknown subtype that cannot be proven to have a subtype/supertype relationship with `SequencedSet` at compile time.

The workaround is to assign to a `Class` variable first:

```java
Class rawClass = getSetClass();
boolean isSequenced = rawClass == SequencedSet.class; // compiles in both
```

### Additional Notes

The same issue occurs with `Map`:

```java
static Class> getMapClass() {
return java.util.Map.class;
}

// ECJ accepts, javac rejects:
boolean isSequenced = getMapClass() == java.util.SequencedMap.class;
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.