1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Infer.java Fri Apr 18 23:50:41 2014 +0100 1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java Fri Apr 18 23:58:05 2014 +0100 1.3 @@ -516,6 +516,32 @@ 1.4 /** max number of incorporation rounds */ 1.5 static final int MAX_INCORPORATION_STEPS = 100; 1.6 1.7 + /* If for two types t and s there is a least upper bound that is a 1.8 + * parameterized type G, then there exists a supertype of 't' of the form 1.9 + * G<T1, ..., Tn> and a supertype of 's' of the form G<S1, ..., Sn> 1.10 + * which will be returned by this method. If no such supertypes exists then 1.11 + * null is returned. 1.12 + * 1.13 + * As an example for the following input: 1.14 + * 1.15 + * t = java.util.ArrayList<java.lang.String> 1.16 + * s = java.util.List<T> 1.17 + * 1.18 + * we get this ouput: 1.19 + * 1.20 + * Pair[java.util.List<java.lang.String>,java.util.List<T>] 1.21 + */ 1.22 + private Pair<Type, Type> getParameterizedSupers(Type t, Type s) { 1.23 + Type lubResult = types.lub(t, s); 1.24 + if (lubResult == syms.errType || lubResult == syms.botType || 1.25 + !lubResult.isParameterized()) { 1.26 + return null; 1.27 + } 1.28 + Type asSuperOfT = types.asSuper(t, lubResult.tsym); 1.29 + Type asSuperOfS = types.asSuper(s, lubResult.tsym); 1.30 + return new Pair<>(asSuperOfT, asSuperOfS); 1.31 + } 1.32 + 1.33 /** 1.34 * This enumeration defines an entry point for doing inference variable 1.35 * bound incorporation - it can be used to inject custom incorporation 1.36 @@ -651,6 +677,53 @@ 1.37 } 1.38 }, 1.39 /** 1.40 + * Given a bound set containing {@code alpha <: P<T>} and 1.41 + * {@code alpha <: P<S>} where P is a parameterized type, 1.42 + * perform {@code T = S} (which could lead to new bounds). 1.43 + */ 1.44 + CROSS_UPPER_UPPER() { 1.45 + @Override 1.46 + public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { 1.47 + Infer infer = inferenceContext.infer(); 1.48 + List<Type> boundList = uv.getBounds(InferenceBound.UPPER); 1.49 + List<Type> boundListTail = boundList.tail; 1.50 + while (boundList.nonEmpty()) { 1.51 + List<Type> tmpTail = boundListTail; 1.52 + while (tmpTail.nonEmpty()) { 1.53 + Type b1 = boundList.head; 1.54 + Type b2 = tmpTail.head; 1.55 + if (b1 != b2) { 1.56 + Pair<Type, Type> commonSupers = infer.getParameterizedSupers(b1, b2); 1.57 + if (commonSupers != null) { 1.58 + List<Type> allParamsSuperBound1 = commonSupers.fst.allparams(); 1.59 + List<Type> allParamsSuperBound2 = commonSupers.snd.allparams(); 1.60 + while (allParamsSuperBound1.nonEmpty() && allParamsSuperBound2.nonEmpty()) { 1.61 + //traverse the list of all params comparing them 1.62 + if (!allParamsSuperBound1.head.hasTag(WILDCARD) && 1.63 + !allParamsSuperBound2.head.hasTag(WILDCARD)) { 1.64 + isSameType(inferenceContext.asUndetVar(allParamsSuperBound1.head), 1.65 + inferenceContext.asUndetVar(allParamsSuperBound2.head), infer); 1.66 + } 1.67 + allParamsSuperBound1 = allParamsSuperBound1.tail; 1.68 + allParamsSuperBound2 = allParamsSuperBound2.tail; 1.69 + } 1.70 + Assert.check(allParamsSuperBound1.isEmpty() && allParamsSuperBound2.isEmpty()); 1.71 + } 1.72 + } 1.73 + tmpTail = tmpTail.tail; 1.74 + } 1.75 + boundList = boundList.tail; 1.76 + boundListTail = boundList.tail; 1.77 + } 1.78 + } 1.79 + 1.80 + @Override 1.81 + boolean accepts(UndetVar uv, InferenceContext inferenceContext) { 1.82 + return !uv.isCaptured() && 1.83 + uv.getBounds(InferenceBound.UPPER).nonEmpty(); 1.84 + } 1.85 + }, 1.86 + /** 1.87 * Given a bound set containing {@code alpha == S} and {@code alpha == T} 1.88 * perform {@code S == T} (which could lead to new bounds). 1.89 */