mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
type distinction when assignment to parameter bound doesn't work (IDEA-205883)
This commit is contained in:
@@ -17,8 +17,9 @@ package com.intellij.psi.util;
|
||||
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.psi.*;
|
||||
import java.util.HashSet;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class TypesDistinctProver {
|
||||
@@ -107,14 +108,16 @@ public class TypesDistinctProver {
|
||||
final PsiClass boundClass2 = classResolveResult2.getElement();
|
||||
|
||||
if (boundClass1 instanceof PsiTypeParameter && level < 2) {
|
||||
if (!distinguishFromTypeParam((PsiTypeParameter)boundClass1, boundClass2, type1, type2)) return false;
|
||||
if (!distinguishFromTypeParam((PsiTypeParameter)boundClass1, type1, type2)) return false;
|
||||
}
|
||||
|
||||
if (boundClass2 instanceof PsiTypeParameter && level < 2) {
|
||||
if (!distinguishFromTypeParam((PsiTypeParameter)boundClass2, boundClass1, type2, type1)) return false;
|
||||
if (!distinguishFromTypeParam((PsiTypeParameter)boundClass2, type2, type1)) return false;
|
||||
}
|
||||
|
||||
if (Comparing.equal(TypeConversionUtil.erasure(type1), TypeConversionUtil.erasure(type2))) {
|
||||
if (Comparing.equal(TypeConversionUtil.erasure(type1), TypeConversionUtil.erasure(type2)) &&
|
||||
!(boundClass1 instanceof PsiTypeParameter) &&
|
||||
!(boundClass2 instanceof PsiTypeParameter)) {
|
||||
final PsiSubstitutor substitutor1 = classResolveResult1.getSubstitutor();
|
||||
final PsiSubstitutor substitutor2 = classResolveResult2.getSubstitutor();
|
||||
for (PsiTypeParameter parameter : substitutor1.getSubstitutionMap().keySet()) {
|
||||
@@ -147,23 +150,11 @@ public class TypesDistinctProver {
|
||||
}
|
||||
|
||||
private static boolean distinguishFromTypeParam(PsiTypeParameter typeParam,
|
||||
PsiClass boundClass,
|
||||
PsiType type1,
|
||||
PsiType type2) {
|
||||
final PsiClassType[] paramBounds = typeParam.getExtendsListTypes();
|
||||
if (paramBounds.length == 0 && type1 instanceof PsiClassType) return false;
|
||||
for (PsiClassType classType : paramBounds) {
|
||||
final PsiClass paramBound = classType.resolve();
|
||||
if (paramBound != null &&
|
||||
(InheritanceUtil.isInheritorOrSelf(paramBound, boundClass, true) ||
|
||||
InheritanceUtil.isInheritorOrSelf(boundClass, paramBound, true))) {
|
||||
return false;
|
||||
}
|
||||
if (type2 instanceof PsiArrayType && TypeConversionUtil.isAssignable(classType, type2)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
if (paramBounds.length == 0) return !(type1 instanceof PsiClassType);
|
||||
return Arrays.stream(paramBounds).anyMatch(paramBound -> !TypeConversionUtil.isAssignable(paramBound.rawType(), type2));
|
||||
}
|
||||
|
||||
public static boolean provablyDistinct(PsiWildcardType type1, PsiWildcardType type2, boolean rejectInconsistentRaw, int level) {
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
class MyTest {
|
||||
static <T extends Object & Serializable, J> void m1(List<J> other) {
|
||||
List<T> list = (List<T>) other;
|
||||
}
|
||||
static <T extends Object & Serializable> void m2(List<Object> other) {
|
||||
List<T> list = <error descr="Inconvertible types; cannot cast 'java.util.List<java.lang.Object>' to 'java.util.List<T>'">(List<T>) other</error>;
|
||||
}
|
||||
static <T extends Serializable> void m3(List<Object> other) {
|
||||
List<T> list = <error descr="Inconvertible types; cannot cast 'java.util.List<java.lang.Object>' to 'java.util.List<T>'">(List<T>) other</error>;
|
||||
}
|
||||
}
|
||||
+1
@@ -416,6 +416,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
public void testReturnTypeSubstitutableForSameOverrideEquivalentMethods() { doTest7(false); }
|
||||
public void testCaptureConversionWithWildcardBounds() { doTest7(false); }
|
||||
public void testIDEA106811() { doTest7(false); }
|
||||
public void testTypeParameterDistinction() { doTest7(false); }
|
||||
public void testRawTypeCheckForNestedClassWithOuterClassTypeParameters() { doTest7(false); }
|
||||
public void testArrayContainsInTypeParameterWithSerializableBound() { doTest7(true); }
|
||||
public void testIntersectTypeParameterBounds() { doTest7(false); }
|
||||
|
||||
Reference in New Issue
Block a user