From c8c558b5754a24a2b634b9bf7b173e9ee1ea4ae8 Mon Sep 17 00:00:00 2001 From: "Denis.Zharkov" Date: Wed, 23 Jun 2021 15:19:35 +0300 Subject: [PATCH] FIR: Use Any? expect type to the argument list of == ^KT-47409 Related --- ...TouchedTilContractsPhaseTestGenerated.java | 5 +++++ .../testData/resolve/inference/equals.fir.txt | 18 +++++++++++++++ .../testData/resolve/inference/equals.kt | 6 +++++ .../runners/FirDiagnosticTestGenerated.java | 6 +++++ ...DiagnosticsWithLightTreeTestGenerated.java | 6 +++++ .../FirExpressionsResolveTransformer.kt | 22 ++++++++++++++----- ...veEqualsOperatorWithAnyExpectedType.fir.kt | 11 ---------- ...esolveEqualsOperatorWithAnyExpectedType.kt | 1 + ...nosisCompilerFirTestdataTestGenerated.java | 6 +++++ 9 files changed, 64 insertions(+), 17 deletions(-) create mode 100644 compiler/fir/analysis-tests/testData/resolve/inference/equals.fir.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/inference/equals.kt delete mode 100644 compiler/testData/diagnostics/tests/callableReference/resolve/resolveEqualsOperatorWithAnyExpectedType.fir.kt diff --git a/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java b/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java index 8af97b72d97..5db74e8328f 100644 --- a/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java +++ b/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java @@ -2421,6 +2421,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract runTest("compiler/fir/analysis-tests/testData/resolve/inference/elvisAndUnit.kt"); } + @TestMetadata("equals.kt") + public void testEquals() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/inference/equals.kt"); + } + @TestMetadata("extensionCallableReferences.kt") public void testExtensionCallableReferences() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/inference/extensionCallableReferences.kt"); diff --git a/compiler/fir/analysis-tests/testData/resolve/inference/equals.fir.txt b/compiler/fir/analysis-tests/testData/resolve/inference/equals.fir.txt new file mode 100644 index 00000000000..cf310f85b6f --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/inference/equals.fir.txt @@ -0,0 +1,18 @@ +FILE: equals.kt + public final fun materialize(): R|T| { + ^materialize R|kotlin/TODO|() + } + public final fun main(): R|kotlin/Unit| { + when () { + ==(String(), R|/materialize|()) -> { + ^main Unit + } + } + + when () { + ==(R|/materialize|(), String()) -> { + ^main Unit + } + } + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/inference/equals.kt b/compiler/fir/analysis-tests/testData/resolve/inference/equals.kt new file mode 100644 index 00000000000..250fad800c4 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/inference/equals.kt @@ -0,0 +1,6 @@ +fun materialize(): T = TODO() + +fun main() { + if ("" == materialize()) return // FE1.0: OK, type argument inferred to Any? + if (materialize() == "") return // FE1.0: Error, uninferred type argument for `T` +} diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java index ccb19648aeb..d53c85d4422 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java @@ -2751,6 +2751,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest { runTest("compiler/fir/analysis-tests/testData/resolve/inference/elvisAndUnit.kt"); } + @Test + @TestMetadata("equals.kt") + public void testEquals() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/inference/equals.kt"); + } + @Test @TestMetadata("extensionCallableReferences.kt") public void testExtensionCallableReferences() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java index 01bd93f1530..93e5ead0a0a 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java @@ -2751,6 +2751,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos runTest("compiler/fir/analysis-tests/testData/resolve/inference/elvisAndUnit.kt"); } + @Test + @TestMetadata("equals.kt") + public void testEquals() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/inference/equals.kt"); + } + @Test @TestMetadata("extensionCallableReferences.kt") public void testExtensionCallableReferences() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index 2c3246ad967..7c40ae080b9 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -26,12 +26,16 @@ import org.jetbrains.kotlin.fir.resolve.diagnostics.* import org.jetbrains.kotlin.fir.resolve.inference.FirStubInferenceSession import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor -import org.jetbrains.kotlin.fir.resolve.transformers.* +import org.jetbrains.kotlin.fir.resolve.transformers.InvocationKindTransformer +import org.jetbrains.kotlin.fir.resolve.transformers.StoreReceiver +import org.jetbrains.kotlin.fir.resolve.transformers.firClassLike import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef -import org.jetbrains.kotlin.fir.visitors.* +import org.jetbrains.kotlin.fir.visitors.FirDefaultTransformer +import org.jetbrains.kotlin.fir.visitors.TransformData +import org.jetbrains.kotlin.fir.visitors.transformSingle import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.resolve.calls.inference.buildAbstractResultingSubstitutor @@ -490,10 +494,16 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform equalityOperatorCall: FirEqualityOperatorCall, data: ResolutionMode ): FirStatement { - val result = (equalityOperatorCall.transformChildren(transformer, ResolutionMode.ContextIndependent) as FirEqualityOperatorCall) - .also { it.resultType = equalityOperatorCall.typeRef.resolvedTypeFromPrototype(builtinTypes.booleanType.type) } - dataFlowAnalyzer.exitEqualityOperatorCall(result) - return result + // Currently, we use expectedType=Any? for both operands + // In FE1.0, it's only used for the right + // But it seems a bit inconsistent (see KT-47409) + // Also it's kind of complicated to transform different arguments with different expectType considering current FIR structure + equalityOperatorCall.transformAnnotations(transformer, ResolutionMode.ContextIndependent) + equalityOperatorCall.argumentList.transformArguments(transformer, withExpectedType(builtinTypes.nullableAnyType)) + equalityOperatorCall.resultType = equalityOperatorCall.typeRef.resolvedTypeFromPrototype(builtinTypes.booleanType.type) + + dataFlowAnalyzer.exitEqualityOperatorCall(equalityOperatorCall) + return equalityOperatorCall } private inline fun resolveCandidateForAssignmentOperatorCall(block: () -> T): T { diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/resolveEqualsOperatorWithAnyExpectedType.fir.kt b/compiler/testData/diagnostics/tests/callableReference/resolve/resolveEqualsOperatorWithAnyExpectedType.fir.kt deleted file mode 100644 index 92c5803826d..00000000000 --- a/compiler/testData/diagnostics/tests/callableReference/resolve/resolveEqualsOperatorWithAnyExpectedType.fir.kt +++ /dev/null @@ -1,11 +0,0 @@ -// !LANGUAGE: +NewInference - -interface Base - -fun materialize(): K = TODO() - -fun Base.transform(): T = materialize() - -fun test(child: Base) { - child == child.transform() -} diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/resolveEqualsOperatorWithAnyExpectedType.kt b/compiler/testData/diagnostics/tests/callableReference/resolve/resolveEqualsOperatorWithAnyExpectedType.kt index c479d68d729..90f2e95306c 100644 --- a/compiler/testData/diagnostics/tests/callableReference/resolve/resolveEqualsOperatorWithAnyExpectedType.kt +++ b/compiler/testData/diagnostics/tests/callableReference/resolve/resolveEqualsOperatorWithAnyExpectedType.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !LANGUAGE: +NewInference interface Base diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java b/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java index 6af6b3fc2fa..0ef99b32275 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java @@ -2751,6 +2751,12 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis runTest("compiler/fir/analysis-tests/testData/resolve/inference/elvisAndUnit.kt"); } + @Test + @TestMetadata("equals.kt") + public void testEquals() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/inference/equals.kt"); + } + @Test @TestMetadata("extensionCallableReferences.kt") public void testExtensionCallableReferences() throws Exception {