JDK-8081318 : Diamond inference fails to infer capture variable parameterization
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 9
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2015-05-27
  • Updated: 2018-06-09
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbd_minorUnresolved
Related Reports
Blocks :  
Relates :  
Relates :  
Description
let's consider following example:

    class Par<U> {
        U f;
    }

    class Cls<T> {
        Cls(T t) {}
    }

    public class Test70  {
        public static void test() {
            Par<?> a = new Par<>();
            new Cls<>(a.f) { };
        }
    }

JDK9b60 compiles it successfully however according to my understanding compilation should have failed because:

1. The type of 'a' local variable is a parameterized type Par<?>.
2. According to following assertion from JLS 4.5.2 the type of the field "f" of Par<?> is a fresh capture variable: null-type <: CAP <: Object:

    If any of the type arguments in the parameterization of C are wildcards, then: 

        The types of the fields, methods, and constructors in C<T1,...,Tn> are the types of the fields, methods, and constructors in the capture conversion of C<T1,...,Tn> (��5.1.10).

3. 'new Cls<>(a.f) { }' causes T to be inferred as capture variable CAP presented in step 2.
4. According to following new assertion presented in JDK-8073593 issue comment compilation error should occur because superclass of the anonymous class is inferred as a type parameterized by type variable that was not declared as a type parameter (the capture variable CAP).

    ***It is a compile-time error if the superclass or superinterface type of the anonymous class, T, or any subexpression of T, has one of the following forms:
    - A type variable (4.4) that was not declared as a type parameter (such as a type variable produced by capture conversion (5.1.10))
    - An intersection type (4.9)
    - A class or interface type, where the class or interface declaration is not accessible from the class or interface in which the expression appears.***
    The term "subexpression" includes type arguments of parameterized types (4.5), bounds of wildcards (4.5.1), and element types of array types (10.1). It excludes bounds of type variables.*** 
Comments
The current behavior is a side-effect of how javac copes with wildcards with wildcard-parameterized upper bounds (per Maurizio's comment above and JDK-6391995). To get rid of the current coping mechanism, we have to first address JDK-7034922.
10-12-2015

This is related to a long standing javac behavior, described in the following comment: /** * javac has a long-standing 'simplification' (see 6391995): * given an actual argument type, the method check is performed * on its upper bound. This leads to inconsistencies when an * argument type is checked against itself. For example, given * a type-variable T, it is not true that {@code U(T) <: T}, * so we need to guard against that. */ See also JDK-6391995
27-05-2015