[Inference] Add ability to approximate local types in AbstractTypeApproximator
This commit is contained in:
committed by
TeamCityServer
parent
73616107b4
commit
3626008ed2
@@ -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.toSymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolved
|
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolved
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
import org.jetbrains.kotlin.fir.symbols.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||||
@@ -44,6 +42,11 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
|||||||
return this is ConeIntegerLiteralType
|
return this is ConeIntegerLiteralType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun TypeConstructorMarker.isLocalType(): Boolean {
|
||||||
|
if (this !is ConeClassLikeLookupTag) return false
|
||||||
|
return classId.isLocal
|
||||||
|
}
|
||||||
|
|
||||||
override fun SimpleTypeMarker.possibleIntegerTypes(): Collection<KotlinTypeMarker> {
|
override fun SimpleTypeMarker.possibleIntegerTypes(): Collection<KotlinTypeMarker> {
|
||||||
return (this as? ConeIntegerLiteralType)?.possibleTypes ?: emptyList()
|
return (this as? ConeIntegerLiteralType)?.possibleTypes ?: emptyList()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -269,6 +269,11 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
|
|||||||
|
|
||||||
override fun TypeConstructorMarker.isIntegerLiteralTypeConstructor() = false
|
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 {
|
override fun createFlexibleType(lowerBound: SimpleTypeMarker, upperBound: SimpleTypeMarker): KotlinTypeMarker {
|
||||||
require(lowerBound.isNothing())
|
require(lowerBound.isNothing())
|
||||||
require(upperBound is IrType && upperBound.isNullableAny())
|
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
|
||||||
|
|||||||
+18
-3
@@ -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 {
|
private fun isIntersectionTypeEffectivelyNothing(constructor: IntersectionTypeConstructorMarker): Boolean {
|
||||||
// We consider intersection as Nothing only if one of it's component is a primitive number type
|
// 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
|
// 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
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
return null // simple classifier type
|
return approximateLocalTypes(type, conf, toSuper) // simple classifier type
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun approximateDefinitelyNotNullType(
|
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) }
|
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 {
|
private fun KotlinTypeMarker.defaultResult(toSuper: Boolean) = if (toSuper) nullableAnyType() else {
|
||||||
|
|||||||
+1
@@ -22,6 +22,7 @@ open class TypeApproximatorConfiguration {
|
|||||||
open val definitelyNotNullType: Boolean get() = true
|
open val definitelyNotNullType: Boolean get() = true
|
||||||
open val intersection: IntersectionStrategy = IntersectionStrategy.TO_COMMON_SUPERTYPE
|
open val intersection: IntersectionStrategy = IntersectionStrategy.TO_COMMON_SUPERTYPE
|
||||||
open val intersectionTypesInContravariantPositions = false
|
open val intersectionTypesInContravariantPositions = false
|
||||||
|
open val localTypes = false
|
||||||
|
|
||||||
open val typeVariable: (TypeVariableTypeConstructorMarker) -> Boolean = { false }
|
open val typeVariable: (TypeVariableTypeConstructorMarker) -> Boolean = { false }
|
||||||
open fun capturedType(ctx: TypeSystemInferenceExtensionContext, type: CapturedTypeMarker): Boolean =
|
open fun capturedType(ctx: TypeSystemInferenceExtensionContext, type: CapturedTypeMarker): Boolean =
|
||||||
|
|||||||
@@ -304,6 +304,7 @@ interface TypeSystemContext : TypeSystemOptimizationContext {
|
|||||||
fun TypeConstructorMarker.isIntersection(): Boolean
|
fun TypeConstructorMarker.isIntersection(): Boolean
|
||||||
fun TypeConstructorMarker.isClassTypeConstructor(): Boolean
|
fun TypeConstructorMarker.isClassTypeConstructor(): Boolean
|
||||||
fun TypeConstructorMarker.isIntegerLiteralTypeConstructor(): Boolean
|
fun TypeConstructorMarker.isIntegerLiteralTypeConstructor(): Boolean
|
||||||
|
fun TypeConstructorMarker.isLocalType(): Boolean
|
||||||
|
|
||||||
fun TypeParameterMarker.getVariance(): TypeVariance
|
fun TypeParameterMarker.getVariance(): TypeVariance
|
||||||
fun TypeParameterMarker.upperBoundCount(): Int
|
fun TypeParameterMarker.upperBoundCount(): Int
|
||||||
|
|||||||
@@ -17,10 +17,7 @@ import org.jetbrains.kotlin.name.FqNameUnsafe
|
|||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.CapturedType
|
import org.jetbrains.kotlin.resolve.calls.inference.CapturedType
|
||||||
import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor
|
import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.*
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasExactAnnotation
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasNoInferAnnotation
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isExactAnnotation
|
|
||||||
import org.jetbrains.kotlin.resolve.isInlineClass
|
import org.jetbrains.kotlin.resolve.isInlineClass
|
||||||
import org.jetbrains.kotlin.resolve.substitutedUnderlyingType
|
import org.jetbrains.kotlin.resolve.substitutedUnderlyingType
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
@@ -42,6 +39,11 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
|
|||||||
return this is IntegerLiteralTypeConstructor
|
return this is IntegerLiteralTypeConstructor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun TypeConstructorMarker.isLocalType(): Boolean {
|
||||||
|
require(this is TypeConstructor, this::errorMessage)
|
||||||
|
return declarationDescriptor?.classId?.isLocal == true
|
||||||
|
}
|
||||||
|
|
||||||
override fun SimpleTypeMarker.possibleIntegerTypes(): Collection<KotlinTypeMarker> {
|
override fun SimpleTypeMarker.possibleIntegerTypes(): Collection<KotlinTypeMarker> {
|
||||||
val typeConstructor = typeConstructor()
|
val typeConstructor = typeConstructor()
|
||||||
require(typeConstructor is IntegerLiteralTypeConstructor, this::errorMessage)
|
require(typeConstructor is IntegerLiteralTypeConstructor, this::errorMessage)
|
||||||
|
|||||||
Reference in New Issue
Block a user