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 89e6caad21ad..62914df25d0b 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
@@ -32,6 +32,10 @@ public class TypesDistinctProver {
}
public static boolean provablyDistinct(PsiType type1, PsiType type2) {
+ return provablyDistinct(type1, type2, 0);
+ }
+
+ private static boolean provablyDistinct(PsiType type1, PsiType type2, int level) {
if (type1 instanceof PsiClassType && ((PsiClassType)type1).resolve() instanceof PsiTypeParameter) return false;
if (type2 instanceof PsiClassType && ((PsiClassType)type2).resolve() instanceof PsiTypeParameter) return false;
if (type1 instanceof PsiWildcardType) {
@@ -40,7 +44,7 @@ public class TypesDistinctProver {
}
if (type2 instanceof PsiCapturedWildcardType) {
- return ((PsiWildcardType)type1).isExtends() ||
+ return ((PsiWildcardType)type1).isExtends() && level > 0 ||
provablyDistinct((PsiWildcardType)type1, ((PsiCapturedWildcardType)type2).getWildcard());
}
@@ -75,9 +79,9 @@ public class TypesDistinctProver {
return proveArrayTypeDistinct(((PsiWildcardType)type1).getManager().getProject(), (PsiArrayType)type2, type1);
}
}
- if (type1 instanceof PsiCapturedWildcardType) return provablyDistinct(((PsiCapturedWildcardType)type1).getWildcard(), type2);
+ if (type1 instanceof PsiCapturedWildcardType) return provablyDistinct(((PsiCapturedWildcardType)type1).getWildcard(), type2, level +1);
- if (type2 instanceof PsiWildcardType || type2 instanceof PsiCapturedWildcardType) return provablyDistinct(type2, type1);
+ if (type2 instanceof PsiWildcardType || type2 instanceof PsiCapturedWildcardType) return provablyDistinct(type2, type1, level +1);
final PsiClassType.ClassResolveResult classResolveResult1 = PsiUtil.resolveGenericsClassInType(type1);
@@ -94,7 +98,7 @@ public class TypesDistinctProver {
if (!TypeConversionUtil.isAssignable(type, substitutedType1 != null ? substitutedType1 : substitutedType2, false)) return true;
}
} else {
- if (provablyDistinct(substitutedType1, substitutedType2)) return true;
+ if (provablyDistinct(substitutedType1, substitutedType2, level + 1)) return true;
if (substitutedType1 instanceof PsiWildcardType && !((PsiWildcardType)substitutedType1).isBounded()) return true;
}
}
@@ -121,7 +125,7 @@ public class TypesDistinctProver {
if (boundClass1 != null && boundClass2 != null) {
return proveExtendsBoundsDistinct(type1, type2, boundClass1, boundClass2);
}
- return provablyDistinct(extendsBound1, extendsBound2);
+ return provablyDistinct(extendsBound1, extendsBound2, 1);
}
if (type2.isExtends()) return provablyDistinct(type2, type1);
if (type1.isExtends() && type2.isSuper()) {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/WildcardTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/WildcardTypes.java
index 1a586323851c..f5483d41ed6f 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/WildcardTypes.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/WildcardTypes.java
@@ -216,4 +216,19 @@ class IDEA73377 {
//noinspection unchecked
return (Iterator, ?>>)map.entrySet().iterator();
}
+}
+
+class IDEA91481 {
+ void bar(){
+ BeanBuilder extends DirectBean> builder = (BeanBuilder extends DirectBean>) builder();
+ System.out.println(builder);
+ }
+
+ BeanBuilder extends Bean> builder() {
+ return null;
+ }
+
+ class BeanBuilder<T> {}
+ class Bean {}
+ class DirectBean extends Bean {}
}
\ No newline at end of file