[FIR] Introduce ConeStubType to have subtyping for non-fixed variables
Currently, it's needed after changes in d7b47108f70a107818a04c8b8db33bfbf7c7e590 Later it'll be also used for builder-inference
This commit is contained in:
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.types
|
|||||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag
|
import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.types.model.*
|
import org.jetbrains.kotlin.types.model.*
|
||||||
|
|
||||||
sealed class ConeKotlinTypeProjection : TypeArgumentMarker {
|
sealed class ConeKotlinTypeProjection : TypeArgumentMarker {
|
||||||
@@ -193,3 +194,17 @@ class ConeIntersectionType(
|
|||||||
fun ConeIntersectionType.mapTypes(func: (ConeKotlinType) -> ConeKotlinType): ConeIntersectionType {
|
fun ConeIntersectionType.mapTypes(func: (ConeKotlinType) -> ConeKotlinType): ConeIntersectionType {
|
||||||
return ConeIntersectionType(intersectedTypes.map(func))
|
return ConeIntersectionType(intersectedTypes.map(func))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ConeStubType(val variable: ConeTypeVariable, override val nullability: ConeNullability) : StubTypeMarker, ConeKotlinType() {
|
||||||
|
override val typeArguments: Array<out ConeKotlinTypeProjection>
|
||||||
|
get() = emptyArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
open class ConeTypeVariable(name: String) : TypeVariableMarker {
|
||||||
|
val typeConstructor = ConeTypeVariableTypeConstructor(name)
|
||||||
|
val defaultType = ConeTypeVariableType(ConeNullability.NOT_NULL, typeConstructor)
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConeTypeVariableTypeConstructor(val debugName: String) : ConeClassifierLookupTag(), TypeVariableTypeConstructorMarker {
|
||||||
|
override val name: Name get() = Name.identifier(debugName)
|
||||||
|
}
|
||||||
|
|||||||
@@ -46,5 +46,6 @@ fun ConeKotlinType.render(): String {
|
|||||||
postfix = ")"
|
postfix = ")"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
is ConeStubType -> "stub type: $variable"
|
||||||
} + nullabilitySuffix
|
} + nullabilitySuffix
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ fun ConeKotlinType.toIrType(session: FirSession, declarationStorage: Fir2IrDecla
|
|||||||
// TODO: add intersectionTypeApproximation
|
// TODO: add intersectionTypeApproximation
|
||||||
intersectedTypes.first().toIrType(session, declarationStorage)
|
intersectedTypes.first().toIrType(session, declarationStorage)
|
||||||
}
|
}
|
||||||
|
is ConeStubType -> createErrorType()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -222,7 +222,8 @@ private const val ERROR_TYPE_STUB = CommonClassNames.JAVA_LANG_OBJECT
|
|||||||
private fun ConeKotlinType.mapToCanonicalString(session: FirSession): String {
|
private fun ConeKotlinType.mapToCanonicalString(session: FirSession): String {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is ConeClassLikeType -> mapToCanonicalString(session)
|
is ConeClassLikeType -> mapToCanonicalString(session)
|
||||||
is ConeTypeVariableType, is ConeFlexibleType, is ConeCapturedType, is ConeDefinitelyNotNullType, is ConeIntersectionType ->
|
is ConeTypeVariableType, is ConeFlexibleType, is ConeCapturedType,
|
||||||
|
is ConeDefinitelyNotNullType, is ConeIntersectionType, is ConeStubType ->
|
||||||
error("Unexpected type: $this [${this::class}]")
|
error("Unexpected type: $this [${this::class}]")
|
||||||
is ConeLookupTagBasedType -> lookupTag.name.asString()
|
is ConeLookupTagBasedType -> lookupTag.name.asString()
|
||||||
}
|
}
|
||||||
@@ -250,7 +251,7 @@ private fun ConeClassType.mapToCanonicalString(session: FirSession): String {
|
|||||||
} + "[]"
|
} + "[]"
|
||||||
}
|
}
|
||||||
|
|
||||||
val context = ConeTypeCheckerContext(false, session)
|
val context = ConeTypeCheckerContext(isErrorTypeEqualsToAnything = false, isStubTypeEqualsToAnything = true, session = session)
|
||||||
|
|
||||||
with(context) {
|
with(context) {
|
||||||
val typeConstructor = typeConstructor()
|
val typeConstructor = typeConstructor()
|
||||||
|
|||||||
@@ -223,7 +223,8 @@ private const val ERROR_TYPE_STUB = CommonClassNames.JAVA_LANG_OBJECT
|
|||||||
private fun ConeKotlinType.mapToCanonicalString(session: FirSession): String {
|
private fun ConeKotlinType.mapToCanonicalString(session: FirSession): String {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is ConeClassLikeType -> mapToCanonicalString(session)
|
is ConeClassLikeType -> mapToCanonicalString(session)
|
||||||
is ConeTypeVariableType, is ConeFlexibleType, is ConeCapturedType, is ConeDefinitelyNotNullType, is ConeIntersectionType ->
|
is ConeTypeVariableType, is ConeFlexibleType, is ConeCapturedType,
|
||||||
|
is ConeDefinitelyNotNullType, is ConeIntersectionType, is ConeStubType ->
|
||||||
error("Unexpected type: $this [${this::class}]")
|
error("Unexpected type: $this [${this::class}]")
|
||||||
is ConeLookupTagBasedType -> lookupTag.name.asString()
|
is ConeLookupTagBasedType -> lookupTag.name.asString()
|
||||||
}
|
}
|
||||||
@@ -251,7 +252,7 @@ private fun ConeClassType.mapToCanonicalString(session: FirSession): String {
|
|||||||
} + "[]"
|
} + "[]"
|
||||||
}
|
}
|
||||||
|
|
||||||
val context = ConeTypeCheckerContext(false, session)
|
val context = ConeTypeCheckerContext(isErrorTypeEqualsToAnything = false, isStubTypeEqualsToAnything = true, session = session)
|
||||||
|
|
||||||
with(context) {
|
with(context) {
|
||||||
val typeConstructor = typeConstructor()
|
val typeConstructor = typeConstructor()
|
||||||
|
|||||||
@@ -178,6 +178,7 @@ fun <T : ConeKotlinType> T.withNullability(nullability: ConeNullability): T {
|
|||||||
ConeNullability.UNKNOWN -> this // TODO: is that correct?
|
ConeNullability.UNKNOWN -> this // TODO: is that correct?
|
||||||
ConeNullability.NOT_NULL -> this
|
ConeNullability.NOT_NULL -> this
|
||||||
} as T
|
} as T
|
||||||
|
is ConeStubType -> ConeStubType(variable, nullability) as T
|
||||||
else -> error("sealed: ${this::class}")
|
else -> error("sealed: ${this::class}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class FirSamResolverImpl(
|
|||||||
getFunctionTypeForPossibleSamType(type.lowerBound) ?: return null,
|
getFunctionTypeForPossibleSamType(type.lowerBound) ?: return null,
|
||||||
getFunctionTypeForPossibleSamType(type.upperBound) ?: return null
|
getFunctionTypeForPossibleSamType(type.upperBound) ?: return null
|
||||||
)
|
)
|
||||||
is ConeClassErrorType -> null
|
is ConeClassErrorType, is ConeStubType -> null
|
||||||
// TODO: support those types as well
|
// TODO: support those types as well
|
||||||
is ConeAbbreviatedType, is ConeTypeParameterType, is ConeTypeVariableType,
|
is ConeAbbreviatedType, is ConeTypeParameterType, is ConeTypeVariableType,
|
||||||
is ConeCapturedType, is ConeDefinitelyNotNullType, is ConeIntersectionType -> null
|
is ConeCapturedType, is ConeDefinitelyNotNullType, is ConeIntersectionType -> null
|
||||||
|
|||||||
+2
-1
@@ -213,7 +213,8 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun createStubType(typeVariable: TypeVariableMarker): StubTypeMarker {
|
override fun createStubType(typeVariable: TypeVariableMarker): StubTypeMarker {
|
||||||
TODO("not implemented")
|
require(typeVariable is ConeTypeVariable) { "$typeVariable should subtype of ${ConeTypeVariable::class.qualifiedName}" }
|
||||||
|
return ConeStubType(typeVariable, ConeNullability.create(typeVariable.defaultType().isMarkedNullable()))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun KotlinTypeMarker.removeAnnotations(): KotlinTypeMarker {
|
override fun KotlinTypeMarker.removeAnnotations(): KotlinTypeMarker {
|
||||||
|
|||||||
@@ -41,18 +41,9 @@ fun ConeTypeContext.hasNullableSuperType(type: ConeKotlinType): Boolean {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConeTypeVariableTypeConstructor(val debugName: String) : ConeClassifierLookupTag(), TypeVariableTypeConstructorMarker {
|
|
||||||
override val name: Name get() = Name.identifier(debugName)
|
|
||||||
}
|
|
||||||
|
|
||||||
class TypeParameterBasedTypeVariable(val typeParameterSymbol: FirTypeParameterSymbol) :
|
class TypeParameterBasedTypeVariable(val typeParameterSymbol: FirTypeParameterSymbol) :
|
||||||
ConeTypeVariable(typeParameterSymbol.name.identifier)
|
ConeTypeVariable(typeParameterSymbol.name.identifier)
|
||||||
|
|
||||||
open class ConeTypeVariable(name: String) : TypeVariableMarker {
|
|
||||||
val typeConstructor = ConeTypeVariableTypeConstructor(name)
|
|
||||||
val defaultType = ConeTypeVariableType(ConeNullability.NOT_NULL, typeConstructor)
|
|
||||||
}
|
|
||||||
|
|
||||||
class InferenceComponents(
|
class InferenceComponents(
|
||||||
val ctx: TypeSystemInferenceExtensionContextDelegate,
|
val ctx: TypeSystemInferenceExtensionContextDelegate,
|
||||||
val session: FirSession,
|
val session: FirSession,
|
||||||
|
|||||||
+1
@@ -75,6 +75,7 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor() {
|
|||||||
is ConeCapturedType -> return null
|
is ConeCapturedType -> return null
|
||||||
is ConeDefinitelyNotNullType -> this.substituteOriginal()
|
is ConeDefinitelyNotNullType -> this.substituteOriginal()
|
||||||
is ConeIntersectionType -> this.substituteIntersectedTypes()
|
is ConeIntersectionType -> this.substituteIntersectedTypes()
|
||||||
|
is ConeStubType -> return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.fir.FirSession
|
|||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.ConeInferenceContext
|
import org.jetbrains.kotlin.fir.resolve.calls.ConeInferenceContext
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.ConeTypeVariableTypeConstructor
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.hasNullableSuperType
|
import org.jetbrains.kotlin.fir.resolve.calls.hasNullableSuperType
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||||
@@ -64,6 +63,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
|||||||
is ConeDefinitelyNotNullType -> this
|
is ConeDefinitelyNotNullType -> this
|
||||||
is ConeIntersectionType -> this
|
is ConeIntersectionType -> this
|
||||||
is ConeFlexibleType -> null
|
is ConeFlexibleType -> null
|
||||||
|
is ConeStubType -> this
|
||||||
else -> error("Unknown simpleType: $this")
|
else -> error("Unknown simpleType: $this")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,6 +131,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
|||||||
?: ErrorTypeConstructor("Failed to expand alias: ${this}")
|
?: ErrorTypeConstructor("Failed to expand alias: ${this}")
|
||||||
is ConeLookupTagBasedType -> this.lookupTag.toSymbol(session) ?: ErrorTypeConstructor("Unresolved: ${this.lookupTag}")
|
is ConeLookupTagBasedType -> this.lookupTag.toSymbol(session) ?: ErrorTypeConstructor("Unresolved: ${this.lookupTag}")
|
||||||
is ConeIntersectionType -> this
|
is ConeIntersectionType -> this
|
||||||
|
is ConeStubType -> variable.typeConstructor
|
||||||
else -> error("?: ${this}")
|
else -> error("?: ${this}")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,6 +353,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
|||||||
if (this is ConeCapturedType) return true
|
if (this is ConeCapturedType) return true
|
||||||
if (this is ConeTypeVariableType) return false
|
if (this is ConeTypeVariableType) return false
|
||||||
if (this is ConeIntersectionType) return false
|
if (this is ConeIntersectionType) return false
|
||||||
|
if (this is ConeStubType) return true
|
||||||
require(this is ConeLookupTagBasedType)
|
require(this is ConeLookupTagBasedType)
|
||||||
val typeConstructor = this.typeConstructor()
|
val typeConstructor = this.typeConstructor()
|
||||||
return typeConstructor is FirClassSymbol<*> ||
|
return typeConstructor is FirClassSymbol<*> ||
|
||||||
@@ -367,7 +369,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun SimpleTypeMarker.isStubType(): Boolean {
|
override fun SimpleTypeMarker.isStubType(): Boolean {
|
||||||
return false // TODO
|
return this is StubTypeMarker
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun intersectTypes(types: List<SimpleTypeMarker>): SimpleTypeMarker {
|
override fun intersectTypes(types: List<SimpleTypeMarker>): SimpleTypeMarker {
|
||||||
|
|||||||
Reference in New Issue
Block a user