inference: check glb with captured wildcard: if not assignable check if it is an interface

This commit is contained in:
Anna Kozlova
2016-02-17 16:26:28 +01:00
parent e3a4f7386c
commit 0ac147ad95
3 changed files with 45 additions and 14 deletions

View File

@@ -46,23 +46,24 @@ public class InferenceSession {
private static final Function<Pair<PsiType, PsiType>, PsiType> UPPER_BOUND_FUNCTION = new Function<Pair<PsiType, PsiType>, PsiType>() {
@Override
public PsiType fun(Pair<PsiType, PsiType> pair) {
if (pair.first instanceof PsiArrayType && TypesDistinctProver.proveArrayTypeDistinct((PsiArrayType)pair.first, pair.second)) {
return null;
}
if (pair.second instanceof PsiArrayType && TypesDistinctProver.proveArrayTypeDistinct((PsiArrayType)pair.second, pair.first)) {
return null;
}
if (pair.first instanceof PsiCapturedWildcardType && TypesDistinctProver.provablyDistinct(((PsiCapturedWildcardType)pair.first).getUpperBound(), pair.second)) {
return null;
}
if (!isValidGlb(pair.first, pair.second)) return null;
if (!isValidGlb(pair.second, pair.first)) return null;
if (pair.second instanceof PsiCapturedWildcardType && TypesDistinctProver.provablyDistinct(((PsiCapturedWildcardType)pair.second).getUpperBound(), pair.first)) {
return null;
}
return GenericsUtil.getGreatestLowerBound(pair.first, pair.second);
}
private boolean isValidGlb(PsiType first, PsiType second) {
if (second instanceof PsiArrayType && TypesDistinctProver.proveArrayTypeDistinct((PsiArrayType)second, first)) {
return false;
}
if (second instanceof PsiCapturedWildcardType && !first.isAssignableFrom(second)) {
final PsiClass conjunct = PsiUtil.resolveClassInType(first);
if (conjunct != null && !conjunct.isInterface() ) {
return false;
}
}
return true;
}
};
private static final String EQUALITY_CONSTRAINTS_PRESENTATION = "equality constraints";

View File

@@ -0,0 +1,26 @@
interface Condition<T> {
boolean value(T t);
}
abstract class Test {
protected static <Impl extends AbstractCache, T extends OCSymbol> T findNearestTopLevelSymbol(Class<Impl> clazz,
Condition<? super T> condition) {
return null;
}
interface OCSymbol {}
interface SwiftSymbol extends OCSymbol {}
class AbstractCache<T extends OCSymbol> {}
class SwiftCache extends AbstractCache<SwiftSymbol> {}
private static void foo(final Condition<? super SwiftSymbol> condition) {
SwiftSymbol s = findNearestTopLevelSymbol(SwiftCache.class, condition);
}
private static void foo1(final Condition<? extends SwiftSymbol> condition) {
SwiftSymbol s = findNearestTopLevelSymbol(SwiftCache.class, condition);
}
}

View File

@@ -391,6 +391,10 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase
doTest();
}
public void testGlbValidityWithCapturedWildcards() throws Exception {
doTest();
}
private void doTest() throws Exception {
doTest(false);
}