JDK-8033718 : Inference ignores capture variable as upper bound
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 7u45,8
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2014-02-05
  • Updated: 2016-12-07
  • Resolved: 2014-05-06
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 8 JDK 9
8u20Fixed 9 b13Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
This produces an unexpected error:

  class C<T> {}
  <X> void m(C<? super X> arg) {}
  void test(C<?> arg) {
    m(arg);
  }

error: method m in class cannot be applied to given types;
    m(arg);
    ^
  required: C<? super X>
  found: C<CAP#1>
  reason: cannot infer type-variable(s) X
    (argument mismatch; C<CAP#1> cannot be converted to C<? super X>)
  where X is a type-variable:
    X extends Object declared in method <X>m(C<? super X>)
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Object from capture of ?
1 error

The error is the same under both -source 8 and -source 7.

This is a regression: there is also an error in javac 7, but not javac 6.
Comments
As a result of 8044546, this started to occur more since JDK 9 b22.
12-01-2015

For any outstanding issues in this space, please see JDK-8039214.
12-01-2015

Solution: Refactored Types.lowerBound into two distinct operations, Types.wildLowerBound and Types.cvarLowerBound. It should never be necessary to apply both of these, since operations on wildcards and type variables should be occurring in different contexts. After this refactoring, Types.containsType can get wildcard lower bounds without touching capture variables. This allows capture variables to flow into subtyping and inference, which revealed a few other bugs, which I fixed as part of the patch.
07-05-2014

I'm spinning off the upper-bound case (see previous comment) into a separate bug, JDK-8039214. A couple of reasons for this: - It's not a regression, so isn't as high priority and has a higher risk of breaking code. - The fix breaks existing code in jax-ws (JDK-8039210).
03-04-2014

Related test, with a bound in the opposite direction: interface I<X1,X2> {} class C<T> implements I<T,T> {} <X> void m(I<? extends X, X> arg) {} void test(C<?> arg) { m(arg); } This one fails in 6, 7, and 8.
21-03-2014

Priority justification: Impact: high, regression Likelhood: low, corner case that hasn't been reported Workaround: medium, can use a raw type, but that's hard to understand ILW = HLM => P3
10-03-2014

Release team: Approved for deferral.
11-02-2014

8-defer justification: not a new problem, not a common use case.
07-02-2014