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 §18.5.2.1:
"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,
Bernard
[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