diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java index 9b03ad906ae..5e4e9b077d4 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java @@ -14366,6 +14366,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia runTest("compiler/testData/diagnostics/tests/inference/errorsOnImplicitInvokeInSimpleCall.kt"); } + @Test + @TestMetadata("exclExclInference.kt") + public void testExclExclInference() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/exclExclInference.kt"); + } + @Test @TestMetadata("expectedTypeAdditionalTest.kt") public void testExpectedTypeAdditionalTest() throws Exception { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java index e58d2bf3f16..f0972556e3a 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java @@ -14366,6 +14366,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated runTest("compiler/testData/diagnostics/tests/inference/errorsOnImplicitInvokeInSimpleCall.kt"); } + @Test + @TestMetadata("exclExclInference.kt") + public void testExclExclInference() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/exclExclInference.kt"); + } + @Test @TestMetadata("expectedTypeAdditionalTest.kt") public void testExpectedTypeAdditionalTest() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java index bbcadcc120f..004e6d48ca0 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java @@ -14366,6 +14366,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir runTest("compiler/testData/diagnostics/tests/inference/errorsOnImplicitInvokeInSimpleCall.kt"); } + @Test + @TestMetadata("exclExclInference.kt") + public void testExclExclInference() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/exclExclInference.kt"); + } + @Test @TestMetadata("expectedTypeAdditionalTest.kt") public void testExpectedTypeAdditionalTest() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java index 2c1c39bc7e5..96a1a7d42b7 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java @@ -14372,6 +14372,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia runTest("compiler/testData/diagnostics/tests/inference/errorsOnImplicitInvokeInSimpleCall.kt"); } + @Test + @TestMetadata("exclExclInference.kt") + public void testExclExclInference() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/exclExclInference.kt"); + } + @Test @TestMetadata("expectedTypeAdditionalTest.kt") public void testExpectedTypeAdditionalTest() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSyntheticCallGenerator.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSyntheticCallGenerator.kt index 71f2fef9d8c..4a3a9184279 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSyntheticCallGenerator.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSyntheticCallGenerator.kt @@ -239,7 +239,10 @@ class FirSyntheticCallGenerator( containingDeclarations = components.containingDeclarations ) - private fun generateSyntheticSelectTypeParameter(functionSymbol: FirSyntheticFunctionSymbol): Pair { + private fun generateSyntheticSelectTypeParameter( + functionSymbol: FirSyntheticFunctionSymbol, + isNullableBound: Boolean = true, + ): Pair { val typeParameterSymbol = FirTypeParameterSymbol() val typeParameter = buildTypeParameter { @@ -251,7 +254,12 @@ class FirSyntheticCallGenerator( containingDeclarationSymbol = functionSymbol variance = Variance.INVARIANT isReified = false - addDefaultBoundIfNecessary() + + if (!isNullableBound) { + bounds += moduleData.session.builtinTypes.anyType + } else { + addDefaultBoundIfNecessary() + } } val typeParameterTypeRef = buildResolvedTypeRef { type = ConeTypeParameterTypeImpl(typeParameterSymbol.toLookupTag(), false) } @@ -280,13 +288,9 @@ class FirSyntheticCallGenerator( private fun generateSyntheticCheckNotNullFunction(): FirSimpleFunction { // Synthetic function signature: - // fun checkNotNull(arg: K?): K - // - // Note: The upper bound of `K` cannot be `Any` because of the following case: - // fun test(a: X) = a!! - // `X` is not a subtype of `Any` and hence cannot satisfy `K` if it had an upper bound of `Any`. + // fun checkNotNull(arg: K?): K val functionSymbol = FirSyntheticFunctionSymbol(SyntheticCallableId.CHECK_NOT_NULL) - val (typeParameter, returnType) = generateSyntheticSelectTypeParameter(functionSymbol) + val (typeParameter, returnType) = generateSyntheticSelectTypeParameter(functionSymbol, isNullableBound = false) val argumentType = buildResolvedTypeRef { type = returnType.type.withNullability(ConeNullability.NULLABLE, session.typeContext) diff --git a/compiler/testData/diagnostics/tests/collectionLiterals/kt34515.fir.kt b/compiler/testData/diagnostics/tests/collectionLiterals/kt34515.fir.kt index d7e31c0b25d..dfaec0bd92a 100644 --- a/compiler/testData/diagnostics/tests/collectionLiterals/kt34515.fir.kt +++ b/compiler/testData/diagnostics/tests/collectionLiterals/kt34515.fir.kt @@ -1,3 +1,3 @@ fun main() { - []!!!! + []!!!! } diff --git a/compiler/testData/diagnostics/tests/inference/exclExclInference.fir.kt b/compiler/testData/diagnostics/tests/inference/exclExclInference.fir.kt new file mode 100644 index 00000000000..e010467c400 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/exclExclInference.fir.kt @@ -0,0 +1,17 @@ +// FIR_DUMP +// ISSUE: KT-55804 + +fun foo() { + val x: String? + x = materialize()!! // Should be treated as non-nullable assignment + x.length // Should be allowed +} + +fun materialize(): E = TODO() + +fun test(f: F) = f!! + +fun main() { + test("").length + test(null).length // `.length` should be allowed because return type of "test" should be inferred to `F & Any` +} diff --git a/compiler/testData/diagnostics/tests/inference/exclExclInference.fir.txt b/compiler/testData/diagnostics/tests/inference/exclExclInference.fir.txt new file mode 100644 index 00000000000..9fd3f3609fb --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/exclExclInference.fir.txt @@ -0,0 +1,16 @@ +FILE: exclExclInference.fir.kt + public final fun foo(): R|kotlin/Unit| { + lval x: R|kotlin/String?| + R|/x| = R|/materialize|()!! + R|/x|.R|kotlin/String.length| + } + public final fun materialize(): R|E| { + ^materialize R|kotlin/TODO|() + } + public final fun test(f: R|F|): R|F & Any| { + ^test R|/f|!! + } + public final fun main(): R|kotlin/Unit| { + R|/test|(String()).R|kotlin/String.length| + R|/test|(Null(null)).R|kotlin/String.length| + } diff --git a/compiler/testData/diagnostics/tests/inference/exclExclInference.kt b/compiler/testData/diagnostics/tests/inference/exclExclInference.kt new file mode 100644 index 00000000000..21bb5ca8a70 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/exclExclInference.kt @@ -0,0 +1,17 @@ +// FIR_DUMP +// ISSUE: KT-55804 + +fun foo() { + val x: String? + x = materialize()!! // Should be treated as non-nullable assignment + x.length // Should be allowed +} + +fun materialize(): E = TODO() + +fun test(f: F) = f!! + +fun main() { + test("").length + test(null).length // `.length` should be allowed because return type of "test" should be inferred to `F & Any` +} diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt36342.fir.kt b/compiler/testData/diagnostics/tests/inference/regressions/kt36342.fir.kt index 873ab9f02d9..27b6afb8c7f 100644 --- a/compiler/testData/diagnostics/tests/inference/regressions/kt36342.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/regressions/kt36342.fir.kt @@ -4,8 +4,8 @@ import java.lang.Exception fun id(arg: K): K = arg fun test() { - id(unresolved)!! - unresolved!!!! + id(unresolved)!! + unresolved!!!! try { id(unresolved) } catch (e: Exception) { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 67954b46905..4d643a4ba2b 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -14372,6 +14372,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/inference/errorsOnImplicitInvokeInSimpleCall.kt"); } + @Test + @TestMetadata("exclExclInference.kt") + public void testExclExclInference() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/exclExclInference.kt"); + } + @Test @TestMetadata("expectedTypeAdditionalTest.kt") public void testExpectedTypeAdditionalTest() throws Exception {