Take into account captured types with variables during fixation

#KT-41202 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2020-08-26 09:44:57 +03:00
parent 5dbb6fdf50
commit cba13c3c35
11 changed files with 75 additions and 11 deletions
@@ -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");
@@ -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<KotlinTypeMarker>): List<KotlinTypeMarker> {
@@ -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)
@@ -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
}
@@ -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"
}
@@ -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");
@@ -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");
@@ -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");
@@ -15,4 +15,4 @@ enum class ExplicitApiMode(val state: String) {
fun availableValues() = values().joinToString(prefix = "{", postfix = "}") { it.state }
}
}
}
@@ -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");
@@ -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");
@@ -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");