diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolutionOldInference.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolutionOldInference.kt index a85ee089618..2d976d95678 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolutionOldInference.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolutionOldInference.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.resolve.calls.tower +import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor @@ -155,7 +156,14 @@ class NewResolutionOldInference( val dynamicScope = dynamicCallableDescriptors.createDynamicDescriptorScope(context.call, context.scope.ownerDescriptor) val scopeTower = ImplicitScopeTowerImpl(context, dynamicScope, syntheticScopes, syntheticConstructorsProvider, context.call.createLookupLocation()) - val processor = kind.createTowerProcessor(this, name, tracing, scopeTower, detailedReceiver, context) + val shouldUseOperatorRem = languageVersionSettings.supportsFeature(LanguageFeature.OperatorRem) + val isBinaryRemOperator = isBinaryRemOperator(context.call) + val nameToResolve = if (isBinaryRemOperator && !shouldUseOperatorRem) + OperatorConventions.REM_TO_MOD_OPERATION_NAMES[name]!! + else + name + + val processor = kind.createTowerProcessor(this, nameToResolve, tracing, scopeTower, detailedReceiver, context) if (context.collectAllCandidates) { return allCandidatesResult(towerResolver.collectAllCandidates(scopeTower, processor)) @@ -168,14 +176,14 @@ class NewResolutionOldInference( candidates.all { it.candidateStatus.resultingApplicability == ResolutionCandidateApplicability.INAPPLICABLE } - if (emptyOrInapplicableCandidates && isBinaryRemOperator(context.call)) { + if (isBinaryRemOperator && shouldUseOperatorRem && emptyOrInapplicableCandidates) { val deprecatedName = OperatorConventions.REM_TO_MOD_OPERATION_NAMES[name] val processorForDeprecatedName = kind.createTowerProcessor(this, deprecatedName!!, tracing, scopeTower, detailedReceiver, context) candidates = towerResolver.runResolve(scopeTower, processorForDeprecatedName, useOrder = kind != ResolutionKind.CallableReference) } if (candidates.isEmpty()) { - if (reportAdditionalDiagnosticIfNoCandidates(context, name, kind, scopeTower, detailedReceiver)) { + if (reportAdditionalDiagnosticIfNoCandidates(context, nameToResolve, kind, scopeTower, detailedReceiver)) { return OverloadResolutionResultsImpl.nameNotFound() } } diff --git a/compiler/testData/diagnostics/tests/operatorRem/resolveToModWhenNoOperatorRemFeature.kt b/compiler/testData/diagnostics/tests/operatorRem/resolveToModWhenNoOperatorRemFeature.kt new file mode 100644 index 00000000000..e1a29748c33 --- /dev/null +++ b/compiler/testData/diagnostics/tests/operatorRem/resolveToModWhenNoOperatorRemFeature.kt @@ -0,0 +1,39 @@ +// !LANGUAGE: -OperatorRem +// !DIAGNOSTICS: -UNUSED_PARAMETER + +object ModAndRem { + operator fun mod(x: Int) = 0 + operator fun rem(x: Int) = "" +} + +object ModAssignAndRemAssign { + operator fun modAssign(x: String) {} + operator fun remAssign(x: Int) {} +} + +object RemAndModAssign { + operator fun modAssign(x: Int) {} + operator fun rem(x: Int) = RemAndModAssign +} + +object OnlyRem { + operator fun rem(x: Int) {} + operator fun remAssign(x: Int) {} +} + +fun test() { + takeInt(ModAndRem % 1) + + val c = ModAssignAndRemAssign + c %= "" + + var c1 = RemAndModAssign + c1 %= 1 + + OnlyRem % 1 + + val c2 = OnlyRem + c2 %= 1 +} + +fun takeInt(x: Int) {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/operatorRem/resolveToModWhenNoOperatorRemFeature.txt b/compiler/testData/diagnostics/tests/operatorRem/resolveToModWhenNoOperatorRemFeature.txt new file mode 100644 index 00000000000..2627be97f57 --- /dev/null +++ b/compiler/testData/diagnostics/tests/operatorRem/resolveToModWhenNoOperatorRemFeature.txt @@ -0,0 +1,40 @@ +package + +public fun takeInt(/*0*/ x: kotlin.Int): kotlin.Unit +public fun test(): kotlin.Unit + +public object ModAndRem { + private constructor ModAndRem() + 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 final operator fun mod(/*0*/ x: kotlin.Int): kotlin.Int + public final operator fun rem(/*0*/ x: kotlin.Int): kotlin.String + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public object ModAssignAndRemAssign { + private constructor ModAssignAndRemAssign() + 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 final operator fun modAssign(/*0*/ x: kotlin.String): kotlin.Unit + public final operator fun remAssign(/*0*/ x: kotlin.Int): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public object OnlyRem { + private constructor OnlyRem() + 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 final operator fun rem(/*0*/ x: kotlin.Int): kotlin.Unit + public final operator fun remAssign(/*0*/ x: kotlin.Int): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public object RemAndModAssign { + private constructor RemAndModAssign() + 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 final operator fun modAssign(/*0*/ x: kotlin.Int): kotlin.Unit + public final operator fun rem(/*0*/ x: kotlin.Int): RemAndModAssign + 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 e89a120b044..9e2524e6aa8 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -13426,6 +13426,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("resolveToModWhenNoOperatorRemFeature.kt") + public void testResolveToModWhenNoOperatorRemFeature() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/operatorRem/resolveToModWhenNoOperatorRemFeature.kt"); + doTest(fileName); + } + @TestMetadata("remAndRemAssignAmbiguity.kt") public void testRemAndRemAssignAmbiguity() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/operatorRem/remAndRemAssignAmbiguity.kt");