From 7a0e44b8f99d4babf05f6d7e7c39bee6a14f5f33 Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Thu, 8 Dec 2016 16:16:36 +0300 Subject: [PATCH] Resolve '%' as 'mod' when LV=1.0 --- .../calls/tower/NewResolutionOldInference.kt | 14 +++++-- .../resolveToModWhenNoOperatorRemFeature.kt | 39 ++++++++++++++++++ .../resolveToModWhenNoOperatorRemFeature.txt | 40 +++++++++++++++++++ .../checkers/DiagnosticsTestGenerated.java | 6 +++ 4 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/operatorRem/resolveToModWhenNoOperatorRemFeature.kt create mode 100644 compiler/testData/diagnostics/tests/operatorRem/resolveToModWhenNoOperatorRemFeature.txt 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");