From 703a353d2e7f8d379d1841bddff39550841a0cd8 Mon Sep 17 00:00:00 2001 From: Victor Petukhov Date: Fri, 30 Apr 2021 13:25:08 +0300 Subject: [PATCH] Determine empty constraint system for a builder inference call by presense of not fixed type variables --- ...irOldFrontendDiagnosticsTestGenerated.java | 20 ++-- ...DiagnosticsWithLightTreeTestGenerated.java | 20 ++-- .../inference/BuilderInferenceSession.kt | 21 +--- .../bySpecifiedReturnType.kt | 36 ------- .../bySpecifiedReturnType.txt | 10 -- .../builderInference/constraints/violating.kt | 0 .../withExpectedType.fir.kt} | 3 + .../constraints/withExpectedType.kt | 95 +++++++++++++++++++ .../constraints/withExpectedType.txt | 19 ++++ .../test/runners/DiagnosticTestGenerated.java | 20 ++-- 10 files changed, 160 insertions(+), 84 deletions(-) delete mode 100644 compiler/testData/diagnostics/tests/inference/builderInference/addingConstraints/bySpecifiedReturnType.kt delete mode 100644 compiler/testData/diagnostics/tests/inference/builderInference/addingConstraints/bySpecifiedReturnType.txt create mode 100644 compiler/testData/diagnostics/tests/inference/builderInference/constraints/violating.kt rename compiler/testData/diagnostics/tests/inference/builderInference/{addingConstraints/bySpecifiedReturnType.fir.kt => constraints/withExpectedType.fir.kt} (90%) create mode 100644 compiler/testData/diagnostics/tests/inference/builderInference/constraints/withExpectedType.kt create mode 100644 compiler/testData/diagnostics/tests/inference/builderInference/constraints/withExpectedType.txt diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index 2d6dcb8ef9d..be4e19c01f3 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -12693,18 +12693,24 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti } @Nested - @TestMetadata("compiler/testData/diagnostics/tests/inference/builderInference/addingConstraints") + @TestMetadata("compiler/testData/diagnostics/tests/inference/builderInference/constraints") @TestDataPath("$PROJECT_ROOT") - public class AddingConstraints { + public class Constraints { @Test - public void testAllFilesPresentInAddingConstraints() throws Exception { - KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/builderInference/addingConstraints"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); + public void testAllFilesPresentInConstraints() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/builderInference/constraints"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } @Test - @TestMetadata("bySpecifiedReturnType.kt") - public void testBySpecifiedReturnType() throws Exception { - runTest("compiler/testData/diagnostics/tests/inference/builderInference/addingConstraints/bySpecifiedReturnType.kt"); + @TestMetadata("violating.kt") + public void testViolating() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/constraints/violating.kt"); + } + + @Test + @TestMetadata("withExpectedType.kt") + public void testWithExpectedType() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/constraints/withExpectedType.kt"); } } diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index fbd9eda2bc0..5acf8f7f5ad 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -12693,18 +12693,24 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac } @Nested - @TestMetadata("compiler/testData/diagnostics/tests/inference/builderInference/addingConstraints") + @TestMetadata("compiler/testData/diagnostics/tests/inference/builderInference/constraints") @TestDataPath("$PROJECT_ROOT") - public class AddingConstraints { + public class Constraints { @Test - public void testAllFilesPresentInAddingConstraints() throws Exception { - KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/builderInference/addingConstraints"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); + public void testAllFilesPresentInConstraints() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/builderInference/constraints"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } @Test - @TestMetadata("bySpecifiedReturnType.kt") - public void testBySpecifiedReturnType() throws Exception { - runTest("compiler/testData/diagnostics/tests/inference/builderInference/addingConstraints/bySpecifiedReturnType.kt"); + @TestMetadata("violating.kt") + public void testViolating() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/constraints/violating.kt"); + } + + @Test + @TestMetadata("withExpectedType.kt") + public void testWithExpectedType() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/constraints/withExpectedType.kt"); } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/BuilderInferenceSession.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/BuilderInferenceSession.kt index d80f63b32f8..43262a17fd2 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/BuilderInferenceSession.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/BuilderInferenceSession.kt @@ -267,7 +267,7 @@ class BuilderInferenceSession( storage: ConstraintStorage, nonFixedToVariablesSubstitutor: NewTypeSubstitutor, shouldIntegrateAllConstraints: Boolean - ): Boolean { + ) { storage.notFixedTypeVariables.values.forEach { if (it.typeVariable.freshTypeConstructor(commonSystem.typeSystemContext) !in commonSystem.allTypeVariables) { commonSystem.registerVariable(it.typeVariable) @@ -287,8 +287,6 @@ class BuilderInferenceSession( * */ val callSubstitutor = storage.buildResultingSubstitutor(commonSystem, transformTypeVariablesToErrorTypes = false) - var introducedConstraint = false - for (initialConstraint in storage.initialConstraints) { val lowerCallSubstituted = callSubstitutor.safeSubstitute(initialConstraint.a as UnwrappedType) val upperCallSubstituted = callSubstitutor.safeSubstitute(initialConstraint.b as UnwrappedType) @@ -297,8 +295,6 @@ class BuilderInferenceSession( if (commonSystem.isProperType(lower) && commonSystem.isProperType(upper)) continue - introducedConstraint = true - when (initialConstraint.constraintKind) { ConstraintKind.LOWER -> error("LOWER constraint shouldn't be used, please use UPPER") @@ -317,11 +313,8 @@ class BuilderInferenceSession( val typeVariable = storage.allTypeVariables.getValue(variableConstructor) commonSystem.registerVariable(typeVariable) commonSystem.addEqualityConstraint((typeVariable as NewTypeVariable).defaultType, type, CoroutinePosition) - introducedConstraint = true } } - - return introducedConstraint } fun addExpectedTypeConstraint( @@ -379,20 +372,14 @@ class BuilderInferenceSession( integrateConstraints(initialStorage, nonFixedToVariablesSubstitutor, false) - var effectivelyEmptyCommonSystem = true - for (call in commonCalls) { - val hasConstraints = - integrateConstraints(call.callResolutionResult.constraintSystem, nonFixedToVariablesSubstitutor, false) - if (hasConstraints) effectivelyEmptyCommonSystem = false + integrateConstraints(call.callResolutionResult.constraintSystem, nonFixedToVariablesSubstitutor, false) } for (call in partiallyResolvedCallsInfo) { - val hasConstraints = - integrateConstraints(call.callResolutionResult.constraintSystem, nonFixedToVariablesSubstitutor, true) - if (hasConstraints) effectivelyEmptyCommonSystem = false + integrateConstraints(call.callResolutionResult.constraintSystem, nonFixedToVariablesSubstitutor, true) } - return effectivelyEmptyCommonSystem + return commonSystem.notFixedTypeVariables.all { it.value.constraints.isEmpty() } } private fun reportErrors(completedCall: CallInfo, resolvedCall: ResolvedCall<*>, errors: List) { diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/addingConstraints/bySpecifiedReturnType.kt b/compiler/testData/diagnostics/tests/inference/builderInference/addingConstraints/bySpecifiedReturnType.kt deleted file mode 100644 index 9dec54e4b28..00000000000 --- a/compiler/testData/diagnostics/tests/inference/builderInference/addingConstraints/bySpecifiedReturnType.kt +++ /dev/null @@ -1,36 +0,0 @@ -// WITH_RUNTIME - -interface A { - fun foo(): MutableList -} - -@ExperimentalStdlibApi -fun main() { - buildList { - add(3) - object : A { - override fun foo(): MutableList = this@buildList - } - } - buildList { - add(3) - val x: String = get(0) - } - buildList { - add("3") - val x: MutableList = this@buildList - } - buildList { - val y: CharSequence = "" - add(y) - val x: MutableList = this@buildList - } - buildList { - add("") - val x: MutableList = this@buildList - } - buildList { - add("") - val x: StringBuilder = get(0) - } -} diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/addingConstraints/bySpecifiedReturnType.txt b/compiler/testData/diagnostics/tests/inference/builderInference/addingConstraints/bySpecifiedReturnType.txt deleted file mode 100644 index be25776a15c..00000000000 --- a/compiler/testData/diagnostics/tests/inference/builderInference/addingConstraints/bySpecifiedReturnType.txt +++ /dev/null @@ -1,10 +0,0 @@ -package - -@kotlin.ExperimentalStdlibApi public fun main(): kotlin.Unit - -public interface A { - public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - public abstract fun foo(): kotlin.collections.MutableList - public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int - public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String -} diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/constraints/violating.kt b/compiler/testData/diagnostics/tests/inference/builderInference/constraints/violating.kt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/addingConstraints/bySpecifiedReturnType.fir.kt b/compiler/testData/diagnostics/tests/inference/builderInference/constraints/withExpectedType.fir.kt similarity index 90% rename from compiler/testData/diagnostics/tests/inference/builderInference/addingConstraints/bySpecifiedReturnType.fir.kt rename to compiler/testData/diagnostics/tests/inference/builderInference/constraints/withExpectedType.fir.kt index b805ca8b5cd..5de75a7c432 100644 --- a/compiler/testData/diagnostics/tests/inference/builderInference/addingConstraints/bySpecifiedReturnType.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/builderInference/constraints/withExpectedType.fir.kt @@ -33,4 +33,7 @@ fun main() { add("") val x: StringBuilder = get(0) } + buildMap { + val x: Function2 = ::put + } } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/constraints/withExpectedType.kt b/compiler/testData/diagnostics/tests/inference/builderInference/constraints/withExpectedType.kt new file mode 100644 index 00000000000..63fae382639 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/constraints/withExpectedType.kt @@ -0,0 +1,95 @@ +// WITH_RUNTIME +// !DIAGNOSTICS: -EXPERIMENTAL_API_USAGE_ERROR + +interface A { + fun foo(): MutableList +} + +fun id(x: K): K = x + +fun build(@BuilderInference builderAction: MutableMap.() -> V) {} + +fun build2(@BuilderInference builderAction: MutableMap.() -> K) {} + +fun build3(@BuilderInference builderAction: MutableMap.(K) -> Unit) {} + +fun build4(@BuilderInference builderAction: MutableMap.() -> MutableMap) {} + +fun build5(@BuilderInference builderAction: MutableMap.() -> MutableMap) {} + +fun build6(@BuilderInference builderAction: MutableMap.() -> MutableMap) {} + +fun build7(@BuilderInference builderAction: MutableMap.() -> MutableMap): MutableMap {} + +@ExperimentalStdlibApi +fun main() { + buildList { + add(3) + object : A { + override fun foo(): MutableList = this@buildList + } + } + buildList { + add(3) + val x: String = get(0) + } + buildList { + add("3") + val x: MutableList = this@buildList + } + buildList { + val y: CharSequence = "" + add(y) + val x: MutableList = this@buildList + } + buildList { + add("") + val x: MutableList = this@buildList + } + buildList { + add("") + val x: StringBuilder = get(0) + } + buildMap { + val x: Function2 = ::put + } + + build { + get("") + "" + } + + build2 { + val x: String = this.values.first() + 1 + } + + build2 { + take(this.values.first()) + 1 + } + + build3 { key: String -> + take(this.values.first()) + } + + build3 { this.foo() } + + build4 { this } + + build4 { this.run { this } } + + build4 { run { this } } + build4 { id(run { this }) } + + build5 { id(run { this }) } + build6 { id(run { this }) } + + val x: MutableMap = build7 { + id(run { this }) + } +} + +fun MutableMap.foo() {} + +fun take(x: String) {} diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/constraints/withExpectedType.txt b/compiler/testData/diagnostics/tests/inference/builderInference/constraints/withExpectedType.txt new file mode 100644 index 00000000000..9bf9150d1f6 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/constraints/withExpectedType.txt @@ -0,0 +1,19 @@ +package + +public fun build(/*0*/ @kotlin.BuilderInference builderAction: kotlin.collections.MutableMap.() -> V): kotlin.Unit +public fun build2(/*0*/ @kotlin.BuilderInference builderAction: kotlin.collections.MutableMap.() -> K): kotlin.Unit +public fun build3(/*0*/ @kotlin.BuilderInference builderAction: kotlin.collections.MutableMap.(K) -> kotlin.Unit): kotlin.Unit +public fun build4(/*0*/ @kotlin.BuilderInference builderAction: kotlin.collections.MutableMap.() -> kotlin.collections.MutableMap): kotlin.Unit +public fun build5(/*0*/ @kotlin.BuilderInference builderAction: kotlin.collections.MutableMap.() -> kotlin.collections.MutableMap): kotlin.Unit +public fun build6(/*0*/ @kotlin.BuilderInference builderAction: kotlin.collections.MutableMap.() -> kotlin.collections.MutableMap): kotlin.Unit +public fun id(/*0*/ x: K): K +@kotlin.ExperimentalStdlibApi public fun main(): kotlin.Unit +public fun take(/*0*/ x: kotlin.String): kotlin.Unit +public fun kotlin.collections.MutableMap.foo(): kotlin.Unit + +public interface A { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun foo(): kotlin.collections.MutableList + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index f8c18499ea5..911c0443a5a 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -12699,18 +12699,24 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { } @Nested - @TestMetadata("compiler/testData/diagnostics/tests/inference/builderInference/addingConstraints") + @TestMetadata("compiler/testData/diagnostics/tests/inference/builderInference/constraints") @TestDataPath("$PROJECT_ROOT") - public class AddingConstraints { + public class Constraints { @Test - public void testAllFilesPresentInAddingConstraints() throws Exception { - KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/builderInference/addingConstraints"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); + public void testAllFilesPresentInConstraints() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/builderInference/constraints"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } @Test - @TestMetadata("bySpecifiedReturnType.kt") - public void testBySpecifiedReturnType() throws Exception { - runTest("compiler/testData/diagnostics/tests/inference/builderInference/addingConstraints/bySpecifiedReturnType.kt"); + @TestMetadata("violating.kt") + public void testViolating() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/constraints/violating.kt"); + } + + @Test + @TestMetadata("withExpectedType.kt") + public void testWithExpectedType() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/constraints/withExpectedType.kt"); } }