good code is red: take bounds into account during types agree (IDEA-76283)

This commit is contained in:
anna
2012-04-05 12:12:38 +02:00
parent 8e6cd35a1a
commit 5e682f1319
5 changed files with 63 additions and 2 deletions
@@ -512,7 +512,9 @@ public final class PsiUtil extends PsiUtilCore {
final PsiTypeParameter[] typeParameters2 = bClass.getTypeParameters();
if (typeParameters1.length != typeParameters2.length) return false;
for (int i = 0; i < typeParameters1.length; i++) {
if (!Comparing.equal(s1.substitute(typeParameters1[i]), s2.substitute(typeParameters2[i]))) return false;
final PsiType substituted2 = s2.substitute(typeParameters2[i]);
if (!Comparing.equal(s1.substituteWithBoundsPromotion(typeParameters1[i]), substituted2) &&
!Comparing.equal(s1.substitute(typeParameters1[i]), substituted2)) return false;
}
if (aClass.hasModifierProperty(PsiModifier.STATIC)) return true;
final PsiClass containingClass1 = aClass.getContainingClass();
@@ -741,6 +741,15 @@ public class TypeConversionUtil {
}
private static boolean isAssignableFromWildcard(PsiType left, PsiWildcardType rightWildcardType) {
if (rightWildcardType.isSuper()) {
final PsiClass aClass = PsiUtil.resolveClassInType(rightWildcardType.getSuperBound());
if (aClass instanceof PsiTypeParameter) {
final PsiClassType[] types = aClass.getExtendsListTypes();
for (PsiClassType type : types) {
if (isAssignable(left, type)) return true;
}
}
}
return isAssignable(left, rightWildcardType.getExtendsBound());
}
@@ -0,0 +1,49 @@
import java.util.*;
public class IDEA76283 {
}
interface Parametrized<T extends Number> {
}
class Bug1<T extends Number> {
<I extends Number> Parametrized<I> foo(Parametrized<I> param) {
return null;
}
void bug1(Parametrized<? super T> param) {
foo(param);
}
void bug2(Set<Parametrized<? extends Number>> parametrizeds) {
Set<Parametrized<?>> items = parametrizeds;
}
void bug3(Set<Parametrized<?>> parametrizeds) {
Set<Parametrized<?>> items = parametrizeds;
}
void bug4(Set<Parametrized<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>>> parametrizeds) {
<error descr="Incompatible types. Found: 'java.util.Set<Parametrized<? extends java.lang.String>>', required: 'java.util.Set<Parametrized<?>>'">Set<Parametrized<?>> items = parametrizeds;</error>
}
void bug5(Set<Parametrized<? extends Integer>> parametrizeds) {
<error descr="Incompatible types. Found: 'java.util.Set<Parametrized<? extends java.lang.Integer>>', required: 'java.util.Set<Parametrized<?>>'">Set<Parametrized<?>> items = parametrizeds;</error>
}
void bug6(Set<Parametrized<? super Number>> parametrizeds) {
<error descr="Incompatible types. Found: 'java.util.Set<Parametrized<? super java.lang.Number>>', required: 'java.util.Set<Parametrized<?>>'">Set<Parametrized<?>> items = parametrizeds;</error>
}
void bug7(Set<Parametrized<? super Integer>> parametrizeds) {
<error descr="Incompatible types. Found: 'java.util.Set<Parametrized<? super java.lang.Integer>>', required: 'java.util.Set<Parametrized<?>>'">Set<Parametrized<?>> items = parametrizeds;</error>
}
void bug8(Set<Parametrized<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>>> parametrizeds) {
<error descr="Incompatible types. Found: 'java.util.Set<Parametrized<? super java.lang.String>>', required: 'java.util.Set<Parametrized<?>>'">Set<Parametrized<?>> items = parametrizeds;</error>
}
void bug9(Set<Parametrized<<error descr="Type parameter '? super Object' is not within its bound; should extend 'java.lang.Number'">? super Object</error>>> parametrizeds) {
<error descr="Incompatible types. Found: 'java.util.Set<Parametrized<? super java.lang.Object>>', required: 'java.util.Set<Parametrized<?>>'">Set<Parametrized<?>> items = parametrizeds;</error>
}
}
@@ -68,7 +68,7 @@ class Test {
}
abstract class F<T extends Throwable> {
<error descr="'foo(F<?>)' clashes with 'foo(F<? extends Throwable>)'; both methods have same erasure">abstract void foo(F<?> y)</error>;
<error descr="'foo(F<?>)' is already defined in 'Test.F'">abstract void foo(F<?> y)</error>;
abstract void foo(F<? extends Throwable> y);
}
@@ -127,6 +127,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testIDEA66311() throws Exception { doTest17Incompatibility();}
public void testIDEA66311_16() throws Exception { doTest(false);}
public void testIDEA76283() throws Exception {doTest(false);}
public void testJavaUtilCollections_NoVerify() throws Exception {
PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule()));