From 57a3b1a773202edb480ff1403835c2d3f8b9650a Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Mon, 8 Apr 2019 15:46:57 +0300 Subject: [PATCH] Abstract TypeApproximator from NewCapturedType --- .../kotlin/types/TypeApproximator.kt | 30 +++++++++++-------- .../types/checker/ClassicTypeSystemContext.kt | 5 ++++ .../kotlin/types/model/MarkerExtensions.kt | 5 ++++ .../kotlin/types/model/TypeSystemContext.kt | 3 ++ 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/types/TypeApproximator.kt b/compiler/resolution/src/org/jetbrains/kotlin/types/TypeApproximator.kt index 06980214553..d354c39ab56 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/types/TypeApproximator.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/types/TypeApproximator.kt @@ -46,8 +46,9 @@ open class TypeApproximatorConfiguration { open val definitelyNotNullType get() = true open val intersection: IntersectionStrategy = TO_COMMON_SUPERTYPE - open val typeVariable: (TypeVariableTypeConstructor) -> Boolean = { false } - open val capturedType: (NewCapturedType) -> Boolean = { false } // true means that this type we can leave as is + open val typeVariable: (TypeVariableTypeConstructorMarker) -> Boolean = { false } + open fun capturedType(ctx: TypeSystemInferenceExtensionContext, type: CapturedTypeMarker): Boolean = + false // true means that this type we can leave as is abstract class AllFlexibleSameValue : TypeApproximatorConfiguration() { abstract val allFlexible: Boolean @@ -77,9 +78,11 @@ open class TypeApproximatorConfiguration { override val errorType get() = true // i.e. will be approximated only approximatedCapturedStatus captured types - override val capturedType get() = { it: NewCapturedType -> it.captureStatus != approximatedCapturedStatus } + override fun capturedType(ctx: TypeSystemInferenceExtensionContext, type: CapturedTypeMarker): Boolean = + type.captureStatus(ctx) != approximatedCapturedStatus + override val intersection get() = IntersectionStrategy.ALLOWED - override val typeVariable: (TypeVariableTypeConstructor) -> Boolean get() = { true } + override val typeVariable: (TypeVariableTypeConstructorMarker) -> Boolean get() = { true } } object IncorporationConfiguration : TypeApproximatorConfiguration.AbstractCapturedTypesApproximation(FOR_INCORPORATION) @@ -242,14 +245,14 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon } private fun approximateCapturedType( - type: NewCapturedType, + type: CapturedTypeMarker, conf: TypeApproximatorConfiguration, toSuper: Boolean, depth: Int ): KotlinTypeMarker? { val supertypes = type.typeConstructor().supertypes() val baseSuperType = when (supertypes.size) { - 0 -> type.builtIns.nullableAnyType // Let C = in Int, then superType for C and C? is Any? + 0 -> nullableAnyType() // Let C = in Int, then superType for C and C? is Any? 1 -> supertypes.single() // Consider the following example: @@ -271,9 +274,9 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon else -> type.typeConstructorProjection().getType()//.unwrap() } - val baseSubType = type.lowerType ?: type.builtIns.nothingType + val baseSubType = type.lowerType() ?: nothingType() - if (conf.capturedType(type)) { + if (conf.capturedType(ctx, type)) { /** * Here everything is ok if bounds for this captured type should not be approximated. * But. If such bounds contains some unauthorized types, then we cannot leave this captured type "as is". @@ -294,7 +297,7 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon // C = in Int, Int <: C => Int? <: C? // C = out Number, C <: Number => C? <: Number? - return if (type.isMarkedNullable) baseResult.withNullability(true) else baseResult + return if (type.isMarkedNullable()) baseResult.withNullability(true) else baseResult } private fun approximateSimpleToSuperType(type: SimpleTypeMarker, conf: TypeApproximatorConfiguration, depth: Int) = @@ -327,20 +330,21 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon val typeConstructor = type.typeConstructor() - if (typeConstructor is NewCapturedTypeConstructor) { - assert(type is NewCapturedType) { + if (typeConstructor.isCapturedTypeConstructor()) { + val capturedType = type.asCapturedType() + require(capturedType != null) { // KT-16147 "Type is inconsistent -- somewhere we create type with typeConstructor = $typeConstructor " + "and class: ${type::class.java.canonicalName}. type.toString() = $type" } - return approximateCapturedType(type as NewCapturedType, conf, toSuper, depth) + return approximateCapturedType(capturedType, conf, toSuper, depth) } if (typeConstructor.isIntersection()) { return approximateIntersectionType(type, conf, toSuper, depth) } - if (typeConstructor is TypeVariableTypeConstructor) { + if (typeConstructor is TypeVariableTypeConstructorMarker) { return if (conf.typeVariable(typeConstructor)) null else type.defaultResult(toSuper) } 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 b21dd43c32d..a433172aacd 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt @@ -481,6 +481,11 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext { require(constructor is TypeConstructor, constructor::errorMessage) return ErrorUtils.createErrorTypeWithCustomConstructor(debugName, constructor) } + + override fun TypeConstructorMarker.isCapturedTypeConstructor(): Boolean { + return this is NewCapturedTypeConstructor + } + } private fun captureFromExpressionInternal(type: UnwrappedType) = captureFromExpression(type) diff --git a/core/type-system/src/org/jetbrains/kotlin/types/model/MarkerExtensions.kt b/core/type-system/src/org/jetbrains/kotlin/types/model/MarkerExtensions.kt index 6868655572b..80077dbdd63 100644 --- a/core/type-system/src/org/jetbrains/kotlin/types/model/MarkerExtensions.kt +++ b/core/type-system/src/org/jetbrains/kotlin/types/model/MarkerExtensions.kt @@ -22,4 +22,9 @@ fun KotlinTypeMarker.dependsOnTypeParameters(c: TypeSystemInferenceExtensionCont with(c) { val typeConstructors = typeParameters.mapTo(mutableSetOf()) { it.getTypeConstructor() } dependsOnTypeConstructor(c, typeConstructors) + } + +fun CapturedTypeMarker.captureStatus(c: TypeSystemInferenceExtensionContext) = + with(c) { + captureStatus() } \ No newline at end of file diff --git a/core/type-system/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt b/core/type-system/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt index aa23c622bbb..bf0126a5124 100644 --- a/core/type-system/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt +++ b/core/type-system/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt @@ -24,6 +24,7 @@ interface StubTypeMarker : SimpleTypeMarker interface TypeArgumentListMarker interface TypeVariableMarker +interface TypeVariableTypeConstructorMarker : TypeConstructorMarker interface TypeSubstitutorMarker @@ -88,6 +89,8 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui fun TypeConstructorMarker.getApproximatedIntegerLiteralType(): KotlinTypeMarker + fun TypeConstructorMarker.isCapturedTypeConstructor(): Boolean + fun Collection.singleBestRepresentative(): KotlinTypeMarker? fun KotlinTypeMarker.isUnit(): Boolean