[Inference] Add ability to approximate local types in AbstractTypeApproximator

This commit is contained in:
Dmitriy Novozhilov
2021-02-18 17:27:02 +03:00
committed by TeamCityServer
parent 73616107b4
commit 3626008ed2
6 changed files with 38 additions and 11 deletions
@@ -21,9 +21,7 @@ import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolved
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.symbols.*
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe
@@ -44,6 +42,11 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
return this is ConeIntegerLiteralType
}
override fun TypeConstructorMarker.isLocalType(): Boolean {
if (this !is ConeClassLikeLookupTag) return false
return classId.isLocal
}
override fun SimpleTypeMarker.possibleIntegerTypes(): Collection<KotlinTypeMarker> {
return (this as? ConeIntegerLiteralType)?.possibleTypes ?: emptyList()
}
@@ -269,6 +269,11 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
override fun TypeConstructorMarker.isIntegerLiteralTypeConstructor() = false
override fun TypeConstructorMarker.isLocalType(): Boolean {
if (this !is IrClassSymbol) return false
return this.owner.classId?.isLocal == true
}
override fun createFlexibleType(lowerBound: SimpleTypeMarker, upperBound: SimpleTypeMarker): KotlinTypeMarker {
require(lowerBound.isNothing())
require(upperBound is IrType && upperBound.isNullableAny())
@@ -516,4 +521,4 @@ fun extractTypeParameters(parent: IrDeclarationParent): List<IrTypeParameter> {
}
class IrTypeSystemContextImpl(override val irBuiltIns: IrBuiltIns) : IrTypeSystemContext
class IrTypeSystemContextImpl(override val irBuiltIns: IrBuiltIns) : IrTypeSystemContext
@@ -162,6 +162,20 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon
}
}
private fun approximateLocalTypes(type: SimpleTypeMarker, conf: TypeApproximatorConfiguration, toSuper: Boolean): SimpleTypeMarker? {
if (!toSuper) return null
if (!conf.localTypes) return null
val constructor = type.typeConstructor()
val needApproximate = conf.localTypes && constructor.isLocalType()
if (!needApproximate) return null
val superConstructor = constructor.supertypes().first().typeConstructor()
val typeCheckerContext = newBaseTypeCheckerContext(
errorTypesEqualToAnything = false,
stubTypesEqualToAnything = false
)
return AbstractTypeChecker.findCorrespondingSupertypes(typeCheckerContext, type, superConstructor).first()
}
private fun isIntersectionTypeEffectivelyNothing(constructor: IntersectionTypeConstructorMarker): Boolean {
// We consider intersection as Nothing only if one of it's component is a primitive number type
// It's intentional we're not trying to prove population of some type as it was in OI
@@ -326,7 +340,7 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon
null
}
return null // simple classifier type
return approximateLocalTypes(type, conf, toSuper) // simple classifier type
}
private fun approximateDefinitelyNotNullType(
@@ -518,10 +532,11 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon
}
}
if (newArguments.all { it == null }) return null
if (newArguments.all { it == null }) return approximateLocalTypes(type, conf, toSuper)
val newArgumentsList = List(type.argumentsCount()) { index -> newArguments[index] ?: type.getArgument(index) }
return type.replaceArguments(newArgumentsList)
val approximatedType = type.replaceArguments(newArgumentsList)
return approximateLocalTypes(approximatedType, conf, toSuper) ?: approximatedType
}
private fun KotlinTypeMarker.defaultResult(toSuper: Boolean) = if (toSuper) nullableAnyType() else {
@@ -22,6 +22,7 @@ open class TypeApproximatorConfiguration {
open val definitelyNotNullType: Boolean get() = true
open val intersection: IntersectionStrategy = IntersectionStrategy.TO_COMMON_SUPERTYPE
open val intersectionTypesInContravariantPositions = false
open val localTypes = false
open val typeVariable: (TypeVariableTypeConstructorMarker) -> Boolean = { false }
open fun capturedType(ctx: TypeSystemInferenceExtensionContext, type: CapturedTypeMarker): Boolean =