From cab034049777cd1779b6c38b0a21e5439427ac56 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Wed, 25 Jan 2023 17:56:13 +0100 Subject: [PATCH] K1: report also TYPE_MISMATCH_WARNING in JvmSyntheticAssignmentChecker #KT-56061 Fixed --- .../checkers/JvmSyntheticAssignmentChecker.kt | 22 ++++++-- .../diagnostics/tests/syntheticSet.fir.kt | 51 ++++++++++++++++--- .../diagnostics/tests/syntheticSet.kt | 49 +++++++++++++++--- .../diagnostics/tests/syntheticSet.txt | 12 ++++- 4 files changed, 113 insertions(+), 21 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmSyntheticAssignmentChecker.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmSyntheticAssignmentChecker.kt index 977326df6c9..1d2cee74d85 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmSyntheticAssignmentChecker.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmSyntheticAssignmentChecker.kt @@ -6,11 +6,14 @@ package org.jetbrains.kotlin.resolve.jvm.checkers import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor +import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.psi.KtBinaryExpression import org.jetbrains.kotlin.resolve.calls.checkers.AssignmentChecker import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext +import org.jetbrains.kotlin.resolve.calls.checkers.isAssignmentCorrectWithDataFlowInfo import org.jetbrains.kotlin.resolve.calls.tower.isSynthesized import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall +import org.jetbrains.kotlin.resolve.calls.util.getType import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor import org.jetbrains.kotlin.types.IndexedParametersSubstitution @@ -20,6 +23,9 @@ import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.typeUtil.isNothing object JvmSyntheticAssignmentChecker : AssignmentChecker { + + private val TYPE_MISMATCH_ERRORS = setOf(Errors.TYPE_MISMATCH, Errors.CONSTANT_EXPECTED_TYPE_MISMATCH, Errors.NULL_FOR_NONNULL_TYPE) + override fun check(assignmentExpression: KtBinaryExpression, context: CallCheckerContext) { val left = assignmentExpression.left ?: return val resolvedCall = left.getResolvedCall(context.trace.bindingContext) ?: return @@ -43,8 +49,16 @@ object JvmSyntheticAssignmentChecker : AssignmentChecker { substitutionParameters.toTypedArray(), substitutionArguments.toTypedArray(), approximateContravariantCapturedTypes = true ) ) - val substitutedPropertyType = substitutor.substitute(propertyType.unwrap(), Variance.IN_VARIANCE) - if (substitutedPropertyType == null || !substitutedPropertyType.isNothing()) return - context.trace.report(ErrorsJvm.SYNTHETIC_SETTER_PROJECTED_OUT.on(left, resultingDescriptor)) + val substitutedPropertyType = substitutor.substitute(propertyType.unwrap(), Variance.IN_VARIANCE) ?: return + if (substitutedPropertyType.isNothing()) { + context.trace.report(ErrorsJvm.SYNTHETIC_SETTER_PROJECTED_OUT.on(left, resultingDescriptor)) + return + } + val rValue = assignmentExpression.right ?: return + val rValueType = rValue.getType(context.trace.bindingContext) ?: return + if (isAssignmentCorrectWithDataFlowInfo(substitutedPropertyType, rValue, rValueType, context)) return + if (context.trace.bindingContext.diagnostics.forElement(rValue).none { it.factory in TYPE_MISMATCH_ERRORS }) { + context.trace.report(Errors.TYPE_MISMATCH_WARNING.on(rValue, substitutedPropertyType, rValueType)) + } } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/syntheticSet.fir.kt b/compiler/testData/diagnostics/tests/syntheticSet.fir.kt index 29a16afb52f..14ea2c56eb5 100644 --- a/compiler/testData/diagnostics/tests/syntheticSet.fir.kt +++ b/compiler/testData/diagnostics/tests/syntheticSet.fir.kt @@ -31,6 +31,11 @@ fun foo(container: Container<*>, wrapper: Wrapper) { container.simple = "123" container.setSimple("123") + container.simple = null + container.setSimple(null) + container.simple = container.simple + container.setSimple(container.getSimple()) + container.simple = null!! } fun bar(container: Container, wrapper: Wrapper) { @@ -47,32 +52,62 @@ fun baz(container: Container, wrapper: Wrapper) { container.setSimple("123") } -fun gau(container: Container, wrapper: Wrapper) { +fun gau(container: Container, wrapper: Wrapper, arg: Any) { container.wrapper = wrapper container.simple = 456 + container.simple = arg + container.simple = x + container.simple = O + if (arg is String) { + container.simple = arg + } } fun dif(container: Container, wrapper: Wrapper) { container.wrapper = wrapper } +object O + fun out(container: Container, wrapper: Wrapper) { container.wrapper = wrapper container.setWrapper(wrapper) - container.simple = "123" - container.setSimple("123") -} - -fun inn(container: Container, wrapper: Wrapper) { - container.wrapper = wrapper - container.setWrapper(wrapper) + container.simple = x + container.setSimple(x) + container.simple = O + container.setSimple(O) container.simple = 456 container.setSimple(456) } +val x = 456 + +fun inn(container: Container, wrapper: Wrapper, arg: Any) { + container.wrapper = wrapper + container.setWrapper(wrapper) + container.simple = x + container.setSimple(x) + container.simple = O + container.setSimple(O) + container.simple = 456 + container.setSimple(456) + container.simple = arg + container.setSimple(arg) + if (arg is String) { + container.simple = arg + container.setSimple(arg) + } +} + fun generic(container: Container, wrapper: Wrapper, arg: T) { container.wrapper = wrapper container.setWrapper(wrapper) + container.simple = x + container.setSimple(x) + container.simple = O + container.setSimple(O) + container.simple = 456 + container.setSimple(456) container.simple = arg container.setSimple(arg) } diff --git a/compiler/testData/diagnostics/tests/syntheticSet.kt b/compiler/testData/diagnostics/tests/syntheticSet.kt index 14360d3b2f2..cdb14766f7d 100644 --- a/compiler/testData/diagnostics/tests/syntheticSet.kt +++ b/compiler/testData/diagnostics/tests/syntheticSet.kt @@ -29,8 +29,13 @@ fun foo(container: Container<*>, wrapper: Wrapper) { container.wrapper = wrapper container.setWrapper(wrapper) - container.simple = "123" + container.simple = "123" container.setSimple("123") + container.simple = null + container.setSimple(null) + container.simple = container.simple + container.setSimple(container.getSimple()) + container.simple = null!! } fun bar(container: Container, wrapper: Wrapper) { @@ -47,32 +52,62 @@ fun baz(container: Container, wrapper: Wrapper) { container.setSimple("123") } -fun gau(container: Container, wrapper: Wrapper) { +fun gau(container: Container, wrapper: Wrapper, arg: Any) { container.wrapper = wrapper container.simple = 456 + container.simple = arg + container.simple = x + container.simple = O + if (arg is String) { + container.simple = arg + } } fun dif(container: Container, wrapper: Wrapper) { container.wrapper = wrapper } +object O + fun out(container: Container, wrapper: Wrapper) { container.wrapper = wrapper container.setWrapper(wrapper) - container.simple = "123" - container.setSimple("123") + container.simple = x + container.setSimple(x) + container.simple = O + container.setSimple(O) + container.simple = 456 + container.setSimple(456) } -fun inn(container: Container, wrapper: Wrapper) { +val x = 456 + +fun inn(container: Container, wrapper: Wrapper, arg: Any) { container.wrapper = wrapper container.setWrapper(wrapper) - container.simple = 456 + container.simple = x + container.setSimple(x) + container.simple = O + container.setSimple(O) + container.simple = 456 container.setSimple(456) + container.simple = arg + container.setSimple(arg) + if (arg is String) { + container.simple = arg + container.setSimple(arg) + } } fun generic(container: Container, wrapper: Wrapper, arg: T) { container.wrapper = wrapper container.setWrapper(wrapper) - container.simple = arg + container.simple = x + container.setSimple(x) + container.simple = O + container.setSimple(O) + container.simple = 456 + container.setSimple(456) + container.simple = arg container.setSimple(arg) } diff --git a/compiler/testData/diagnostics/tests/syntheticSet.txt b/compiler/testData/diagnostics/tests/syntheticSet.txt index 4dc60906c78..d7da884f91e 100644 --- a/compiler/testData/diagnostics/tests/syntheticSet.txt +++ b/compiler/testData/diagnostics/tests/syntheticSet.txt @@ -1,12 +1,13 @@ package +public val x: kotlin.Int = 456 public fun bar(/*0*/ container: Container, /*1*/ wrapper: Wrapper): kotlin.Unit public fun baz(/*0*/ container: Container, /*1*/ wrapper: Wrapper): kotlin.Unit public fun dif(/*0*/ container: Container, /*1*/ wrapper: Wrapper): kotlin.Unit public fun foo(/*0*/ container: Container<*>, /*1*/ wrapper: Wrapper): kotlin.Unit -public fun gau(/*0*/ container: Container, /*1*/ wrapper: Wrapper): kotlin.Unit +public fun gau(/*0*/ container: Container, /*1*/ wrapper: Wrapper, /*2*/ arg: kotlin.Any): kotlin.Unit public fun generic(/*0*/ container: Container, /*1*/ wrapper: Wrapper, /*2*/ arg: T): kotlin.Unit -public fun inn(/*0*/ container: Container, /*1*/ wrapper: Wrapper): kotlin.Unit +public fun inn(/*0*/ container: Container, /*1*/ wrapper: Wrapper, /*2*/ arg: kotlin.Any): kotlin.Unit public fun out(/*0*/ container: Container, /*1*/ wrapper: Wrapper): kotlin.Unit public open class Container { @@ -21,6 +22,13 @@ public open class Container { public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } +public object O { + private constructor 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 open class Wrapper { public constructor Wrapper() public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean