type arguments in bounds check: ensure capture conversion (IDEA-175899)

This commit is contained in:
Anna.Kozlova
2017-07-18 19:13:24 +02:00
parent 2cee5e8cdb
commit b59ffe20e4
3 changed files with 26 additions and 1 deletions
@@ -462,8 +462,12 @@ public class GenericsUtil {
}
public static boolean checkNotInBounds(PsiType type, PsiType bound, PsiReferenceParameterList referenceParameterList) {
//4.10.2
//Given a generic type declaration C<F1,...,Fn> (n > 0), the direct supertypes of the parameterized type C<R1,...,Rn> where at least one of the Ri is a wildcard
//type argument, are the direct supertypes of the parameterized type C<X1,...,Xn> which is the result of applying capture conversion to C<R1,...,Rn>.
PsiType capturedType = PsiUtil.captureToplevelWildcards(type, referenceParameterList);
//allow unchecked conversions in method calls but not in type declaration
return checkNotInBounds(type, bound, PsiTreeUtil.getParentOfType(referenceParameterList, PsiCallExpression.class) != null);
return checkNotInBounds(capturedType, bound, PsiTreeUtil.getParentOfType(referenceParameterList, PsiCallExpression.class) != null);
}
public static boolean checkNotInBounds(PsiType type, PsiType bound, boolean uncheckedConversionByDefault) {
@@ -0,0 +1,20 @@
class EnumBug {
static class Enum<E extends Enum<E>> {
}
static class Option<T> extends Enum<Option<T>> {
}
static class EnumSet<E extends Enum<E>> {
static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
return null;
}
}
public static void main(String[] args) {
EnumSet<<error descr="Type parameter 'EnumBug.Option' is not within its bound; should extend 'EnumBug.Enum<EnumBug.Option<?>>'">Option<?></error>> enumSet = EnumSet.<<error descr="Type parameter 'EnumBug.Option' is not within its bound; should extend 'EnumBug.Enum<EnumBug.Option<?>>'">Option<?></error>>noneOf(Option.class);
EnumSet<<error descr="Type parameter 'EnumBug.Option' is not within its bound; should extend 'EnumBug.Enum<EnumBug.Option>'">Option</error>> enumSetRaw = EnumSet.<Option>noneOf(Option.class);
}
}
@@ -426,4 +426,5 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testEnclosingRefInTopLevelClassExtendingInnerWhichExtendsItsOuter() { doTest8Incompatibility(true); }
public void testGenericThrowTypes() { doTest5(false); }
public void testRecursiveParamBoundsWhenSuperSubstitution() { doTest6(false); }
public void testCaptureForBoundCheck() { doTest6(false); }
}