[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.ConeClassifierLookupTag
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.model.*
sealed class ConeKotlinTypeProjection : TypeArgumentMarker {
@@ -193,3 +194,17 @@ class ConeIntersectionType(
fun ConeIntersectionType.mapTypes(func: (ConeKotlinType) -> ConeKotlinType): ConeIntersectionType {
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 = ")"
)
}
is ConeStubType -> "stub type: $variable"
} + nullabilitySuffix
}
@@ -70,6 +70,7 @@ fun ConeKotlinType.toIrType(session: FirSession, declarationStorage: Fir2IrDecla
// TODO: add intersectionTypeApproximation
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 {
return when (this) {
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}]")
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) {
val typeConstructor = typeConstructor()
@@ -223,7 +223,8 @@ private const val ERROR_TYPE_STUB = CommonClassNames.JAVA_LANG_OBJECT
private fun ConeKotlinType.mapToCanonicalString(session: FirSession): String {
return when (this) {
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}]")
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) {
val typeConstructor = typeConstructor()
@@ -178,6 +178,7 @@ fun <T : ConeKotlinType> T.withNullability(nullability: ConeNullability): T {
ConeNullability.UNKNOWN -> this // TODO: is that correct?
ConeNullability.NOT_NULL -> this
} as T
is ConeStubType -> ConeStubType(variable, nullability) as T
else -> error("sealed: ${this::class}")
}
}
@@ -51,7 +51,7 @@ class FirSamResolverImpl(
getFunctionTypeForPossibleSamType(type.lowerBound) ?: return null,
getFunctionTypeForPossibleSamType(type.upperBound) ?: return null
)
is ConeClassErrorType -> null
is ConeClassErrorType, is ConeStubType -> null
// TODO: support those types as well
is ConeAbbreviatedType, is ConeTypeParameterType, is ConeTypeVariableType,
is ConeCapturedType, is ConeDefinitelyNotNullType, is ConeIntersectionType -> null
@@ -213,7 +213,8 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext,
}
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 {
@@ -41,18 +41,9 @@ fun ConeTypeContext.hasNullableSuperType(type: ConeKotlinType): Boolean {
return false
}
class ConeTypeVariableTypeConstructor(val debugName: String) : ConeClassifierLookupTag(), TypeVariableTypeConstructorMarker {
override val name: Name get() = Name.identifier(debugName)
}
class TypeParameterBasedTypeVariable(val typeParameterSymbol: FirTypeParameterSymbol) :
ConeTypeVariable(typeParameterSymbol.name.identifier)
open class ConeTypeVariable(name: String) : TypeVariableMarker {
val typeConstructor = ConeTypeVariableTypeConstructor(name)
val defaultType = ConeTypeVariableType(ConeNullability.NOT_NULL, typeConstructor)
}
class InferenceComponents(
val ctx: TypeSystemInferenceExtensionContextDelegate,
val session: FirSession,
@@ -75,6 +75,7 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor() {
is ConeCapturedType -> return null
is ConeDefinitelyNotNullType -> this.substituteOriginal()
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.resolve.*
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.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
@@ -64,6 +63,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
is ConeDefinitelyNotNullType -> this
is ConeIntersectionType -> this
is ConeFlexibleType -> null
is ConeStubType -> this
else -> error("Unknown simpleType: $this")
}
}
@@ -131,6 +131,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
?: ErrorTypeConstructor("Failed to expand alias: ${this}")
is ConeLookupTagBasedType -> this.lookupTag.toSymbol(session) ?: ErrorTypeConstructor("Unresolved: ${this.lookupTag}")
is ConeIntersectionType -> this
is ConeStubType -> variable.typeConstructor
else -> error("?: ${this}")
}
@@ -352,6 +353,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
if (this is ConeCapturedType) return true
if (this is ConeTypeVariableType) return false
if (this is ConeIntersectionType) return false
if (this is ConeStubType) return true
require(this is ConeLookupTagBasedType)
val typeConstructor = this.typeConstructor()
return typeConstructor is FirClassSymbol<*> ||
@@ -367,7 +369,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
}
override fun SimpleTypeMarker.isStubType(): Boolean {
return false // TODO
return this is StubTypeMarker
}
override fun intersectTypes(types: List<SimpleTypeMarker>): SimpleTypeMarker {