Process captured types with type variable inside properly, in the operations related with the type variables fixation
This commit is contained in:
+1
-1
@@ -143,7 +143,7 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("javaAnnotationArrayValueDefault.kt")
|
@TestMetadata("javaAnnotatestInferenceWithTypeVariableInsideCapturedType tionArrayValueDefault.kt")
|
||||||
public void testJavaAnnotationArrayValueDefault() throws Exception {
|
public void testJavaAnnotationArrayValueDefault() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/annotations/javaAnnotationArrayValueDefault.kt");
|
runTest("compiler/testData/codegen/box/annotations/javaAnnotationArrayValueDefault.kt");
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -94,7 +94,7 @@ class ConstraintIncorporator(
|
|||||||
val freshTypeConstructor = typeVariable.freshTypeConstructor()
|
val freshTypeConstructor = typeVariable.freshTypeConstructor()
|
||||||
for (typeVariableWithConstraint in this@insideOtherConstraint.allTypeVariablesWithConstraints) {
|
for (typeVariableWithConstraint in this@insideOtherConstraint.allTypeVariablesWithConstraints) {
|
||||||
val constraintsWhichConstraintMyVariable = typeVariableWithConstraint.constraints.filter {
|
val constraintsWhichConstraintMyVariable = typeVariableWithConstraint.constraints.filter {
|
||||||
it.type.contains { it.typeConstructor() == freshTypeConstructor }
|
containsTypeVariable(it.type, freshTypeConstructor)
|
||||||
}
|
}
|
||||||
constraintsWhichConstraintMyVariable.forEach {
|
constraintsWhichConstraintMyVariable.forEach {
|
||||||
generateNewConstraint(typeVariableWithConstraint.typeVariable, it, typeVariable, constraint)
|
generateNewConstraint(typeVariableWithConstraint.typeVariable, it, typeVariable, constraint)
|
||||||
@@ -130,7 +130,7 @@ class ConstraintIncorporator(
|
|||||||
otherConstraint: Constraint
|
otherConstraint: Constraint
|
||||||
) {
|
) {
|
||||||
val isBaseGenericType = baseConstraint.type.argumentsCount() != 0
|
val isBaseGenericType = baseConstraint.type.argumentsCount() != 0
|
||||||
val isOtherCapturedType = otherConstraint.type.isCapturedType()
|
val isBaseOrOtherCapturedType = baseConstraint.type.isCapturedType() || otherConstraint.type.isCapturedType()
|
||||||
val (type, needApproximation) = when (otherConstraint.kind) {
|
val (type, needApproximation) = when (otherConstraint.kind) {
|
||||||
ConstraintKind.EQUALITY -> {
|
ConstraintKind.EQUALITY -> {
|
||||||
otherConstraint.type to false
|
otherConstraint.type to false
|
||||||
@@ -145,9 +145,9 @@ class ConstraintIncorporator(
|
|||||||
* incorporatedConstraint = Approx(CapturedType(out Number)) <: TypeVariable(A) => Nothing <: TypeVariable(A)
|
* incorporatedConstraint = Approx(CapturedType(out Number)) <: TypeVariable(A) => Nothing <: TypeVariable(A)
|
||||||
* TODO: implement this for generics and captured types
|
* TODO: implement this for generics and captured types
|
||||||
*/
|
*/
|
||||||
if (baseConstraint.kind == ConstraintKind.LOWER && !isBaseGenericType && !isOtherCapturedType) {
|
if (baseConstraint.kind == ConstraintKind.LOWER && !isBaseGenericType && !isBaseOrOtherCapturedType) {
|
||||||
nothingType() to false
|
nothingType() to false
|
||||||
} else if (baseConstraint.kind == ConstraintKind.UPPER && !isBaseGenericType && !isOtherCapturedType) {
|
} else if (baseConstraint.kind == ConstraintKind.UPPER && !isBaseGenericType && !isBaseOrOtherCapturedType) {
|
||||||
otherConstraint.type to false
|
otherConstraint.type to false
|
||||||
} else {
|
} else {
|
||||||
createCapturedType(
|
createCapturedType(
|
||||||
@@ -168,9 +168,9 @@ class ConstraintIncorporator(
|
|||||||
* incorporatedConstraint = TypeVariable(A) <: Approx(CapturedType(in Number)) => TypeVariable(A) <: Any?
|
* incorporatedConstraint = TypeVariable(A) <: Approx(CapturedType(in Number)) => TypeVariable(A) <: Any?
|
||||||
* TODO: implement this for generics and captured types
|
* TODO: implement this for generics and captured types
|
||||||
*/
|
*/
|
||||||
if (baseConstraint.kind == ConstraintKind.UPPER && !isBaseGenericType && !isOtherCapturedType) {
|
if (baseConstraint.kind == ConstraintKind.UPPER && !isBaseGenericType && !isBaseOrOtherCapturedType) {
|
||||||
nullableAnyType() to false
|
nullableAnyType() to false
|
||||||
} else if (baseConstraint.kind == ConstraintKind.LOWER && !isBaseGenericType && !isOtherCapturedType) {
|
} else if (baseConstraint.kind == ConstraintKind.LOWER && !isBaseGenericType && !isBaseOrOtherCapturedType) {
|
||||||
otherConstraint.type to false
|
otherConstraint.type to false
|
||||||
} else {
|
} else {
|
||||||
createCapturedType(
|
createCapturedType(
|
||||||
|
|||||||
+27
-11
@@ -168,17 +168,33 @@ class VariableFixationFinder(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun TypeSystemInferenceExtensionContext.isProperTypeForFixation(
|
inline fun TypeSystemInferenceExtensionContext.isProperTypeForFixation(type: KotlinTypeMarker, isProper: (KotlinTypeMarker) -> Boolean) =
|
||||||
type: KotlinTypeMarker,
|
isProper(type) && extractProjectionsForAllCapturedTypes(type).all(isProper)
|
||||||
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
|
@OptIn(ExperimentalStdlibApi::class)
|
||||||
|
fun TypeSystemInferenceExtensionContext.extractProjectionsForAllCapturedTypes(baseType: KotlinTypeMarker): Set<KotlinTypeMarker> {
|
||||||
|
val simpleBaseType = baseType.asSimpleType()
|
||||||
|
|
||||||
|
return buildSet {
|
||||||
|
val projectionType = if (simpleBaseType is CapturedTypeMarker) {
|
||||||
|
val typeArgument = simpleBaseType.typeConstructorProjection().takeIf { !it.isStarProjection() } ?: return@buildSet
|
||||||
|
typeArgument.getType().also(::add)
|
||||||
|
} else baseType
|
||||||
|
val argumentsCount = projectionType.argumentsCount().takeIf { it != 0 } ?: return@buildSet
|
||||||
|
|
||||||
|
for (i in 0 until argumentsCount) {
|
||||||
|
val typeArgument = projectionType.getArgument(i).takeIf { !it.isStarProjection() } ?: continue
|
||||||
|
addAll(extractProjectionsForAllCapturedTypes(typeArgument.getType()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun TypeSystemInferenceExtensionContext.containsTypeVariable(type: KotlinTypeMarker, typeVariable: TypeConstructorMarker): Boolean {
|
||||||
|
if (type.contains { it.typeConstructor() == typeVariable }) return true
|
||||||
|
|
||||||
|
val typeProjections = extractProjectionsForAllCapturedTypes(type)
|
||||||
|
|
||||||
|
return typeProjections.any { typeProjectionsType ->
|
||||||
|
typeProjectionsType.contains { it.typeConstructor() == typeVariable }
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-3
@@ -336,9 +336,7 @@ class NewConstraintSystemImpl(
|
|||||||
val variableWithConstraints = notFixedTypeVariables.remove(freshTypeConstructor)
|
val variableWithConstraints = notFixedTypeVariables.remove(freshTypeConstructor)
|
||||||
|
|
||||||
for (otherVariableWithConstraints in notFixedTypeVariables.values) {
|
for (otherVariableWithConstraints in notFixedTypeVariables.values) {
|
||||||
otherVariableWithConstraints.removeConstrains { otherConstraint ->
|
otherVariableWithConstraints.removeConstrains { containsTypeVariable(it.type, freshTypeConstructor) }
|
||||||
otherConstraint.type.contains { it.typeConstructor() == freshTypeConstructor }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
storage.fixedTypeVariables[freshTypeConstructor] = resultType
|
storage.fixedTypeVariables[freshTypeConstructor] = resultType
|
||||||
|
|||||||
Reference in New Issue
Block a user