inference: check intersection type for raw conversion separately (IDEA-196523)

This commit is contained in:
Anna.Kozlova
2018-08-01 11:08:49 +02:00
parent 1261d28c87
commit fbb178fb85
3 changed files with 45 additions and 11 deletions

View File

@@ -67,25 +67,39 @@ public class TypeCompatibilityConstraint implements ConstraintFormula {
}
public static boolean isUncheckedConversion(final PsiType t, final PsiType s) {
if (t instanceof PsiClassType && !((PsiClassType)t).isRaw() && s instanceof PsiClassType) {
if (t instanceof PsiClassType && !((PsiClassType)t).isRaw()) {
final PsiClassType.ClassResolveResult tResult = ((PsiClassType)t).resolveGenerics();
final PsiClassType.ClassResolveResult sResult = ((PsiClassType)s).resolveGenerics();
final PsiClass tClass = tResult.getElement();
final PsiClass sClass = sResult.getElement();
if (tClass != null && sClass != null && !(sClass instanceof InferenceVariable)) {
final PsiSubstitutor sSubstitutor = TypeConversionUtil.getClassSubstitutor(tClass, sClass, sResult.getSubstitutor());
if (sSubstitutor != null) {
if (PsiUtil.isRawSubstitutor(tClass, sSubstitutor)) {
if (s instanceof PsiClassType && isUncheckedConversion(tClass, (PsiClassType)s)) {
return true;
}
else if (s instanceof PsiIntersectionType) {
for (PsiType conjunct : ((PsiIntersectionType)s).getConjuncts()) {
if (conjunct instanceof PsiClassType && isUncheckedConversion(tClass, (PsiClassType)conjunct)) {
return true;
}
}
else if (tClass instanceof InferenceVariable && ((PsiClassType)s).isRaw() && tClass.isInheritor(sClass, true)) {
}
}
else if (t instanceof PsiArrayType && s != null && t.getArrayDimensions() == s.getArrayDimensions()) {
return isUncheckedConversion(t.getDeepComponentType(), s.getDeepComponentType());
}
return false;
}
private static boolean isUncheckedConversion(PsiClass tClass, PsiClassType s) {
final PsiClassType.ClassResolveResult sResult = s.resolveGenerics();
final PsiClass sClass = sResult.getElement();
if (tClass != null && sClass != null && !(sClass instanceof InferenceVariable)) {
final PsiSubstitutor sSubstitutor = TypeConversionUtil.getClassSubstitutor(tClass, sClass, sResult.getSubstitutor());
if (sSubstitutor != null) {
if (PsiUtil.isRawSubstitutor(tClass, sSubstitutor)) {
return true;
}
}
}
else if (t instanceof PsiArrayType && s != null && t.getArrayDimensions() == s.getArrayDimensions()) {
return isUncheckedConversion(t.getDeepComponentType(), s.getDeepComponentType());
else if (tClass instanceof InferenceVariable && s.isRaw() && tClass.isInheritor(sClass, true)) {
return true;
}
}
return false;
}

View File

@@ -0,0 +1,19 @@
class Main {
public interface Entity<T> {
}
public interface HasOrder {
}
public static <T extends Entity<K> & HasOrder, K> void beforeRemove(T item) {
}
public static void main(String[] args) {
Object o = null;
beforeRemove( (Entity & HasOrder) o);
}
}

View File

@@ -192,6 +192,7 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase
public void testSameNamedFreshVariables() { doTest(); }
public void testEnsureOrderOfFreshVariablesWhenCaptureNonProperTypes() { doTest(); }
public void testFreshVariablesBounds() { doTest(); }
public void testRawInIntersection() { doTest(); }
public void testApplicabilityCheckFailsExpressionTypeCheckPasses() {
doTest();