Fixed the case of "Any is/as List<*>" for erased cast diagnostic

This commit is contained in:
Andrey Breslav
2013-09-06 12:26:03 +04:00
parent 4cf5b94a4a
commit fca6182288
5 changed files with 45 additions and 13 deletions
@@ -121,24 +121,31 @@ public class CastDiagnosticsUtil {
// Now, let's find a supertype of List<T> that is a Collection of something,
// in this case it will be Collection<T>
JetType supertypeWithVariables = TypeCheckingProcedure.findCorrespondingSupertype(subtypeWithVariables, supertype);
if (supertypeWithVariables == null) return true;
// Now, let's try to unify Collection<T> and Collection<Foo>
// solution is a map from T to Foo
final List<TypeParameterDescriptor> variables = subtypeWithVariables.getConstructor().getParameters();
TypeUnifier.UnificationResult solution = TypeUnifier.unify(
new TypeProjection(supertype), new TypeProjection(supertypeWithVariables),
new Predicate<TypeConstructor>() {
@Override
public boolean apply(TypeConstructor typeConstructor) {
ClassifierDescriptor descriptor = typeConstructor.getDeclarationDescriptor();
return descriptor instanceof TypeParameterDescriptor && variables.contains(descriptor);
}
});
Map<TypeConstructor, TypeProjection> substitution;
if (supertypeWithVariables != null) {
// Now, let's try to unify Collection<T> and Collection<Foo> solution is a map from T to Foo
TypeUnifier.UnificationResult solution = TypeUnifier.unify(
new TypeProjection(supertype), new TypeProjection(supertypeWithVariables),
new Predicate<TypeConstructor>() {
@Override
public boolean apply(TypeConstructor typeConstructor) {
ClassifierDescriptor descriptor = typeConstructor.getDeclarationDescriptor();
return descriptor instanceof TypeParameterDescriptor && variables.contains(descriptor);
}
});
substitution = Maps.newHashMap(solution.getSubstitution());
}
else {
// If there's no corresponding supertype, no variables are determined
// This may be OK, e.g. in case 'Any as List<*>'
substitution = Maps.newHashMapWithExpectedSize(variables.size());
}
// If some of the parameters are not determined by unification, it means that these parameters are lost,
// let's put stars instead, so that we can only cast to something like List<*>, e.g. (a: Any) as List<*>
Map<TypeConstructor, TypeProjection> substitution = Maps.newHashMap(solution.getSubstitution());
for (TypeParameterDescriptor variable : variables) {
TypeProjection value = substitution.get(variable.getTypeConstructor());
if (value == null) {
@@ -0,0 +1,3 @@
class G<T>
fun f(q: Any) = q is G<*>
@@ -0,0 +1,3 @@
class G<T>
fun f<Q>(q: Q) = q is G<*>
@@ -0,0 +1,4 @@
class G<T>
trait Tr
fun f(q: Tr) = q is G<*>
@@ -1060,6 +1060,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
doTest("compiler/testData/diagnostics/tests/cast/IsErasedAllowSameParameterParameter.kt");
}
@TestMetadata("isErasedAnyAndStarred.kt")
public void testIsErasedAnyAndStarred() throws Exception {
doTest("compiler/testData/diagnostics/tests/cast/isErasedAnyAndStarred.kt");
}
@TestMetadata("IsErasedDisallowDifferentArgInvariantPosition.kt")
public void testIsErasedDisallowDifferentArgInvariantPosition() throws Exception {
doTest("compiler/testData/diagnostics/tests/cast/IsErasedDisallowDifferentArgInvariantPosition.kt");
@@ -1120,6 +1125,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
doTest("compiler/testData/diagnostics/tests/cast/IsErasedStar.kt");
}
@TestMetadata("isErasedTAndStarred.kt")
public void testIsErasedTAndStarred() throws Exception {
doTest("compiler/testData/diagnostics/tests/cast/isErasedTAndStarred.kt");
}
@TestMetadata("IsErasedTasT.kt")
public void testIsErasedTasT() throws Exception {
doTest("compiler/testData/diagnostics/tests/cast/IsErasedTasT.kt");
@@ -1130,6 +1140,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
doTest("compiler/testData/diagnostics/tests/cast/IsErasedToErrorType.kt");
}
@TestMetadata("isErasedUnrelatedAndStarred.kt")
public void testIsErasedUnrelatedAndStarred() throws Exception {
doTest("compiler/testData/diagnostics/tests/cast/isErasedUnrelatedAndStarred.kt");
}
@TestMetadata("IsRecursionSustainable.kt")
public void testIsRecursionSustainable() throws Exception {
doTest("compiler/testData/diagnostics/tests/cast/IsRecursionSustainable.kt");