new inference: do not instantiate vars with upper bounds mix when incomplete substitutor is supposed

(cherry picked from commit ff73c519f10ec947b86832a0c4ce5d6ee9b9e4c3)
This commit is contained in:
anna
2013-11-25 16:48:06 +01:00
parent 80e8321a48
commit 3188589850
3 changed files with 41 additions and 6 deletions
@@ -462,7 +462,7 @@ public class InferenceSession {
return true;
}
private PsiSubstitutor resolveBounds(final Collection<InferenceVariable> inferenceVariables, PsiSubstitutor substitutor, boolean acceptObject) {
private PsiSubstitutor resolveBounds(final Collection<InferenceVariable> inferenceVariables, PsiSubstitutor substitutor, boolean acceptInitialUpperBound) {
final List<List<InferenceVariable>> independentVars = InferenceVariablesOrder.resolveOrder(inferenceVariables, this);
for (List<InferenceVariable> variables : independentVars) {
for (InferenceVariable inferenceVariable : variables) {
@@ -509,23 +509,33 @@ public class InferenceSession {
inferenceVariable.setInstantiation(lub instanceof PsiCapturedWildcardType ? ((PsiCapturedWildcardType)lub).getWildcard() : lub);
}
else {
boolean inferred = false;
PsiType glb = null;
if (isThrowable(upperBounds)) {
glb = PsiType.getJavaLangRuntimeException(myManager, GlobalSearchScope.allScope(myManager.getProject()));
inferred = true;
} else {
int boundCandidatesNumber = 0;
for (PsiType upperBound : upperBounds) {
upperBound = acceptBoundsWithRecursiveDependencies(inferenceVariable, upperBound, substitutor);
if (isProperType(upperBound)) {
PsiType substitutedBound = acceptBoundsWithRecursiveDependencies(inferenceVariable, upperBound, substitutor);
if (isProperType(substitutedBound)) {
boundCandidatesNumber++;
if (!upperBound.equals(substitutedBound)) {
inferred = true;
}
if (glb == null) {
glb = upperBound;
glb = substitutedBound;
}
else {
glb = GenericsUtil.getGreatestLowerBound(glb, upperBound);
glb = GenericsUtil.getGreatestLowerBound(glb, substitutedBound);
}
}
}
if (!inferred) {
inferred = boundCandidatesNumber > typeParameter.getExtendsListTypes().length && (typeParameter.getExtendsListTypes().length > 0 || boundCandidatesNumber > 1);
}
}
if (glb != null && (acceptObject || !glb.equalsToText(CommonClassNames.JAVA_LANG_OBJECT))) {
if (glb != null && (acceptInitialUpperBound || inferred)) {
inferenceVariable.setInstantiation(glb);
}
}
@@ -0,0 +1,21 @@
import java.util.*;
class Test {
interface I<T> {
T foo();
}
class Inner<T> { }
<M1 extends List<?>> Inner<M1> staticFactory() {
return null;
}
<M2 extends List<?>> void foo(I<M2> coll,
Inner<M2> assertion) { }
void test(I<List<List<Integer>>> coll) {
foo(coll, staticFactory());
}
}
@@ -99,6 +99,10 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase
doTest();
}
public void testIncompleteSubstitution() throws Exception {
doTest();
}
private void doTest() throws Exception {
doTest(false);
}