From afd59f0d468b83bce022929244f7b7544892a5b3 Mon Sep 17 00:00:00 2001 From: Pavel Kirpichenkov Date: Wed, 20 Nov 2019 15:22:25 +0300 Subject: [PATCH] [NI] Fix 'only input type' check for intersection types Check worked incorrectly in case when argument type and expected type are the same intersection type, which is possible for local variables without explicit type declaration. --- .../calls/inference/model/NewConstraintSystemImpl.kt | 8 +++----- .../inference/intersectionInputType.kt | 12 ++++++++++++ .../inference/intersectionInputType.txt | 3 +++ .../checkers/DiagnosticsTestWithStdLibGenerated.java | 5 +++++ ...DiagnosticsTestWithStdLibUsingJavacGenerated.java | 5 +++++ 5 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 compiler/testData/diagnostics/testsWithStdLib/inference/intersectionInputType.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/inference/intersectionInputType.txt diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt index bdb7a069929..2257a0af47b 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt @@ -275,11 +275,9 @@ class NewConstraintSystemImpl( if (variableWithConstraints == null || variableWithConstraints.typeVariable.safeAs()?.hasOnlyInputTypesAnnotation() != true ) return val projectedInputCallTypes = variableWithConstraints.projectedInputCallTypes val resultTypeIsInputType = projectedInputCallTypes.any { inputType -> - val constructor = inputType.constructor - if (constructor is IntersectionTypeConstructor) - constructor.supertypes.any { NewKotlinTypeChecker.Default.equalTypes(resultType, it) } - else - NewKotlinTypeChecker.Default.equalTypes(resultType, inputType) + NewKotlinTypeChecker.Default.equalTypes(resultType, inputType) || + inputType.constructor is IntersectionTypeConstructor + && inputType.constructor.supertypes.any { NewKotlinTypeChecker.Default.equalTypes(resultType, it) } } if (!resultTypeIsInputType) { addError(OnlyInputTypesDiagnostic(variableWithConstraints.typeVariable as NewTypeVariable)) diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/intersectionInputType.kt b/compiler/testData/diagnostics/testsWithStdLib/inference/intersectionInputType.kt new file mode 100644 index 00000000000..0b312e318b3 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/intersectionInputType.kt @@ -0,0 +1,12 @@ +// !LANGUAGE: +NewInference + +import kotlin.test.assertEquals + +fun test() { + val u = when (true) { + true -> 42 + else -> 1.0 + } + + assertEquals(42, u) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/intersectionInputType.txt b/compiler/testData/diagnostics/testsWithStdLib/inference/intersectionInputType.txt new file mode 100644 index 00000000000..93e27f34c8c --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/intersectionInputType.txt @@ -0,0 +1,3 @@ +package + +public fun test(): kotlin.Unit diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java index 258e58f7a21..03afad08c4f 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java @@ -2716,6 +2716,11 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW runTest("compiler/testData/diagnostics/testsWithStdLib/inference/integerLiterals.kt"); } + @TestMetadata("intersectionInputType.kt") + public void testIntersectionInputType() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/intersectionInputType.kt"); + } + @TestMetadata("kt11266.kt") public void testKt11266() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt11266.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java index 0f0e44936bb..ebabdbe2240 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java @@ -2716,6 +2716,11 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno runTest("compiler/testData/diagnostics/testsWithStdLib/inference/integerLiterals.kt"); } + @TestMetadata("intersectionInputType.kt") + public void testIntersectionInputType() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/intersectionInputType.kt"); + } + @TestMetadata("kt11266.kt") public void testKt11266() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt11266.kt");