276 if (t.tag == ERROR) |
276 if (t.tag == ERROR) |
277 return true; |
277 return true; |
278 boolean tPrimitive = t.isPrimitive(); |
278 boolean tPrimitive = t.isPrimitive(); |
279 boolean sPrimitive = s.isPrimitive(); |
279 boolean sPrimitive = s.isPrimitive(); |
280 if (tPrimitive == sPrimitive) { |
280 if (tPrimitive == sPrimitive) { |
281 checkUnsafeVarargsConversion(t, s, warn); |
|
282 return isSubtypeUnchecked(t, s, warn); |
281 return isSubtypeUnchecked(t, s, warn); |
283 } |
282 } |
284 if (!allowBoxing) return false; |
283 if (!allowBoxing) return false; |
285 return tPrimitive |
284 return tPrimitive |
286 ? isSubtype(boxedClass(t).type, s) |
285 ? isSubtype(boxedClass(t).type, s) |
287 : isSubtype(unboxedType(t), s); |
286 : isSubtype(unboxedType(t), s); |
288 } |
287 } |
289 //where |
|
290 private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) { |
|
291 if (t.tag != ARRAY || isReifiable(t)) return; |
|
292 ArrayType from = (ArrayType)t; |
|
293 boolean shouldWarn = false; |
|
294 switch (s.tag) { |
|
295 case ARRAY: |
|
296 ArrayType to = (ArrayType)s; |
|
297 shouldWarn = from.isVarargs() && |
|
298 !to.isVarargs() && |
|
299 !isReifiable(from); |
|
300 break; |
|
301 case CLASS: |
|
302 shouldWarn = from.isVarargs() && |
|
303 isSubtype(from, s); |
|
304 break; |
|
305 } |
|
306 if (shouldWarn) { |
|
307 warn.warn(LintCategory.VARARGS); |
|
308 } |
|
309 } |
|
310 |
288 |
311 /** |
289 /** |
312 * Is t a subtype of or convertiable via boxing/unboxing |
290 * Is t a subtype of or convertiable via boxing/unboxing |
313 * convertions to s? |
291 * convertions to s? |
314 */ |
292 */ |
326 } |
304 } |
327 /** |
305 /** |
328 * Is t an unchecked subtype of s? |
306 * Is t an unchecked subtype of s? |
329 */ |
307 */ |
330 public boolean isSubtypeUnchecked(Type t, Type s, Warner warn) { |
308 public boolean isSubtypeUnchecked(Type t, Type s, Warner warn) { |
331 if (t.tag == ARRAY && s.tag == ARRAY) { |
309 boolean result = isSubtypeUncheckedInternal(t, s, warn); |
332 if (((ArrayType)t).elemtype.tag <= lastBaseTag) { |
310 if (result) { |
333 return isSameType(elemtype(t), elemtype(s)); |
311 checkUnsafeVarargsConversion(t, s, warn); |
334 } else { |
312 } |
335 ArrayType from = (ArrayType)t; |
313 return result; |
336 ArrayType to = (ArrayType)s; |
314 } |
337 if (from.isVarargs() && |
315 //where |
338 !to.isVarargs() && |
316 private boolean isSubtypeUncheckedInternal(Type t, Type s, Warner warn) { |
339 !isReifiable(from)) { |
317 if (t.tag == ARRAY && s.tag == ARRAY) { |
340 warn.warn(LintCategory.VARARGS); |
318 if (((ArrayType)t).elemtype.tag <= lastBaseTag) { |
341 } |
319 return isSameType(elemtype(t), elemtype(s)); |
342 return isSubtypeUnchecked(elemtype(t), elemtype(s), warn); |
320 } else { |
343 } |
321 return isSubtypeUnchecked(elemtype(t), elemtype(s), warn); |
344 } else if (isSubtype(t, s)) { |
322 } |
345 return true; |
323 } else if (isSubtype(t, s)) { |
346 } |
|
347 else if (t.tag == TYPEVAR) { |
|
348 return isSubtypeUnchecked(t.getUpperBound(), s, warn); |
|
349 } |
|
350 else if (s.tag == UNDETVAR) { |
|
351 UndetVar uv = (UndetVar)s; |
|
352 if (uv.inst != null) |
|
353 return isSubtypeUnchecked(t, uv.inst, warn); |
|
354 } |
|
355 else if (!s.isRaw()) { |
|
356 Type t2 = asSuper(t, s.tsym); |
|
357 if (t2 != null && t2.isRaw()) { |
|
358 if (isReifiable(s)) |
|
359 warn.silentWarn(LintCategory.UNCHECKED); |
|
360 else |
|
361 warn.warn(LintCategory.UNCHECKED); |
|
362 return true; |
324 return true; |
363 } |
325 } |
364 } |
326 else if (t.tag == TYPEVAR) { |
365 return false; |
327 return isSubtypeUnchecked(t.getUpperBound(), s, warn); |
366 } |
328 } |
|
329 else if (s.tag == UNDETVAR) { |
|
330 UndetVar uv = (UndetVar)s; |
|
331 if (uv.inst != null) |
|
332 return isSubtypeUnchecked(t, uv.inst, warn); |
|
333 } |
|
334 else if (!s.isRaw()) { |
|
335 Type t2 = asSuper(t, s.tsym); |
|
336 if (t2 != null && t2.isRaw()) { |
|
337 if (isReifiable(s)) |
|
338 warn.silentWarn(LintCategory.UNCHECKED); |
|
339 else |
|
340 warn.warn(LintCategory.UNCHECKED); |
|
341 return true; |
|
342 } |
|
343 } |
|
344 return false; |
|
345 } |
|
346 |
|
347 private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) { |
|
348 if (t.tag != ARRAY || isReifiable(t)) return; |
|
349 ArrayType from = (ArrayType)t; |
|
350 boolean shouldWarn = false; |
|
351 switch (s.tag) { |
|
352 case ARRAY: |
|
353 ArrayType to = (ArrayType)s; |
|
354 shouldWarn = from.isVarargs() && |
|
355 !to.isVarargs() && |
|
356 !isReifiable(from); |
|
357 break; |
|
358 case CLASS: |
|
359 shouldWarn = from.isVarargs(); |
|
360 break; |
|
361 } |
|
362 if (shouldWarn) { |
|
363 warn.warn(LintCategory.VARARGS); |
|
364 } |
|
365 } |
367 |
366 |
368 /** |
367 /** |
369 * Is t a subtype of s?<br> |
368 * Is t a subtype of s?<br> |
370 * (not defined for Method and ForAll types) |
369 * (not defined for Method and ForAll types) |
371 */ |
370 */ |