diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index f692d2f8bb3..b8b28132200 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -14066,6 +14066,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/inference/dontThrowEmptyIntersectionException.kt"); } + @Test + @TestMetadata("elvisInsideWhen.kt") + public void testElvisInsideWhen() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/elvisInsideWhen.kt"); + } + @Test @TestMetadata("equalitySubstitutionInsideNonInvariantType.kt") public void testEqualitySubstitutionInsideNonInvariantType() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index 4991abc2a9d..a3238759a57 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -14072,6 +14072,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/inference/dontThrowEmptyIntersectionException.kt"); } + @Test + @TestMetadata("elvisInsideWhen.kt") + public void testElvisInsideWhen() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/elvisInsideWhen.kt"); + } + @Test @TestMetadata("equalitySubstitutionInsideNonInvariantType.kt") public void testEqualitySubstitutionInsideNonInvariantType() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index 40946fb6912..d47ba025319 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -14066,6 +14066,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/inference/dontThrowEmptyIntersectionException.kt"); } + @Test + @TestMetadata("elvisInsideWhen.kt") + public void testElvisInsideWhen() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/elvisInsideWhen.kt"); + } + @Test @TestMetadata("equalitySubstitutionInsideNonInvariantType.kt") public void testEqualitySubstitutionInsideNonInvariantType() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt index 655ea3eeb00..7cce967be32 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt @@ -243,6 +243,13 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyRes if (elvisExpression.calleeReference is FirResolvedNamedReference) return elvisExpression elvisExpression.transformAnnotations(transformer, data) + // Do not use expect type when it's came from if/when (when it doesn't require completion) + // It returns us to K1 behavior in the case of when-elvis combination (see testData/diagnostics/tests/inference/elvisInsideWhen.kt) + // But this is mostly a hack that I hope might be lifted once KT-55692 is considered + // NB: Currently situation `it is ResolutionMode.WithExpectedType && !it.forceFullCompletion` might only happen in case of when branches + @Suppress("NAME_SHADOWING") + val data = data.takeUnless { it is ResolutionMode.WithExpectedType && !it.forceFullCompletion } ?: ResolutionMode.ContextDependent + val expectedType = data.expectedType?.coneTypeSafe() val mayBeCoercionToUnitApplied = (data as? ResolutionMode.WithExpectedType)?.mayBeCoercionToUnitApplied == true diff --git a/compiler/testData/diagnostics/tests/inference/elvisInsideWhen.kt b/compiler/testData/diagnostics/tests/inference/elvisInsideWhen.kt new file mode 100644 index 00000000000..6d911426d39 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/elvisInsideWhen.kt @@ -0,0 +1,19 @@ +// FIR_IDENTICAL +// SKIP_TXT + +fun select(vararg x: X): X = x[0] +fun myOut(): Out = TODO() + +interface Out + +fun foo(x: Int, o: Out, oNullable: Out?) { + val y: Out<*> = when { + x > 0 -> when { + x == 1 -> o + // Once elvis is being analyzed with expected type Out<*>, because of the @Exact annotation it sticks to that type + // While here, it's better to use the Out type from the main branch + else -> oNullable ?: myOut() + } + else -> myOut() + } +} 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 0487a3f7c91..a02a365c895 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 @@ -14072,6 +14072,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/inference/dontThrowEmptyIntersectionException.kt"); } + @Test + @TestMetadata("elvisInsideWhen.kt") + public void testElvisInsideWhen() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/elvisInsideWhen.kt"); + } + @Test @TestMetadata("equalitySubstitutionInsideNonInvariantType.kt") public void testEqualitySubstitutionInsideNonInvariantType() throws Exception {