From ba25b0faafbe7adbb438af3f735d88239c0a3465 Mon Sep 17 00:00:00 2001 From: Pavel Kirpichenkov Date: Thu, 13 Feb 2020 17:18:21 +0300 Subject: [PATCH] [NI] Report unsafe invoke properly for flexible types `isNullable` check returns `true` for flexible types, which leads to false positive unsafe invoke error, when receiver for invoke's property is flexible. ^KT-30695 Fixed --- .../calls/components/ResolutionParts.kt | 2 +- .../tests/resolve/invoke/kt30695_2.fir.kt | 18 ++++++++++++++++++ .../tests/resolve/invoke/kt30695_2.kt | 18 ++++++++++++++++++ .../tests/resolve/invoke/kt30695_2.txt | 11 +++++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt index 95a12b63553..483fb571795 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt @@ -343,7 +343,7 @@ private fun KotlinResolutionCandidate.checkUnsafeImplicitInvokeAfterSafeCall(arg } } ?: error("Receiver kind does not match receiver argument") - if (receiverArgument.receiver.stableType.isNullable()) { + if (receiverArgument.isSafeCall && receiverArgument.receiver.stableType.isNullable()) { addDiagnostic(UnsafeCallError(argument, isForImplicitInvoke = true)) return ImplicitInvokeCheckStatus.UNSAFE_INVOKE_REPORTED } diff --git a/compiler/testData/diagnostics/tests/resolve/invoke/kt30695_2.fir.kt b/compiler/testData/diagnostics/tests/resolve/invoke/kt30695_2.fir.kt index 574de7f7751..3a58f4da652 100644 --- a/compiler/testData/diagnostics/tests/resolve/invoke/kt30695_2.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/invoke/kt30695_2.fir.kt @@ -1,3 +1,13 @@ +// FILE: JavaClass.java + +public class JavaClass { + public static Cls createFlexible() { + return new Cls(); + } +} + +// FILE: test.kt + class MemberInvokeOwner { operator fun invoke() {} } @@ -23,3 +33,11 @@ fun testNotNullableReceiver(notNullable: Cls) { notNullable.nullableExtensionProperty() notNullable?.extensionProperty() } + +fun testFlexibleReceiver() { + val flexible = JavaClass.createFlexible() + flexible.extensionProperty() + flexible?.extensionProperty() + flexible.nullableExtensionProperty() + flexible?.nullableExtensionProperty() +} diff --git a/compiler/testData/diagnostics/tests/resolve/invoke/kt30695_2.kt b/compiler/testData/diagnostics/tests/resolve/invoke/kt30695_2.kt index eb9e9bccb54..5480498728d 100644 --- a/compiler/testData/diagnostics/tests/resolve/invoke/kt30695_2.kt +++ b/compiler/testData/diagnostics/tests/resolve/invoke/kt30695_2.kt @@ -1,3 +1,13 @@ +// FILE: JavaClass.java + +public class JavaClass { + public static Cls createFlexible() { + return new Cls(); + } +} + +// FILE: test.kt + class MemberInvokeOwner { operator fun invoke() {} } @@ -23,3 +33,11 @@ fun testNotNullableReceiver(notNullable: Cls) { notNullable.nullableExtensionProperty() notNullable?.extensionProperty() } + +fun testFlexibleReceiver() { + val flexible = JavaClass.createFlexible() + flexible.extensionProperty() + flexible?.extensionProperty() + flexible.nullableExtensionProperty() + flexible?.nullableExtensionProperty() +} diff --git a/compiler/testData/diagnostics/tests/resolve/invoke/kt30695_2.txt b/compiler/testData/diagnostics/tests/resolve/invoke/kt30695_2.txt index 2827f06c42f..9f0fe8b66ca 100644 --- a/compiler/testData/diagnostics/tests/resolve/invoke/kt30695_2.txt +++ b/compiler/testData/diagnostics/tests/resolve/invoke/kt30695_2.txt @@ -2,6 +2,7 @@ package public val Cls.extensionProperty: MemberInvokeOwner public val Cls.nullableExtensionProperty: MemberInvokeOwner? +public fun testFlexibleReceiver(): kotlin.Unit public fun testNotNullableReceiver(/*0*/ notNullable: Cls): kotlin.Unit public fun testNullableReceiver(/*0*/ nullable: Cls?): kotlin.Unit @@ -13,6 +14,16 @@ public final class Cls { public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } +public open class JavaClass { + public constructor JavaClass() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public open fun createFlexible(): Cls! +} + public final class MemberInvokeOwner { public constructor MemberInvokeOwner() public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean