[NI] Disable capturing/approximation type in TypeSubstitutor with enabled NI

This commit is contained in:
Dmitriy Novozhilov
2019-05-29 10:35:46 +03:00
parent dad334ffcd
commit 7c4101e21c
80 changed files with 890 additions and 201 deletions
@@ -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() =