From 78095fd61d9d1320f2cc117a318841fd66e4ab0e Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 14 May 2019 09:41:10 +0200 Subject: [PATCH] inference: check lower bounds assignability to upper bounds lub may break some capture invariants GitOrigin-RevId: c7857bf255c357471fd9f14fc161d2ca03769f4b --- .../graphInference/InferenceSession.java | 17 +++++++++-------- .../LowerBoundAssignabilityCheck.java | 11 +++++++++++ .../lambda/GenericsHighlighting8Test.java | 1 + 3 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/LowerBoundAssignabilityCheck.java diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java index d88afe7ea6c7..fd149b5d3594 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java @@ -1205,17 +1205,18 @@ public class InferenceSession { else { for (PsiType upperType : var.getBounds(InferenceBound.UPPER)) { if (myErrorMessages == null && isProperType(upperType)) { - String incompatibleBoundsMessage = null; if (type != lowerBound && !TypeConversionUtil.isAssignable(upperType, type)) { - incompatibleBoundsMessage = incompatibleBoundsMessage(var, substitutor, InferenceBound.EQ, EQUALITY_CONSTRAINTS_PRESENTATION, InferenceBound.UPPER, UPPER_BOUNDS_PRESENTATION); - } - else if (type == lowerBound && !TypeConversionUtil.isAssignable(upperType, lowerBound)) { - incompatibleBoundsMessage = incompatibleBoundsMessage(var, substitutor, InferenceBound.LOWER, LOWER_BOUNDS_PRESENTATION, InferenceBound.UPPER, UPPER_BOUNDS_PRESENTATION); - } - if (incompatibleBoundsMessage != null) { - registerIncompatibleErrorMessage(incompatibleBoundsMessage); + registerIncompatibleErrorMessage(incompatibleBoundsMessage(var, substitutor, InferenceBound.EQ, EQUALITY_CONSTRAINTS_PRESENTATION, InferenceBound.UPPER, UPPER_BOUNDS_PRESENTATION)); return PsiType.NULL; } + else if (type == lowerBound) { + for (PsiType lowerBoundConjunct : var.getBounds(InferenceBound.LOWER)) { + if (isProperType(lowerBoundConjunct) && !TypeConversionUtil.isAssignable(upperType, lowerBoundConjunct)) { + registerIncompatibleErrorMessage(incompatibleBoundsMessage(var, substitutor, InferenceBound.LOWER, LOWER_BOUNDS_PRESENTATION, InferenceBound.UPPER, UPPER_BOUNDS_PRESENTATION)); + return PsiType.NULL; + } + } + } } } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/LowerBoundAssignabilityCheck.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/LowerBoundAssignabilityCheck.java new file mode 100644 index 000000000000..2d8ebc794eaf --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/LowerBoundAssignabilityCheck.java @@ -0,0 +1,11 @@ +class MyTest { + static void m(Ref commentRef) { + commentRef = coalesce(commentRef, commentRef); + } + + static T coalesce(T t1, T t2) { + return t1; + } + + static class Ref { } +} diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/lambda/GenericsHighlighting8Test.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/lambda/GenericsHighlighting8Test.java index c6be10a3e868..3e214035245a 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/lambda/GenericsHighlighting8Test.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/lambda/GenericsHighlighting8Test.java @@ -1043,5 +1043,6 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase { public void testNestedWildcardsWithImplicitBounds() { doTest(); } public void testCallOnRawWithExplicitTypeArguments() { doTest(); } public void testNoCaptureConversionDuringDetectingSupertypesDeepInHierarchy() { doTest(); } + public void testLowerBoundAssignabilityCheck() { doTest(); } public void testIgnoreErasureForProperTypeBound() { doTest(); } }