[NI] Consider intersection type with number type as Nothing
Currently, only for "in": In<in Int & A> == In<in Nothing> == In<*> #KT-37302 Fixed
This commit is contained in:
+1
-1
@@ -94,7 +94,7 @@ fun CallableDescriptor.substituteAndApproximateTypes(
|
||||
}
|
||||
}
|
||||
|
||||
return substitute(TypeSubstitutor.create(wrappedSubstitution))
|
||||
return substitute(TypeSubstitutor.create(wrappedSubstitution)) ?: this
|
||||
}
|
||||
|
||||
internal fun <E> MutableList<E>.trimToSize(newSize: Int) = subList(newSize, size).clear()
|
||||
|
||||
+2
-2
@@ -149,7 +149,7 @@ class ResultTypeResolver(
|
||||
|
||||
return typeApproximator.approximateToSuperType(
|
||||
commonSuperType,
|
||||
TypeApproximatorConfiguration.CapturedAndIntegerLiteralsTypesApproximation
|
||||
TypeApproximatorConfiguration.InternalTypesApproximation
|
||||
) ?: commonSuperType
|
||||
}
|
||||
|
||||
@@ -202,7 +202,7 @@ class ResultTypeResolver(
|
||||
|
||||
return typeApproximator.approximateToSubType(
|
||||
upperType,
|
||||
TypeApproximatorConfiguration.CapturedAndIntegerLiteralsTypesApproximation
|
||||
TypeApproximatorConfiguration.InternalTypesApproximation
|
||||
) ?: upperType
|
||||
}
|
||||
return null
|
||||
|
||||
@@ -17,9 +17,6 @@
|
||||
package org.jetbrains.kotlin.resolve.calls.tower
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.getReceiverValueWithSmartCast
|
||||
@@ -144,11 +141,11 @@ internal class MemberScopeTowerLevel(
|
||||
Variance.INVARIANT -> null
|
||||
Variance.OUT_VARIANCE -> approximator.approximateToSuperType(
|
||||
topLevelType.unwrap(),
|
||||
TypeApproximatorConfiguration.CapturedAndIntegerLiteralsTypesApproximation
|
||||
TypeApproximatorConfiguration.InternalTypesApproximation
|
||||
)
|
||||
Variance.IN_VARIANCE -> approximator.approximateToSubType(
|
||||
topLevelType.unwrap(),
|
||||
TypeApproximatorConfiguration.CapturedAndIntegerLiteralsTypesApproximation
|
||||
TypeApproximatorConfiguration.InternalTypesApproximation
|
||||
)
|
||||
} ?: topLevelType
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.types.TypeApproximatorConfiguration.IntersectionStra
|
||||
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.isSignedOrUnsignedNumberType
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
|
||||
@@ -42,6 +43,7 @@ open class TypeApproximatorConfiguration {
|
||||
open val integerLiteralType: Boolean = false // IntegerLiteralTypeConstructor
|
||||
open val definitelyNotNullType get() = true
|
||||
open val intersection: IntersectionStrategy = TO_COMMON_SUPERTYPE
|
||||
open val intersectionTypesInContravariantPositions = false
|
||||
|
||||
open val typeVariable: (TypeVariableTypeConstructorMarker) -> Boolean = { false }
|
||||
open fun capturedType(ctx: TypeSystemInferenceExtensionContext, type: CapturedTypeMarker): Boolean =
|
||||
@@ -60,6 +62,7 @@ open class TypeApproximatorConfiguration {
|
||||
override val intersection get() = ALLOWED
|
||||
override val errorType get() = true
|
||||
override val integerLiteralType: Boolean get() = true
|
||||
override val intersectionTypesInContravariantPositions: Boolean get() = true
|
||||
}
|
||||
|
||||
object PublicDeclaration : AllFlexibleSameValue() {
|
||||
@@ -67,6 +70,7 @@ open class TypeApproximatorConfiguration {
|
||||
override val errorType get() = true
|
||||
override val definitelyNotNullType get() = false
|
||||
override val integerLiteralType: Boolean get() = true
|
||||
override val intersectionTypesInContravariantPositions: Boolean get() = true
|
||||
}
|
||||
|
||||
abstract class AbstractCapturedTypesApproximation(val approximatedCapturedStatus: CaptureStatus) :
|
||||
@@ -84,13 +88,15 @@ open class TypeApproximatorConfiguration {
|
||||
|
||||
object IncorporationConfiguration : TypeApproximatorConfiguration.AbstractCapturedTypesApproximation(FOR_INCORPORATION)
|
||||
object SubtypeCapturedTypesApproximation : TypeApproximatorConfiguration.AbstractCapturedTypesApproximation(FOR_SUBTYPING)
|
||||
object CapturedAndIntegerLiteralsTypesApproximation : TypeApproximatorConfiguration.AbstractCapturedTypesApproximation(FROM_EXPRESSION) {
|
||||
object InternalTypesApproximation : TypeApproximatorConfiguration.AbstractCapturedTypesApproximation(FROM_EXPRESSION) {
|
||||
override val integerLiteralType: Boolean get() = true
|
||||
override val intersectionTypesInContravariantPositions: Boolean get() = true
|
||||
}
|
||||
|
||||
object FinalApproximationAfterResolutionAndInference :
|
||||
TypeApproximatorConfiguration.AbstractCapturedTypesApproximation(FROM_EXPRESSION) {
|
||||
override val integerLiteralType: Boolean get() = true
|
||||
override val intersectionTypesInContravariantPositions: Boolean get() = true
|
||||
}
|
||||
|
||||
object IntegerLiteralsTypesApproximation : TypeApproximatorConfiguration.AllFlexibleSameValue() {
|
||||
@@ -279,6 +285,13 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon
|
||||
}
|
||||
}
|
||||
|
||||
private fun isIntersectionTypeEffectivelyNothing(constructor: IntersectionTypeConstructor): 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
|
||||
|
||||
return constructor.supertypes.any { !it.isMarkedNullable && it.isSignedOrUnsignedNumberType() }
|
||||
}
|
||||
|
||||
private fun approximateIntersectionType(
|
||||
type: SimpleTypeMarker,
|
||||
conf: TypeApproximatorConfiguration,
|
||||
@@ -512,6 +525,18 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon
|
||||
} else type.defaultResult(toSuper)
|
||||
}
|
||||
TypeVariance.OUT, TypeVariance.IN -> {
|
||||
if (
|
||||
conf.intersectionTypesInContravariantPositions &&
|
||||
effectiveVariance == TypeVariance.IN &&
|
||||
argumentType.typeConstructor().isIntersection()
|
||||
) {
|
||||
val intersectionTypeConstructor = argumentType.typeConstructor() as? IntersectionTypeConstructor
|
||||
if (intersectionTypeConstructor != null && isIntersectionTypeEffectivelyNothing(intersectionTypeConstructor)) {
|
||||
newArguments[index] = createStarProjection(parameter)
|
||||
continue@loop
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Out<Foo> <: Out<superType(Foo)>
|
||||
* Inv<out Foo> <: Inv<out superType(Foo)>
|
||||
|
||||
Reference in New Issue
Block a user