From 3e44bc805fe37070eaf701febea8e7c1f99021b8 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Thu, 1 Aug 2019 19:02:35 +0300 Subject: [PATCH] [FIR] Return error type from common super type if it present --- .../kotlin/fir/resolve/calls/ConeInferenceContext.kt | 2 ++ .../transformers/FirBodyResolveTransformer.kt | 5 +++++ .../jetbrains/kotlin/fir/types/ConeTypeContext.kt | 6 +++++- .../jetbrains/kotlin/ir/types/IrTypeSystemContext.kt | 10 ++++++++++ .../resolve/calls/NewCommonSuperTypeCalculator.kt | 9 +++++++++ .../kotlin/types/checker/ClassicTypeSystemContext.kt | 10 ++++++++++ .../kotlin/types/model/TypeSystemContext.kt | 12 ++++++++++++ 7 files changed, 53 insertions(+), 1 deletion(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeInferenceContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeInferenceContext.kt index 5633886b431..ebbe126936f 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeInferenceContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeInferenceContext.kt @@ -28,6 +28,8 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, val symbolProvider: FirSymbolProvider get() = session.service() + override val isErrorTypeAllowed: Boolean get() = false + override fun nullableNothingType(): SimpleTypeMarker { return StandardClassIds.Nothing(symbolProvider).constructType(emptyArray(), true) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt index e97f3b85cf3..1b2c6f7c829 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt @@ -778,6 +778,11 @@ private fun inferenceComponents(session: FirSession, returnTypeCalculator: Retur override fun KotlinTypeMarker.removeExactAnnotation(): KotlinTypeMarker { return this } + + override fun TypeConstructorMarker.toErrorType(): SimpleTypeMarker { + require(this is ErrorTypeConstructor) + return ConeClassErrorType(reason) + } }, session, returnTypeCalculator, scopeSession) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt index e5de3d2dee2..ce7c7fca250 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt @@ -29,7 +29,7 @@ import org.jetbrains.kotlin.types.AbstractTypeCheckerContext import org.jetbrains.kotlin.types.checker.convertVariance import org.jetbrains.kotlin.types.model.* -class ErrorTypeConstructor(reason: String) : TypeConstructorMarker +class ErrorTypeConstructor(val reason: String) : TypeConstructorMarker interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, TypeCheckerProviderContext { val session: FirSession @@ -417,6 +417,10 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty // TODO: Intersection types return false } + + override fun TypeConstructorMarker.isError(): Boolean { + return this is ErrorTypeConstructor + } } class ConeTypeCheckerContext(override val isErrorTypeEqualsToAnything: Boolean, override val session: FirSession) : diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt index dac3ac9e7a7..fed837fbc14 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt @@ -34,6 +34,8 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon val irBuiltIns: IrBuiltIns + override val isErrorTypeAllowed: Boolean get() = true + override fun KotlinTypeMarker.asSimpleType() = this as? SimpleTypeMarker override fun KotlinTypeMarker.asFlexibleType() = this as? IrDynamicType @@ -237,6 +239,14 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon return maxInArguments + 1 } + override fun TypeConstructorMarker.toErrorType(): SimpleTypeMarker { + throw IllegalStateException("Should not be called") + } + + override fun TypeConstructorMarker.isError(): Boolean { + throw IllegalStateException("Should not be called") + } + override fun findCommonIntegerLiteralTypesSuperType(explicitSupertypes: List): SimpleTypeMarker? = irBuiltIns.intType as IrSimpleType diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/NewCommonSuperTypeCalculator.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/NewCommonSuperTypeCalculator.kt index 4167074a11a..87fff026f3c 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/NewCommonSuperTypeCalculator.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/NewCommonSuperTypeCalculator.kt @@ -131,6 +131,7 @@ object NewCommonSuperTypeCalculator { val explicitSupertypes = filterSupertypes(uniqueTypes) if (explicitSupertypes.size == 1) return explicitSupertypes.single() + findErrorTypeInSupertypesIfItIsNeeded(explicitSupertypes)?.let { return it } findCommonIntegerLiteralTypesSuperType(explicitSupertypes)?.let { return it } // IntegerLiteralTypeConstructor.findCommonSuperType(explicitSupertypes)?.let { return it } @@ -138,6 +139,14 @@ object NewCommonSuperTypeCalculator { return findSuperTypeConstructorsAndIntersectResult(explicitSupertypes, depth) } + private fun TypeSystemCommonSuperTypesContext.findErrorTypeInSupertypesIfItIsNeeded(types: List): SimpleTypeMarker? { + if (isErrorTypeAllowed) return null + for (type in types) { + collectAllSupertypes(type).firstOrNull { it.isError() }?.let { return it.toErrorType() } + } + return null + } + private fun TypeSystemCommonSuperTypesContext.findSuperTypeConstructorsAndIntersectResult( types: List, depth: Int 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 055441d7bde..6db28969a8e 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt @@ -30,6 +30,8 @@ import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSystemCommonBackendContext { + override val isErrorTypeAllowed: Boolean get() = true + override fun TypeConstructorMarker.isDenotable(): Boolean { require(this is TypeConstructor, this::errorMessage) return this.isDenotable @@ -56,6 +58,10 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy return this.isError } + override fun TypeConstructorMarker.toErrorType(): SimpleTypeMarker { + throw IllegalStateException("Should not be called") + } + override fun KotlinTypeMarker.isUninferredParameter(): Boolean { require(this is KotlinType, this::errorMessage) return ErrorUtils.isUninferredParameter(this) @@ -469,6 +475,10 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy return IntegerLiteralTypeConstructor.findCommonSuperType(explicitSupertypes) } + override fun TypeConstructorMarker.isError(): Boolean { + throw IllegalStateException("Should not be called") + } + override fun TypeConstructorMarker.getApproximatedIntegerLiteralType(): KotlinTypeMarker { require(this is IntegerLiteralTypeConstructor, this::errorMessage) return this.getApproximatedType().unwrap() 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 cf3dfa76c0c..786f771a7b5 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 @@ -67,6 +67,11 @@ interface TypeCheckerProviderContext { } interface TypeSystemCommonSuperTypesContext : TypeSystemContext, TypeSystemTypeFactoryContext, TypeCheckerProviderContext { + /* + * If set in false then if there is an error type in input types list of `commonSuperType` it will be return + * That flag is needed for FIR where there are a problems with recursive class hierarchies + */ + val isErrorTypeAllowed: Boolean fun KotlinTypeMarker.anySuperTypeConstructor(predicate: (TypeConstructorMarker) -> Boolean) = newBaseTypeCheckerContext(false).anySupertype(lowerBoundIfFlexible(), { @@ -84,6 +89,12 @@ interface TypeSystemCommonSuperTypesContext : TypeSystemContext, TypeSystemTypeF } fun findCommonIntegerLiteralTypesSuperType(explicitSupertypes: List): SimpleTypeMarker? + + /* + * Converts error type constructor to error type + * Used only in FIR + */ + fun TypeConstructorMarker.toErrorType(): SimpleTypeMarker } interface TypeSystemInferenceExtensionContextDelegate : TypeSystemInferenceExtensionContext @@ -151,6 +162,7 @@ interface TypeSystemContext : TypeSystemOptimizationContext { fun KotlinTypeMarker.asFlexibleType(): FlexibleTypeMarker? fun KotlinTypeMarker.isError(): Boolean + fun TypeConstructorMarker.isError(): Boolean fun KotlinTypeMarker.isUninferredParameter(): Boolean fun FlexibleTypeMarker.asDynamicType(): DynamicTypeMarker?