From 582bee8427d14b3d356c9fd8b93bd8f0154b22d1 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Mon, 28 Jan 2019 18:25:32 +0100 Subject: [PATCH] type distinction when assignment to parameter bound doesn't work (IDEA-205883) --- .../psi/util/TypesDistinctProver.java | 27 +++++++------------ .../TypeParameterDistinction.java | 15 +++++++++++ .../daemon/GenericsHighlightingTest.java | 1 + 3 files changed, 25 insertions(+), 18 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/TypeParameterDistinction.java diff --git a/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java b/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java index c860ca56636b..dd5882aa09b5 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java +++ b/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java @@ -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) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/TypeParameterDistinction.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/TypeParameterDistinction.java new file mode 100644 index 000000000000..cac7fd92bddb --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/TypeParameterDistinction.java @@ -0,0 +1,15 @@ + +import java.io.Serializable; +import java.util.List; + +class MyTest { + static void m1(List other) { + List list = (List) other; + } + static void m2(List other) { + List list = (List) other; + } + static void m3(List other) { + List list = (List) other; + } +} diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/GenericsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/GenericsHighlightingTest.java index b72b01204bad..4374fbe26dbd 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/GenericsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/GenericsHighlightingTest.java @@ -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); }