this.bits |= ASTNode.UnsafeCast;
return true;
}
// [JLS 5.5] S has no subtype X != T, such that |X| == |T|
// if I2<T,U> extends I1<T>, then cast from I1<T> to I2<T,U> is unchecked
ParameterizedTypeBinding paramCastType = (ParameterizedTypeBinding) castType;
ParameterizedTypeBinding paramMatch = (ParameterizedTypeBinding) match;
// easy case if less parameters on match
TypeBinding[] castArguments = paramCastType.arguments;
int length = castArguments.length;
if (paramMatch.arguments == null || length > paramMatch.arguments.length) {
this.bits |= ASTNode.UnsafeCast;
} else if ((paramCastType.tagBits & (TagBits.HasDirectWildcard|TagBits.HasTypeVariable)) != 0) {
// verify alternate cast type, substituting different type arguments
nextAlternateArgument: for (int i = 0; i < length; i++) {
switch (castArguments[i].kind()) {
case Binding.WILDCARD_TYPE :
case Binding.TYPE_PARAMETER :
break; // check substituting with other
default:
continue nextAlternateArgument; // no alternative possible
}
TypeBinding[] alternateArguments;
// need to clone for each iteration to avoid env paramtype cache interference
System.arraycopy(paramCastType.arguments, 0, alternateArguments = new TypeBinding[length], 0, length);
alternateArguments[i] = scope.getJavaLangObject();
LookupEnvironment environment = scope.environment();
ParameterizedTypeBinding alternateCastType = environment.createParameterizedType((ReferenceBinding)castType.erasure(), alternateArguments, castType.enclosingType());
if (alternateCastType.findSuperTypeOriginatingFrom(expressionType) == match) {
this.bits |= ASTNode.UnsafeCast;
break;
}
}
}