From c0b6a593e0abb382ae4a4ba41ded235da019e88b Mon Sep 17 00:00:00 2001 From: "Denis.Zharkov" Date: Thu, 11 Nov 2021 12:55:40 +0300 Subject: [PATCH] FIR: Fix incorrect type of block generated for inc operator Previously, it was obtained from expected type of a variable being assigned, but it's better to use the type of resulting expression Initially this part was brought in 4ab0897d7d7343268179247efc89d6144ede9b69, but as we see in commit message and tests it was all about unit-coercion --- ...gnosisCompilerTestFE10TestdataTestGenerated.java | 6 ++++++ .../testData/resolveWithStdlib/functionX.kt | 4 ++-- .../FirOldFrontendDiagnosticsTestGenerated.java | 6 ++++++ ...ontendDiagnosticsWithLightTreeTestGenerated.java | 6 ++++++ .../resolve/FirExpressionsResolveTransformer.kt | 4 ++-- .../debug/localVariables/suspend/mergeLvt.kt | 2 -- .../namedFunAsLastExpressionInBlock.fir.kt | 4 ++-- .../postponedArgumentsAnalysis/basic.fir.kt | 2 +- .../modifierOnParameterInFunctionType.fir.kt | 2 +- .../incForAssignmentSmartCast.fir.kt | 13 +++++++++++++ .../incForAssignmentSmartCast.kt | 13 +++++++++++++ .../TypeMismatchOnUnaryOperations.fir.kt | 8 ++++---- .../ir/irText/expressions/coercionToUnit.fir.ir.txt | 4 ++-- .../ir/irText/expressions/coercionToUnit.fir.kt.txt | 2 +- .../irText/lambdas/lambdaReturningUnit.fir.ir.txt | 3 +-- .../irText/lambdas/lambdaReturningUnit.fir.kt.txt | 2 +- .../test/runners/DiagnosticTestGenerated.java | 6 ++++++ 17 files changed, 67 insertions(+), 20 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/operatorsOverloading/incForAssignmentSmartCast.fir.kt create mode 100644 compiler/testData/diagnostics/tests/operatorsOverloading/incForAssignmentSmartCast.kt 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 2e0aa3b0131..c17352a68ff 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 @@ -21075,6 +21075,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/operatorsOverloading/compareToNullable.kt"); } + @Test + @TestMetadata("incForAssignmentSmartCast.kt") + public void testIncForAssignmentSmartCast() throws Exception { + runTest("compiler/testData/diagnostics/tests/operatorsOverloading/incForAssignmentSmartCast.kt"); + } + @Test @TestMetadata("InconsistentGetSet.kt") public void testInconsistentGetSet() throws Exception { diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/functionX.kt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/functionX.kt index 34f2806e9cf..b31c74a9183 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/functionX.kt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/functionX.kt @@ -2,10 +2,10 @@ import kotlin.jvm.functions.Function0 -val x: Function0 = { 42 } +val x: Function0 = { 42 } val y: Function1 = { it } class MyFunction : Function2 { override fun invoke(p1: Int, p2: String) {} -} \ No newline at end of file +} 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 b9ccfe18a03..38ccd91b5c1 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 @@ -21075,6 +21075,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/operatorsOverloading/compareToNullable.kt"); } + @Test + @TestMetadata("incForAssignmentSmartCast.kt") + public void testIncForAssignmentSmartCast() throws Exception { + runTest("compiler/testData/diagnostics/tests/operatorsOverloading/incForAssignmentSmartCast.kt"); + } + @Test @TestMetadata("InconsistentGetSet.kt") public void testInconsistentGetSet() 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 d25ee4569a5..9d448b151ad 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 @@ -21075,6 +21075,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/operatorsOverloading/compareToNullable.kt"); } + @Test + @TestMetadata("incForAssignmentSmartCast.kt") + public void testIncForAssignmentSmartCast() throws Exception { + runTest("compiler/testData/diagnostics/tests/operatorsOverloading/incForAssignmentSmartCast.kt"); + } + @Test @TestMetadata("InconsistentGetSet.kt") public void testInconsistentGetSet() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index 2733a5dde33..d16809d1767 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -408,8 +408,8 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform TransformData.Data(value) } block.transformOtherChildren(transformer, data) - if (data is ResolutionMode.WithExpectedType && data.expectedTypeRef is FirResolvedTypeRef) { - // Top-down propagation: from the explicit type of the enclosing declaration to the block type + if (data is ResolutionMode.WithExpectedType && data.expectedTypeRef.coneTypeSafe()?.isUnitOrFlexibleUnit == true) { + // Unit-coercion block.resultType = data.expectedTypeRef } else { // Bottom-up propagation: from the return type of the last expression in the block to the block type diff --git a/compiler/testData/debug/localVariables/suspend/mergeLvt.kt b/compiler/testData/debug/localVariables/suspend/mergeLvt.kt index 07089a4e910..c6bb66273e5 100644 --- a/compiler/testData/debug/localVariables/suspend/mergeLvt.kt +++ b/compiler/testData/debug/localVariables/suspend/mergeLvt.kt @@ -41,9 +41,7 @@ suspend fun box() { // test.kt:16 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int, $this$extensionFun$iv$iv:AtomicInt=AtomicInt, $i$f$extensionFun:int=0:int // test.kt:20 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int // test.kt:21 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$suspendBar$2$iv:int=0:int -// EXPECTATIONS CLASSIC_FRONTEND // test.kt:22 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$suspendBar$2$iv:int=0:int -// EXPECTATIONS // test.kt:20 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int // test.kt:23 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int // test.kt:26 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null diff --git a/compiler/testData/diagnostics/tests/declarationChecks/namedFunAsLastExpressionInBlock.fir.kt b/compiler/testData/diagnostics/tests/declarationChecks/namedFunAsLastExpressionInBlock.fir.kt index f329e25eb25..4afacf0b32c 100644 --- a/compiler/testData/diagnostics/tests/declarationChecks/namedFunAsLastExpressionInBlock.fir.kt +++ b/compiler/testData/diagnostics/tests/declarationChecks/namedFunAsLastExpressionInBlock.fir.kt @@ -6,8 +6,8 @@ fun test() { val x = fun named1(x: Int): Int { return 1 } x checkType { _>() } - foo { fun named2(): Int {return 1} } - foo({ fun named3() = 1 }) + foo { fun named2(): Int {return 1} } + foo({ fun named3() = 1 }) val x1 = if (1 == 1) diff --git a/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/basic.fir.kt b/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/basic.fir.kt index dfa0c2e3511..d2dfa2a385d 100644 --- a/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/basic.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/basic.fir.kt @@ -155,7 +155,7 @@ fun main() { select(id(id(fun(x: String, y: String) { }), fun String.(x: String) {}), { x, y -> x }) val x26: Int.(String) -> Int = fun (x: String) = 10 // it must be error, see KT-38439 // Receiver must be specified in anonymous function declaration - val x27: Int.(String) -> Int = id(fun (x: String) = 10) + val x27: Int.(String) -> Int = id(fun (x: String) = 10) select(id Unit> {}, { x: Int, y: String -> x }) // Inferring lambda parameter types by partially specified parameter types of other lambdas diff --git a/compiler/testData/diagnostics/tests/modifiers/modifierOnParameterInFunctionType.fir.kt b/compiler/testData/diagnostics/tests/modifiers/modifierOnParameterInFunctionType.fir.kt index ebcab0ac6d5..4cdb4dd913e 100644 --- a/compiler/testData/diagnostics/tests/modifiers/modifierOnParameterInFunctionType.fir.kt +++ b/compiler/testData/diagnostics/tests/modifiers/modifierOnParameterInFunctionType.fir.kt @@ -16,7 +16,7 @@ class A : (vararg Int)->Unit { } val prop: (vararg x: Int)->Unit - get(): (vararg x: Int)->Unit = {} + get(): (vararg x: Int)->Unit = {} } val allProhibited: (abstract diff --git a/compiler/testData/diagnostics/tests/operatorsOverloading/incForAssignmentSmartCast.fir.kt b/compiler/testData/diagnostics/tests/operatorsOverloading/incForAssignmentSmartCast.fir.kt new file mode 100644 index 00000000000..ec57060cb8b --- /dev/null +++ b/compiler/testData/diagnostics/tests/operatorsOverloading/incForAssignmentSmartCast.fir.kt @@ -0,0 +1,13 @@ +// SKIP_TXT +var c = 1 + +fun nullable(): Int? = null + +fun foo(): Int { + var x = nullable() + if (x == null) { + x = c++ + } + + return x +} diff --git a/compiler/testData/diagnostics/tests/operatorsOverloading/incForAssignmentSmartCast.kt b/compiler/testData/diagnostics/tests/operatorsOverloading/incForAssignmentSmartCast.kt new file mode 100644 index 00000000000..10a2f5f1164 --- /dev/null +++ b/compiler/testData/diagnostics/tests/operatorsOverloading/incForAssignmentSmartCast.kt @@ -0,0 +1,13 @@ +// SKIP_TXT +var c = 1 + +fun nullable(): Int? = null + +fun foo(): Int { + var x = nullable() + if (x == null) { + x = c++ + } + + return x +} diff --git a/compiler/testData/diagnostics/tests/regressions/TypeMismatchOnUnaryOperations.fir.kt b/compiler/testData/diagnostics/tests/regressions/TypeMismatchOnUnaryOperations.fir.kt index d9cbd608db7..748fda1aeeb 100644 --- a/compiler/testData/diagnostics/tests/regressions/TypeMismatchOnUnaryOperations.fir.kt +++ b/compiler/testData/diagnostics/tests/regressions/TypeMismatchOnUnaryOperations.fir.kt @@ -3,10 +3,10 @@ fun main() { var v = 1 val b : String = v; val f : String = a!!; - val g : String = v++; - val g1 : String = ++v; - val h : String = v--; - val h1 : String = --v; + val g : String = v++; + val g1 : String = ++v; + val h : String = v--; + val h1 : String = --v; val i : String = !true; val j : String = foo@ true; val k : String = foo@ bar@ true; diff --git a/compiler/testData/ir/irText/expressions/coercionToUnit.fir.ir.txt b/compiler/testData/ir/irText/expressions/coercionToUnit.fir.ir.txt index caf330547c4..3ab2be2bdd7 100644 --- a/compiler/testData/ir/irText/expressions/coercionToUnit.fir.ir.txt +++ b/compiler/testData/ir/irText/expressions/coercionToUnit.fir.ir.txt @@ -2,8 +2,8 @@ FILE fqName: fileName:/coercionToUnit.kt PROPERTY name:test1 visibility:public modality:FINAL [val] FIELD PROPERTY_BACKING_FIELD name:test1 type:kotlin.Function0 visibility:private [final,static] EXPRESSION_BODY - FUN_EXPR type=kotlin.Function0 origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:kotlin.Int + FUN_EXPR type=kotlin.Function0 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit CONST Int type=kotlin.Int value=42 diff --git a/compiler/testData/ir/irText/expressions/coercionToUnit.fir.kt.txt b/compiler/testData/ir/irText/expressions/coercionToUnit.fir.kt.txt index 32663ac01e9..314dbdee30e 100644 --- a/compiler/testData/ir/irText/expressions/coercionToUnit.fir.kt.txt +++ b/compiler/testData/ir/irText/expressions/coercionToUnit.fir.kt.txt @@ -1,5 +1,5 @@ val test1: Function0 - field = local fun (): Int { + field = local fun () { 42 /*~> Unit */ } diff --git a/compiler/testData/ir/irText/lambdas/lambdaReturningUnit.fir.ir.txt b/compiler/testData/ir/irText/lambdas/lambdaReturningUnit.fir.ir.txt index de94d045322..a3963177d69 100644 --- a/compiler/testData/ir/irText/lambdas/lambdaReturningUnit.fir.ir.txt +++ b/compiler/testData/ir/irText/lambdas/lambdaReturningUnit.fir.ir.txt @@ -11,5 +11,4 @@ FILE fqName: fileName:/lambdaReturningUnit.kt block: FUN_EXPR type=kotlin.Function0 origin=LAMBDA FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:kotlin.Any? BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (): kotlin.Any? declared in .box' - GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit + GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit diff --git a/compiler/testData/ir/irText/lambdas/lambdaReturningUnit.fir.kt.txt b/compiler/testData/ir/irText/lambdas/lambdaReturningUnit.fir.kt.txt index 7f77b344a30..0d430a654ee 100644 --- a/compiler/testData/ir/irText/lambdas/lambdaReturningUnit.fir.kt.txt +++ b/compiler/testData/ir/irText/lambdas/lambdaReturningUnit.fir.kt.txt @@ -4,7 +4,7 @@ inline fun flaf(block: Function0) { suspend fun box() { flaf(block = local fun (): Any? { - return Unit + Unit } ) } 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 1a1e6d4e406..81168651d0f 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 @@ -21081,6 +21081,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/operatorsOverloading/compareToNullable.kt"); } + @Test + @TestMetadata("incForAssignmentSmartCast.kt") + public void testIncForAssignmentSmartCast() throws Exception { + runTest("compiler/testData/diagnostics/tests/operatorsOverloading/incForAssignmentSmartCast.kt"); + } + @Test @TestMetadata("InconsistentGetSet.kt") public void testInconsistentGetSet() throws Exception {