Fir2IrTypeConverter: simplify captured type cache

This commit is contained in:
Mikhail Glukhikh
2020-11-16 13:20:04 +03:00
committed by teamcityserver
parent cb77b76c0d
commit 4f7b45dfcc
@@ -59,10 +59,10 @@ class Fir2IrTypeConverter(
) )
private val capturedTypeCache = mutableMapOf<ConeCapturedType, IrType>() private val capturedTypeCache = mutableMapOf<ConeCapturedType, IrType>()
private val capturedTypeStack = mutableSetOf<ConeCapturedType>() private val errorTypeForCapturedTypeStub by lazy { createErrorType() }
fun FirTypeRef.toIrType(typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT): IrType { fun FirTypeRef.toIrType(typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT): IrType {
capturedTypeStack.clear() capturedTypeCache.clear()
return when (this) { return when (this) {
!is FirResolvedTypeRef -> createErrorType() !is FirResolvedTypeRef -> createErrorType()
!is FirImplicitBuiltinTypeRef -> type.toIrType(typeContext, annotations) !is FirImplicitBuiltinTypeRef -> type.toIrType(typeContext, annotations)
@@ -110,15 +110,19 @@ class Fir2IrTypeConverter(
upperBound.toIrType(typeContext) upperBound.toIrType(typeContext)
} }
is ConeCapturedType -> { is ConeCapturedType -> {
if (capturedTypeStack.add(this)) { val cached = capturedTypeCache[this]
val irType = lowerType?.toIrType(typeContext) ?: constructor.supertypes!!.first().toIrType(typeContext) if (cached == null) {
val irType = lowerType?.toIrType(typeContext) ?: run {
capturedTypeCache[this] = errorTypeForCapturedTypeStub
constructor.supertypes!!.first().toIrType(typeContext)
}
capturedTypeCache[this] = irType capturedTypeCache[this] = irType
irType irType
} else { } else {
// Potentially recursive captured type, e.g., Recursive<R> where R : Recursive<R>, ... // Potentially recursive captured type, e.g., Recursive<R> where R : Recursive<R>, ...
// That should have been handled during type argument conversion, though. // That should have been handled during type argument conversion, though.
// Or, simply repeated captured type, e.g., FunctionN<..., *, ..., *>, literally same captured types. // Or, simply repeated captured type, e.g., FunctionN<..., *, ..., *>, literally same captured types.
capturedTypeCache[this] ?: createErrorType() cached
} }
} }
is ConeDefinitelyNotNullType -> { is ConeDefinitelyNotNullType -> {
@@ -145,7 +149,7 @@ class Fir2IrTypeConverter(
makeTypeProjection(irType, Variance.OUT_VARIANCE) makeTypeProjection(irType, Variance.OUT_VARIANCE)
} }
is ConeKotlinType -> { is ConeKotlinType -> {
if (this is ConeCapturedType && capturedTypeStack.contains(this) && this.isRecursive(mutableSetOf())) { if (this is ConeCapturedType && this in capturedTypeCache && this.isRecursive(mutableSetOf())) {
// Recursive captured type, e.g., Recursive<R> where R : Recursive<R>, ... // Recursive captured type, e.g., Recursive<R> where R : Recursive<R>, ...
// We can return * early here to avoid recursive type conversions. // We can return * early here to avoid recursive type conversions.
IrStarProjectionImpl IrStarProjectionImpl