src/share/classes/com/sun/tools/javac/comp/Infer.java

changeset 828
19c900c703c6
parent 820
2d5aff89aaa3
child 832
57e3b9bc7fb8
equal deleted inserted replaced
827:b6f95173e769 828:19c900c703c6
203 203
204 /** Instantiate undetermined type variable to its minimal upper bound. 204 /** Instantiate undetermined type variable to its minimal upper bound.
205 * Throw a NoInstanceException if this not possible. 205 * Throw a NoInstanceException if this not possible.
206 */ 206 */
207 void maximizeInst(UndetVar that, Warner warn) throws NoInstanceException { 207 void maximizeInst(UndetVar that, Warner warn) throws NoInstanceException {
208 List<Type> hibounds = Type.filter(that.hibounds, errorFilter);
208 if (that.inst == null) { 209 if (that.inst == null) {
209 if (that.hibounds.isEmpty()) 210 if (hibounds.isEmpty())
210 that.inst = syms.objectType; 211 that.inst = syms.objectType;
211 else if (that.hibounds.tail.isEmpty()) 212 else if (hibounds.tail.isEmpty())
212 that.inst = that.hibounds.head; 213 that.inst = hibounds.head;
213 else 214 else
214 that.inst = types.glb(that.hibounds); 215 that.inst = types.glb(hibounds);
215 } 216 }
216 if (that.inst == null || 217 if (that.inst == null ||
217 that.inst.isErroneous()) 218 that.inst.isErroneous())
218 throw ambiguousNoInstanceException 219 throw ambiguousNoInstanceException
219 .setMessage("no.unique.maximal.instance.exists", 220 .setMessage("no.unique.maximal.instance.exists",
220 that.qtype, that.hibounds); 221 that.qtype, hibounds);
221 } 222 }
222 //where 223 //where
223 private boolean isSubClass(Type t, final List<Type> ts) { 224 private boolean isSubClass(Type t, final List<Type> ts) {
224 t = t.baseType(); 225 t = t.baseType();
225 if (t.tag == TYPEVAR) { 226 if (t.tag == TYPEVAR) {
239 } 240 }
240 } 241 }
241 return true; 242 return true;
242 } 243 }
243 244
245 private Filter<Type> errorFilter = new Filter<Type>() {
246 @Override
247 public boolean accepts(Type t) {
248 return !t.isErroneous();
249 }
250 };
251
244 /** Instantiate undetermined type variable to the lub of all its lower bounds. 252 /** Instantiate undetermined type variable to the lub of all its lower bounds.
245 * Throw a NoInstanceException if this not possible. 253 * Throw a NoInstanceException if this not possible.
246 */ 254 */
247 void minimizeInst(UndetVar that, Warner warn) throws NoInstanceException { 255 void minimizeInst(UndetVar that, Warner warn) throws NoInstanceException {
256 List<Type> lobounds = Type.filter(that.lobounds, errorFilter);
248 if (that.inst == null) { 257 if (that.inst == null) {
249 if (that.lobounds.isEmpty()) 258 if (lobounds.isEmpty())
250 that.inst = syms.botType; 259 that.inst = syms.botType;
251 else if (that.lobounds.tail.isEmpty()) 260 else if (lobounds.tail.isEmpty())
252 that.inst = that.lobounds.head.isPrimitive() ? syms.errType : that.lobounds.head; 261 that.inst = lobounds.head.isPrimitive() ? syms.errType : lobounds.head;
253 else { 262 else {
254 that.inst = types.lub(that.lobounds); 263 that.inst = types.lub(lobounds);
255 } 264 }
256 if (that.inst == null || that.inst.tag == ERROR) 265 if (that.inst == null || that.inst.tag == ERROR)
257 throw ambiguousNoInstanceException 266 throw ambiguousNoInstanceException
258 .setMessage("no.unique.minimal.instance.exists", 267 .setMessage("no.unique.minimal.instance.exists",
259 that.qtype, that.lobounds); 268 that.qtype, lobounds);
260 // VGJ: sort of inlined maximizeInst() below. Adding 269 // VGJ: sort of inlined maximizeInst() below. Adding
261 // bounds can cause lobounds that are above hibounds. 270 // bounds can cause lobounds that are above hibounds.
262 if (that.hibounds.isEmpty()) 271 List<Type> hibounds = Type.filter(that.hibounds, errorFilter);
272 if (hibounds.isEmpty())
263 return; 273 return;
264 Type hb = null; 274 Type hb = null;
265 if (that.hibounds.tail.isEmpty()) 275 if (hibounds.tail.isEmpty())
266 hb = that.hibounds.head; 276 hb = hibounds.head;
267 else for (List<Type> bs = that.hibounds; 277 else for (List<Type> bs = hibounds;
268 bs.nonEmpty() && hb == null; 278 bs.nonEmpty() && hb == null;
269 bs = bs.tail) { 279 bs = bs.tail) {
270 if (isSubClass(bs.head, that.hibounds)) 280 if (isSubClass(bs.head, hibounds))
271 hb = types.fromUnknownFun.apply(bs.head); 281 hb = types.fromUnknownFun.apply(bs.head);
272 } 282 }
273 if (hb == null || 283 if (hb == null ||
274 !types.isSubtypeUnchecked(hb, that.hibounds, warn) || 284 !types.isSubtypeUnchecked(hb, hibounds, warn) ||
275 !types.isSubtypeUnchecked(that.inst, hb, warn)) 285 !types.isSubtypeUnchecked(that.inst, hb, warn))
276 throw ambiguousNoInstanceException; 286 throw ambiguousNoInstanceException;
277 } 287 }
278 } 288 }
279 289
526 Warner warn) 536 Warner warn)
527 throws InvalidInstanceException { 537 throws InvalidInstanceException {
528 for (List<Type> tvs = tvars, args = arguments; 538 for (List<Type> tvs = tvars, args = arguments;
529 tvs.nonEmpty(); 539 tvs.nonEmpty();
530 tvs = tvs.tail, args = args.tail) { 540 tvs = tvs.tail, args = args.tail) {
531 if (args.head instanceof UndetVar) continue; 541 if (args.head instanceof UndetVar ||
542 tvars.head.getUpperBound().isErroneous()) continue;
532 List<Type> bounds = types.subst(types.getBounds((TypeVar)tvs.head), tvars, arguments); 543 List<Type> bounds = types.subst(types.getBounds((TypeVar)tvs.head), tvars, arguments);
533 if (!types.isSubtypeUnchecked(args.head, bounds, warn)) 544 if (!types.isSubtypeUnchecked(args.head, bounds, warn))
534 throw invalidInstanceException 545 throw invalidInstanceException
535 .setMessage("inferred.do.not.conform.to.bounds", 546 .setMessage("inferred.do.not.conform.to.bounds",
536 args.head, bounds); 547 args.head, bounds);

mercurial