JDK-8151503 : Compiler fails to infer generic type
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8,8u74
  • Priority: P3
  • Status: Closed
  • Resolution: Won't Fix
  • CPU: x86
  • Submitted: 2016-03-08
  • Updated: 2019-08-02
  • Resolved: 2016-03-10
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_74"
Java(TM) SE Runtime Environment (build 1.8.0_74-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Windows 10,
Fedora 22,


A DESCRIPTION OF THE PROBLEM :
When using JDK8 and using -source 1.8 -target 1.8 compiling of code provided  below fails to compile with error
"incompatible types: java.lang.Object cannot be converted to T"

If we use -source 1.7 -target 1.7 JDK8 javac compiles the code without problems.

Same code compiles on JDK7

If we use JDK9-ea+107, it also compiles without problems no mater what -source/-target we use.

Simple reproducer can also be found at https://github.com/ctomc/jdk8-compiler

REGRESSION.  Last worked in version 7u76

ADDITIONAL REGRESSION INFORMATION: 
java version "1.7.0_72"
Java(TM) SE Runtime Environment (build 1.7.0_72-b14)
Java HotSpot(TM) Client VM (build 24.72-b04, mixed mode, sharing)

It also compiles correctly when using JDK9-ea (both jigsaw and normal builds)
java version "9-ea"
Java(TM) SE Runtime Environment (build 9-ea+107-jigsaw-nightly-h4560-20160301)
Java HotSpot(TM) 64-Bit Server VM (build 9-ea+107-jigsaw-nightly-h4560-20160301, mixed mode)

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Use JDK8 with -source 1.8 -target 1.8 and try to compile



EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
compile successes 
ACTUAL -
compile fails

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Option.java:[12,37] incompatible types: java.lang.Object cannot be converted to T

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class Option {
    interface ValueParser<T> {
        T parseValue(String string, ClassLoader classLoader) throws IllegalArgumentException;
    }

    static <T> Option.ValueParser<T> getEnumParser(final Class<T> enumType) {
        return new ValueParser<T>() {
            public T parseValue(final String string, final ClassLoader classLoader) throws IllegalArgumentException {
                return enumType.cast(Enum.valueOf(enumType.asSubclass(Enum.class), string.trim()));
            }
        };
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Rearrange code and manually cast.

  static <T, E extends Enum<E>> Option.ValueParser<T> getEnumParser(final Class<T> enumType) {
        return new ValueParser<T>() {
            public T parseValue(final String string, final ClassLoader classLoader) throws IllegalArgumentException {
                return enumType.cast(Enum.<E>valueOf(asEnum(enumType), string.trim()));
            }
        };
    }

    @SuppressWarnings("unchecked")
    private static <T, E extends Enum<E>> Class<E> asEnum(final Class<T> enumType) {
        return (Class<E>) enumType;
    }


Comments
In JDK 1.8.0, it is a regression from build 66 onwards, It is working correctly up to build 65. In JDK 9, up to the build 102, this issue was there. It is fixed in build 103 onwards.
11-03-2016

This will be fixed in JDK 9.
10-03-2016