ensure bounds are promoted on derived type otherwise bounds from super could appear on unbounded wildcards (IDEA-162882)

This commit is contained in:
Anna.Kozlova
2016-11-02 15:51:14 +01:00
parent bf259fed79
commit d336733d3e
3 changed files with 39 additions and 6 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@ import com.intellij.psi.impl.source.resolve.graphInference.InferenceBound;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import java.util.HashSet;
@@ -141,15 +140,23 @@ public class StrictSubtypingConstraint implements ConstraintFormula {
if (sType == null) return false;
final PsiClassType.ClassResolveResult SResult = sType.resolveGenerics();
PsiClass SClass = SResult.getElement();
if (SClass == null) return false;
PsiSubstitutor substitutor = SResult.getSubstitutor();
for (PsiTypeParameter typeParameter : SClass.getTypeParameters()) {
substitutor = substitutor.put(typeParameter, substitutor.substituteWithBoundsPromotion(typeParameter));
}
if (((PsiClassType)myT).isRaw()) {
return SClass != null && InheritanceUtil.isInheritorOrSelf(SClass, CClass, true);
return InheritanceUtil.isInheritorOrSelf(SClass, CClass, true);
}
final PsiSubstitutor tSubstitutor = TResult.getSubstitutor();
final PsiSubstitutor sSubstitutor = SClass != null ? TypeConversionUtil.getClassSubstitutor(CClass, SClass, SResult.getSubstitutor()) : null;
final PsiSubstitutor sSubstitutor = TypeConversionUtil.getClassSubstitutor(CClass, SClass, substitutor);
if (sSubstitutor != null) {
for (PsiTypeParameter parameter : CClass.getTypeParameters()) {
final PsiType tSubstituted = tSubstitutor.substitute(parameter);
final PsiType sSubstituted = sSubstitutor.substituteWithBoundsPromotion(parameter);
final PsiType sSubstituted = sSubstitutor.substitute(parameter);
if (tSubstituted == null ^ sSubstituted == null) {
return false;
}
@@ -0,0 +1,23 @@
import java.util.Collection;
interface NumberCollection<N extends Number> extends Collection<N> {
}
interface IntegerCollection<I extends Integer> extends NumberCollection<I> {}
interface IntegerCollection1<I extends Integer, L extends I> extends NumberCollection<L> {}
class Test {
<T extends Number, C extends NumberCollection<? extends T>> Collection<T> filter(Collection<C> input) {
return null;
}
public void foo(Collection<IntegerCollection<?>> input) {
Collection<Integer> filtered = filter(input);
}
public void foo1(Collection<IntegerCollection1<?, ?>> input) {
Collection<Integer> filtered = filter(input);
}
}
@@ -21,7 +21,6 @@ import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection;
import com.intellij.codeInspection.unusedImport.UnusedImportLocalInspection;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.testFramework.IdeaTestUtil;
@@ -1009,4 +1008,8 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase {
public void testTypeParameterBoundsWithSubstitutionWhenMethodHierarchyIsChecked() throws Exception {
doTest();
}
public void testBoundsPromotionForDerivedType() throws Exception {
doTest();
}
}