From 7898922066a06649bdcac4a937ccf0458733bad6 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Wed, 25 Dec 2019 16:41:17 +0300 Subject: [PATCH] NI: Fix type mismatch caused by smartcast ^KT-25434 Fixed --- ...irOldFrontendDiagnosticsTestGenerated.java | 5 +++ .../tests/inference/tooEagerSmartcast.fir.kt | 42 +++++++++++++++++++ .../tests/inference/tooEagerSmartcast.kt | 42 +++++++++++++++++++ .../checkers/DiagnosticsTestGenerated.java | 5 +++ .../DiagnosticsUsingJavacTestGenerated.java | 5 +++ .../kotlin/types/AbstractTypeChecker.kt | 6 +-- 6 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/inference/tooEagerSmartcast.fir.kt create mode 100644 compiler/testData/diagnostics/tests/inference/tooEagerSmartcast.kt diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java index 2bf92a94dd9..b7433aef74c 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java @@ -10023,6 +10023,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte runTest("compiler/testData/diagnostics/tests/inference/starApproximationFlexible.kt"); } + @TestMetadata("tooEagerSmartcast.kt") + public void testTooEagerSmartcast() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/tooEagerSmartcast.kt"); + } + @TestMetadata("tryNumberLowerBoundsBeforeUpperBounds.kt") public void testTryNumberLowerBoundsBeforeUpperBounds() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/tryNumberLowerBoundsBeforeUpperBounds.kt"); diff --git a/compiler/testData/diagnostics/tests/inference/tooEagerSmartcast.fir.kt b/compiler/testData/diagnostics/tests/inference/tooEagerSmartcast.fir.kt new file mode 100644 index 00000000000..b1a627aa850 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/tooEagerSmartcast.fir.kt @@ -0,0 +1,42 @@ +// SKIP_TXT +// !DIAGNOSTICS: -UNUSED_VARIABLE +// !LANGUAGE: +NewInference + +interface OutBase +interface OutDerived : OutBase + +fun OutBase.myLast(): X = TODO() + +fun foo(x: OutBase) { + if (x is OutDerived<*>) { + val l: T = x.myLast() // required T, found Cap(*). Only in NI + } +} + +interface InvBase +interface InvDerived : InvBase + +fun InvBase.myLastInv(): X = TODO() + +fun fooInv(x: InvBase) { + if (x is InvDerived<*>) { + val l: T = x.myLastInv() // required T, found Cap(*). Only in NI + } +} + +interface Base + +fun Base.foo(): Q = TODO() +fun Base.baz(): Q = TODO() + +interface Derived : Base + +fun Number.num() {} + +fun main(b: Base) { + b.foo().num() + if (b is Derived<*>) { + b.foo().num() + b.baz().length + } +} diff --git a/compiler/testData/diagnostics/tests/inference/tooEagerSmartcast.kt b/compiler/testData/diagnostics/tests/inference/tooEagerSmartcast.kt new file mode 100644 index 00000000000..8ce727216cc --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/tooEagerSmartcast.kt @@ -0,0 +1,42 @@ +// SKIP_TXT +// !DIAGNOSTICS: -UNUSED_VARIABLE +// !LANGUAGE: +NewInference + +interface OutBase +interface OutDerived : OutBase + +fun OutBase.myLast(): X = TODO() + +fun foo(x: OutBase) { + if (x is OutDerived<*>) { + val l: T = x.myLast() // required T, found Cap(*). Only in NI + } +} + +interface InvBase +interface InvDerived : InvBase + +fun InvBase.myLastInv(): X = TODO() + +fun fooInv(x: InvBase) { + if (x is InvDerived<*>) { + val l: T = x.myLastInv() // required T, found Cap(*). Only in NI + } +} + +interface Base + +fun Base.foo(): Q = TODO() +fun Base.baz(): Q = TODO() + +interface Derived : Base + +fun Number.num() {} + +fun main(b: Base) { + b.foo().num() + if (b is Derived<*>) { + b.foo().num() + b.baz().length + } +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 444c67c36c7..14a62f9d20b 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -10030,6 +10030,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { runTest("compiler/testData/diagnostics/tests/inference/starApproximationFlexible.kt"); } + @TestMetadata("tooEagerSmartcast.kt") + public void testTooEagerSmartcast() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/tooEagerSmartcast.kt"); + } + @TestMetadata("tryNumberLowerBoundsBeforeUpperBounds.kt") public void testTryNumberLowerBoundsBeforeUpperBounds() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/tryNumberLowerBoundsBeforeUpperBounds.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index ca669c2af14..3efae0e6fa0 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -10025,6 +10025,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/inference/starApproximationFlexible.kt"); } + @TestMetadata("tooEagerSmartcast.kt") + public void testTooEagerSmartcast() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/tooEagerSmartcast.kt"); + } + @TestMetadata("tryNumberLowerBoundsBeforeUpperBounds.kt") public void testTryNumberLowerBoundsBeforeUpperBounds() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/tryNumberLowerBoundsBeforeUpperBounds.kt"); diff --git a/core/type-system/src/org/jetbrains/kotlin/types/AbstractTypeChecker.kt b/core/type-system/src/org/jetbrains/kotlin/types/AbstractTypeChecker.kt index 7c924eec5d6..3b35de221cc 100644 --- a/core/type-system/src/org/jetbrains/kotlin/types/AbstractTypeChecker.kt +++ b/core/type-system/src/org/jetbrains/kotlin/types/AbstractTypeChecker.kt @@ -269,8 +269,6 @@ object AbstractTypeChecker { 1 -> return isSubtypeForSameConstructor(supertypesWithSameConstructor.first().asArgumentList(), superType) else -> { // at least 2 supertypes with same constructors. Such case is rare - if (supertypesWithSameConstructor.any { isSubtypeForSameConstructor(it.asArgumentList(), superType) }) return true - val newArguments = ArgumentList(superConstructor.parametersCount()) for (index in 0 until superConstructor.parametersCount()) { val allProjections = supertypesWithSameConstructor.map { @@ -283,7 +281,9 @@ object AbstractTypeChecker { newArguments.add(intersection) } - return isSubtypeForSameConstructor(newArguments, superType) + if (isSubtypeForSameConstructor(newArguments, superType)) return true + + return supertypesWithSameConstructor.any { isSubtypeForSameConstructor(it.asArgumentList(), superType) } } } }