[FIR] Fully expand the bounds of type parameters for canBeNull check

This is required because a not-null bound `Foo` can resolve to a
`typealias Foo = Bar?` in which case we must return true.

#KT-64645 Fixed
This commit is contained in:
Kirill Rakhman
2024-01-02 15:45:41 +01:00
committed by Space Team
parent 438b2dd164
commit 1018ff280e
23 changed files with 100 additions and 54 deletions
@@ -6,14 +6,16 @@
package org.jetbrains.kotlin.fir.resolve.dfa
import kotlinx.collections.immutable.*
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.types.AbstractTypeChecker
import java.util.*
import kotlin.math.max
abstract class LogicSystem(private val context: ConeInferenceContext) {
private val nullableNothingType = context.session.builtinTypes.nullableNothingType.type
private val anyType = context.session.builtinTypes.anyType.type
val session: FirSession get() = context.session
private val nullableNothingType = session.builtinTypes.nullableNothingType.type
private val anyType = session.builtinTypes.anyType.type
abstract val variableStorage: VariableStorageImpl
@@ -340,7 +342,7 @@ abstract class LogicSystem(private val context: ConeInferenceContext) {
val result = when {
unified.isNullableAny -> return null
unified.isAcceptableForSmartcast() -> unified
unified.canBeNull -> return null
unified.canBeNull(context.session) -> return null
else -> context.anyType()
}
return PersistentTypeStatement(variable, persistentSetOf(result))
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.resolve.dfa
import org.jetbrains.kotlin.contracts.description.LogicOperationKind
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.contracts.description.*
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.types.canBeNull
@@ -45,7 +46,7 @@ fun LogicSystem.approveContractStatement(
substitutedType.isNullableNothing -> it.processEqNull(isType)
else -> {
// x is (T & Any) || x !is T? => x != null
val fromNullability = if ((isType && !type.canBeNull) || (!isType && type.isMarkedNullable))
val fromNullability = if ((isType && !type.canBeNull(session)) || (!isType && type.isMarkedNullable))
it.processEqNull(false)
else
mapOf()