Skip to content

Different behaviour between ECJ and javac for generic type inference#4990

Closed
snjeza wants to merge 1 commit into
eclipse-jdt:masterfrom
snjeza:issue-3351
Closed

Different behaviour between ECJ and javac for generic type inference#4990
snjeza wants to merge 1 commit into
eclipse-jdt:masterfrom
snjeza:issue-3351

Conversation

@snjeza

@snjeza snjeza commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

Fixes #3351
Related to #4838 (comment)

I have created a simpler class to reproduce the issue.

import java.util.List;
import java.util.Collections;
public class Test {
    static <E extends Comparable<E>> List<E> sort(List<E> list) {
        return list;
    }
    public static void main(String[] args) {
        sort(Collections.emptyList());
        System.out.println("hello");
    }
}

The IDEA editor also doesn’t report any error in these cases.
If the class is tried to be run, IDEA will report an error when the javac compiler is used.

The InferenceContext18.resolve() method will add the V = java.lang.Object bound if it cannot resolve some inference variable.
The PR tries to postpone or skip this decision unless there is a bound that:

  • isn’t a variable bound
  • doesn’t include raw types
  • doesn’t include a lambda expression

@stephan-herrmann

Copy link
Copy Markdown
Contributor

Some background analysis:

Adding a same-bound Object as fallback has been introduced for https://bugs.eclipse.org/bugs/show_bug.cgi?id=426652

In that bug the fallback was added to prevent that inference would get stuck, i.e., simply not make any progress for an ivar without suitable upper nor lower bounds.

OTOH, not having any bound in some cases seems to be a bug introduced in 550a751 (no bugzilla reference). @srikanth-sankaran fyi.

But the test case discussed here would not benefit from resolving the above wrinkles.


When I look the simplicity of the spec implemented here:

a candidate instantiation Ti is defined for each αi:

  • [...]
  • Otherwise, where αi has proper upper bounds U1, ..., Uk, Ti = glb(U1, ..., Uk) (§5.1.10).

... and compare this with the complexity of the proposed fix, I'm afraid we might be looking in the wrong place.

@stephan-herrmann

Copy link
Copy Markdown
Contributor

I just tried this example against work in progress in #5004 and this is what I get

1. ERROR in /tmp/Test.java (at line 8)
        sort(Collections.emptyList());
        ^^^^
The method sort(java.util.List<E extends java.lang.Comparable<E>>) in the type Test is not applicable for the arguments (java.util.List<E extends java.lang.Comparable<E>>)

Given that this matches to what javac answers, perhaps we don't need a specific fix for this test case :)
I will retest when #5004 is nearing completion.

@stephan-herrmann

Copy link
Copy Markdown
Contributor

I just tried this example against work in progress in #5004 and this is what I get

1. ERROR in /tmp/Test.java (at line 8)
        sort(Collections.emptyList());
        ^^^^
The method sort(java.util.List<E extends java.lang.Comparable<E>>) in the type Test is not applicable for the arguments (java.util.List<E extends java.lang.Comparable<E>>)

Given that this matches to what javac answers, perhaps we don't need a specific fix for this test case :) I will retest when #5004 is nearing completion.

Same result with #5129 (with plans to improve the error message via #5078 ).

With this we are done.

Thanks anyway, @snjeza for your efforts.

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.

Different behaviour between ECJ and javac for generic type inference

2 participants