try narrowing conversion

This commit is contained in:
anna
2011-06-07 12:14:20 +04:00
parent eb54cf6fe5
commit ca8f1063b2
3 changed files with 28 additions and 11 deletions
@@ -31,3 +31,21 @@ public class Test {
IConverter<String> converter2 = <error descr="Inferred type 'java.lang.String' for type parameter 'C' is not within its bound; should extend 'java.lang.Double'">getConverter2(String.class)</error>;
}
}
class Z {
}
class TestNonNarrowingConversion<T extends Z> {
public TestNonNarrowingConversion(T u) {
}
public T z = null;
public int a() {
<error descr="Incompatible types. Found: 'TestNonNarrowingConversion<Z>', required: 'TestNonNarrowingConversion<T>'">TestNonNarrowingConversion<T> x = new TestNonNarrowingConversion<Z>(new Z());</error>
return 1;
}
}
@@ -207,7 +207,7 @@ public class TypeConversionUtil {
final LanguageLevel languageLevel = toClassType.getLanguageLevel();
if (!fromClass.isInterface()) {
if (toClass.isInterface()) {
return !fromClass.hasModifierProperty(PsiModifier.FINAL) &&
return (!fromClass.hasModifierProperty(PsiModifier.FINAL) || fromClass.isInheritor(toClass, true))&&
checkSuperTypesWithDifferentTypeArguments(toResult, fromClass, manager, fromResult.getSubstitutor(), null, languageLevel);
}
else {
@@ -337,6 +337,13 @@ public class TypeConversionUtil {
PsiType typeArg2 = substitutor2.substitute(typeParameter);
if (typeArg1 == null || typeArg2 == null) return true;
if (TypesDistinctProver.provablyDistinct(typeArg1, typeArg2)) return false;
final PsiClass class1 = PsiUtil.resolveClassInType(typeArg1);
if (class1 instanceof PsiTypeParameter) {
for (PsiType type : class1.getExtendsListTypes()) {
if (TypesDistinctProver.provablyDistinct(type, typeArg2)) return false;
}
}
}
return true;
@@ -867,14 +874,6 @@ public class TypeConversionUtil {
}
}
else {
final PsiClass leftClass = PsiUtil.resolveClassInType(typeLeft);
if (leftClass instanceof PsiTypeParameter) {
for (PsiClassType leftClassType : leftClass.getExtendsListTypes()) {
if (TypesDistinctProver.provablyDistinct(leftClassType, typeRight)) return false;
}
if (!(typeRight instanceof PsiCapturedWildcardType || typeRight instanceof PsiWildcardType)) return true;
}
return typeLeft.equals(typeRight);
}
}
@@ -408,8 +408,8 @@ public class MethodResolverProcessor extends ResolverProcessor {
if (argTypes != null && argTypes.length > i) {
PsiType argType = argTypes[i];
if (argType != null) {
final boolean converts1 = TypesUtil.isAssignable(type1, argType, manager, scope, false);
final boolean converts2 = TypesUtil.isAssignable(type2, argType, manager, scope, false);
final boolean converts1 = TypesUtil.isAssignable(TypeConversionUtil.erasure(type1), argType, manager, scope, false);
final boolean converts2 = TypesUtil.isAssignable(TypeConversionUtil.erasure(type2), argType, manager, scope, false);
if (converts1 != converts2) {
return converts2;
}