From 954c9cecca636cf9741e492b2a91c6599ce912ba Mon Sep 17 00:00:00 2001 From: Victor Petukhov Date: Wed, 23 Dec 2020 14:36:34 +0300 Subject: [PATCH] Compute type for callable references and lambdas inside not null assertion if couldn't get already recorded type --- .../BasicExpressionTypingVisitor.java | 5 +- ...ialCallsWithCallableReferencesErrorType.kt | 113 ++++++++++++++++++ ...allsWithCallableReferencesErrorType.fir.kt | 86 +++++++++++++ ...ialCallsWithCallableReferencesErrorType.kt | 86 +++++++++++++ .../ir/irText/expressions/kt36963.txt | 4 +- .../codegen/BlackBoxCodegenTestGenerated.java | 5 + 6 files changed, 293 insertions(+), 6 deletions(-) create mode 100644 compiler/testData/codegen/box/inference/builderInference/specialCallsWithCallableReferencesErrorType.kt create mode 100644 compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithCallableReferencesErrorType.fir.kt create mode 100644 compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithCallableReferencesErrorType.kt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java index 99fd1c63a4b..e230aca5d63 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java @@ -823,10 +823,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { DiagnosticFactory0 diagnosticFactory = isFunctionLiteral ? NOT_NULL_ASSERTION_ON_LAMBDA_EXPRESSION : NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE; context.trace.report(diagnosticFactory.on(operationSign)); - if (baseTypeInfo == null) { - return TypeInfoFactoryKt.createTypeInfo(ErrorUtils.createErrorType("Unresolved lambda expression"), context); - } - return baseTypeInfo; + return baseTypeInfo != null ? baseTypeInfo : components.expressionTypingServices.getTypeInfo(baseExpression, context); } assert baseTypeInfo != null : "Base expression was not processed: " + expression; KotlinType baseType = baseTypeInfo.getType(); diff --git a/compiler/testData/codegen/box/inference/builderInference/specialCallsWithCallableReferencesErrorType.kt b/compiler/testData/codegen/box/inference/builderInference/specialCallsWithCallableReferencesErrorType.kt new file mode 100644 index 00000000000..343601db436 --- /dev/null +++ b/compiler/testData/codegen/box/inference/builderInference/specialCallsWithCallableReferencesErrorType.kt @@ -0,0 +1,113 @@ +// WITH_RUNTIME + +import kotlin.experimental.ExperimentalTypeInference + +fun FlowCollector.bar(): K = null as K +fun FlowCollector.foo(): K = null as K + +fun bar2(): Int = 1 +fun foo2(): Float = 1f + +fun materialize() = null as T + +interface FlowCollector {} + +@Suppress("EXPERIMENTAL_API_USAGE_ERROR") +fun flow(@BuilderInference block: suspend FlowCollector.() -> Unit) = Flow(block) + +class Flow(private val block: suspend FlowCollector.() -> Unit) + +fun select(vararg x: R) = x[0] + +fun poll01(): Flow { + return flow { + val inv = select(::bar2, ::foo2) + inv() + } +} + +fun poll1(flag: Boolean): Flow { + return flow { + val inv = if (flag) { ::bar2 } else { ::foo2 } + inv() + } +} + +fun poll11(flag: Boolean): Flow { + return flow { + val inv = if (flag) { ::bar2 } else { ::foo2 } + inv() + } +} + + +fun poll21(flag: Boolean): Flow { + return flow { + val inv = when (flag) { true -> ::bar2 else -> ::foo2 } + inv() + } +} + +fun poll31(flag: Boolean): Flow { + return flow { + val inv = when (flag) { true -> ::bar2 false -> ::foo2 } + inv() + } +} + +fun poll41(): Flow { + return flow { + val inv = try { ::bar2 } finally { ::foo2 } + inv() + } +} + +fun poll51(): Flow { + return flow { + val inv = try { ::bar2 } catch (e: Exception) { ::foo2 } finally { ::foo2 } + inv() + } +} + +fun poll61(): Flow { + return flow { + val inv = ::bar2 + inv + } +} + +fun poll71(): Flow { + return flow { + val inv = ::bar2!! + inv() + } +} + +fun poll81(): Flow { + return flow { + val inv = ::bar2 in setOf(::foo2) + inv + } +} + +fun poll91(): Flow { + return flow { + val inv = ::foo2 in setOf(::foo2) + inv + } +} + +fun box(): String { + poll01() + poll1(true) + poll11(true) + poll21(true) + poll31(true) + poll41() + poll51() + poll61() + poll71() + poll81() + poll91() + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithCallableReferencesErrorType.fir.kt b/compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithCallableReferencesErrorType.fir.kt new file mode 100644 index 00000000000..c53792ca78e --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithCallableReferencesErrorType.fir.kt @@ -0,0 +1,86 @@ +// WITH_RUNTIME +// SKIP_TXT +// !DIAGNOSTICS: -CAST_NEVER_SUCCEEDS -UNCHECKED_CAST -UNUSED_PARAMETER -UNUSED_VARIABLE -EXPERIMENTAL_API_USAGE_ERROR -UNUSED_EXPRESSION + +import kotlin.experimental.ExperimentalTypeInference + +fun FlowCollector.bar(): K = null as K +fun FlowCollector.foo(): K = null as K + +fun K.bar3(): K = null as K +fun K.foo3(): K = null as K + +fun bar2(): Int = 1 +fun foo2(): Float = 1f + +val bar4: Int + get() = 1 + +var foo4: Float + get() = 1f + set(value) {} + +val FlowCollector.bar5: K get() = null as K +val FlowCollector.foo5: K get() = null as K + +class Foo6 + +class Foo7 +fun foo7() = null as Foo7 + +interface FlowCollector {} + +fun flow(@BuilderInference block: suspend FlowCollector.() -> Unit) = Flow(block) + +class Flow(private val block: suspend FlowCollector.() -> Unit) + + +fun poll7(): Flow { + return flow { + val inv = ::bar!! + inv() + } +} + +fun poll71(): Flow { + return flow { + val inv = ::bar2!! + inv() + } +} + +fun poll72(): Flow { + return flow { + val inv = ::bar3!! + inv() + } +} + +fun poll73(): Flow { + return flow { + val inv = ::bar4!! + inv + } +} + +fun poll74(): Flow { + return flow { + val inv = ::bar5!! + inv + } +} + +fun poll75(): Flow { + return flow { + val inv = ::Foo6!! + inv + } +} + +fun poll76(): Flow { + return flow { + val inv = ::Foo7!! + inv + } +} + diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithCallableReferencesErrorType.kt b/compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithCallableReferencesErrorType.kt new file mode 100644 index 00000000000..e8e69041c03 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithCallableReferencesErrorType.kt @@ -0,0 +1,86 @@ +// WITH_RUNTIME +// SKIP_TXT +// !DIAGNOSTICS: -CAST_NEVER_SUCCEEDS -UNCHECKED_CAST -UNUSED_PARAMETER -UNUSED_VARIABLE -EXPERIMENTAL_API_USAGE_ERROR -UNUSED_EXPRESSION + +import kotlin.experimental.ExperimentalTypeInference + +fun FlowCollector.bar(): K = null as K +fun FlowCollector.foo(): K = null as K + +fun K.bar3(): K = null as K +fun K.foo3(): K = null as K + +fun bar2(): Int = 1 +fun foo2(): Float = 1f + +val bar4: Int + get() = 1 + +var foo4: Float + get() = 1f + set(value) {} + +val FlowCollector.bar5: K get() = null as K +val FlowCollector.foo5: K get() = null as K + +class Foo6 + +class Foo7 +fun foo7() = null as Foo7 + +interface FlowCollector {} + +fun flow(@BuilderInference block: suspend FlowCollector.() -> Unit) = Flow(block) + +class Flow(private val block: suspend FlowCollector.() -> Unit) + + +fun poll7(): Flow { + return flow { + val inv = ::bar!! + inv() + } +} + +fun poll71(): Flow { + return flow { + val inv = ::bar2!! + inv() + } +} + +fun poll72(): Flow { + return flow { + val inv = ::bar3!! + inv() + } +} + +fun poll73(): Flow { + return flow { + val inv = ::bar4!! + inv + } +} + +fun poll74(): Flow { + return flow { + val inv = ::bar5!! + inv + } +} + +fun poll75(): Flow { + return flow { + val inv = ::Foo6!! + inv + } +} + +fun poll76(): Flow { + return flow { + val inv = ::Foo7!! + inv + } +} + diff --git a/compiler/testData/ir/irText/expressions/kt36963.txt b/compiler/testData/ir/irText/expressions/kt36963.txt index 2930185f6f7..334ffd0f603 100644 --- a/compiler/testData/ir/irText/expressions/kt36963.txt +++ b/compiler/testData/ir/irText/expressions/kt36963.txt @@ -1,9 +1,9 @@ FILE fqName: fileName:/kt36963.kt FUN name:foo visibility:public modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY - FUN name:test visibility:public modality:FINAL <> () returnType:IrErrorType + FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.reflect.KFunction0 BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun test (): IrErrorType declared in ' + RETURN type=kotlin.Nothing from='public final fun test (): kotlin.reflect.KFunction0 declared in ' CALL 'public final fun CHECK_NOT_NULL (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.reflect.KFunction0 origin=EXCLEXCL : kotlin.reflect.KFunction0 arg0: FUNCTION_REFERENCE 'public final fun foo (): kotlin.Unit declared in ' type=kotlin.reflect.KFunction0 origin=null reflectionTarget= diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 5a3536d7bea..2b85cc4dc4b 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -13501,6 +13501,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/inference/builderInference/lackOfNullCheckOnNullableInsideBuild.kt"); } + @TestMetadata("specialCallsWithCallableReferencesErrorType.kt") + public void testSpecialCallsWithCallableReferencesErrorType() throws Exception { + runTest("compiler/testData/codegen/box/inference/builderInference/specialCallsWithCallableReferencesErrorType.kt"); + } + @TestMetadata("substituteStubTypeIntoCR.kt") public void testSubstituteStubTypeIntoCR() throws Exception { runTest("compiler/testData/codegen/box/inference/builderInference/substituteStubTypeIntoCR.kt");