[NI] Disable capturing/approximation type in TypeSubstitutor with enabled NI
There is added a new service named `SubstitutingScopeProvider`, that provides factory that creates captured types and approximator for them. In OI they are the same as before commit, for NI they are empty, because that approximation interferes with NI algorithm That service is injected into function descriptors and property descriptors and used for creating `SubstitutingScope` with correct services Also there is changed time when we approximate captured types in NI (after all call checkers) #KT-25290 Fixed
This commit is contained in:
+28
-7
@@ -60,6 +60,20 @@ val CallableDescriptor.returnTypeOrNothing: UnwrappedType
|
||||
|
||||
fun TypeSubstitutor.substitute(type: UnwrappedType): UnwrappedType = safeSubstitute(type, Variance.INVARIANT).unwrap()
|
||||
|
||||
fun CallableDescriptor.substituteAndApproximateIntegerLiteralTypes(substitutor: NewTypeSubstitutor): CallableDescriptor {
|
||||
val wrappedSubstitution = object : TypeSubstitution() {
|
||||
override fun get(key: KotlinType): TypeProjection? = null
|
||||
|
||||
override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) =
|
||||
substitutor.safeSubstitute(topLevelType.unwrap()).let { substitutedType ->
|
||||
TypeApproximator(builtIns).approximateToSuperType(substitutedType, TypeApproximatorConfiguration.IntegerLiteralsTypesApproximation)
|
||||
?: substitutedType
|
||||
}
|
||||
}
|
||||
|
||||
return substitute(TypeSubstitutor.create(wrappedSubstitution))
|
||||
}
|
||||
|
||||
fun CallableDescriptor.substitute(substitutor: NewTypeSubstitutor): CallableDescriptor {
|
||||
val wrappedSubstitution = object : TypeSubstitution() {
|
||||
override fun get(key: KotlinType): TypeProjection? = null
|
||||
@@ -68,18 +82,25 @@ fun CallableDescriptor.substitute(substitutor: NewTypeSubstitutor): CallableDesc
|
||||
return substitute(TypeSubstitutor.create(wrappedSubstitution))
|
||||
}
|
||||
|
||||
fun CallableDescriptor.substituteAndApproximateCapturedTypes(substitutor: NewTypeSubstitutor): CallableDescriptor {
|
||||
fun <D: CallableDescriptor> D.approximateCapturedTypes(): D {
|
||||
val approximator = TypeApproximator(builtIns)
|
||||
var anyChanges = false
|
||||
val wrappedSubstitution = object : TypeSubstitution() {
|
||||
override fun get(key: KotlinType): TypeProjection? = null
|
||||
|
||||
override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) =
|
||||
substitutor.safeSubstitute(topLevelType.unwrap()).let { substitutedType ->
|
||||
TypeApproximator(builtIns).approximateToSuperType(substitutedType, TypeApproximatorConfiguration.CapturedAndIntegerLiteralsTypesApproximation)
|
||||
?: substitutedType
|
||||
override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance): KotlinType {
|
||||
val type = topLevelType.unwrap()
|
||||
val approximatedType =
|
||||
approximator.approximateToSuperType(type, TypeApproximatorConfiguration.CapturedAndIntegerLiteralsTypesApproximation)
|
||||
if (approximatedType != null) {
|
||||
anyChanges = true
|
||||
}
|
||||
return approximatedType as? KotlinType ?: type
|
||||
}
|
||||
}
|
||||
|
||||
return substitute(TypeSubstitutor.create(wrappedSubstitution))
|
||||
val substitutedDescriptor = substitute(TypeSubstitutor.create(wrappedSubstitution)) as D
|
||||
return if (anyChanges) substitutedDescriptor else this
|
||||
}
|
||||
|
||||
internal fun <E> MutableList<E>.trimToSize(newSize: Int) = subList(newSize, size).clear()
|
||||
internal fun <E> MutableList<E>.trimToSize(newSize: Int) = subList(newSize, size).clear()
|
||||
@@ -21,14 +21,10 @@ import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.resolve.calls.NewCommonSuperTypeCalculator
|
||||
import org.jetbrains.kotlin.resolve.calls.components.ClassicTypeSystemContextForCS
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableTypeConstructor
|
||||
import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor
|
||||
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration.IntersectionStrategy.*
|
||||
import org.jetbrains.kotlin.types.checker.NewCapturedType
|
||||
import org.jetbrains.kotlin.types.checker.NewCapturedTypeConstructor
|
||||
import org.jetbrains.kotlin.types.model.*
|
||||
import org.jetbrains.kotlin.types.model.CaptureStatus.*
|
||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||
|
||||
|
||||
open class TypeApproximatorConfiguration {
|
||||
@@ -424,6 +420,8 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon
|
||||
if (argument.isStarProjection()) continue
|
||||
|
||||
val argumentType = argument.getType()//.unwrap()
|
||||
val argumentTypeIsNullable = argumentType.asSimpleType()?.isMarkedNullable() ?: false
|
||||
|
||||
val effectiveVariance = AbstractTypeChecker.effectiveVariance(parameter.getVariance(), argument.getVariance())
|
||||
when (effectiveVariance) {
|
||||
null -> {
|
||||
@@ -487,7 +485,7 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon
|
||||
*/
|
||||
if (argumentType.typeConstructor() is NewCapturedTypeConstructor) {
|
||||
val subType = approximateToSubType(argumentType, conf, depth) ?: continue@loop
|
||||
if (!subType.isTrivialSub()) {
|
||||
if (!subType.isTrivialSub(argumentTypeIsNullable)) {
|
||||
newArguments[index] = createTypeArgument(subType, TypeVariance.IN)
|
||||
continue@loop
|
||||
}
|
||||
@@ -498,7 +496,7 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon
|
||||
if (approximatedSuperType.isTrivialSuper()) {
|
||||
val approximatedSubType =
|
||||
approximateToSubType(argumentType, conf, depth) ?: continue@loop // seems like this is never null
|
||||
if (!approximatedSubType.isTrivialSub()) {
|
||||
if (!approximatedSubType.isTrivialSub(argumentTypeIsNullable)) {
|
||||
newArguments[index] = createTypeArgument(approximatedSubType, TypeVariance.IN)
|
||||
continue@loop
|
||||
}
|
||||
@@ -527,7 +525,12 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon
|
||||
private fun KotlinTypeMarker.isTrivialSuper() = upperBoundIfFlexible().isNullableAny()
|
||||
|
||||
// Nothing or Nothing!
|
||||
private fun KotlinTypeMarker.isTrivialSub() = lowerBoundIfFlexible().isNothing()
|
||||
private fun KotlinTypeMarker.isTrivialSub(originalIsNullable: Boolean) = lowerBoundIfFlexible().let {
|
||||
if (originalIsNullable)
|
||||
it.isNothing() || it.isNullableNothing()
|
||||
else
|
||||
it.isNothing()
|
||||
}
|
||||
}
|
||||
//
|
||||
//internal fun KotlinTypeMarker.typeDepth() =
|
||||
|
||||
Reference in New Issue
Block a user