FIR: Do not leave cyclic upper bounds of type parameters
This commit is contained in:
+35
-3
@@ -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<FirDeclaration> {
|
||||
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<FirTypeParameter>
|
||||
): Boolean {
|
||||
if (visited.isNotEmpty() && currentTypeParameter == typeParameter) return true
|
||||
if (!visited.add(currentTypeParameter)) return false
|
||||
|
||||
return currentTypeParameter.bounds.any {
|
||||
val nextTypeParameter = it.coneTypeSafe<ConeTypeParameterType>()?.lookupTag?.typeParameterSymbol?.fir ?: return@any false
|
||||
|
||||
hasSupertypePathToParameter(nextTypeParameter, typeParameter, visited)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,11 +44,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
|
||||
override fun SimpleTypeMarker.fastCorrespondingSupertypes(constructor: TypeConstructorMarker): List<SimpleTypeMarker>? {
|
||||
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 {
|
||||
|
||||
@@ -38,5 +38,7 @@ abstract class FirTypeParameter : FirPureAbstractElement(), FirTypeParameterRef,
|
||||
|
||||
abstract override fun replaceResolvePhase(newResolvePhase: FirResolvePhase)
|
||||
|
||||
abstract fun replaceBounds(newBounds: List<FirTypeRef>)
|
||||
|
||||
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirTypeParameter
|
||||
}
|
||||
|
||||
+5
@@ -60,4 +60,9 @@ internal class FirTypeParameterImpl(
|
||||
override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) {
|
||||
resolvePhase = newResolvePhase
|
||||
}
|
||||
|
||||
override fun replaceBounds(newBounds: List<FirTypeRef>) {
|
||||
bounds.clear()
|
||||
bounds.addAll(newBounds)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -291,7 +291,7 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
|
||||
+symbol("FirTypeParameterSymbol")
|
||||
+field(varianceType)
|
||||
+booleanField("isReified")
|
||||
+fieldList("bounds", typeRef)
|
||||
+fieldList("bounds", typeRef, withReplace = true)
|
||||
+annotations
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user