150 return visit(t.bound); |
150 return visit(t.bound); |
151 } |
151 } |
152 }; |
152 }; |
153 // </editor-fold> |
153 // </editor-fold> |
154 |
154 |
155 // <editor-fold defaultstate="collapsed" desc="lowerBound"> |
155 // <editor-fold defaultstate="collapsed" desc="wildLowerBound"> |
156 /** |
156 /** |
157 * The "lvalue conversion".<br> |
157 * Get a wildcard's lower bound, returning non-wildcards unchanged. |
158 * The lower bound of most types is the type |
158 * @param t a type argument, either a wildcard or a type |
159 * itself. Wildcards, on the other hand have upper |
159 */ |
160 * and lower bounds. |
160 public Type wildLowerBound(Type t) { |
|
161 if (t.hasTag(WILDCARD)) { |
|
162 WildcardType w = (WildcardType) t; |
|
163 return w.isExtendsBound() ? syms.botType : wildLowerBound(w.type); |
|
164 } |
|
165 else return t; |
|
166 } |
|
167 // </editor-fold> |
|
168 |
|
169 // <editor-fold defaultstate="collapsed" desc="cvarLowerBound"> |
|
170 /** |
|
171 * Get a capture variable's lower bound, returning other types unchanged. |
161 * @param t a type |
172 * @param t a type |
162 * @return the lower bound of the given type |
173 */ |
163 */ |
174 public Type cvarLowerBound(Type t) { |
164 public Type lowerBound(Type t) { |
175 if (t.hasTag(TYPEVAR) && ((TypeVar) t).isCaptured()) { |
165 return lowerBound.visit(t); |
176 return cvarLowerBound(t.getLowerBound()); |
166 } |
177 } |
167 // where |
178 else return t; |
168 private final MapVisitor<Void> lowerBound = new MapVisitor<Void>() { |
179 } |
169 |
|
170 @Override |
|
171 public Type visitWildcardType(WildcardType t, Void ignored) { |
|
172 return t.isExtendsBound() ? syms.botType : visit(t.type); |
|
173 } |
|
174 |
|
175 @Override |
|
176 public Type visitCapturedType(CapturedType t, Void ignored) { |
|
177 return visit(t.getLowerBound()); |
|
178 } |
|
179 }; |
|
180 // </editor-fold> |
180 // </editor-fold> |
181 |
181 |
182 // <editor-fold defaultstate="collapsed" desc="isUnbounded"> |
182 // <editor-fold defaultstate="collapsed" desc="isUnbounded"> |
183 /** |
183 /** |
184 * Checks that all the arguments to a class are unbounded |
184 * Checks that all the arguments to a class are unbounded |
826 return false; |
826 return false; |
827 } |
827 } |
828 return true; |
828 return true; |
829 } |
829 } |
830 |
830 |
831 Type lower = lowerBound(s); |
831 // Generally, if 's' is a type variable, recur on lower bound; but |
832 if (s != lower) |
832 // for alpha <: CAP, alpha should get upper bound CAP |
833 return isSubtype(capture ? capture(t) : t, lower, false); |
833 if (!t.hasTag(UNDETVAR)) { |
|
834 // TODO: JDK-8039198, bounds checking sometimes passes in a wildcard as s |
|
835 Type lower = cvarLowerBound(wildLowerBound(s)); |
|
836 if (s != lower) |
|
837 return isSubtype(capture ? capture(t) : t, lower, false); |
|
838 } |
834 |
839 |
835 return isSubtype.visit(capture ? capture(t) : t, s); |
840 return isSubtype.visit(capture ? capture(t) : t, s); |
836 } |
841 } |
837 // where |
842 // where |
838 private TypeRelation isSubtype = new TypeRelation() |
843 private TypeRelation isSubtype = new TypeRelation() |
1135 |
1140 |
1136 if (s.isPartial()) |
1141 if (s.isPartial()) |
1137 return visit(s, t); |
1142 return visit(s, t); |
1138 |
1143 |
1139 if (s.isSuperBound() && !s.isExtendsBound()) |
1144 if (s.isSuperBound() && !s.isExtendsBound()) |
1140 return visit(t, upperBound(s)) && visit(t, lowerBound(s)); |
1145 return visit(t, upperBound(s)) && visit(t, wildLowerBound(s)); |
1141 |
1146 |
1142 if (t.isCompound() && s.isCompound()) { |
1147 if (t.isCompound() && s.isCompound()) { |
1143 if (!visit(supertype(t), supertype(s))) |
1148 if (!visit(supertype(t), supertype(s))) |
1144 return false; |
1149 return false; |
1145 |
1150 |
1290 Type bound = upperBound(s); |
1295 Type bound = upperBound(s); |
1291 undetvar.addBound(InferenceBound.UPPER, bound, this); |
1296 undetvar.addBound(InferenceBound.UPPER, bound, this); |
1292 break; |
1297 break; |
1293 } |
1298 } |
1294 case SUPER: { |
1299 case SUPER: { |
1295 Type bound = lowerBound(s); |
1300 Type bound = wildLowerBound(s); |
1296 undetvar.addBound(InferenceBound.LOWER, bound, this); |
1301 undetvar.addBound(InferenceBound.LOWER, bound, this); |
1297 break; |
1302 break; |
1298 } |
1303 } |
1299 } |
1304 } |
1300 return true; |
1305 return true; |
1383 // System.err.format(" %s U(%s) <: U(%s) %s = %s%n", |
1388 // System.err.format(" %s U(%s) <: U(%s) %s = %s%n", |
1384 // upperBound(s), s, t, U(t), |
1389 // upperBound(s), s, t, U(t), |
1385 // t.isSuperBound() |
1390 // t.isSuperBound() |
1386 // || isSubtypeNoCapture(upperBound(s), U(t))); |
1391 // || isSubtypeNoCapture(upperBound(s), U(t))); |
1387 // System.err.format(" %s L(%s) <: L(%s) %s = %s%n", |
1392 // System.err.format(" %s L(%s) <: L(%s) %s = %s%n", |
1388 // L(t), t, s, lowerBound(s), |
1393 // L(t), t, s, wildLowerBound(s), |
1389 // t.isExtendsBound() |
1394 // t.isExtendsBound() |
1390 // || isSubtypeNoCapture(L(t), lowerBound(s))); |
1395 // || isSubtypeNoCapture(L(t), wildLowerBound(s))); |
1391 // System.err.println(); |
1396 // System.err.println(); |
1392 // } |
1397 // } |
1393 |
1398 |
1394 @Override |
1399 @Override |
1395 public Boolean visitWildcardType(WildcardType t, Type s) { |
1400 public Boolean visitWildcardType(WildcardType t, Type s) { |
1397 return containedBy(s, t); |
1402 return containedBy(s, t); |
1398 else { |
1403 else { |
1399 // debugContainsType(t, s); |
1404 // debugContainsType(t, s); |
1400 return isSameWildcard(t, s) |
1405 return isSameWildcard(t, s) |
1401 || isCaptureOf(s, t) |
1406 || isCaptureOf(s, t) |
1402 || ((t.isExtendsBound() || isSubtypeNoCapture(L(t), lowerBound(s))) && |
1407 || ((t.isExtendsBound() || isSubtypeNoCapture(L(t), wildLowerBound(s))) && |
1403 (t.isSuperBound() || isSubtypeNoCapture(upperBound(s), U(t)))); |
1408 (t.isSuperBound() || isSubtypeNoCapture(upperBound(s), U(t)))); |
1404 } |
1409 } |
1405 } |
1410 } |
1406 |
1411 |
1407 @Override |
1412 @Override |
1759 |
1764 |
1760 if (t.isExtendsBound()) { |
1765 if (t.isExtendsBound()) { |
1761 if (s.isExtendsBound()) |
1766 if (s.isExtendsBound()) |
1762 return !isCastableRecursive(t.type, upperBound(s)); |
1767 return !isCastableRecursive(t.type, upperBound(s)); |
1763 else if (s.isSuperBound()) |
1768 else if (s.isSuperBound()) |
1764 return notSoftSubtypeRecursive(lowerBound(s), t.type); |
1769 return notSoftSubtypeRecursive(wildLowerBound(s), t.type); |
1765 } else if (t.isSuperBound()) { |
1770 } else if (t.isSuperBound()) { |
1766 if (s.isExtendsBound()) |
1771 if (s.isExtendsBound()) |
1767 return notSoftSubtypeRecursive(t.type, upperBound(s)); |
1772 return notSoftSubtypeRecursive(t.type, upperBound(s)); |
1768 } |
1773 } |
1769 return false; |
1774 return false; |
1770 } |
1775 } |
1771 }; |
1776 }; |
1772 // </editor-fold> |
1777 // </editor-fold> |
1773 |
1778 |
1774 // <editor-fold defaultstate="collapsed" desc="lowerBoundArgtypes"> |
1779 // <editor-fold defaultstate="collapsed" desc="cvarLowerBounds"> |
1775 /** |
1780 public List<Type> cvarLowerBounds(List<Type> ts) { |
1776 * Returns the lower bounds of the formals of a method. |
1781 return map(ts, cvarLowerBoundMapping); |
1777 */ |
1782 } |
1778 public List<Type> lowerBoundArgtypes(Type t) { |
1783 private final Mapping cvarLowerBoundMapping = new Mapping("cvarLowerBound") { |
1779 return lowerBounds(t.getParameterTypes()); |
|
1780 } |
|
1781 public List<Type> lowerBounds(List<Type> ts) { |
|
1782 return map(ts, lowerBoundMapping); |
|
1783 } |
|
1784 private final Mapping lowerBoundMapping = new Mapping("lowerBound") { |
|
1785 public Type apply(Type t) { |
1784 public Type apply(Type t) { |
1786 return lowerBound(t); |
1785 return cvarLowerBound(t); |
1787 } |
1786 } |
1788 }; |
1787 }; |
1789 // </editor-fold> |
1788 // </editor-fold> |
1790 |
1789 |
1791 // <editor-fold defaultstate="collapsed" desc="notSoftSubtype"> |
1790 // <editor-fold defaultstate="collapsed" desc="notSoftSubtype"> |
2250 } |
2249 } |
2251 // </editor-fold> |
2250 // </editor-fold> |
2252 |
2251 |
2253 // <editor-fold defaultstate="collapsed" desc="makeCompoundType"> |
2252 // <editor-fold defaultstate="collapsed" desc="makeCompoundType"> |
2254 /** |
2253 /** |
2255 * Make a compound type from non-empty list of types |
2254 * Make a compound type from non-empty list of types. The list should be |
|
2255 * ordered according to {@link Symbol#precedes(TypeSymbol,Types)}. |
2256 * |
2256 * |
2257 * @param bounds the types from which the compound type is formed |
2257 * @param bounds the types from which the compound type is formed |
2258 * @param supertype is objectType if all bounds are interfaces, |
2258 * @param supertype is objectType if all bounds are interfaces, |
2259 * null otherwise. |
2259 * null otherwise. |
2260 */ |
2260 */ |
3340 |
3340 |
3341 /** |
3341 /** |
3342 * Insert a type in a closure |
3342 * Insert a type in a closure |
3343 */ |
3343 */ |
3344 public List<Type> insert(List<Type> cl, Type t) { |
3344 public List<Type> insert(List<Type> cl, Type t) { |
3345 if (cl.isEmpty() || t.tsym.precedes(cl.head.tsym, this)) { |
3345 if (cl.isEmpty()) { |
3346 return cl.prepend(t); |
3346 return cl.prepend(t); |
3347 } else if (cl.head.tsym.precedes(t.tsym, this)) { |
3347 } else if (t.tsym == cl.head.tsym) { |
|
3348 return cl; |
|
3349 } else if (t.tsym.precedes(cl.head.tsym, this)) { |
|
3350 return cl.prepend(t); |
|
3351 } else { |
|
3352 // t comes after head, or the two are unrelated |
3348 return insert(cl.tail, t).prepend(cl.head); |
3353 return insert(cl.tail, t).prepend(cl.head); |
3349 } else { |
|
3350 return cl; |
|
3351 } |
3354 } |
3352 } |
3355 } |
3353 |
3356 |
3354 /** |
3357 /** |
3355 * Form the union of two closures |
3358 * Form the union of two closures |
3357 public List<Type> union(List<Type> cl1, List<Type> cl2) { |
3360 public List<Type> union(List<Type> cl1, List<Type> cl2) { |
3358 if (cl1.isEmpty()) { |
3361 if (cl1.isEmpty()) { |
3359 return cl2; |
3362 return cl2; |
3360 } else if (cl2.isEmpty()) { |
3363 } else if (cl2.isEmpty()) { |
3361 return cl1; |
3364 return cl1; |
|
3365 } else if (cl1.head.tsym == cl2.head.tsym) { |
|
3366 return union(cl1.tail, cl2.tail).prepend(cl1.head); |
3362 } else if (cl1.head.tsym.precedes(cl2.head.tsym, this)) { |
3367 } else if (cl1.head.tsym.precedes(cl2.head.tsym, this)) { |
3363 return union(cl1.tail, cl2).prepend(cl1.head); |
3368 return union(cl1.tail, cl2).prepend(cl1.head); |
3364 } else if (cl2.head.tsym.precedes(cl1.head.tsym, this)) { |
3369 } else if (cl2.head.tsym.precedes(cl1.head.tsym, this)) { |
3365 return union(cl1, cl2.tail).prepend(cl2.head); |
3370 return union(cl1, cl2.tail).prepend(cl2.head); |
3366 } else { |
3371 } else { |
3367 return union(cl1.tail, cl2.tail).prepend(cl1.head); |
3372 // unrelated types |
|
3373 return union(cl1.tail, cl2).prepend(cl1.head); |
3368 } |
3374 } |
3369 } |
3375 } |
3370 |
3376 |
3371 /** |
3377 /** |
3372 * Intersect two closures |
3378 * Intersect two closures |
3472 * compoundMin or glb. |
3478 * compoundMin or glb. |
3473 */ |
3479 */ |
3474 private List<Type> closureMin(List<Type> cl) { |
3480 private List<Type> closureMin(List<Type> cl) { |
3475 ListBuffer<Type> classes = new ListBuffer<>(); |
3481 ListBuffer<Type> classes = new ListBuffer<>(); |
3476 ListBuffer<Type> interfaces = new ListBuffer<>(); |
3482 ListBuffer<Type> interfaces = new ListBuffer<>(); |
|
3483 Set<Type> toSkip = new HashSet<>(); |
3477 while (!cl.isEmpty()) { |
3484 while (!cl.isEmpty()) { |
3478 Type current = cl.head; |
3485 Type current = cl.head; |
3479 if (current.isInterface()) |
3486 boolean keep = !toSkip.contains(current); |
3480 interfaces.append(current); |
3487 if (keep && current.hasTag(TYPEVAR)) { |
3481 else |
3488 // skip lower-bounded variables with a subtype in cl.tail |
3482 classes.append(current); |
3489 for (Type t : cl.tail) { |
3483 ListBuffer<Type> candidates = new ListBuffer<>(); |
3490 if (isSubtypeNoCapture(t, current)) { |
3484 for (Type t : cl.tail) { |
3491 keep = false; |
3485 if (!isSubtypeNoCapture(current, t)) |
3492 break; |
3486 candidates.append(t); |
3493 } |
3487 } |
3494 } |
3488 cl = candidates.toList(); |
3495 } |
|
3496 if (keep) { |
|
3497 if (current.isInterface()) |
|
3498 interfaces.append(current); |
|
3499 else |
|
3500 classes.append(current); |
|
3501 for (Type t : cl.tail) { |
|
3502 // skip supertypes of 'current' in cl.tail |
|
3503 if (isSubtypeNoCapture(current, t)) |
|
3504 toSkip.add(t); |
|
3505 } |
|
3506 } |
|
3507 cl = cl.tail; |
3489 } |
3508 } |
3490 return classes.appendList(interfaces).toList(); |
3509 return classes.appendList(interfaces).toList(); |
3491 } |
3510 } |
3492 |
3511 |
3493 /** |
3512 /** |
3643 return t; |
3662 return t; |
3644 else if (isSubtypeNoCapture(s, t)) |
3663 else if (isSubtypeNoCapture(s, t)) |
3645 return s; |
3664 return s; |
3646 |
3665 |
3647 List<Type> closure = union(closure(t), closure(s)); |
3666 List<Type> closure = union(closure(t), closure(s)); |
3648 List<Type> bounds = closureMin(closure); |
3667 return glbFlattened(closure, t); |
|
3668 } |
|
3669 //where |
|
3670 /** |
|
3671 * Perform glb for a list of non-primitive, non-error, non-compound types; |
|
3672 * redundant elements are removed. Bounds should be ordered according to |
|
3673 * {@link Symbol#precedes(TypeSymbol,Types)}. |
|
3674 * |
|
3675 * @param flatBounds List of type to glb |
|
3676 * @param errT Original type to use if the result is an error type |
|
3677 */ |
|
3678 private Type glbFlattened(List<Type> flatBounds, Type errT) { |
|
3679 List<Type> bounds = closureMin(flatBounds); |
3649 |
3680 |
3650 if (bounds.isEmpty()) { // length == 0 |
3681 if (bounds.isEmpty()) { // length == 0 |
3651 return syms.objectType; |
3682 return syms.objectType; |
3652 } else if (bounds.tail.isEmpty()) { // length == 1 |
3683 } else if (bounds.tail.isEmpty()) { // length == 1 |
3653 return bounds.head; |
3684 return bounds.head; |
3654 } else { // length > 1 |
3685 } else { // length > 1 |
3655 int classCount = 0; |
3686 int classCount = 0; |
3656 for (Type bound : bounds) |
3687 List<Type> lowers = List.nil(); |
3657 if (!bound.isInterface()) |
3688 for (Type bound : bounds) { |
|
3689 if (!bound.isInterface()) { |
3658 classCount++; |
3690 classCount++; |
3659 if (classCount > 1) |
3691 Type lower = cvarLowerBound(bound); |
3660 return createErrorType(t); |
3692 if (bound != lower && !lower.hasTag(BOT)) |
|
3693 lowers = insert(lowers, lower); |
|
3694 } |
|
3695 } |
|
3696 if (classCount > 1) { |
|
3697 if (lowers.isEmpty()) |
|
3698 return createErrorType(errT); |
|
3699 else |
|
3700 return glbFlattened(union(bounds, lowers), errT); |
|
3701 } |
3661 } |
3702 } |
3662 return makeCompoundType(bounds); |
3703 return makeCompoundType(bounds); |
3663 } |
3704 } |
3664 // </editor-fold> |
3705 // </editor-fold> |
3665 |
3706 |
4135 @Override |
4176 @Override |
4136 public Void visitWildcardType(WildcardType source, Type target) throws AdaptFailure { |
4177 public Void visitWildcardType(WildcardType source, Type target) throws AdaptFailure { |
4137 if (source.isExtendsBound()) |
4178 if (source.isExtendsBound()) |
4138 adaptRecursive(upperBound(source), upperBound(target)); |
4179 adaptRecursive(upperBound(source), upperBound(target)); |
4139 else if (source.isSuperBound()) |
4180 else if (source.isSuperBound()) |
4140 adaptRecursive(lowerBound(source), lowerBound(target)); |
4181 adaptRecursive(wildLowerBound(source), wildLowerBound(target)); |
4141 return null; |
4182 return null; |
4142 } |
4183 } |
4143 |
4184 |
4144 @Override |
4185 @Override |
4145 public Void visitTypeVar(TypeVar source, Type target) throws AdaptFailure { |
4186 public Void visitTypeVar(TypeVar source, Type target) throws AdaptFailure { |
4147 // already a mapping for $source$, in which case |
4188 // already a mapping for $source$, in which case |
4148 // the old mapping will be merged with the new |
4189 // the old mapping will be merged with the new |
4149 Type val = mapping.get(source.tsym); |
4190 Type val = mapping.get(source.tsym); |
4150 if (val != null) { |
4191 if (val != null) { |
4151 if (val.isSuperBound() && target.isSuperBound()) { |
4192 if (val.isSuperBound() && target.isSuperBound()) { |
4152 val = isSubtype(lowerBound(val), lowerBound(target)) |
4193 val = isSubtype(wildLowerBound(val), wildLowerBound(target)) |
4153 ? target : val; |
4194 ? target : val; |
4154 } else if (val.isExtendsBound() && target.isExtendsBound()) { |
4195 } else if (val.isExtendsBound() && target.isExtendsBound()) { |
4155 val = isSubtype(upperBound(val), upperBound(target)) |
4196 val = isSubtype(upperBound(val), upperBound(target)) |
4156 ? val : target; |
4197 ? val : target; |
4157 } else if (!isSameType(val, target)) { |
4198 } else if (!isSameType(val, target)) { |