[FIR2IR] Approximate non-denotable types when converting ConeType to IrType
This commit is contained in:
committed by
TeamCityServer
parent
c271f953d7
commit
da0fd7cc15
@@ -236,7 +236,8 @@ class ConeRawType(lowerBound: ConeKotlinType, upperBound: ConeKotlinType) : Cone
|
||||
* only via ConeTypeIntersector
|
||||
*/
|
||||
class ConeIntersectionType(
|
||||
val intersectedTypes: Collection<ConeKotlinType>
|
||||
val intersectedTypes: Collection<ConeKotlinType>,
|
||||
val alternativeType: ConeKotlinType? = null,
|
||||
) : ConeSimpleKotlinType(), IntersectionTypeConstructorMarker {
|
||||
override val typeArguments: Array<out ConeTypeProjection>
|
||||
get() = emptyArray()
|
||||
@@ -266,7 +267,10 @@ class ConeIntersectionType(
|
||||
if (hashCode != 0) return hashCode
|
||||
return intersectedTypes.hashCode().also { hashCode = it }
|
||||
}
|
||||
}
|
||||
|
||||
fun ConeIntersectionType.withAlternative(alternativeType: ConeKotlinType): ConeIntersectionType {
|
||||
return ConeIntersectionType(intersectedTypes, alternativeType)
|
||||
}
|
||||
|
||||
fun ConeIntersectionType.mapTypes(func: (ConeKotlinType) -> ConeKotlinType): ConeIntersectionType {
|
||||
|
||||
@@ -8,8 +8,11 @@ package org.jetbrains.kotlin.fir.backend
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.classId
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
@@ -20,6 +23,7 @@ import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
class Fir2IrTypeConverter(
|
||||
@@ -60,6 +64,8 @@ class Fir2IrTypeConverter(
|
||||
private val capturedTypeCache = mutableMapOf<ConeCapturedType, IrType>()
|
||||
private val errorTypeForCapturedTypeStub by lazy { createErrorType() }
|
||||
|
||||
private val typeApproximator = ConeTypeApproximator(session.typeContext)
|
||||
|
||||
fun FirTypeRef.toIrType(typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT): IrType {
|
||||
capturedTypeCache.clear()
|
||||
return when (this) {
|
||||
@@ -106,9 +112,10 @@ class Fir2IrTypeConverter(
|
||||
typeAnnotations += callGenerator.convertToIrConstructorCall(attributeAnnotation) as? IrConstructorCall ?: continue
|
||||
}
|
||||
val expandedType = fullyExpandedType(session)
|
||||
val approximatedType = approximateType(expandedType)
|
||||
IrSimpleTypeImpl(
|
||||
irSymbol, !typeContext.definitelyNotNull && expandedType.isMarkedNullable,
|
||||
expandedType.typeArguments.map { it.toIrTypeArgument(typeContext) },
|
||||
irSymbol, !typeContext.definitelyNotNull && approximatedType.isMarkedNullable,
|
||||
approximatedType.typeArguments.map { it.toIrTypeArgument(typeContext) },
|
||||
typeAnnotations
|
||||
)
|
||||
}
|
||||
@@ -211,6 +218,22 @@ class Fir2IrTypeConverter(
|
||||
private fun getBuiltInClassSymbol(classId: ClassId?): IrClassSymbol? {
|
||||
return classIdToSymbolMap[classId] ?: getArrayClassSymbol(classId)
|
||||
}
|
||||
|
||||
private fun approximateType(type: ConeKotlinType): ConeKotlinType {
|
||||
if (type is ConeClassLikeType && type.typeArguments.isEmpty()) return type
|
||||
val substitutor = object : AbstractConeSubstitutor() {
|
||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||
return if (type is ConeIntersectionType) {
|
||||
type.alternativeType?.let { substituteOrSelf(it) }
|
||||
} else null
|
||||
}
|
||||
}
|
||||
val typeWithSpecifiedIntersectionTypes = substitutor.substituteOrSelf(type)
|
||||
return typeApproximator.approximateToSuperType(
|
||||
typeWithSpecifiedIntersectionTypes,
|
||||
TypeApproximatorConfiguration.PublicDeclaration
|
||||
) ?: type
|
||||
}
|
||||
}
|
||||
|
||||
fun FirTypeRef.toIrType(
|
||||
|
||||
+6
@@ -16616,6 +16616,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("intersectionTypeInArguments.kt")
|
||||
public void testIntersectionTypeInArguments() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/intersectionTypeInArguments.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt10822.kt")
|
||||
public void testKt10822() throws Exception {
|
||||
|
||||
@@ -485,7 +485,11 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
||||
firstCandidate: KotlinTypeMarker,
|
||||
secondCandidate: KotlinTypeMarker
|
||||
): KotlinTypeMarker {
|
||||
// TODO
|
||||
return firstCandidate
|
||||
require(firstCandidate is ConeKotlinType)
|
||||
require(secondCandidate is ConeKotlinType)
|
||||
val intersectionType = firstCandidate.lowerBoundIfFlexible() as? ConeIntersectionType ?: error {
|
||||
"Expected type is intersection, found $firstCandidate"
|
||||
}
|
||||
return intersectionType.withAlternative(secondCandidate)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user