diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java index c75a6f83a5a..8341e33537f 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java @@ -1939,6 +1939,16 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte runTest("compiler/testData/diagnostics/tests/callableReference/referenceAdaptationCompatibility.kt"); } + @TestMetadata("referenceToCompanionObjectMemberViaClassName.kt") + public void testReferenceToCompanionObjectMemberViaClassName() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/referenceToCompanionObjectMemberViaClassName.kt"); + } + + @TestMetadata("referenceToCompanionObjectMemberViaClassNameCompatibility.kt") + public void testReferenceToCompanionObjectMemberViaClassNameCompatibility() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/referenceToCompanionObjectMemberViaClassNameCompatibility.kt"); + } + @TestMetadata("rewriteAtSliceOnGetOperator.kt") public void testRewriteAtSliceOnGetOperator() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/rewriteAtSliceOnGetOperator.kt"); diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index beea1908c79..e663c8fd708 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -2685,6 +2685,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/callableReference/function/privateClassMember.kt"); } + @TestMetadata("referenceToCompanionMember.kt") + public void testReferenceToCompanionMember() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/referenceToCompanionMember.kt"); + } + @TestMetadata("sortListOfStrings.kt") public void testSortListOfStrings() throws Exception { runTest("compiler/testData/codegen/box/callableReference/function/sortListOfStrings.kt"); diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolution.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolution.kt index 8a37f6012e0..912db11b04b 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolution.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolution.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.DISPATCH_RE import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.EXTENSION_RECEIVER import org.jetbrains.kotlin.resolve.calls.tower.* import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns +import org.jetbrains.kotlin.resolve.descriptorUtil.isCompanionObject import org.jetbrains.kotlin.resolve.scopes.receivers.DetailedReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo @@ -213,7 +214,7 @@ class CallableReferencesCandidateFactory( callComponents.builtIns ) - if (needCompatibilityWarning(callableReferenceAdaptation)) { + if (needCompatibilityWarning(callableReferenceAdaptation, candidateDescriptor)) { diagnostics.add(LowerPriorityToPreserveCompatibility) } @@ -261,7 +262,13 @@ class CallableReferencesCandidateFactory( ) } - private fun needCompatibilityWarning(callableReferenceAdaptation: CallableReferenceAdaptation?): Boolean { + private fun needCompatibilityWarning( + callableReferenceAdaptation: CallableReferenceAdaptation?, + candidate: CallableDescriptor + ): Boolean { + // KT-13934: reference to companion object member via class name + if (candidate.containingDeclaration.isCompanionObject() && argument.lhsResult is LHSResult.Type) return true + if (callableReferenceAdaptation == null) return false return callableReferenceAdaptation.defaults != 0 || diff --git a/compiler/testData/codegen/box/callableReference/function/referenceToCompanionMember.kt b/compiler/testData/codegen/box/callableReference/function/referenceToCompanionMember.kt new file mode 100644 index 00000000000..1dc47d1a240 --- /dev/null +++ b/compiler/testData/codegen/box/callableReference/function/referenceToCompanionMember.kt @@ -0,0 +1,32 @@ +// WITH_RUNTIME +// IGNORE_BACKEND_FIR: JVM_IR +// IGNORE_BACKEND: JS + +class A { + companion object { + fun foo(): String = "OK" + } +} + +class B { + companion object { + fun foo(): String = "Fail" + } +} + +fun B.foo(): String = "OK" + +fun call(f: Any): String = if (f is Function0<*>) f.invoke() as String else (f as Function1).invoke(B()) + +fun box(): String { + val call1 = call(A::foo) + if (call1 != "OK") return "fail 1: $call1" + + // Checking compatibility mode: should be resolved to extensions in 1.4 + val call2 = call(B::foo) + if (call2 != "OK") return "fail 2: $call2" + + return "OK" +} + + diff --git a/compiler/testData/diagnostics/tests/callableReference/referenceToCompanionObjectMemberViaClassName.kt b/compiler/testData/diagnostics/tests/callableReference/referenceToCompanionObjectMemberViaClassName.kt new file mode 100644 index 00000000000..1bcd9630ecb --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/referenceToCompanionObjectMemberViaClassName.kt @@ -0,0 +1,37 @@ +// FIR_IDENTICAL +// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER + +class A { + companion object { + fun foo(): Int = 0 + } +} + +class B { + fun foo(): String = "" + + companion object { + fun foo(): Int = 0 + } +} + +fun call(f: () -> T): T = f() + +fun testA(a: A) { + val call1 = call(A::foo) + call1 + + val call2 = call(A.Companion::foo) + call2 +} + +fun testB(b: B) { + val call1 = call(B::foo) + call1 + + val call2 = call(B()::foo) + call2 + + val call3 = call(B.Companion::foo) + call3 +} diff --git a/compiler/testData/diagnostics/tests/callableReference/referenceToCompanionObjectMemberViaClassName.txt b/compiler/testData/diagnostics/tests/callableReference/referenceToCompanionObjectMemberViaClassName.txt new file mode 100644 index 00000000000..6b647e34cbb --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/referenceToCompanionObjectMemberViaClassName.txt @@ -0,0 +1,36 @@ +package + +public fun call(/*0*/ f: () -> T): T +public fun testA(/*0*/ a: A): kotlin.Unit +public fun testB(/*0*/ b: B): kotlin.Unit + +public final class A { + public constructor A() + 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 + + public companion object Companion { + private constructor Companion() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun foo(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +public final class B { + public constructor B() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun foo(): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public companion object Companion { + private constructor Companion() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun foo(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} diff --git a/compiler/testData/diagnostics/tests/callableReference/referenceToCompanionObjectMemberViaClassNameCompatibility.fir.kt b/compiler/testData/diagnostics/tests/callableReference/referenceToCompanionObjectMemberViaClassNameCompatibility.fir.kt new file mode 100644 index 00000000000..2fe0def1097 --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/referenceToCompanionObjectMemberViaClassNameCompatibility.fir.kt @@ -0,0 +1,33 @@ +// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER + +class A { + companion object { + fun foo(): Int = 0 + } +} + +fun A.foo(): Double = 0.0 +fun Any.foo(): Float = 1f + +class B { + fun foo(): String = "" + + companion object { + fun foo(): Int = 0 + } +} + +fun B.foo(): Double = 0.0 + +fun call(a: Any) {} + +fun testA(a: A) { + call(A::foo) + call(A.Companion::foo) +} + +fun testB(b: B) { + call(B::foo) + call(B()::foo) + call(B.Companion::foo) +} diff --git a/compiler/testData/diagnostics/tests/callableReference/referenceToCompanionObjectMemberViaClassNameCompatibility.kt b/compiler/testData/diagnostics/tests/callableReference/referenceToCompanionObjectMemberViaClassNameCompatibility.kt new file mode 100644 index 00000000000..43b7d3ad37b --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/referenceToCompanionObjectMemberViaClassNameCompatibility.kt @@ -0,0 +1,33 @@ +// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER + +class A { + companion object { + fun foo(): Int = 0 + } +} + +fun A.foo(): Double = 0.0 +fun Any.foo(): Float = 1f + +class B { + fun foo(): String = "" + + companion object { + fun foo(): Int = 0 + } +} + +fun B.foo(): Double = 0.0 + +fun call(a: Any) {} + +fun testA(a: A) { + call(A::foo) + call(A.Companion::foo) +} + +fun testB(b: B) { + call(B::foo) + call(B()::foo) + call(B.Companion::foo) +} diff --git a/compiler/testData/diagnostics/tests/callableReference/referenceToCompanionObjectMemberViaClassNameCompatibility.txt b/compiler/testData/diagnostics/tests/callableReference/referenceToCompanionObjectMemberViaClassNameCompatibility.txt new file mode 100644 index 00000000000..2ed290b0865 --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/referenceToCompanionObjectMemberViaClassNameCompatibility.txt @@ -0,0 +1,39 @@ +package + +public fun call(/*0*/ a: kotlin.Any): kotlin.Unit +public fun testA(/*0*/ a: A): kotlin.Unit +public fun testB(/*0*/ b: B): kotlin.Unit +public fun A.foo(): kotlin.Double +public fun B.foo(): kotlin.Double +public fun kotlin.Any.foo(): kotlin.Float + +public final class A { + public constructor A() + 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 + + public companion object Companion { + private constructor Companion() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun foo(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +public final class B { + public constructor B() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun foo(): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public companion object Companion { + private constructor Companion() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun foo(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index ce03af3b83a..2a962e81287 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -1946,6 +1946,16 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali runTest("compiler/testData/diagnostics/tests/callableReference/referenceAdaptationCompatibility.kt"); } + @TestMetadata("referenceToCompanionObjectMemberViaClassName.kt") + public void testReferenceToCompanionObjectMemberViaClassName() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/referenceToCompanionObjectMemberViaClassName.kt"); + } + + @TestMetadata("referenceToCompanionObjectMemberViaClassNameCompatibility.kt") + public void testReferenceToCompanionObjectMemberViaClassNameCompatibility() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/referenceToCompanionObjectMemberViaClassNameCompatibility.kt"); + } + @TestMetadata("rewriteAtSliceOnGetOperator.kt") public void testRewriteAtSliceOnGetOperator() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/rewriteAtSliceOnGetOperator.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 6520f9b6703..18fcd8b9a05 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -1941,6 +1941,16 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/callableReference/referenceAdaptationCompatibility.kt"); } + @TestMetadata("referenceToCompanionObjectMemberViaClassName.kt") + public void testReferenceToCompanionObjectMemberViaClassName() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/referenceToCompanionObjectMemberViaClassName.kt"); + } + + @TestMetadata("referenceToCompanionObjectMemberViaClassNameCompatibility.kt") + public void testReferenceToCompanionObjectMemberViaClassNameCompatibility() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/referenceToCompanionObjectMemberViaClassNameCompatibility.kt"); + } + @TestMetadata("rewriteAtSliceOnGetOperator.kt") public void testRewriteAtSliceOnGetOperator() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/rewriteAtSliceOnGetOperator.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index de77f6ea948..7a2ea08c683 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -2705,6 +2705,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/callableReference/function/privateClassMember.kt"); } + @TestMetadata("referenceToCompanionMember.kt") + public void testReferenceToCompanionMember() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/referenceToCompanionMember.kt"); + } + @TestMetadata("sortListOfStrings.kt") public void testSortListOfStrings() throws Exception { runTest("compiler/testData/codegen/box/callableReference/function/sortListOfStrings.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index ec693983dbb..7824a455c3d 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -2705,6 +2705,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/callableReference/function/privateClassMember.kt"); } + @TestMetadata("referenceToCompanionMember.kt") + public void testReferenceToCompanionMember() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/referenceToCompanionMember.kt"); + } + @TestMetadata("sortListOfStrings.kt") public void testSortListOfStrings() throws Exception { runTest("compiler/testData/codegen/box/callableReference/function/sortListOfStrings.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 09cd53344d3..10b0c75b0a0 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -2685,6 +2685,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/callableReference/function/privateClassMember.kt"); } + @TestMetadata("referenceToCompanionMember.kt") + public void testReferenceToCompanionMember() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/referenceToCompanionMember.kt"); + } + @TestMetadata("sortListOfStrings.kt") public void testSortListOfStrings() throws Exception { runTest("compiler/testData/codegen/box/callableReference/function/sortListOfStrings.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index 969f2e1db44..a30d7938694 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -2065,6 +2065,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/callableReference/function/privateClassMember.kt"); } + @TestMetadata("referenceToCompanionMember.kt") + public void testReferenceToCompanionMember() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/referenceToCompanionMember.kt"); + } + @TestMetadata("sortListOfStrings.kt") public void testSortListOfStrings() throws Exception { runTest("compiler/testData/codegen/box/callableReference/function/sortListOfStrings.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 377e1001d25..ef673b24fbf 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -2075,6 +2075,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/callableReference/function/privateClassMember.kt"); } + @TestMetadata("referenceToCompanionMember.kt") + public void testReferenceToCompanionMember() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/referenceToCompanionMember.kt"); + } + @TestMetadata("sortListOfStrings.kt") public void testSortListOfStrings() throws Exception { runTest("compiler/testData/codegen/box/callableReference/function/sortListOfStrings.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index fcc63b7e209..b1b9b585310 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -2075,6 +2075,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/callableReference/function/privateClassMember.kt"); } + @TestMetadata("referenceToCompanionMember.kt") + public void testReferenceToCompanionMember() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/referenceToCompanionMember.kt"); + } + @TestMetadata("sortListOfStrings.kt") public void testSortListOfStrings() throws Exception { runTest("compiler/testData/codegen/box/callableReference/function/sortListOfStrings.kt");