JDK-6640435 : inference: propagate >> and == constraints to help uninferred type vars
  • Type: Enhancement
  • Component: specification
  • Sub-Component: language
  • Affected Version: 7
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2007-12-11
  • Updated: 2014-08-01
  • Resolved: 2011-07-21
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 rcFixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
JLS 15.12.2.7 generates but does not use supertype constraints of the form S>>T. Such a constraint arises if a formal parameter uses '? super T'. If T is not inferred by 15.12.2.7, then 15.12.2.8 takes over and (in many cases) generates Object>>T. This is not wrong, but is imprecise. There is no reason why the JLS shouldn't propagate the >> constraints from 15.12.2.7 to 15.12.2.8. Also, as per 6650759, it is desirable to propagate == constraints. 15.12.2.8 could say:

"Then, a set of initial constraints consisting of:
- the constraint S >> R'...
- additional constraints Bi[T1=B(T1)..Tn=B(Tn)] >> Ti, where ...
***- for any constraint of the form V >> Ti generated in 15.12.2.7: a constraint V[T1=B(T1)..Tn=B(Tn)] >> Ti***
***- for any constraint of the form Ti == V generated in 15.12.2.7: a constraint Ti == V[T1=B(T1)..Tn=B(Tn)]***"

Comments
EVALUATION Maurizio found that propagating constraints might require an additional check after inference is applied: -- import java.util.*; class TestInference { <Z> List<? super Z> m(List<? extends List<? super Z>> ls) { return ls.get(0); } void test() { ArrayList<ArrayList<Integer>> lli = new ArrayList<ArrayList<Integer>>(); ArrayList<Integer> li = new ArrayList<Integer>(); li.add(2); lli.add(li); List<? super String> ls = m(lli); //here ls.add("crash"); Integer i = li.get(1); } } when m() is called, a constraint of the kind Integer >> Z is derived from actuals. Such constraint is useless in the first step of type-inference; so we should apply inference looking at the return type of the method. This lead to the following constraint: Z >> String This constraint is also useless for return type inference. However, if we have propagation, we could exploit the above constraint and infer Z = glb(Integer) = Integer Basically we end up in inferring a type (Integer) that makes the selected method unapplicable, but this kind of error cannot be detected alone by the sanity checkings described in JLS 15.12.2.2 (actuals <: formals). 12.2.2.5 should be accomodate in order to mandate that the inferred return type of the selected method is assignable to the LHS type. In this case such a test would be: List<? super Integer> <: List<? super String> that is clearly wrong. -- The underlying question is what to do with an inconsistent set of constraints. During return type inference, Integer>>Z and Z>>String are clearly inconsistent - just taking the transitive closure of all constraints will reveal that. The proposed 12.2.2.5 check is essentially a deferred version of that closure. (The necessary invariant is: After substitution, if the actuals <: the formals and the actual return type <: the expected method type, then the set of inferred type vars is somehow self-consistent. Whether we can prove that is another matter. I foresee principal typings in our future.)
28-05-2008

EVALUATION Yes. This increases the quality of inference and expands the space of compilable programs.
11-12-2007