[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:
Mikhail Zarechenskiy
2019-09-03 20:02:14 +03:00
parent 01ad9c47c8
commit 77577dfa6f
11 changed files with 32 additions and 17 deletions
@@ -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
@@ -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,
@@ -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 {