JDK-6862608 : rich diagnostic sometimes contain wrong type variable numbering
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 7
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: unknown
  • Submitted: 2009-07-21
  • Updated: 2012-01-13
  • Resolved: 2012-01-13
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.
JDK 7
7 b70Fixed
Related Reports
Relates :  
Description
Compiling the following program:

import java.util.*;

class Test {

    <T> Comparator<T> compound(Iterable<? extends Comparator<? super T>> it) {}

    public void test(List<Comparator<?>> x) {
        Comparator<String> c3 = compound(x);
    }
}

leads to the following compiler error message:

TestX.java:9: invalid inferred types for T#1; actual arguments do not conforms to inferred formal arguments
        Comparator<String> c3 = compound(x);
                                        ^
    required: Iterable<? extends Comparator<? super String>>
    found: List<Comparator<?>>
  where T#1,T#2 are type-variables:
    T#1 extends Object declared in method <T#2>compound(Iterable<? extends Comparator<? super T#2>>)
    T#2 extends Object declared in method <T#2>compound(Iterable<? extends Comparator<? super T#2>>)
1 error

The error message should be:

TestX.java:9: invalid inferred types for T; actual arguments do not conforms to inferred formal arguments
        Comparator<String> c3 = compound(x);
                                        ^
    required: Iterable<? extends Comparator<? super String>>
    found: List<Comparator<?>>
  where T is a type-variable:
    T extends Object declared in method <T>compound(Iterable<? extends Comparator<? super T>>)
Moreover, when compiling the following example:

class Foo<T extends String, S> {
   <S, T extends S> void foo(T t) {
      test(t);
   }

   void test(T t) {}
}

The output is:

TestX.java:3: method test in class Foo<T#1,S#4> cannot be applied to given types
      test(t);
      ^
  required: T#1
  found: T#2
  where T#1,T#2,S#3,S#4 are type-variables:
    T#1 extends String declared in class Foo
    T#2 extends S#3 declared in method <S#3,T#2>foo(T#2)
    S#3 extends Object declared in method <S#3,T#2>foo(T#2)
    S#4 extends Object declared in class Foo
1 error

When it should have been:

TestX.java:3: method test in class Foo<T#1,S#4> cannot be applied to given types
  test(t);
      ^
  required: T#1
  found: T#2
  where T#1,T#2,S#1,S#2 are type-variables:
    T#1 extends String declared in class Foo
    T#2 extends S#1 declared in method <S#1,T#2>foo(T#2)
    S#1 extends Object declared in method <S#1,T#2>foo(T#2)
    S#2 extends Object declared in class Foo
1 error

[note the wrong numbering of type-variables in the where clause!]

Comments
SUGGESTED FIX A webrev of this fix is available at the following URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/b1e027181dd4
30-07-2009

EVALUATION This first problem is caused by the fact that the Rich formatter used type variables types (instead of symbols) in order to keep track of all the type-variables that are accessed inside a given diagnostic. This lead to errors in situation where (like in this case) one or more substitutions have been performed on a set of type variables; despite the new type variables share the same type symbol with the old ones, a new type is created for them, which makes the type-var conflict resolution scheme implemented by the formatter to fail. The second problem is caused by a flaw in the logic exploited by the rich formatter in order to retrieve the index of a given type-variable. If a conflict is detected, the formatter looks scans all the where clauses regarding type-variables, and sets the type-variable index to be the index of the required where clause inside such list. However, if other type variable (with conflicts) are present, it is possible for the formatter to yield the wrong number. When scanning the list of where clauses involving type-variables, the formatter should filter this list by type-variable name in order to exclude references to non-conflicting type-variables from the numbering,
21-07-2009