Fixed the case of "Any is/as List<*>" for erased cast diagnostic
This commit is contained in:
@@ -121,24 +121,31 @@ public class CastDiagnosticsUtil {
|
|||||||
// Now, let's find a supertype of List<T> that is a Collection of something,
|
// Now, let's find a supertype of List<T> that is a Collection of something,
|
||||||
// in this case it will be Collection<T>
|
// in this case it will be Collection<T>
|
||||||
JetType supertypeWithVariables = TypeCheckingProcedure.findCorrespondingSupertype(subtypeWithVariables, supertype);
|
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();
|
final List<TypeParameterDescriptor> variables = subtypeWithVariables.getConstructor().getParameters();
|
||||||
TypeUnifier.UnificationResult solution = TypeUnifier.unify(
|
|
||||||
new TypeProjection(supertype), new TypeProjection(supertypeWithVariables),
|
Map<TypeConstructor, TypeProjection> substitution;
|
||||||
new Predicate<TypeConstructor>() {
|
if (supertypeWithVariables != null) {
|
||||||
@Override
|
// Now, let's try to unify Collection<T> and Collection<Foo> solution is a map from T to Foo
|
||||||
public boolean apply(TypeConstructor typeConstructor) {
|
TypeUnifier.UnificationResult solution = TypeUnifier.unify(
|
||||||
ClassifierDescriptor descriptor = typeConstructor.getDeclarationDescriptor();
|
new TypeProjection(supertype), new TypeProjection(supertypeWithVariables),
|
||||||
return descriptor instanceof TypeParameterDescriptor && variables.contains(descriptor);
|
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,
|
// 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<*>
|
// 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) {
|
for (TypeParameterDescriptor variable : variables) {
|
||||||
TypeProjection value = substitution.get(variable.getTypeConstructor());
|
TypeProjection value = substitution.get(variable.getTypeConstructor());
|
||||||
if (value == null) {
|
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");
|
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")
|
@TestMetadata("IsErasedDisallowDifferentArgInvariantPosition.kt")
|
||||||
public void testIsErasedDisallowDifferentArgInvariantPosition() throws Exception {
|
public void testIsErasedDisallowDifferentArgInvariantPosition() throws Exception {
|
||||||
doTest("compiler/testData/diagnostics/tests/cast/IsErasedDisallowDifferentArgInvariantPosition.kt");
|
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");
|
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")
|
@TestMetadata("IsErasedTasT.kt")
|
||||||
public void testIsErasedTasT() throws Exception {
|
public void testIsErasedTasT() throws Exception {
|
||||||
doTest("compiler/testData/diagnostics/tests/cast/IsErasedTasT.kt");
|
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");
|
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")
|
@TestMetadata("IsRecursionSustainable.kt")
|
||||||
public void testIsRecursionSustainable() throws Exception {
|
public void testIsRecursionSustainable() throws Exception {
|
||||||
doTest("compiler/testData/diagnostics/tests/cast/IsRecursionSustainable.kt");
|
doTest("compiler/testData/diagnostics/tests/cast/IsRecursionSustainable.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user