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.resolve.ScopeSession
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.createImportingScopes
|
import org.jetbrains.kotlin.fir.scopes.createImportingScopes
|
||||||
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
|
||||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
|
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
|
||||||
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
||||||
import org.jetbrains.kotlin.fir.visitors.compose
|
import org.jetbrains.kotlin.fir.visitors.compose
|
||||||
@@ -60,6 +59,7 @@ class FirTypeResolveTransformer(
|
|||||||
regularClass.typeParameters.forEach {
|
regularClass.typeParameters.forEach {
|
||||||
it.accept(this, data)
|
it.accept(this, data)
|
||||||
}
|
}
|
||||||
|
unboundCyclesInTypeParametersSupertypes(regularClass)
|
||||||
}
|
}
|
||||||
|
|
||||||
return resolveNestedClassesSupertypes(regularClass, data)
|
return resolveNestedClassesSupertypes(regularClass, data)
|
||||||
@@ -101,6 +101,9 @@ class FirTypeResolveTransformer(
|
|||||||
property.getter?.transformReturnTypeRef(StoreType, property.returnTypeRef)
|
property.getter?.transformReturnTypeRef(StoreType, property.returnTypeRef)
|
||||||
property.setter?.valueParameters?.map { it.transformReturnTypeRef(StoreType, property.returnTypeRef) }
|
property.setter?.valueParameters?.map { it.transformReturnTypeRef(StoreType, property.returnTypeRef) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unboundCyclesInTypeParametersSupertypes(property)
|
||||||
|
|
||||||
property.compose()
|
property.compose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,7 +111,36 @@ class FirTypeResolveTransformer(
|
|||||||
override fun transformSimpleFunction(simpleFunction: FirSimpleFunction, data: Nothing?): CompositeTransformResult<FirDeclaration> {
|
override fun transformSimpleFunction(simpleFunction: FirSimpleFunction, data: Nothing?): CompositeTransformResult<FirDeclaration> {
|
||||||
return withScopeCleanup {
|
return withScopeCleanup {
|
||||||
simpleFunction.addTypeParametersScope()
|
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>? {
|
override fun SimpleTypeMarker.fastCorrespondingSupertypes(constructor: TypeConstructorMarker): List<SimpleTypeMarker>? {
|
||||||
require(this is ConeKotlinType)
|
require(this is ConeKotlinType)
|
||||||
return if (this is ConeIntegerLiteralType) {
|
return session.correspondingSupertypesCache.getCorrespondingSupertypes(this, constructor)
|
||||||
supertypes.filter { isEqualTypeConstructors(constructor, it.typeConstructor()) }
|
|
||||||
} else {
|
|
||||||
session.correspondingSupertypesCache.getCorrespondingSupertypes(this, constructor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun SimpleTypeMarker.isIntegerLiteralType(): Boolean {
|
override fun SimpleTypeMarker.isIntegerLiteralType(): Boolean {
|
||||||
|
|||||||
@@ -38,5 +38,7 @@ abstract class FirTypeParameter : FirPureAbstractElement(), FirTypeParameterRef,
|
|||||||
|
|
||||||
abstract override fun replaceResolvePhase(newResolvePhase: FirResolvePhase)
|
abstract override fun replaceResolvePhase(newResolvePhase: FirResolvePhase)
|
||||||
|
|
||||||
|
abstract fun replaceBounds(newBounds: List<FirTypeRef>)
|
||||||
|
|
||||||
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirTypeParameter
|
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirTypeParameter
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -60,4 +60,9 @@ internal class FirTypeParameterImpl(
|
|||||||
override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) {
|
override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) {
|
||||||
resolvePhase = newResolvePhase
|
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")
|
+symbol("FirTypeParameterSymbol")
|
||||||
+field(varianceType)
|
+field(varianceType)
|
||||||
+booleanField("isReified")
|
+booleanField("isReified")
|
||||||
+fieldList("bounds", typeRef)
|
+fieldList("bounds", typeRef, withReplace = true)
|
||||||
+annotations
|
+annotations
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user