diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt index 186a4f29eef2a..62c15be001667 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt @@ -230,6 +230,9 @@ class ConeIntersectionType( override val nullability: ConeNullability get() = ConeNullability.NOT_NULL + val effectiveNullability: ConeNullability + get() = intersectedTypes.maxOf { it.nullability } + override val attributes: ConeAttributes = intersectedTypes.foldMap( { it.attributes }, { a, b -> a.intersect(b) } diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt index 3dec0698c661e..d25f762c56a1f 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt @@ -182,7 +182,9 @@ fun T.withNullability( withoutEnhanced.transformTypesWith { t -> t.withNullability(nullability, typeContext) } ?: withoutEnhanced } - if (this.nullability == nullability && this.attributes == theAttributes) { + if (this.nullability == nullability && this.attributes == theAttributes && this !is ConeIntersectionType) { + // Note: this is an optimization, but it's not applicable for ConeIntersectionType, + // because ConeIntersectionType.nullability is always NOT_NULL, independent on real component nullabilities return this } @@ -213,7 +215,9 @@ fun T.withNullability( } ConeNullability.UNKNOWN -> this // TODO: is that correct? - ConeNullability.NOT_NULL -> this + ConeNullability.NOT_NULL -> if (effectiveNullability == ConeNullability.NOT_NULL) this else this.mapTypes { + it.withNullability(nullability, typeContext, preserveEnhancedNullability = preserveEnhancedNullability) + } } is ConeStubTypeForTypeVariableInSubtyping -> ConeStubTypeForTypeVariableInSubtyping(constructor, nullability) diff --git a/compiler/testData/diagnostics/tests/inference/genericWithUnmatchedNullabilityDelegate.fir.kt b/compiler/testData/diagnostics/tests/inference/genericWithUnmatchedNullabilityDelegate.fir.kt deleted file mode 100644 index 61a71782bd602..0000000000000 --- a/compiler/testData/diagnostics/tests/inference/genericWithUnmatchedNullabilityDelegate.fir.kt +++ /dev/null @@ -1,12 +0,0 @@ -// ISSUE: KT-67912 -// WITH_STDLIB - -interface Bound - -inline fun foo(key: String): F? = null - -fun main() { - val otherValue: Map by lazy { - foo("") ?: emptyMap() - } -} diff --git a/compiler/testData/diagnostics/tests/inference/genericWithUnmatchedNullabilityDelegate.kt b/compiler/testData/diagnostics/tests/inference/genericWithUnmatchedNullabilityDelegate.kt index 6dcb777857cf8..2c70b4ea4eb3b 100644 --- a/compiler/testData/diagnostics/tests/inference/genericWithUnmatchedNullabilityDelegate.kt +++ b/compiler/testData/diagnostics/tests/inference/genericWithUnmatchedNullabilityDelegate.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // ISSUE: KT-67912 // WITH_STDLIB diff --git a/compiler/testData/diagnostics/tests/inference/genericsWithUnmatchedNullabilityNested.fir.kt b/compiler/testData/diagnostics/tests/inference/genericsWithUnmatchedNullabilityNested.fir.kt deleted file mode 100644 index 832e0868dfd2c..0000000000000 --- a/compiler/testData/diagnostics/tests/inference/genericsWithUnmatchedNullabilityNested.fir.kt +++ /dev/null @@ -1,12 +0,0 @@ -// ISSUE: KT-67912 -// WITH_STDLIB - -interface Bound - -inline fun foo(key: String): F? = null - -fun main() { - val value: Map = requireNotNull( - foo("") - ) -} diff --git a/compiler/testData/diagnostics/tests/inference/genericsWithUnmatchedNullabilityNested.kt b/compiler/testData/diagnostics/tests/inference/genericsWithUnmatchedNullabilityNested.kt index a32d720945bcc..7cfa8d6f88d74 100644 --- a/compiler/testData/diagnostics/tests/inference/genericsWithUnmatchedNullabilityNested.kt +++ b/compiler/testData/diagnostics/tests/inference/genericsWithUnmatchedNullabilityNested.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // ISSUE: KT-67912 // WITH_STDLIB diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/11.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/11.fir.kt index adb39e9541992..1d5e999c2a201 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/11.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/11.fir.kt @@ -60,32 +60,32 @@ fun case_3(a: Int?, b: Float?, c: Double?, d: Boolean?) { false -> b null -> c }.apply { - ?")!>this - if (this != null) { - ? & kotlin.Number & kotlin.Comparable")!>this - ? & kotlin.Number & kotlin.Comparable")!>this.equals(null) - ? & kotlin.Number & kotlin.Comparable")!>this.propT - ? & kotlin.Number & kotlin.Comparable")!>this.propAny - ? & kotlin.Number & kotlin.Comparable")!>this.propNullableT - ? & kotlin.Number & kotlin.Comparable")!>this.propNullableAny - ? & kotlin.Number & kotlin.Comparable")!>this.funT() - ? & kotlin.Number & kotlin.Comparable")!>this.funAny() - ? & kotlin.Number & kotlin.Comparable")!>this.funNullableT() - ? & kotlin.Number & kotlin.Comparable")!>this.funNullableAny() + ")!>this + if (this != null) { + ")!>this + ")!>this.equals(null) + ")!>this.propT + ")!>this.propAny + ")!>this.propNullableT + ")!>this.propNullableAny + ")!>this.funT() + ")!>this.funAny() + ")!>this.funNullableT() + ")!>this.funNullableAny() } }.let { - ?")!>it - if (it != null) { - ? & kotlin.Number & kotlin.Comparable")!>it - ? & kotlin.Number & kotlin.Comparable")!>it.equals(null) - ? & kotlin.Number & kotlin.Comparable")!>it.propT - ? & kotlin.Number & kotlin.Comparable")!>it.propAny - ? & kotlin.Number & kotlin.Comparable")!>it.propNullableT - ? & kotlin.Number & kotlin.Comparable")!>it.propNullableAny - ? & kotlin.Number & kotlin.Comparable")!>it.funT() - ? & kotlin.Number & kotlin.Comparable")!>it.funAny() - ? & kotlin.Number & kotlin.Comparable")!>it.funNullableT() - ? & kotlin.Number & kotlin.Comparable")!>it.funNullableAny() + ")!>it + if (it != null) { + ")!>it + ")!>it.equals(null) + ")!>it.propT + ")!>it.propAny + ")!>it.propNullableT + ")!>it.propNullableAny + ")!>it.funT() + ")!>it.funAny() + ")!>it.funNullableT() + ")!>it.funNullableAny() } } }