old inference: include type parameter's bounds in result as intersection if inference from parent type was started (IDEA-153411)

This commit is contained in:
Anna.Kozlova
2016-03-22 17:28:46 +01:00
parent 58299e854f
commit b1a0d687df
5 changed files with 55 additions and 13 deletions

View File

@@ -755,24 +755,28 @@ public class PsiOldInferenceHelper implements PsiInferenceHelper {
}
}
PsiType[] superTypes = typeParameter.getSuperTypes();
final PsiType[] types = PsiType.createArray(superTypes.length);
for (int i = 0; i < superTypes.length; i++) {
PsiType superType = substitutor.substitute(superTypes[i]);
if (superType instanceof PsiClassType && ((PsiClassType)superType).isRaw()) {
superType = TypeConversionUtil.erasure(superType);
}
if (superType == null) superType = PsiType.getJavaLangObject(myManager, scope);
types[i] = superType;
}
if (constraint == null) {
if (methodCall instanceof PsiCallExpression) {
PsiType[] superTypes = typeParameter.getSuperTypes();
if (superTypes.length == 0) return null;
final PsiType[] types = PsiType.createArray(superTypes.length);
for (int i = 0; i < superTypes.length; i++) {
PsiType superType = substitutor.substitute(superTypes[i]);
if (superType instanceof PsiClassType && ((PsiClassType)superType).isRaw()) {
superType = TypeConversionUtil.erasure(superType);
}
if (superType == null) superType = PsiType.getJavaLangObject(myManager, scope);
types[i] = superType;
}
if (types.length == 0) return null;
return policy.getInferredTypeWithNoConstraint(myManager, PsiIntersectionType.createIntersection(types));
}
return null;
}
PsiType guess = constraint.getFirst();
if (guess != null && types.length > 0) {
guess = GenericsUtil.getGreatestLowerBound(guess, PsiIntersectionType.createIntersection(types));
}
guess = policy.adjustInferredType(myManager, guess, constraint.getSecond());
//The following code is the result of deep thought, do not shit it out before discussing with [ven]

View File

@@ -3,5 +3,5 @@ class Neg06 {
static class CSuperFoo<X> {}
static class CFoo<X extends Number> extends CSuperFoo<X> {}
CSuperFoo<String> csf1 = new CFoo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>();
<error descr="Incompatible types. Found: 'Neg06.CFoo<java.lang.String>', required: 'Neg06.CSuperFoo<java.lang.String>'">CSuperFoo<String> csf1 = new CFoo<>();</error>
}

View File

@@ -4,7 +4,7 @@ import java.util.Map;
class Test {
public static void main(String[] args) {
Map<Integer, Object> map = <error descr="Inferred type 'java.lang.Object' for type parameter 'V' is not within its bound; should implement 'java.lang.Comparable'">make()</error>;
<error descr="Incompatible types. Found: 'java.util.Map<java.lang.Integer,java.lang.Comparable>', required: 'java.util.Map<java.lang.Integer,java.lang.Object>'">Map<Integer, Object> map = make();</error>
}

View File

@@ -0,0 +1,34 @@
import java.io.Serializable;
import java.util.Collections;
import java.util.List;
class Main {
<T extends Runnable> List<T> foo(T t) {
t.run();
return Collections.emptyList();
}
<T extends Serializable> void m(Object[] obj) {
List<?> r1 = foo(null);
List<? extends Serializable> r2 = foo(null);
List<? super String> r3 = foo<error descr="'foo(? super java.lang.String & java.lang.Runnable)' in 'Main' cannot be applied to '()'">( )</error>;
List<? extends Runnable> r4 = foo(null);
}
}
class Main2 {
<T extends Serializable> List<T> foo(Class<T> c, String b, Object ... a) {
return Collections.emptyList();
}
<T extends Serializable> List<T> foo(String b, Object ... a) {
return Collections.emptyList();
}
<T extends Serializable> void m(Object[] obj) {
List r1 = foo("", obj);
List<T> r2 = foo("", obj);
List<?> r3 = foo("", obj);
<error descr="Incompatible types. Found: 'java.util.List<java.io.Serializable>', required: 'java.util.List<java.lang.Object>'">List<Object> r4 = foo("", obj);</error>
}
}

View File

@@ -601,4 +601,8 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testCaptureConversionWithWildcardBounds() throws Exception {
doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false);
}
public void testIntersectTypeParameterBounds() throws Exception {
doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false);
}
}