~ cst fix
diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java
index 68ed2be..58051be 100644
--- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java
+++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java
@@ -16420,6 +16420,12 @@
}
@Test
+ @TestMetadata("innerTvFixationFromLowerConstraints.kt")
+ public void testInnerTvFixationFromLowerConstraints() throws Exception {
+ runTest("compiler/testData/diagnostics/tests/inference/builderInference/innerTvFixationFromLowerConstraints.kt");
+ }
+
+ @Test
@TestMetadata("invalidateKeys.kt")
public void testInvalidateKeys() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/builderInference/invalidateKeys.kt");
diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java
index 1fd63e8..3fdd2f4 100644
--- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java
+++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java
@@ -16420,6 +16420,12 @@
}
@Test
+ @TestMetadata("innerTvFixationFromLowerConstraints.kt")
+ public void testInnerTvFixationFromLowerConstraints() throws Exception {
+ runTest("compiler/testData/diagnostics/tests/inference/builderInference/innerTvFixationFromLowerConstraints.kt");
+ }
+
+ @Test
@TestMetadata("invalidateKeys.kt")
public void testInvalidateKeys() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/builderInference/invalidateKeys.kt");
diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java
index 3050112..350f863 100644
--- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java
+++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java
@@ -16414,6 +16414,12 @@
}
@Test
+ @TestMetadata("innerTvFixationFromLowerConstraints.kt")
+ public void testInnerTvFixationFromLowerConstraints() throws Exception {
+ runTest("compiler/testData/diagnostics/tests/inference/builderInference/innerTvFixationFromLowerConstraints.kt");
+ }
+
+ @Test
@TestMetadata("invalidateKeys.kt")
public void testInvalidateKeys() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/builderInference/invalidateKeys.kt");
diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java
index 0295745..37cb735 100644
--- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java
+++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java
@@ -16420,6 +16420,12 @@
}
@Test
+ @TestMetadata("innerTvFixationFromLowerConstraints.kt")
+ public void testInnerTvFixationFromLowerConstraints() throws Exception {
+ runTest("compiler/testData/diagnostics/tests/inference/builderInference/innerTvFixationFromLowerConstraints.kt");
+ }
+
+ @Test
@TestMetadata("invalidateKeys.kt")
public void testInvalidateKeys() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/builderInference/invalidateKeys.kt");
diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt
index c75d763..90b2fdd 100644
--- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt
+++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt
@@ -14,10 +14,7 @@
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
-import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
-import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
-import org.jetbrains.kotlin.fir.resolve.substitution.NoSubstitutor
-import org.jetbrains.kotlin.fir.resolve.substitution.createTypeSubstitutorByTypeConstructor
+import org.jetbrains.kotlin.fir.resolve.substitution.*
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousObjectSymbol
@@ -351,6 +348,15 @@
return ConeSubstitutor.Empty
}
+ override fun createSubstitutionFromSubtypingStubTypesToTypeVariables(): TypeSubstitutorMarker {
+ return object : AbstractConeSubstitutor(this) {
+ override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
+ return ((type as? ConeStubTypeForTypeVariableInSubtyping)
+ ?.constructor?.variable?.defaultType)?.withNullability(type.nullability, this@ConeInferenceContext)
+ }
+ }
+ }
+
override fun TypeSubstitutorMarker.safeSubstitute(type: KotlinTypeMarker): KotlinTypeMarker {
if (this === NoSubstitutor) return type
require(this is ConeSubstitutor)
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt
index a29b0f8..df4f7c34 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt
@@ -603,6 +603,10 @@
return IrTypeSubstitutor(emptyMap())
}
+ override fun createSubstitutionFromSubtypingStubTypesToTypeVariables(): TypeSubstitutorMarker {
+ error("Only for inference")
+ }
+
override fun TypeSubstitutorMarker.safeSubstitute(type: KotlinTypeMarker): KotlinTypeMarker {
require(this is AbstractIrTypeSubstitutor)
require(type is IrType)
diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt
index de12ac5..5517947 100644
--- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt
+++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt
@@ -22,6 +22,7 @@
private val languageVersionSettings: LanguageVersionSettings
) {
interface Context : TypeSystemInferenceExtensionContext {
+ val outerSystemVariablesPrefixSize: Int
fun isProperType(type: KotlinTypeMarker): Boolean
fun buildNotFixedVariablesToStubTypesSubstitutor(): TypeSubstitutorMarker
fun isReified(variable: TypeVariableMarker): Boolean
@@ -220,6 +221,8 @@
if (typesWithoutStubs.isNotEmpty()) {
commonSuperType = computeCommonSuperType(typesWithoutStubs)
+ } else if (outerSystemVariablesPrefixSize > 0) {
+ commonSuperType = createSubstitutionFromSubtypingStubTypesToTypeVariables().safeSubstitute(commonSuperType)
}
}
@@ -273,11 +276,23 @@
}
if (!atLeastOneProper) return emptyList()
- if (!atLeastOneNonProper) return lowerConstraintTypes
+
+ val noOuterTypeVariables = outerSystemVariablesPrefixSize == 0
+ if (!atLeastOneNonProper && noOuterTypeVariables) return lowerConstraintTypes
+
+ // Might be an optimization
+// if (!noOuterTypeVariables && lowerConstraintTypes.size == 1 && isProperTypeForFixation(lowerConstraintTypes.single())) {
+// return lowerConstraintTypes
+// }
val notFixedToStubTypesSubstitutor = buildNotFixedVariablesToStubTypesSubstitutor()
- return lowerConstraintTypes.map { if (isProperTypeForFixation(it)) it else notFixedToStubTypesSubstitutor.safeSubstitute(it) }
+ return lowerConstraintTypes.map {
+ if (noOuterTypeVariables && isProperTypeForFixation(it))
+ it
+ else
+ notFixedToStubTypesSubstitutor.safeSubstitute(it)
+ }
}
private fun Context.sinkIntegerLiteralTypes(types: List<KotlinTypeMarker>): List<KotlinTypeMarker> {
diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/innerTvFixationFromLowerConstraints.fir.kt b/compiler/testData/diagnostics/tests/inference/builderInference/innerTvFixationFromLowerConstraints.fir.kt
new file mode 100644
index 0000000..616a438
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/inference/builderInference/innerTvFixationFromLowerConstraints.fir.kt
@@ -0,0 +1,32 @@
+class Controller<T> {
+ fun yield(t: T): Boolean = true
+}
+
+fun <S> generate(g: suspend Controller<S>.() -> Unit): S = TODO()
+
+fun <E4> select(x: E4, y: E4) {}
+fun <E5> selectL(x: E5, y: E5, l: (E5) -> Unit) {}
+
+fun main(x: Controller<String>) {
+ generate {
+ // Just adding the constraints
+ // Controller<String> <: E4
+ // Controller<S> <: E4
+ // No fixation is required
+ select(x, this)
+ }.length
+
+ generate {
+ // Adding the constraints
+ // Controller<String> <: E5
+ // Controller<S> <: E5
+ // But to analyze lambda we fix E5 to CST(Controller<String>, Controller<S>) = Controller<CST(String, S)>
+ // The question is what is CST(String, S)
+ // And current answer in K2 is that it's String just the same way as when while fixating some TV, it has improper lower constraits
+ // See org.jetbrains.kotlin.resolve.calls.inference.components.ResultTypeResolver.prepareLowerConstraints
+ selectL(x, this) { x ->
+ x.yield(<!ARGUMENT_TYPE_MISMATCH!>1<!>)
+ x.yield("")
+ }
+ }.length
+}
\ No newline at end of file
diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/innerTvFixationFromLowerConstraints.kt b/compiler/testData/diagnostics/tests/inference/builderInference/innerTvFixationFromLowerConstraints.kt
new file mode 100644
index 0000000..aaad0a0
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/inference/builderInference/innerTvFixationFromLowerConstraints.kt
@@ -0,0 +1,32 @@
+class Controller<T> {
+ fun yield(t: T): Boolean = true
+}
+
+fun <S> generate(g: suspend Controller<S>.() -> Unit): S = TODO()
+
+fun <E4> select(x: E4, y: E4) {}
+fun <E5> selectL(x: E5, y: E5, l: (E5) -> Unit) {}
+
+fun main(x: Controller<String>) {
+ generate {
+ // Just adding the constraints
+ // Controller<String> <: E4
+ // Controller<S> <: E4
+ // No fixation is required
+ select(x, this)
+ }.length
+
+ generate {
+ // Adding the constraints
+ // Controller<String> <: E5
+ // Controller<S> <: E5
+ // But to analyze lambda we fix E5 to CST(Controller<String>, Controller<S>) = Controller<CST(String, S)>
+ // The question is what is CST(String, S)
+ // And current answer in K2 is that it's String just the same way as when while fixating some TV, it has improper lower constraits
+ // See org.jetbrains.kotlin.resolve.calls.inference.components.ResultTypeResolver.prepareLowerConstraints
+ selectL(x, this) { x ->
+ x.yield(<!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>)
+ x.yield(<!TYPE_MISMATCH!>""<!>)
+ }
+ }.length
+}
\ No newline at end of file
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 3b69ed7..af3a206 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
@@ -16420,6 +16420,12 @@
}
@Test
+ @TestMetadata("innerTvFixationFromLowerConstraints.kt")
+ public void testInnerTvFixationFromLowerConstraints() throws Exception {
+ runTest("compiler/testData/diagnostics/tests/inference/builderInference/innerTvFixationFromLowerConstraints.kt");
+ }
+
+ @Test
@TestMetadata("invalidateKeys.kt")
public void testInvalidateKeys() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/builderInference/invalidateKeys.kt");
diff --git a/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt b/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt
index 1f26eb4..6a46d3c 100644
--- a/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt
+++ b/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt
@@ -559,6 +559,8 @@
fun typeSubstitutorByTypeConstructor(map: Map<TypeConstructorMarker, KotlinTypeMarker>): TypeSubstitutorMarker
fun createEmptySubstitutor(): TypeSubstitutorMarker
+ fun createSubstitutionFromSubtypingStubTypesToTypeVariables(): TypeSubstitutorMarker
+
/**
* @returns substituted type or [type] if there were no substitution
*/
diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt
index 6518f37..d617635 100644
--- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt
+++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt
@@ -618,6 +618,10 @@
errorSupportedOnlyInTypeInference()
}
+ override fun createSubstitutionFromSubtypingStubTypesToTypeVariables(): TypeSubstitutorMarker {
+ error("Only for K2")
+ }
+
override fun TypeSubstitutorMarker.safeSubstitute(type: KotlinTypeMarker): KotlinTypeMarker {
require(type is UnwrappedType, type::errorMessage)
require(this is TypeSubstitutor, this::errorMessage)