diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DoubleColonExpressionResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DoubleColonExpressionResolver.kt index fcddce9cbdc..7c5ee2b0643 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DoubleColonExpressionResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DoubleColonExpressionResolver.kt @@ -57,7 +57,6 @@ import org.jetbrains.kotlin.types.typeUtil.builtIns import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf import org.jetbrains.kotlin.types.typeUtil.makeNotNullable import org.jetbrains.kotlin.types.typeUtil.makeNullable -import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.yieldIfNotNull import java.lang.UnsupportedOperationException import java.util.* @@ -605,27 +604,30 @@ class DoubleColonExpressionResolver( if (expression.isEmptyLHS) null else resolveDoubleColonLHS(expression, context) - if (lhsResult is DoubleColonLHS.Expression) { - reportUnsupportedIfNeeded(expression, context) - } + val resolutionResults = resolveCallableReferenceRHS(expression, lhsResult, context, resolveArgumentsMode) - val resolutionResults = - resolveCallableReferenceRHS(expression, lhsResult, context, resolveArgumentsMode) - - reportUnsupportedReferenceToSuspendFunction(resolutionResults, expression, context) + reportUnsupportedCallableReferenceIfNeeded(expression, context, lhsResult, resolutionResults) return lhsResult to resolutionResults } - private fun reportUnsupportedReferenceToSuspendFunction( - resolutionResults: OverloadResolutionResults?, + private fun reportUnsupportedCallableReferenceIfNeeded( expression: KtCallableReferenceExpression, - context: ExpressionTypingContext + context: ExpressionTypingContext, + lhsResult: DoubleColonLHS?, + resolutionResults: OverloadResolutionResults? ) { - if (resolutionResults?.isSingleResult == true && - resolutionResults.resultingDescriptor.safeAs()?.isSuspend == true) { + val descriptor = + if (resolutionResults?.isSingleResult == true) resolutionResults.resultingDescriptor as? FunctionDescriptor else null + if (descriptor?.isSuspend == true) { context.trace.report(UNSUPPORTED.on(expression.callableReference, "Callable references to suspend functions")) } + + val expressionResult = lhsResult as? DoubleColonLHS.Expression ?: return + // "::foo" was not supported without bound callable references, except the case of a nested class constructor in an object + if (!expressionResult.isObjectQualifier || descriptor !is ConstructorDescriptor) { + reportUnsupportedIfNeeded(expression, context) + } } private class ResolutionResultsAndTraceCommitCallback( diff --git a/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundCallableReference.kt b/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundCallableReference.kt index 901d8906ab3..84def19b7e8 100644 --- a/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundCallableReference.kt +++ b/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundCallableReference.kt @@ -4,8 +4,14 @@ class C { companion object } val ok1 = C::hashCode val fail1 = C.Companion::hashCode -object O +object O { + class Y { + companion object + } +} val fail2 = O::hashCode +val ok2 = O::Y +val ok3 = O.Y::hashCode fun hashCode() {} diff --git a/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundCallableReference.txt b/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundCallableReference.txt index ffd1644c631..f3b4ba5cd7c 100644 --- a/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundCallableReference.txt +++ b/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundCallableReference.txt @@ -6,6 +6,8 @@ public val fail3: kotlin.reflect.KFunction0 public val fail4: kotlin.reflect.KFunction0 public val fail5: kotlin.reflect.KFunction0 public val ok1: kotlin.reflect.KFunction1 +public val ok2: kotlin.reflect.KFunction0 +public val ok3: kotlin.reflect.KFunction1 public fun hashCode(): kotlin.Unit public final class C { @@ -27,4 +29,18 @@ public object O { 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 final class Y { + public constructor Y() + 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 open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + } }