Possible compiler bug? Code compiles on 8 but not 11

B. Blaser bsrbnd at gmail.com
Fri Feb 7 20:22:50 UTC 2020

Alex, David,

Here is a simpler reproducer:

public class Factory {
    public Factory() {
        String ok = gen(StringGenerator.class);
//        @SuppressWarnings("unchecked")
        String ko = gen(Generator.class);

    public <T, F extends SimpleGenerator<T>> T gen(Class<F> c) { return null; }

class StringGenerator extends SimpleGenerator<String> {}
class Generator<T> extends SimpleGenerator<T> {}

$ javac -Xlint:unchecked Factory.java
Factory.java:5: warning: [unchecked] unchecked method invocation:
method gen in class Factory is applied to given types
        String ko = gen(Generator.class);
  required: Class<F>
  found: Class<Generator>
  where F,T are type-variables:
    F extends SimpleGenerator<T> declared in method <T,F>gen(Class<F>)
    T extends Object declared in method <T,F>gen(Class<F>)
Factory.java:5: error: incompatible types: Object cannot be converted to String
        String ko = gen(Generator.class);
1 error
1 warning

JLS §15.8.2 states:

"The type of C.class, where C is the name of a class, interface, or
array type (§4.3), is Class<C>"

which means that the found type 'Class<Generator>' triggers the
following rule from §18.2.2:

"A constraint formula of the form ‹ S → T › is reduced as follows:
• Otherwise, if T is a parameterized type of the form G<T 1 , ..., T n
> , and there exists no type of the form G< ... > that is a supertype
of S , but the raw type G is a supertype of S , then the constraint
reduces to true.
The fourth and fifth cases are implicit uses of unchecked conversion (§5.1.9)."

implying then §

"If unchecked conversion was necessary for the method to be applicable
during constraint set reduction in §18.5.1, the constraint formula ‹|
R | → T › is reduced and incorporated with B 2 ."

meaning that erasing the return type of 'gen()' to 'Object' looks, at
first sight, correct. I'm not exactly sure what could have changed
between 8 and 11, but we've still made a small fix in this area some
years ago [1], as far as I can remember.

Any feedback is welcome,

[1] http://hg.openjdk.java.net/jdk/jdk/rev/39446351e625

On Fri, 31 Jan 2020 at 20:00, Alex Buckley <alex.buckley at oracle.com> wrote:
> Hi David,
> This is a question of whether javac is conforming to the JLS, and if so,
> whether the JLS is correct. It's best in such cases to quote the
> smallest possible code sample in inline text. Oracle's javac team is not
> looking to reproduce issues in the manner of a support organization, but
> rather to understand as precisely as possible what's going on in the
> type system.
> Alex
> On 1/31/2020 10:36 AM, David Grieve wrote:
> > I have some code that compiles on 8 but not on 11. With 11 (11.0.5, to be exact), the compiler gives an error:
> >
> >> Factory.java
> >> Error:(9, 25) java: incompatible types: java.lang.Object cannot be converted to Manager<java.lang.String>
> >
> > This can be fixed with an explicit cast. But it seems to me that the cast should not be needed.
> >
> > I'm hoping to get an answer for why this compiles cleanly on 8, but not 11.
> >
> > I have uploaded a small sample that reproduces to http://cr.openjdk.java.net/~dgrieve/javac-bug.zip
> >

More information about the compiler-dev mailing list