diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index ad13827d89e..d432392e31d 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -12582,6 +12582,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/inference/earlyReturnInsideCrossinlineLambda.kt"); } + @TestMetadata("inferenceWithTypeVariableInsideCapturedType.kt") + public void testInferenceWithTypeVariableInsideCapturedType() throws Exception { + runTest("compiler/testData/codegen/box/inference/inferenceWithTypeVariableInsideCapturedType.kt"); + } + @TestMetadata("integerLiteralTypeInLamdaReturnType.kt") public void testIntegerLiteralTypeInLamdaReturnType() throws Exception { runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt"); diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt index ad01d41b6be..1e214b2a9db 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt @@ -94,7 +94,7 @@ class ResultTypeResolver( typeApproximator.approximateToSuperType(this, TypeApproximatorConfiguration.PublicDeclaration) ?: this private fun Context.isSuitableType(resultType: KotlinTypeMarker, variableWithConstraints: VariableWithConstraints): Boolean { - val filteredConstraints = variableWithConstraints.constraints.filter { isProperType(it.type) } + val filteredConstraints = variableWithConstraints.constraints.filter { isProperTypeForFixation(it.type) } for (constraint in filteredConstraints) { if (!checkConstraint(this, constraint.type, constraint.kind, resultType)) return false } @@ -171,7 +171,7 @@ class ResultTypeResolver( val type = constraint.type lowerConstraintTypes.add(type) - if (isProperType(type)) { + if (isProperTypeForFixation(type)) { atLeastOneProper = true } else { atLeastOneNonProper = true @@ -183,7 +183,7 @@ class ResultTypeResolver( val notFixedToStubTypesSubstitutor = buildNotFixedVariablesToStubTypesSubstitutor() - return lowerConstraintTypes.map { if (isProperType(it)) it else notFixedToStubTypesSubstitutor.safeSubstitute(it) } + return lowerConstraintTypes.map { if (isProperTypeForFixation(it)) it else notFixedToStubTypesSubstitutor.safeSubstitute(it) } } private fun Context.sinkIntegerLiteralTypes(types: List): List { @@ -196,7 +196,7 @@ class ResultTypeResolver( private fun Context.findSuperType(variableWithConstraints: VariableWithConstraints): KotlinTypeMarker? { val upperConstraints = - variableWithConstraints.constraints.filter { it.kind == ConstraintKind.UPPER && this@findSuperType.isProperType(it.type) } + variableWithConstraints.constraints.filter { it.kind == ConstraintKind.UPPER && this@findSuperType.isProperTypeForFixation(it.type) } if (upperConstraints.isNotEmpty()) { val upperType = intersectTypes(upperConstraints.map { it.type }) @@ -208,10 +208,13 @@ class ResultTypeResolver( return null } + private fun Context.isProperTypeForFixation(type: KotlinTypeMarker): Boolean = + isProperTypeForFixation(type) { isProperType(it) } + private fun findResultIfThereIsEqualsConstraint(c: Context, variableWithConstraints: VariableWithConstraints): KotlinTypeMarker? = with(c) { val properEqualityConstraints = variableWithConstraints.constraints.filter { - it.kind == ConstraintKind.EQUALITY && c.isProperType(it.type) + it.kind == ConstraintKind.EQUALITY && c.isProperTypeForFixation(it.type) } return c.representativeFromEqualityConstraints(properEqualityConstraints) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt index efddd7f0db4..a22b2f61dee 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt @@ -22,10 +22,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.model.Constraint import org.jetbrains.kotlin.resolve.calls.inference.model.DeclaredUpperBoundConstraintPosition import org.jetbrains.kotlin.resolve.calls.inference.model.VariableWithConstraints import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtomMarker -import org.jetbrains.kotlin.types.model.KotlinTypeMarker -import org.jetbrains.kotlin.types.model.TypeConstructorMarker -import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext -import org.jetbrains.kotlin.types.model.TypeVariableMarker +import org.jetbrains.kotlin.types.model.* class VariableFixationFinder( private val trivialConstraintTypeInferenceOracle: TrivialConstraintTypeInferenceOracle @@ -146,8 +143,23 @@ class VariableFixationFinder( && !c.isNullabilityConstraint private fun Context.isProperType(type: KotlinTypeMarker): Boolean = - !type.contains { notFixedTypeVariables.containsKey(it.typeConstructor()) } + isProperTypeForFixation(type) { t -> !t.contains { notFixedTypeVariables.containsKey(it.typeConstructor()) } } private fun Context.isReified(variable: TypeConstructorMarker): Boolean = notFixedTypeVariables[variable]?.typeVariable?.let { isReified(it) } ?: false +} + +inline fun TypeSystemInferenceExtensionContext.isProperTypeForFixation( + type: KotlinTypeMarker, + isProper: (KotlinTypeMarker) -> Boolean +): Boolean { + if (!isProper(type)) return false + if (type.isCapturedType()) { + val projection = (type as? SimpleTypeMarker)?.asCapturedType()?.typeConstructorProjection() ?: return true + if (projection.isStarProjection()) return true + + if (!isProper(projection.getType())) return false + } + + return true } \ No newline at end of file diff --git a/compiler/testData/codegen/box/inference/inferenceWithTypeVariableInsideCapturedType.kt b/compiler/testData/codegen/box/inference/inferenceWithTypeVariableInsideCapturedType.kt new file mode 100644 index 00000000000..4e69563fcb3 --- /dev/null +++ b/compiler/testData/codegen/box/inference/inferenceWithTypeVariableInsideCapturedType.kt @@ -0,0 +1,14 @@ +class Inv + +fun foo(x: T, y: Inv) {} + +fun materializeInvInv(): Inv?> = Inv() + +fun test(inv: Inv) { + foo(inv, materializeInvInv()) +} + +fun box(): String { + test(Inv()) + return "OK" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 5ff1d4242a4..a3d8a6e1043 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -13807,6 +13807,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/inference/earlyReturnInsideCrossinlineLambda.kt"); } + @TestMetadata("inferenceWithTypeVariableInsideCapturedType.kt") + public void testInferenceWithTypeVariableInsideCapturedType() throws Exception { + runTest("compiler/testData/codegen/box/inference/inferenceWithTypeVariableInsideCapturedType.kt"); + } + @TestMetadata("integerLiteralTypeInLamdaReturnType.kt") public void testIntegerLiteralTypeInLamdaReturnType() throws Exception { runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index fc238d6648c..14ce7373fe8 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -13807,6 +13807,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/inference/earlyReturnInsideCrossinlineLambda.kt"); } + @TestMetadata("inferenceWithTypeVariableInsideCapturedType.kt") + public void testInferenceWithTypeVariableInsideCapturedType() throws Exception { + runTest("compiler/testData/codegen/box/inference/inferenceWithTypeVariableInsideCapturedType.kt"); + } + @TestMetadata("integerLiteralTypeInLamdaReturnType.kt") public void testIntegerLiteralTypeInLamdaReturnType() throws Exception { runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 23cd43d0850..579de52fd63 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -12582,6 +12582,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/inference/earlyReturnInsideCrossinlineLambda.kt"); } + @TestMetadata("inferenceWithTypeVariableInsideCapturedType.kt") + public void testInferenceWithTypeVariableInsideCapturedType() throws Exception { + runTest("compiler/testData/codegen/box/inference/inferenceWithTypeVariableInsideCapturedType.kt"); + } + @TestMetadata("integerLiteralTypeInLamdaReturnType.kt") public void testIntegerLiteralTypeInLamdaReturnType() throws Exception { runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt"); diff --git a/compiler/util/src/org/jetbrains/kotlin/config/ExplicitApiMode.kt b/compiler/util/src/org/jetbrains/kotlin/config/ExplicitApiMode.kt index b354681fe68..0abd538a128 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/ExplicitApiMode.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/ExplicitApiMode.kt @@ -15,4 +15,4 @@ enum class ExplicitApiMode(val state: String) { fun availableValues() = values().joinToString(prefix = "{", postfix = "}") { it.state } } -} \ No newline at end of file +} diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index 548eeda8143..88be8d0a231 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -10772,6 +10772,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/inference/earlyReturnInsideCrossinlineLambda.kt"); } + @TestMetadata("inferenceWithTypeVariableInsideCapturedType.kt") + public void testInferenceWithTypeVariableInsideCapturedType() throws Exception { + runTest("compiler/testData/codegen/box/inference/inferenceWithTypeVariableInsideCapturedType.kt"); + } + @TestMetadata("integerLiteralTypeInLamdaReturnType.kt") public void testIntegerLiteralTypeInLamdaReturnType() throws Exception { runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index ebf3b8b4016..e60b12007da 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -10772,6 +10772,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/inference/earlyReturnInsideCrossinlineLambda.kt"); } + @TestMetadata("inferenceWithTypeVariableInsideCapturedType.kt") + public void testInferenceWithTypeVariableInsideCapturedType() throws Exception { + runTest("compiler/testData/codegen/box/inference/inferenceWithTypeVariableInsideCapturedType.kt"); + } + @TestMetadata("integerLiteralTypeInLamdaReturnType.kt") public void testIntegerLiteralTypeInLamdaReturnType() throws Exception { runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index a3ca82a8c47..87120d3385f 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -10837,6 +10837,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/inference/earlyReturnInsideCrossinlineLambda.kt"); } + @TestMetadata("inferenceWithTypeVariableInsideCapturedType.kt") + public void testInferenceWithTypeVariableInsideCapturedType() throws Exception { + runTest("compiler/testData/codegen/box/inference/inferenceWithTypeVariableInsideCapturedType.kt"); + } + @TestMetadata("integerLiteralTypeInLamdaReturnType.kt") public void testIntegerLiteralTypeInLamdaReturnType() throws Exception { runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt");