K2. Restore intended behavior for FirJavaSamConstructorNullabilityChecker
Previously, this checker was built under an assumption that explicit
type arguments for SAM constructor as being stored as are, but
during the initial fix of KT-67999, we've switched to storing
flexible types there (as in K1, see previous commits).
And to restore behavior, the actual explicit type arguments
are being preserved inside a type attribute.
^KT-67999 Fixed
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt
index 0c9b5c8..f95e717 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt
@@ -812,8 +812,9 @@
candidate: Candidate,
): List<FirTypeProjection> {
val typeArguments = computeTypeArgumentTypes(candidate)
- .mapIndexed { index, type ->
+ .mapIndexed { index, typeFromFinalSubstitutor ->
val argument = access.typeArguments.getOrNull(index)
+ val type = typeFromFinalSubstitutor.chooseActualExplicitArgumentIfResultWasMadeFlexibleSynthetically(argument)
val sourceForTypeArgument = argument?.source
?: access.calleeReference.source?.fakeElement(KtFakeSourceElementKind.ImplicitTypeArgument)
when (argument) {
@@ -847,6 +848,19 @@
} else typeArguments
}
+ /**
+ * @see org.jetbrains.kotlin.fir.expressions.ExplicitTypeArgumentIfMadeFlexibleSyntheticallyTypeAttribute
+ * TODO: Get rid of this function once KT-59138 is fixed and the relevant feature for disabling it will be removed
+ */
+ private fun ConeKotlinType.chooseActualExplicitArgumentIfResultWasMadeFlexibleSynthetically(
+ argument: FirTypeProjection?,
+ ): ConeKotlinType {
+ if (this !is ConeFlexibleType) return this
+ if (argument !is FirTypeProjectionWithVariance) return this
+
+ return argument.typeRef.coneType
+ }
+
private fun computeTypeArgumentTypes(
candidate: Candidate,
): List<ConeKotlinType> {
diff --git a/compiler/testData/diagnostics/tests/samConversions/samConversionToGenericWrongNullability.fir.diag.txt b/compiler/testData/diagnostics/tests/samConversions/samConversionToGenericWrongNullability.fir.diag.txt
index 9cf721c..b26daae 100644
--- a/compiler/testData/diagnostics/tests/samConversions/samConversionToGenericWrongNullability.fir.diag.txt
+++ b/compiler/testData/diagnostics/tests/samConversions/samConversionToGenericWrongNullability.fir.diag.txt
@@ -1,5 +1,19 @@
+/test.kt:(194,216): warning: Argument type mismatch: actual type is 'kotlin.String?', but 'kotlin.String' was expected. This will become an error in a future release.
+
+/test.kt:(260,282): warning: Argument type mismatch: actual type is 'kotlin.String?', but 'kotlin.String' was expected. This will become an error in a future release.
+
+/test.kt:(321,358): warning: Argument type mismatch: actual type is 'kotlin.String?', but 'kotlin.String' was expected. This will become an error in a future release.
+
/test.kt:(416,453): warning: Argument type mismatch: actual type is 'kotlin.String?', but 'kotlin.String' was expected. This will become an error in a future release.
+/test.kt:(510,592): warning: Argument type mismatch: actual type is 'kotlin.String?', but 'kotlin.String' was expected. This will become an error in a future release.
+
+/test.kt:(657,679): warning: Argument type mismatch: actual type is 'kotlin.String?', but 'kotlin.String' was expected. This will become an error in a future release.
+
+/test.kt:(710,732): warning: Argument type mismatch: actual type is 'kotlin.String?', but 'kotlin.String' was expected. This will become an error in a future release.
+
+/test.kt:(787,809): warning: Argument type mismatch: actual type is 'kotlin.String?', but 'kotlin.String' was expected. This will become an error in a future release.
+
/test.kt:(1194,1216): warning: Argument type mismatch: actual type is 'kotlin.String?', but 'kotlin.String' was expected. This will become an error in a future release.
/test.kt:(1299,1321): error: Return type mismatch: expected 'kotlin.String', actual 'kotlin.String?'.
@@ -12,10 +26,14 @@
/test.kt:(1458,1480): error: Return type mismatch: expected 'kotlin.String', actual 'kotlin.String?'.
+/test.kt:(1596,1618): warning: Argument type mismatch: actual type is 'kotlin.String?', but 'kotlin.String' was expected. This will become an error in a future release.
+
/test.kt:(1710,1810): error: Argument type mismatch: actual type is 'kotlin.String!', but 'kotlin.Function0<ERROR CLASS: Unknown return lambda parameter type>' was expected.
/test.kt:(1710,1810): error: Argument type mismatch: actual type is 'kotlin.String!', but 'kotlin.Function0<kotlin.String?>' was expected.
+/test.kt:(1875,1897): warning: Argument type mismatch: actual type is 'kotlin.String?', but 'kotlin.String' was expected. This will become an error in a future release.
+
/test.kt:(1976,1983): error: Return type of 'get' is not a subtype of the return type of the overridden member 'fun get(): String'.
/test.kt:(2069,2072): error: Return type of 'get' is not a subtype of the return type of the overridden member 'fun get(): String'.
@@ -34,3 +52,9 @@
/edge-cases.kt:(491,513): error: Argument type mismatch: actual type is 'kotlin.String?', but 'kotlin.Unit' was expected.
/edge-cases.kt:(570,634): error: Argument type mismatch: actual type is 'kotlin.Unit', but 'kotlin.String!' was expected.
+
+/edge-cases.kt:(700,707): warning: Argument type mismatch: actual type is 'T?', but 'T' was expected. This will become an error in a future release.
+
+/edge-cases.kt:(797,804): warning: Argument type mismatch: actual type is 'T?', but 'T' was expected. This will become an error in a future release.
+
+/edge-cases.kt:(920,949): warning: Argument type mismatch: actual type is 'kotlin.String?', but 'kotlin.String' was expected. This will become an error in a future release.
diff --git a/compiler/testData/diagnostics/tests/samConversions/samConversionToGenericWrongNullability.fir.kt b/compiler/testData/diagnostics/tests/samConversions/samConversionToGenericWrongNullability.fir.kt
index bb3f54b..e949267 100644
--- a/compiler/testData/diagnostics/tests/samConversions/samConversionToGenericWrongNullability.fir.kt
+++ b/compiler/testData/diagnostics/tests/samConversions/samConversionToGenericWrongNullability.fir.kt
@@ -33,15 +33,15 @@
fun main() {
Supplier<String> {
- returnNullableString()
+ <!TYPE_MISMATCH_WHEN_FLEXIBILITY_CHANGES!>returnNullableString()<!>
}
Supplier<StringAlias> {
- returnNullableString()
+ <!TYPE_MISMATCH_WHEN_FLEXIBILITY_CHANGES!>returnNullableString()<!>
}
Supplier<String> {
- TestValueProvider.getNullableString()
+ <!TYPE_MISMATCH_WHEN_FLEXIBILITY_CHANGES!>TestValueProvider.getNullableString()<!>
}
val sam: Supplier<String> = Supplier{
@@ -50,17 +50,17 @@
Supplier<String> {
val x = 1
- when(x) {
+ <!TYPE_MISMATCH_WHEN_FLEXIBILITY_CHANGES!>when(x) {
1 -> returnNullableString()
else -> ""
- }
+ }<!>
}
Supplier<String> {
- if (true) return@Supplier returnNullableString()
- run { return@Supplier returnNullableString() }
+ if (true) return@Supplier <!TYPE_MISMATCH_WHEN_FLEXIBILITY_CHANGES!>returnNullableString()<!>
+ run { return@Supplier <!TYPE_MISMATCH_WHEN_FLEXIBILITY_CHANGES!>returnNullableString()<!> }
try {
- if (true) return@Supplier returnNullableString()
+ if (true) return@Supplier <!TYPE_MISMATCH_WHEN_FLEXIBILITY_CHANGES!>returnNullableString()<!>
2
} finally {
Unit
@@ -104,7 +104,7 @@
Supplier<String>(
fun(): String? {
- if (true) return returnNullableString()
+ if (true) return <!TYPE_MISMATCH_WHEN_FLEXIBILITY_CHANGES!>returnNullableString()<!>
return ""
}
)
@@ -117,7 +117,7 @@
}
Supplier<String> {
- if (true) return@Supplier returnNullableString()
+ if (true) return@Supplier <!TYPE_MISMATCH_WHEN_FLEXIBILITY_CHANGES!>returnNullableString()<!>
""
}
@@ -191,13 +191,13 @@
fun <T: Number> test1(x: T) {
Supplier<T> {
- x.foo()
+ <!TYPE_MISMATCH_WHEN_FLEXIBILITY_CHANGES!>x.foo()<!>
}
}
fun <T> test2(x: T) where T: Any?, T: Comparable<T> {
Supplier<T> {
- x.foo()
+ <!TYPE_MISMATCH_WHEN_FLEXIBILITY_CHANGES!>x.foo()<!>
}
}
@@ -207,6 +207,6 @@
fun test() {
Supplier<String> {
- returnNullableString().foo2()
+ <!TYPE_MISMATCH_WHEN_FLEXIBILITY_CHANGES!>returnNullableString().foo2()<!>
}
}
diff --git a/compiler/testData/diagnostics/tests/samConversions/samConversionWithJavaFlexibleType.fir.kt b/compiler/testData/diagnostics/tests/samConversions/samConversionWithJavaFlexibleType.fir.kt
index 1a2f537..45e7381 100644
--- a/compiler/testData/diagnostics/tests/samConversions/samConversionWithJavaFlexibleType.fir.kt
+++ b/compiler/testData/diagnostics/tests/samConversions/samConversionWithJavaFlexibleType.fir.kt
@@ -14,7 +14,7 @@
fun test(){
Supplier<String> {
- JavaBox(null).a
+ <!TYPE_MISMATCH_WHEN_FLEXIBILITY_CHANGES!>JavaBox(null).a<!>
}
val sam : Supplier<String> = Supplier {