Take into account captured types with variables during fixation
#KT-41202 Fixed
This commit is contained in:
Generated
+5
@@ -12582,6 +12582,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/inference/earlyReturnInsideCrossinlineLambda.kt");
|
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")
|
@TestMetadata("integerLiteralTypeInLamdaReturnType.kt")
|
||||||
public void testIntegerLiteralTypeInLamdaReturnType() throws Exception {
|
public void testIntegerLiteralTypeInLamdaReturnType() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt");
|
runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt");
|
||||||
|
|||||||
+8
-5
@@ -94,7 +94,7 @@ class ResultTypeResolver(
|
|||||||
typeApproximator.approximateToSuperType(this, TypeApproximatorConfiguration.PublicDeclaration) ?: this
|
typeApproximator.approximateToSuperType(this, TypeApproximatorConfiguration.PublicDeclaration) ?: this
|
||||||
|
|
||||||
private fun Context.isSuitableType(resultType: KotlinTypeMarker, variableWithConstraints: VariableWithConstraints): Boolean {
|
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) {
|
for (constraint in filteredConstraints) {
|
||||||
if (!checkConstraint(this, constraint.type, constraint.kind, resultType)) return false
|
if (!checkConstraint(this, constraint.type, constraint.kind, resultType)) return false
|
||||||
}
|
}
|
||||||
@@ -171,7 +171,7 @@ class ResultTypeResolver(
|
|||||||
val type = constraint.type
|
val type = constraint.type
|
||||||
lowerConstraintTypes.add(type)
|
lowerConstraintTypes.add(type)
|
||||||
|
|
||||||
if (isProperType(type)) {
|
if (isProperTypeForFixation(type)) {
|
||||||
atLeastOneProper = true
|
atLeastOneProper = true
|
||||||
} else {
|
} else {
|
||||||
atLeastOneNonProper = true
|
atLeastOneNonProper = true
|
||||||
@@ -183,7 +183,7 @@ class ResultTypeResolver(
|
|||||||
|
|
||||||
val notFixedToStubTypesSubstitutor = buildNotFixedVariablesToStubTypesSubstitutor()
|
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<KotlinTypeMarker>): List<KotlinTypeMarker> {
|
private fun Context.sinkIntegerLiteralTypes(types: List<KotlinTypeMarker>): List<KotlinTypeMarker> {
|
||||||
@@ -196,7 +196,7 @@ class ResultTypeResolver(
|
|||||||
|
|
||||||
private fun Context.findSuperType(variableWithConstraints: VariableWithConstraints): KotlinTypeMarker? {
|
private fun Context.findSuperType(variableWithConstraints: VariableWithConstraints): KotlinTypeMarker? {
|
||||||
val upperConstraints =
|
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()) {
|
if (upperConstraints.isNotEmpty()) {
|
||||||
val upperType = intersectTypes(upperConstraints.map { it.type })
|
val upperType = intersectTypes(upperConstraints.map { it.type })
|
||||||
|
|
||||||
@@ -208,10 +208,13 @@ class ResultTypeResolver(
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun Context.isProperTypeForFixation(type: KotlinTypeMarker): Boolean =
|
||||||
|
isProperTypeForFixation(type) { isProperType(it) }
|
||||||
|
|
||||||
private fun findResultIfThereIsEqualsConstraint(c: Context, variableWithConstraints: VariableWithConstraints): KotlinTypeMarker? =
|
private fun findResultIfThereIsEqualsConstraint(c: Context, variableWithConstraints: VariableWithConstraints): KotlinTypeMarker? =
|
||||||
with(c) {
|
with(c) {
|
||||||
val properEqualityConstraints = variableWithConstraints.constraints.filter {
|
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)
|
return c.representativeFromEqualityConstraints(properEqualityConstraints)
|
||||||
|
|||||||
+17
-5
@@ -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.DeclaredUpperBoundConstraintPosition
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.VariableWithConstraints
|
import org.jetbrains.kotlin.resolve.calls.inference.model.VariableWithConstraints
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtomMarker
|
import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtomMarker
|
||||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
import org.jetbrains.kotlin.types.model.*
|
||||||
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
|
||||||
import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext
|
|
||||||
import org.jetbrains.kotlin.types.model.TypeVariableMarker
|
|
||||||
|
|
||||||
class VariableFixationFinder(
|
class VariableFixationFinder(
|
||||||
private val trivialConstraintTypeInferenceOracle: TrivialConstraintTypeInferenceOracle
|
private val trivialConstraintTypeInferenceOracle: TrivialConstraintTypeInferenceOracle
|
||||||
@@ -146,8 +143,23 @@ class VariableFixationFinder(
|
|||||||
&& !c.isNullabilityConstraint
|
&& !c.isNullabilityConstraint
|
||||||
|
|
||||||
private fun Context.isProperType(type: KotlinTypeMarker): Boolean =
|
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 =
|
private fun Context.isReified(variable: TypeConstructorMarker): Boolean =
|
||||||
notFixedTypeVariables[variable]?.typeVariable?.let { isReified(it) } ?: false
|
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
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
class Inv<T>
|
||||||
|
|
||||||
|
fun <T : V, U : V, V> foo(x: T, y: Inv<in U>) {}
|
||||||
|
|
||||||
|
fun <E> materializeInvInv(): Inv<in Inv<E>?> = Inv()
|
||||||
|
|
||||||
|
fun test(inv: Inv<Int>) {
|
||||||
|
foo(inv, materializeInvInv())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
test(Inv<Int>())
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+5
@@ -13807,6 +13807,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/inference/earlyReturnInsideCrossinlineLambda.kt");
|
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")
|
@TestMetadata("integerLiteralTypeInLamdaReturnType.kt")
|
||||||
public void testIntegerLiteralTypeInLamdaReturnType() throws Exception {
|
public void testIntegerLiteralTypeInLamdaReturnType() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt");
|
runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt");
|
||||||
|
|||||||
+5
@@ -13807,6 +13807,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/inference/earlyReturnInsideCrossinlineLambda.kt");
|
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")
|
@TestMetadata("integerLiteralTypeInLamdaReturnType.kt")
|
||||||
public void testIntegerLiteralTypeInLamdaReturnType() throws Exception {
|
public void testIntegerLiteralTypeInLamdaReturnType() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt");
|
runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt");
|
||||||
|
|||||||
+5
@@ -12582,6 +12582,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/inference/earlyReturnInsideCrossinlineLambda.kt");
|
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")
|
@TestMetadata("integerLiteralTypeInLamdaReturnType.kt")
|
||||||
public void testIntegerLiteralTypeInLamdaReturnType() throws Exception {
|
public void testIntegerLiteralTypeInLamdaReturnType() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt");
|
runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt");
|
||||||
|
|||||||
Generated
+5
@@ -10772,6 +10772,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
|||||||
runTest("compiler/testData/codegen/box/inference/earlyReturnInsideCrossinlineLambda.kt");
|
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")
|
@TestMetadata("integerLiteralTypeInLamdaReturnType.kt")
|
||||||
public void testIntegerLiteralTypeInLamdaReturnType() throws Exception {
|
public void testIntegerLiteralTypeInLamdaReturnType() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt");
|
runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt");
|
||||||
|
|||||||
Generated
+5
@@ -10772,6 +10772,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/inference/earlyReturnInsideCrossinlineLambda.kt");
|
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")
|
@TestMetadata("integerLiteralTypeInLamdaReturnType.kt")
|
||||||
public void testIntegerLiteralTypeInLamdaReturnType() throws Exception {
|
public void testIntegerLiteralTypeInLamdaReturnType() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt");
|
runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt");
|
||||||
|
|||||||
+5
@@ -10837,6 +10837,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/inference/earlyReturnInsideCrossinlineLambda.kt");
|
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")
|
@TestMetadata("integerLiteralTypeInLamdaReturnType.kt")
|
||||||
public void testIntegerLiteralTypeInLamdaReturnType() throws Exception {
|
public void testIntegerLiteralTypeInLamdaReturnType() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt");
|
runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user