From 8b71f5e5582ad3662741fa32d197c388a67d9930 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Thu, 30 Jul 2020 15:37:23 +0300 Subject: [PATCH] FIR: Do not leave cyclic upper bounds of type parameters --- .../transformers/FirTypeResolveTransformer.kt | 38 +++++++++++++++++-- .../kotlin/fir/types/ConeTypeContext.kt | 6 +-- .../fir/declarations/FirTypeParameter.kt | 2 + .../declarations/impl/FirTypeParameterImpl.kt | 5 +++ .../fir/tree/generator/NodeConfigurator.kt | 2 +- 5 files changed, 44 insertions(+), 9 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt index 48aa5b1439a..27b5599d1e7 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt @@ -12,8 +12,7 @@ import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.createImportingScopes -import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef -import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult import org.jetbrains.kotlin.fir.visitors.compose @@ -60,6 +59,7 @@ class FirTypeResolveTransformer( regularClass.typeParameters.forEach { it.accept(this, data) } + unboundCyclesInTypeParametersSupertypes(regularClass) } return resolveNestedClassesSupertypes(regularClass, data) @@ -101,6 +101,9 @@ class FirTypeResolveTransformer( property.getter?.transformReturnTypeRef(StoreType, property.returnTypeRef) property.setter?.valueParameters?.map { it.transformReturnTypeRef(StoreType, property.returnTypeRef) } } + + unboundCyclesInTypeParametersSupertypes(property) + property.compose() } } @@ -108,7 +111,36 @@ class FirTypeResolveTransformer( override fun transformSimpleFunction(simpleFunction: FirSimpleFunction, data: Nothing?): CompositeTransformResult { return withScopeCleanup { simpleFunction.addTypeParametersScope() - transformDeclaration(simpleFunction, data) + transformDeclaration(simpleFunction, data).also { + unboundCyclesInTypeParametersSupertypes(it.single as FirTypeParametersOwner) + } + } + } + + private fun unboundCyclesInTypeParametersSupertypes(typeParametersOwner: FirTypeParameterRefsOwner) { + for (typeParameter in typeParametersOwner.typeParameters) { + if (typeParameter !is FirTypeParameter) continue + if (hasSupertypePathToParameter(typeParameter, typeParameter, mutableSetOf())) { + // TODO: Report diagnostic somewhere + typeParameter.replaceBounds( + listOf(session.builtinTypes.nullableAnyType) + ) + } + } + } + + private fun hasSupertypePathToParameter( + currentTypeParameter: FirTypeParameter, + typeParameter: FirTypeParameter, + visited: MutableSet + ): Boolean { + if (visited.isNotEmpty() && currentTypeParameter == typeParameter) return true + if (!visited.add(currentTypeParameter)) return false + + return currentTypeParameter.bounds.any { + val nextTypeParameter = it.coneTypeSafe()?.lookupTag?.typeParameterSymbol?.fir ?: return@any false + + hasSupertypePathToParameter(nextTypeParameter, typeParameter, visited) } } 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 adc7c95ccc7..e0338606fe4 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 @@ -44,11 +44,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty override fun SimpleTypeMarker.fastCorrespondingSupertypes(constructor: TypeConstructorMarker): List? { require(this is ConeKotlinType) - return if (this is ConeIntegerLiteralType) { - supertypes.filter { isEqualTypeConstructors(constructor, it.typeConstructor()) } - } else { - session.correspondingSupertypesCache.getCorrespondingSupertypes(this, constructor) - } + return session.correspondingSupertypesCache.getCorrespondingSupertypes(this, constructor) } override fun SimpleTypeMarker.isIntegerLiteralType(): Boolean { diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirTypeParameter.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirTypeParameter.kt index 424adde8790..d76e62dffa1 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirTypeParameter.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirTypeParameter.kt @@ -38,5 +38,7 @@ abstract class FirTypeParameter : FirPureAbstractElement(), FirTypeParameterRef, abstract override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) + abstract fun replaceBounds(newBounds: List) + abstract override fun transformAnnotations(transformer: FirTransformer, data: D): FirTypeParameter } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirTypeParameterImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirTypeParameterImpl.kt index ca1646d0655..ac8e36e3dcf 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirTypeParameterImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirTypeParameterImpl.kt @@ -60,4 +60,9 @@ internal class FirTypeParameterImpl( override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) { resolvePhase = newResolvePhase } + + override fun replaceBounds(newBounds: List) { + bounds.clear() + bounds.addAll(newBounds) + } } diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt index 3064ff39140..05d8794696c 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt @@ -291,7 +291,7 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild +symbol("FirTypeParameterSymbol") +field(varianceType) +booleanField("isReified") - +fieldList("bounds", typeRef) + +fieldList("bounds", typeRef, withReplace = true) +annotations }