one more case of KT-445 Don't allow deep instanceof for erased parameters
=== (a : List<out Any>) is List<out Int> ===
This commit is contained in:
+49
-25
@@ -248,7 +248,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
if (typeChecker.isSubtypeOf(actualType, targetType)) {
|
||||
context.trace.report(USELESS_CAST.on(expression, expression.getOperationSign()));
|
||||
} else {
|
||||
if (isCastErased(actualType, targetType)) {
|
||||
if (isCastErased(actualType, targetType, typeChecker)) {
|
||||
context.trace.report(Errors.UNCHECKED_CAST.on(expression, actualType, targetType));
|
||||
}
|
||||
}
|
||||
@@ -259,46 +259,70 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
* Check if assignment from ActualType to TargetType is erased.
|
||||
* It is an error in "is" statement and warning in "as".
|
||||
*/
|
||||
public static boolean isCastErased(JetType actualType, JetType targetType) {
|
||||
public static boolean isCastErased(JetType actualType, JetType targetType, JetTypeChecker typeChecker) {
|
||||
|
||||
if (!(targetType.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor)) {
|
||||
// TODO: what if it is TypeParameterDescriptor?
|
||||
return false;
|
||||
}
|
||||
|
||||
JetType targetTypeClerared = TypeUtils.makeUnsubstitutedType(
|
||||
(ClassDescriptor) targetType.getConstructor().getDeclarationDescriptor(), null);
|
||||
{
|
||||
Multimap<TypeConstructor, TypeProjection> typeSubstitutionMap =
|
||||
TypeUtils.buildDeepSubstitutionMultimap(targetType);
|
||||
|
||||
Multimap<TypeConstructor, TypeProjection> clearTypeSubstitutionMap =
|
||||
TypeUtils.buildDeepSubstitutionMultimap(targetTypeClerared);
|
||||
for (int i = 0; i < actualType.getConstructor().getParameters().size(); ++i) {
|
||||
TypeProjection actualTypeParameter = actualType.getArguments().get(i);
|
||||
TypeParameterDescriptor subjectTypeParameterDescriptor = actualType.getConstructor().getParameters().get(i);
|
||||
|
||||
Set<JetType> clearSubstituted = new HashSet<JetType>();
|
||||
if (subjectTypeParameterDescriptor.isReified()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < actualType.getConstructor().getParameters().size(); ++i) {
|
||||
TypeParameterDescriptor subjectTypeParameterDescriptor = actualType.getConstructor().getParameters().get(i);
|
||||
|
||||
Collection<TypeProjection> subst = clearTypeSubstitutionMap.get(subjectTypeParameterDescriptor.getTypeConstructor());
|
||||
for (TypeProjection proj : subst) {
|
||||
clearSubstituted.add(proj.getType());
|
||||
Collection<TypeProjection> subst = typeSubstitutionMap.get(subjectTypeParameterDescriptor.getTypeConstructor());
|
||||
for (TypeProjection proj : subst) {
|
||||
//if (!proj.getType().equals(actualTypeParameter.getType())) {
|
||||
if (!typeChecker.isSubtypeOf(actualTypeParameter.getType(), proj.getType())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < targetType.getConstructor().getParameters().size(); ++i) {
|
||||
TypeParameterDescriptor typeParameter = targetType.getConstructor().getParameters().get(i);
|
||||
TypeProjection typeProjection = targetType.getArguments().get(i);
|
||||
{
|
||||
JetType targetTypeClerared = TypeUtils.makeUnsubstitutedType(
|
||||
(ClassDescriptor) targetType.getConstructor().getDeclarationDescriptor(), null);
|
||||
|
||||
if (typeParameter.isReified()) {
|
||||
continue;
|
||||
Multimap<TypeConstructor, TypeProjection> clearTypeSubstitutionMap =
|
||||
TypeUtils.buildDeepSubstitutionMultimap(targetTypeClerared);
|
||||
|
||||
Set<JetType> clearSubstituted = new HashSet<JetType>();
|
||||
|
||||
for (int i = 0; i < actualType.getConstructor().getParameters().size(); ++i) {
|
||||
TypeParameterDescriptor subjectTypeParameterDescriptor = actualType.getConstructor().getParameters().get(i);
|
||||
|
||||
Collection<TypeProjection> subst = clearTypeSubstitutionMap.get(subjectTypeParameterDescriptor.getTypeConstructor());
|
||||
for (TypeProjection proj : subst) {
|
||||
clearSubstituted.add(proj.getType());
|
||||
}
|
||||
}
|
||||
|
||||
// "is List<*>"
|
||||
if (typeProjection.equals(TypeUtils.makeStarProjection(typeParameter))) {
|
||||
continue;
|
||||
}
|
||||
for (int i = 0; i < targetType.getConstructor().getParameters().size(); ++i) {
|
||||
TypeParameterDescriptor typeParameter = targetType.getConstructor().getParameters().get(i);
|
||||
TypeProjection typeProjection = targetType.getArguments().get(i);
|
||||
|
||||
// if parameter is mapped to nothing then it is erased
|
||||
if (!clearSubstituted.contains(typeParameter.getDefaultType())) {
|
||||
return true;
|
||||
if (typeParameter.isReified()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// "is List<*>"
|
||||
if (typeProjection.equals(TypeUtils.makeStarProjection(typeParameter))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if parameter is mapped to nothing then it is erased
|
||||
if (!clearSubstituted.contains(typeParameter.getDefaultType())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
+1
-1
@@ -246,7 +246,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
||||
return;
|
||||
}
|
||||
|
||||
if (BasicExpressionTypingVisitor.isCastErased(subjectType, type)) {
|
||||
if (BasicExpressionTypingVisitor.isCastErased(subjectType, type, context.semanticServices.getTypeChecker())) {
|
||||
context.trace.report(Errors.CANNOT_CHECK_FOR_ERASED.on(reportErrorOn, type));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
// +JDK
|
||||
|
||||
import java.util.List
|
||||
|
||||
fun f(a : List<out Any>) = a is <!CANNOT_CHECK_FOR_ERASED!>List<out Int><!>
|
||||
@@ -4,5 +4,5 @@
|
||||
class IdUnavailableException() : Exception() {}
|
||||
|
||||
fun <T : Any> T.getJavaClass() : Class<T> {
|
||||
return ((this <!CAST_NEVER_SUCCEEDS!>as<!> Object).getClass()) as Class<T> // Some error here, because of Exception() used above. ?!!!
|
||||
return <!UNCHECKED_CAST!>((this <!CAST_NEVER_SUCCEEDS!>as<!> Object).getClass()) as Class<T><!> // Some error here, because of Exception() used above. ?!!!
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user