[FIR] Introduce ConeDynamicType

This commit is contained in:
Nikolay Lunyak
2021-12-17 18:09:54 +03:00
committed by teamcity
parent e763197c3e
commit be9e97d044
13 changed files with 66 additions and 63 deletions
@@ -45,9 +45,7 @@ object FirTopLevelTypeAliasChecker : FirTypeAliasChecker() {
val expandedTypeRef = declaration.expandedTypeRef
val fullyExpandedType = expandedTypeRef.coneType.fullyExpandedType(context.session)
if (containsTypeParameter(fullyExpandedType) ||
fullyExpandedType is ConeErrorType && fullyExpandedType.diagnostic is ConeUnsupportedDynamicType
) {
if (containsTypeParameter(fullyExpandedType) || fullyExpandedType is ConeDynamicType) {
reporter.reportOn(
declaration.expandedTypeRef.source,
FirErrors.TYPEALIAS_SHOULD_EXPAND_TO_CLASS,
@@ -80,9 +80,9 @@ open class ConeFlexibleType(
final override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as ConeFlexibleType
// I suppose dynamic type (see below) and flexible type should use the same equals,
// because ft<Any?, Nothing> should never be created
if (other !is ConeFlexibleType) return false
if (lowerBound != other.lowerBound) return false
if (upperBound != other.upperBound) return false
@@ -97,6 +97,16 @@ open class ConeFlexibleType(
}
}
@RequiresOptIn(message = "Please use ConeDynamicType.create instead")
annotation class DynamicTypeConstructor
class ConeDynamicType @DynamicTypeConstructor constructor(
lowerBound: ConeSimpleKotlinType,
upperBound: ConeSimpleKotlinType
) : ConeFlexibleType(lowerBound, upperBound), DynamicTypeMarker {
companion object
}
fun ConeSimpleKotlinType.unwrapDefinitelyNotNull(): ConeSimpleKotlinType {
return when (this) {
is ConeDefinitelyNotNullType -> original
@@ -30,6 +30,11 @@ fun ConeKotlinType.render(): String {
is ConeLookupTagBasedType -> {
"${renderAttributes()}${lookupTag.name.asString()}"
}
is ConeDynamicType -> {
buildString {
append("dynamic")
}
}
is ConeFlexibleType -> {
buildString {
append("ft<")
@@ -115,7 +115,15 @@ class FirTypeDeserializer(
if (proto.hasFlexibleTypeCapabilitiesId()) {
val lowerBound = simpleType(proto, attributes)
val upperBound = simpleType(proto.flexibleUpperBound(typeTable)!!, attributes)
return ConeFlexibleType(lowerBound!!, upperBound!!)
val isDynamic = lowerBound == moduleData.session.builtinTypes.nothingType.coneType &&
upperBound == moduleData.session.builtinTypes.nullableAnyType.coneType
return if (isDynamic) {
ConeDynamicType.create(moduleData.session)
} else {
ConeFlexibleType(lowerBound!!, upperBound!!)
}
}
return simpleType(proto, attributes) ?: ConeErrorType(ConeSimpleDiagnostic("?!id:0", DiagnosticKind.DeserializationError))
@@ -44,6 +44,7 @@ fun ConeClassLikeType.fullyExpandedType(
fun ConeKotlinType.fullyExpandedType(
useSiteSession: FirSession
): ConeKotlinType = when (this) {
is ConeDynamicType -> this
is ConeFlexibleType ->
ConeFlexibleType(lowerBound.fullyExpandedType(useSiteSession), upperBound.fullyExpandedType(useSiteSession))
is ConeClassLikeType -> fullyExpandedType(useSiteSession)
@@ -108,9 +108,9 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
return this is ConeErrorType && this.isUninferredParameter
}
override fun FlexibleTypeMarker.asDynamicType(): DynamicTypeMarker? {
override fun FlexibleTypeMarker.asDynamicType(): ConeDynamicType? {
assert(this is ConeKotlinType)
return null // TODO
return this as? ConeDynamicType
}
override fun FlexibleTypeMarker.asRawType(): RawTypeMarker? {
@@ -94,6 +94,11 @@ fun ConeDefinitelyNotNullType.Companion.create(
}
}
@OptIn(DynamicTypeConstructor::class)
fun ConeDynamicType.Companion.create(session: FirSession): ConeDynamicType =
ConeDynamicType(session.builtinTypes.nothingType.type, session.builtinTypes.nullableAnyType.type)
fun ConeKotlinType.makeConeTypeDefinitelyNotNullOrNotNull(
typeContext: ConeTypeContext,
avoidComprehensiveCheck: Boolean = false,
@@ -124,6 +129,7 @@ fun <T : ConeKotlinType> T.withArguments(arguments: Array<out ConeTypeProjection
fun <T : ConeKotlinType> T.withArguments(replacement: (ConeTypeProjection) -> ConeTypeProjection) =
withArguments(typeArguments.map(replacement).toTypedArray())
@OptIn(DynamicTypeConstructor::class)
fun <T : ConeKotlinType> T.withAttributes(attributes: ConeAttributes): T {
if (this.attributes == attributes) {
return this
@@ -136,6 +142,7 @@ fun <T : ConeKotlinType> T.withAttributes(attributes: ConeAttributes): T {
is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType(original.withAttributes(attributes))
is ConeTypeParameterTypeImpl -> ConeTypeParameterTypeImpl(lookupTag, nullability.isNullable, attributes)
is ConeRawType -> ConeRawType(lowerBound.withAttributes(attributes), upperBound.withAttributes(attributes))
is ConeDynamicType -> ConeDynamicType(lowerBound.withAttributes(attributes), upperBound.withAttributes(attributes))
is ConeFlexibleType -> ConeFlexibleType(lowerBound.withAttributes(attributes), upperBound.withAttributes(attributes))
is ConeTypeVariableType -> ConeTypeVariableType(nullability, lookupTag, attributes)
is ConeCapturedType -> ConeCapturedType(
@@ -165,6 +172,7 @@ fun <T : ConeKotlinType> T.withNullability(
is ConeErrorType -> this
is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, typeArguments, nullability.isNullable, attributes)
is ConeTypeParameterTypeImpl -> ConeTypeParameterTypeImpl(lookupTag, nullability.isNullable, attributes)
is ConeDynamicType -> this
is ConeFlexibleType -> {
if (nullability == ConeNullability.UNKNOWN) {
if (lowerBound.nullability != upperBound.nullability || lowerBound.nullability == ConeNullability.UNKNOWN) {
@@ -523,7 +523,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
) to (result as? TypeResolutionResult.Resolved)?.typeCandidate?.diagnostic
}
is FirFunctionTypeRef -> createFunctionalType(typeRef) to null
is FirDynamicTypeRef -> ConeErrorType(ConeUnsupportedDynamicType()) to null
is FirDynamicTypeRef -> ConeDynamicType.create(session) to null
is FirIntersectionTypeRef -> {
val leftType = typeRef.leftType.coneType
val rightType = typeRef.rightType.coneType