FIR: enable useCorrectedNullabilityForFlexibleTypeParameters
It's necessary for correct substitution of `T & Any` with `T = V..V?`.
This commit is contained in:
@@ -143,8 +143,7 @@ private fun ConeKotlinType.enhanceInflexibleType(
|
||||
val mergedAttributes = if (shouldAddAttribute) attributes + CompilerConeAttributes.EnhancedNullability else attributes
|
||||
val enhancedType = enhancedTag.constructType(mergedArguments, enhancedNullability, mergedAttributes)
|
||||
return if (effectiveQualifiers.isNotNullTypeParameter)
|
||||
ConeDefinitelyNotNullType.create(enhancedType, session.typeContext, useCorrectedNullabilityForFlexibleTypeParameters = true)
|
||||
?: enhancedType
|
||||
ConeDefinitelyNotNullType.create(enhancedType, session.typeContext) ?: enhancedType
|
||||
else
|
||||
enhancedType
|
||||
}
|
||||
|
||||
@@ -21,9 +21,7 @@ import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.NewCommonSuperTypeCalculator
|
||||
import org.jetbrains.kotlin.types.AbstractStrictEqualityTypeChecker
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.model.*
|
||||
|
||||
fun ConeInferenceContext.commonSuperTypeOrNull(types: List<ConeKotlinType>): ConeKotlinType? {
|
||||
@@ -47,20 +45,27 @@ fun ConeInferenceContext.intersectTypesOrNull(types: List<ConeKotlinType>): Cone
|
||||
fun TypeCheckerProviderContext.equalTypes(a: ConeKotlinType, b: ConeKotlinType): Boolean =
|
||||
AbstractTypeChecker.equalTypes(this, a, b)
|
||||
|
||||
private fun ConeTypeContext.makesSenseToBeDefinitelyNotNull(type: ConeKotlinType): Boolean = when (type) {
|
||||
is ConeTypeParameterType -> type.isNullableType()
|
||||
// Actually, this branch should work for type parameters as well, but it breaks some cases. See KT-40114.
|
||||
// Basically, if we have `T : X..X?`, then `T <: Any` but we still have `T` != `T & Any`.
|
||||
is ConeTypeVariableType, is ConeCapturedType ->
|
||||
!AbstractNullabilityChecker.isSubtypeOfAny(
|
||||
newTypeCheckerState(errorTypesEqualToAnything = false, stubTypesEqualToAnything = false), type
|
||||
)
|
||||
// For all other types `T & Any` is the same as `T` without a question mark.
|
||||
// TODO: not true for flexible types.
|
||||
else -> false
|
||||
}
|
||||
|
||||
// TODO: leave only one of `create` and `makeConeTypeDefinitelyNotNullOrNotNull`
|
||||
fun ConeDefinitelyNotNullType.Companion.create(
|
||||
original: ConeKotlinType,
|
||||
typeContext: ConeTypeContext,
|
||||
useCorrectedNullabilityForFlexibleTypeParameters: Boolean = false,
|
||||
typeContext: ConeTypeContext
|
||||
): ConeDefinitelyNotNullType? {
|
||||
return when {
|
||||
original is ConeDefinitelyNotNullType -> original
|
||||
typeContext
|
||||
.newTypeCheckerState(errorTypesEqualToAnything = false, stubTypesEqualToAnything = false)
|
||||
.makesSenseToBeDefinitelyNotNull(original, useCorrectedNullabilityForFlexibleTypeParameters) ->
|
||||
|
||||
ConeDefinitelyNotNullType(
|
||||
original.lowerBoundIfFlexible()
|
||||
)
|
||||
typeContext.makesSenseToBeDefinitelyNotNull(original) -> ConeDefinitelyNotNullType(original)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
@@ -81,10 +86,7 @@ fun <T : ConeKotlinType> T.withArguments(arguments: Array<out ConeTypeProjection
|
||||
return when (this) {
|
||||
is ConeClassErrorType -> this
|
||||
is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, arguments, nullability.isNullable) as T
|
||||
is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType.create(
|
||||
original.withArguments(arguments, typeSystemContext),
|
||||
typeSystemContext
|
||||
)!! as T
|
||||
is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType(original.withArguments(arguments, typeSystemContext)) as T
|
||||
else -> error("Not supported: $this: ${this.render()}")
|
||||
}
|
||||
}
|
||||
@@ -101,10 +103,7 @@ fun <T : ConeKotlinType> T.withAttributes(attributes: ConeAttributes, typeSystem
|
||||
return when (this) {
|
||||
is ConeClassErrorType -> this
|
||||
is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, typeArguments, nullability.isNullable, attributes)
|
||||
is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType.create(
|
||||
original.withAttributes(attributes, typeSystemContext),
|
||||
typeSystemContext
|
||||
)!!
|
||||
is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType(original.withAttributes(attributes, typeSystemContext))
|
||||
is ConeTypeParameterTypeImpl -> ConeTypeParameterTypeImpl(lookupTag, nullability.isNullable, attributes)
|
||||
is ConeFlexibleType -> ConeFlexibleType(
|
||||
lowerBound.withAttributes(attributes, typeSystemContext),
|
||||
|
||||
@@ -14,8 +14,6 @@ import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
import org.jetbrains.kotlin.types.AbstractNullabilityChecker
|
||||
import org.jetbrains.kotlin.types.TypeCheckerState
|
||||
import org.jetbrains.kotlin.types.ConstantValueKind
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.contract
|
||||
@@ -151,41 +149,6 @@ fun FirTypeProjection.toConeTypeProjection(): ConeTypeProjection =
|
||||
else -> error("!")
|
||||
}
|
||||
|
||||
fun TypeCheckerState.makesSenseToBeDefinitelyNotNull(
|
||||
type: ConeKotlinType,
|
||||
useCorrectedNullabilityForFlexibleTypeParameters: Boolean
|
||||
): Boolean {
|
||||
if (!type.canHaveUndefinedNullability()) return false
|
||||
|
||||
// Replacing `useCorrectedNullabilityForFlexibleTypeParameters` with true for all call-sites seems to be correct
|
||||
// But it seems that it should be a new feature: KT-28785 would be automatically fixed then
|
||||
// (see the tests org.jetbrains.kotlin.spec.checkers.DiagnosticsTestSpecGenerated.NotLinked.Dfa.Pos.test12/13)
|
||||
// So it should be a language feature, but it's hard correctly identify language version settings for all call sites
|
||||
// Thus, we have non-trivial value at org.jetbrains.kotlin.load.java.typeEnhancement.JavaTypeEnhancement.notNullTypeParameter
|
||||
// that run under related language-feature only
|
||||
if (useCorrectedNullabilityForFlexibleTypeParameters && type is ConeTypeParameterType) {
|
||||
// Effectively checks if the type is flexible or has nullable bound
|
||||
return with(typeSystemContext) {
|
||||
type.isNullableType()
|
||||
}
|
||||
}
|
||||
|
||||
// Actually, this code should work for type parameters as well, but it breaks some cases
|
||||
// See KT-40114
|
||||
|
||||
return !AbstractNullabilityChecker.isSubtypeOfAny(this, type)
|
||||
}
|
||||
|
||||
fun ConeKotlinType.canHaveUndefinedNullability(): Boolean {
|
||||
return when (this) {
|
||||
is ConeTypeVariableType,
|
||||
is ConeCapturedType,
|
||||
is ConeTypeParameterType
|
||||
-> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
private fun ConeTypeParameterType.hasNotNullUpperBound(): Boolean {
|
||||
return lookupTag.typeParameterSymbol.fir.bounds.any {
|
||||
val boundType = it.coneType
|
||||
|
||||
@@ -82,25 +82,12 @@ FILE fqName:<root> fileName:/AbstractMutableMap.kt
|
||||
VALUE_PARAMETER name:p0 index:0 type:K of <root>.MyMap
|
||||
VALUE_PARAMETER name:p1 index:1 type:@[EnhancedNullability] V of <root>.MyMap
|
||||
VALUE_PARAMETER name:p2 index:2 type:@[EnhancedNullability] java.util.function.BiFunction<in @[EnhancedNullability] V of <root>.MyMap, in @[EnhancedNullability] V of <root>.MyMap, out V of <root>.MyMap?>
|
||||
FUN FAKE_OVERRIDE name:merge visibility:public modality:OPEN <> ($this:kotlin.collections.MutableMap<K of kotlin.collections.MutableMap, V of kotlin.collections.MutableMap>, p0:@[FlexibleNullability] K of <root>.MyMap?, p1:V of <root>.MyMap, p2:@[EnhancedNullability] java.util.function.BiFunction<in V of <root>.MyMap, in V of <root>.MyMap, out V of <root>.MyMap?>) returnType:V of <root>.MyMap? [fake_override]
|
||||
overridden:
|
||||
public open fun merge (p0: @[FlexibleNullability] K of kotlin.collections.AbstractMutableMap?, p1: V of kotlin.collections.AbstractMutableMap, p2: @[EnhancedNullability] java.util.function.BiFunction<in V of kotlin.collections.AbstractMutableMap, in V of kotlin.collections.AbstractMutableMap, out V of kotlin.collections.AbstractMutableMap?>): V of kotlin.collections.AbstractMutableMap? [fake_override] declared in kotlin.collections.AbstractMutableMap
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.collections.MutableMap<K of kotlin.collections.MutableMap, V of kotlin.collections.MutableMap>
|
||||
VALUE_PARAMETER name:p0 index:0 type:@[FlexibleNullability] K of <root>.MyMap?
|
||||
VALUE_PARAMETER name:p1 index:1 type:V of <root>.MyMap
|
||||
VALUE_PARAMETER name:p2 index:2 type:@[EnhancedNullability] java.util.function.BiFunction<in V of <root>.MyMap, in V of <root>.MyMap, out V of <root>.MyMap?>
|
||||
FUN FAKE_OVERRIDE name:computeIfPresent visibility:public modality:OPEN <> ($this:kotlin.collections.MutableMap<K of kotlin.collections.MutableMap, V of kotlin.collections.MutableMap>, p0:K of <root>.MyMap, p1:@[EnhancedNullability] java.util.function.BiFunction<in K of <root>.MyMap, in @[EnhancedNullability] V of <root>.MyMap, out V of <root>.MyMap?>) returnType:V of <root>.MyMap? [fake_override]
|
||||
overridden:
|
||||
public open fun computeIfPresent (p0: K of kotlin.collections.AbstractMutableMap, p1: @[EnhancedNullability] java.util.function.BiFunction<in K of kotlin.collections.AbstractMutableMap, in @[EnhancedNullability] V of kotlin.collections.AbstractMutableMap, out V of kotlin.collections.AbstractMutableMap?>): V of kotlin.collections.AbstractMutableMap? [fake_override] declared in kotlin.collections.AbstractMutableMap
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.collections.MutableMap<K of kotlin.collections.MutableMap, V of kotlin.collections.MutableMap>
|
||||
VALUE_PARAMETER name:p0 index:0 type:K of <root>.MyMap
|
||||
VALUE_PARAMETER name:p1 index:1 type:@[EnhancedNullability] java.util.function.BiFunction<in K of <root>.MyMap, in @[EnhancedNullability] V of <root>.MyMap, out V of <root>.MyMap?>
|
||||
FUN FAKE_OVERRIDE name:computeIfPresent visibility:public modality:OPEN <> ($this:kotlin.collections.MutableMap<K of kotlin.collections.MutableMap, V of kotlin.collections.MutableMap>, p0:@[FlexibleNullability] K of <root>.MyMap?, p1:@[EnhancedNullability] java.util.function.BiFunction<in @[FlexibleNullability] K of <root>.MyMap?, in V of <root>.MyMap, out V of <root>.MyMap?>) returnType:V of <root>.MyMap? [fake_override]
|
||||
overridden:
|
||||
public open fun computeIfPresent (p0: @[FlexibleNullability] K of kotlin.collections.AbstractMutableMap?, p1: @[EnhancedNullability] java.util.function.BiFunction<in @[FlexibleNullability] K of kotlin.collections.AbstractMutableMap?, in V of kotlin.collections.AbstractMutableMap, out V of kotlin.collections.AbstractMutableMap?>): V of kotlin.collections.AbstractMutableMap? [fake_override] declared in kotlin.collections.AbstractMutableMap
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.collections.MutableMap<K of kotlin.collections.MutableMap, V of kotlin.collections.MutableMap>
|
||||
VALUE_PARAMETER name:p0 index:0 type:@[FlexibleNullability] K of <root>.MyMap?
|
||||
VALUE_PARAMETER name:p1 index:1 type:@[EnhancedNullability] java.util.function.BiFunction<in @[FlexibleNullability] K of <root>.MyMap?, in V of <root>.MyMap, out V of <root>.MyMap?>
|
||||
FUN FAKE_OVERRIDE name:putIfAbsent visibility:public modality:OPEN <> ($this:kotlin.collections.MutableMap<K of kotlin.collections.MutableMap, V of kotlin.collections.MutableMap>, p0:K of <root>.MyMap, p1:V of <root>.MyMap) returnType:V of <root>.MyMap? [fake_override]
|
||||
overridden:
|
||||
public open fun putIfAbsent (p0: K of kotlin.collections.AbstractMutableMap, p1: V of kotlin.collections.AbstractMutableMap): V of kotlin.collections.AbstractMutableMap? [fake_override] declared in kotlin.collections.AbstractMutableMap
|
||||
|
||||
Reference in New Issue
Block a user