JDK-5052943 : 4.10.4: Improve lub for lower-bounded wildcards and variables
  • Type: Enhancement
  • Component: specification
  • Sub-Component: language
  • Affected Version: 5.0,7,8
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: generic
  • CPU: generic
  • Submitted: 2004-05-26
  • Updated: 2024-04-12
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
tbdUnresolved
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
In:

  static <T> T choose(boolean b, T trueValue, T falseValue) {
    return b ? trueValue : falseValue;
  }
  boolean b = false;
  List<? super Number> s = null;
  s = b ? s : s;
  s = choose(b, s, s);

Inference can't handle lower/super bounded wildcards leading to errors like:

Choose.java:10: incompatible types
found   : java.util.List<capture of ? extends java.lang.Object>
required: java.util.List<? super java.lang.Number>
        s = b ? s : s;
              ^
Choose.java:11: incompatible types
found   : java.util.List<capture of ? extends java.lang.Object>
required: java.util.List<? super java.lang.Number>
        s = choose(b, s, s);
                  ^

See the attached file Choose.java

###@###.### 2004-05-25

Comments
Clarification: the case in question is _not_ lub(Foo<? super Bar>, Foo<? super Bar>). Due to capture of variable reference expression types, the case is lub(Foo<CAP1>, Foo<CAP2>), where both CAP1 and CAP2 are lower-bounded by Bar.
08-10-2014

Some care should be taken to special-case unbounded wildcards in lcta (current behavior seems to be undefined!). If JDK-6480391 is applied, these special-case rules would also apply to "? extends Object".
02-07-2013

This is a particularly egregious case ("lub(Foo<? super Bar>, Foo<? super Bar>)" becoming "Foo<? extends Object>"), but, more generally, lub (specifically lcta) should produce "? super" wildcards whenever it is reasonable to do so. The hardest case is when there is a non-trivial upper _and_ lower bound. In this case, the language (specifically the wildcard grammar) could be extended to support both bounds ("? extends Foo super Bar"), or we could stick with the current behavior of arbitrarily choosing the upper bound and discarding the lower bound.
02-07-2013

EVALUATION .
02-11-2010

EVALUATION An upgrade to lcta to better calculate the join of type arguments would be desirable.
29-10-2010

EVALUATION After some investigation I think this is a JLS problem. Here's a reduced test case (omit ternary for now): class Test { <T> T choose(T t1, T t2) { return null; } void test(List<? super Number> s) { s = choose(s, s); } } The types of the actual arguments applied to the 'choose' method are two (not one): List<#1> and List<#2>, respectively, where both Object <: #1,#2 <: Number. This means that, T == lub(List<#1>, List<#2>), hence we need to look at the function lcta (see JLS 3rd 15.12.2.7) in order to merge the two type-parameters - here are the relevant lines: lcta(U,V) = U if U == V, ? extends lub(U,V) otherwise. This means that lcta(#1,#2) = ? extends lub(#1, #2) = ? extends Object, since Object is the only common supertype between #1 and #2. In other words, javac is behaving according to the JLS. To demonstrate this, let's rewrite the example as follows: class Test { <T> T choose(T t1) { return null; } //one argument removed!!! void test(List<? super Number> s) { s = choose(s); // Note only one actual argument to choose() now } } This now works, because lcta is not needed anymore (only one constraint).
12-10-2010

EVALUATION .
28-11-2006