Skip to content

Commit b165a34

Browse files
mglukhikhSpace Team
authored and
Space Team
committed
K2: fix withNullability() for ConeIntersectionType
Before this commit, we assumed that ConeIntersectionType is always NOT_NULL, so (SomeType? & OtherType?).withNullability(NOT_NULL) changed nothing in the input type. However, in fact it should return (SomeType & OtherType), so this commit fixes withNullability logic in accordance. #KT-67912 Fixed
1 parent f6a80b8 commit b165a34

File tree

7 files changed

+35
-50
lines changed

7 files changed

+35
-50
lines changed

compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,9 @@ class ConeIntersectionType(
230230
override val nullability: ConeNullability
231231
get() = ConeNullability.NOT_NULL
232232

233+
val effectiveNullability: ConeNullability
234+
get() = intersectedTypes.maxOf { it.nullability }
235+
233236
override val attributes: ConeAttributes = intersectedTypes.foldMap(
234237
{ it.attributes },
235238
{ a, b -> a.intersect(b) }

compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,9 @@ fun <T : ConeKotlinType> T.withNullability(
182182
withoutEnhanced.transformTypesWith { t -> t.withNullability(nullability, typeContext) } ?: withoutEnhanced
183183
}
184184

185-
if (this.nullability == nullability && this.attributes == theAttributes) {
185+
if (this.nullability == nullability && this.attributes == theAttributes && this !is ConeIntersectionType) {
186+
// Note: this is an optimization, but it's not applicable for ConeIntersectionType,
187+
// because ConeIntersectionType.nullability is always NOT_NULL, independent on real component nullabilities
186188
return this
187189
}
188190

@@ -213,7 +215,9 @@ fun <T : ConeKotlinType> T.withNullability(
213215
}
214216

215217
ConeNullability.UNKNOWN -> this // TODO: is that correct?
216-
ConeNullability.NOT_NULL -> this
218+
ConeNullability.NOT_NULL -> if (effectiveNullability == ConeNullability.NOT_NULL) this else this.mapTypes {
219+
it.withNullability(nullability, typeContext, preserveEnhancedNullability = preserveEnhancedNullability)
220+
}
217221
}
218222

219223
is ConeStubTypeForTypeVariableInSubtyping -> ConeStubTypeForTypeVariableInSubtyping(constructor, nullability)

compiler/testData/diagnostics/tests/inference/genericWithUnmatchedNullabilityDelegate.fir.kt

Lines changed: 0 additions & 12 deletions
This file was deleted.

compiler/testData/diagnostics/tests/inference/genericWithUnmatchedNullabilityDelegate.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// FIR_IDENTICAL
12
// ISSUE: KT-67912
23
// WITH_STDLIB
34

compiler/testData/diagnostics/tests/inference/genericsWithUnmatchedNullabilityNested.fir.kt

Lines changed: 0 additions & 12 deletions
This file was deleted.

compiler/testData/diagnostics/tests/inference/genericsWithUnmatchedNullabilityNested.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// FIR_IDENTICAL
12
// ISSUE: KT-67912
23
// WITH_STDLIB
34

compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/11.fir.kt

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -60,32 +60,32 @@ fun case_3(a: Int?, b: Float?, c: Double?, d: Boolean?) {
6060
false -> b
6161
null -> c
6262
}.apply {
63-
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>?")!>this<!>
64-
if (this != null) {
65-
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>
66-
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.equals(null)
67-
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.propT
68-
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.propAny
69-
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.propNullableT
70-
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.propNullableAny
71-
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.funT()
72-
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.funAny()
73-
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.funNullableT()
74-
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.funNullableAny()
63+
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>
64+
if (<!SENSELESS_COMPARISON!>this != null<!>) {
65+
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>
66+
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.equals(null)
67+
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.propT
68+
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.propAny
69+
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.propNullableT
70+
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.propNullableAny
71+
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.funT()
72+
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.funAny()
73+
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.funNullableT()
74+
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.funNullableAny()
7575
}
7676
}.let {
77-
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>?")!>it<!>
78-
if (it != null) {
79-
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>
80-
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.equals(null)
81-
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.propT
82-
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.propAny
83-
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.propNullableT
84-
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.propNullableAny
85-
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.funT()
86-
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.funAny()
87-
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.funNullableT()
88-
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.funNullableAny()
77+
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>
78+
if (<!SENSELESS_COMPARISON!>it != null<!>) {
79+
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>
80+
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.equals(null)
81+
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.propT
82+
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.propAny
83+
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.propNullableT
84+
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.propNullableAny
85+
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.funT()
86+
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.funAny()
87+
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.funNullableT()
88+
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.funNullableAny()
8989
}
9090
}
9191
}

0 commit comments

Comments
 (0)