[NI] Discard DefNotNull types inside invariant positions

#KT-30297 Fixed
 #KT-32168 Fixed
 #KT-27722 Fixed (actually, it was fixed with addition of DefNotNullTypes, and now test was added to save this behavior)
 #KT-32345 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2019-10-31 14:51:30 +03:00
parent 4fc1bd9ec5
commit 5582fd4056
16 changed files with 251 additions and 10 deletions
@@ -73,7 +73,7 @@ fun CallableDescriptor.substitute(substitutor: NewTypeSubstitutor): CallableDesc
return substitute(TypeSubstitutor.create(wrappedSubstitution))
}
fun CallableDescriptor.substituteAndApproximateCapturedTypes(
fun CallableDescriptor.substituteAndApproximateTypes(
substitutor: NewTypeSubstitutor,
typeApproximator: TypeApproximator
): CallableDescriptor {
@@ -82,8 +82,10 @@ fun CallableDescriptor.substituteAndApproximateCapturedTypes(
override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) =
substitutor.safeSubstitute(topLevelType.unwrap()).let { substitutedType ->
typeApproximator.approximateToSuperType(substitutedType, TypeApproximatorConfiguration.CapturedAndIntegerLiteralsTypesApproximation)
?: substitutedType
typeApproximator.approximateToSuperType(
substitutedType,
TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference
) ?: substitutedType
}
}
@@ -41,6 +41,7 @@ open class TypeApproximatorConfiguration {
open val errorType get() = false
open val integerLiteralType: Boolean = false // IntegerLiteralTypeConstructor
open val definitelyNotNullType get() = true
open val definitelyNotNullTypeInInvariantPosition get() = true
open val intersection: IntersectionStrategy = TO_COMMON_SUPERTYPE
open val typeVariable: (TypeVariableTypeConstructorMarker) -> Boolean = { false }
@@ -88,6 +89,12 @@ open class TypeApproximatorConfiguration {
override val integerLiteralType: Boolean get() = true
}
object FinalApproximationAfterResolutionAndInference :
TypeApproximatorConfiguration.AbstractCapturedTypesApproximation(FROM_EXPRESSION) {
override val integerLiteralType: Boolean get() = true
override val definitelyNotNullTypeInInvariantPosition: Boolean get() = false
}
object IntegerLiteralsTypesApproximation : TypeApproximatorConfiguration.AllFlexibleSameValue() {
override val integerLiteralType: Boolean get() = true
override val allFlexible: Boolean get() = true
@@ -468,8 +475,17 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon
if (argument.isStarProjection()) continue
val argumentType = argument.getType()
when (val effectiveVariance = AbstractTypeChecker.effectiveVariance(parameter.getVariance(), argument.getVariance())) {
val effectiveVariance = AbstractTypeChecker.effectiveVariance(parameter.getVariance(), argument.getVariance())
if (effectiveVariance == TypeVariance.INV) {
val argumentType = argument.getType()
if (argumentType is DefinitelyNotNullTypeMarker && !conf.definitelyNotNullTypeInInvariantPosition) {
newArguments[index] = argumentType.original().withNullability(false).asTypeArgument()
}
}
val argumentType = newArguments[index]?.getType() ?: argument.getType()
when (effectiveVariance) {
null -> {
return if (conf.errorType) {
createErrorType(