Introduce deprecation cycle for reporting errors on some illegal equality calls inside a builder inference call

^KT-43493 Fixed
This commit is contained in:
Victor Petukhov
2021-08-10 12:04:50 +03:00
committed by TeamCityServer
parent 060af85a93
commit a4a2f71fca
17 changed files with 142 additions and 25 deletions
@@ -14011,6 +14011,18 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
runTest("compiler/testData/diagnostics/tests/inference/builderInference/changingResolveIfDontUseBuilderInference.kt");
}
@Test
@TestMetadata("equalityChecksOnIntegerTypes.kt")
public void testEqualityChecksOnIntegerTypes() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/builderInference/equalityChecksOnIntegerTypes.kt");
}
@Test
@TestMetadata("equalityChecksOnIntegerTypesProgressive.kt")
public void testEqualityChecksOnIntegerTypesProgressive() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/builderInference/equalityChecksOnIntegerTypesProgressive.kt");
}
@Test
@TestMetadata("kt47744.kt")
public void testKt47744() throws Exception {
@@ -14011,6 +14011,18 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/inference/builderInference/changingResolveIfDontUseBuilderInference.kt");
}
@Test
@TestMetadata("equalityChecksOnIntegerTypes.kt")
public void testEqualityChecksOnIntegerTypes() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/builderInference/equalityChecksOnIntegerTypes.kt");
}
@Test
@TestMetadata("equalityChecksOnIntegerTypesProgressive.kt")
public void testEqualityChecksOnIntegerTypesProgressive() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/builderInference/equalityChecksOnIntegerTypesProgressive.kt");
}
@Test
@TestMetadata("kt47744.kt")
public void testKt47744() throws Exception {
@@ -14011,6 +14011,18 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/inference/builderInference/changingResolveIfDontUseBuilderInference.kt");
}
@Test
@TestMetadata("equalityChecksOnIntegerTypes.kt")
public void testEqualityChecksOnIntegerTypes() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/builderInference/equalityChecksOnIntegerTypes.kt");
}
@Test
@TestMetadata("equalityChecksOnIntegerTypesProgressive.kt")
public void testEqualityChecksOnIntegerTypesProgressive() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/builderInference/equalityChecksOnIntegerTypesProgressive.kt");
}
@Test
@TestMetadata("kt47744.kt")
public void testKt47744() throws Exception {
@@ -964,6 +964,8 @@ public interface Errors {
DiagnosticFactory0<KtSimpleNameExpression> EQUALS_MISSING = DiagnosticFactory0.create(ERROR);
DiagnosticFactory3<KtBinaryExpression, KtSimpleNameExpression, KotlinType, KotlinType> EQUALITY_NOT_APPLICABLE =
DiagnosticFactory3.create(ERROR);
DiagnosticFactory3<KtBinaryExpression, KtSimpleNameExpression, KotlinType, KotlinType> EQUALITY_NOT_APPLICABLE_WARNING =
DiagnosticFactory3.create(WARNING);
DiagnosticFactory2<KtElement, KotlinType, KotlinType> INCOMPATIBLE_ENUM_COMPARISON =
DiagnosticFactory2.create(WARNING);
@@ -840,10 +840,8 @@ public class DefaultErrorMessages {
MAP.put(INCONSISTENT_TYPE_PARAMETER_VALUES, "Type parameter {0} of ''{1}'' has inconsistent values: {2}", NAME, NAME, RENDER_COLLECTION_OF_TYPES);
MAP.put(INCONSISTENT_TYPE_PARAMETER_BOUNDS, "Type parameter {0} of ''{1}'' has inconsistent bounds: {2}", NAME, NAME, RENDER_COLLECTION_OF_TYPES);
MAP.put(EQUALITY_NOT_APPLICABLE, "Operator ''{0}'' cannot be applied to ''{1}'' and ''{2}''", (nameExpression, context) -> {
//noinspection ConstantConditions
return nameExpression.getReferencedName();
}, RENDER_TYPE, RENDER_TYPE);
MAP.put(EQUALITY_NOT_APPLICABLE, "Operator ''{0}'' cannot be applied to ''{1}'' and ''{2}''", (nameExpression, context) -> nameExpression.getReferencedName(), RENDER_TYPE, RENDER_TYPE);
MAP.put(EQUALITY_NOT_APPLICABLE_WARNING, "Operator ''{0}'' cannot be applied to ''{1}'' and ''{2}''. It will became an error in future releases.", (nameExpression, context) -> nameExpression.getReferencedName(), RENDER_TYPE, RENDER_TYPE);
MAP.put(INCOMPATIBLE_ENUM_COMPARISON, "Comparison of incompatible enums ''{0}'' and ''{1}'' is always unsuccessful", RENDER_TYPE, RENDER_TYPE);
MAP.put(INCOMPATIBLE_ENUM_COMPARISON_ERROR, "Comparison of incompatible enums ''{0}'' and ''{1}'' is always unsuccessful", RENDER_TYPE, RENDER_TYPE);
@@ -176,6 +176,8 @@ public interface BindingContext {
WritableSlice<Pair<AnonymousFunctionDescriptor, Integer>, Boolean> SUSPEND_LAMBDA_PARAMETER_USED = Slices.createSimpleSlice();
WritableSlice<KtBinaryExpression, Boolean> MARKED_EQUALIY_CALL_PROPER_IN_BUILDER_INFERENCE = Slices.createSimpleSlice();
/**
* Has type of current expression has been already resolved
*/
@@ -7,9 +7,12 @@ package org.jetbrains.kotlin.resolve.calls.checkers
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
import org.jetbrains.kotlin.resolve.calls.inference.BuilderInferenceSession
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.isInlineClassType
import org.jetbrains.kotlin.types.KotlinType
@@ -88,7 +91,14 @@ object EqualityCallChecker : CallChecker {
val rightType = context.trace.getType(right) ?: return
if (TypeIntersector.isIntersectionEmpty(leftType, rightType)) {
context.trace.report(Errors.EQUALITY_NOT_APPLICABLE.on(expression, expression.operationReference, leftType, rightType))
val isProperEqualityChecksEnabled =
context.languageVersionSettings.supportsFeature(LanguageFeature.ProperEqualityChecksInBuilderInferenceCalls)
val shouldReportWarnings = !isProperEqualityChecksEnabled
&& context.inferenceSession is BuilderInferenceSession
&& context.trace.get(BindingContext.MARKED_EQUALIY_CALL_PROPER_IN_BUILDER_INFERENCE, expression) != null
val diagnostic = if (shouldReportWarnings) Errors.EQUALITY_NOT_APPLICABLE_WARNING else Errors.EQUALITY_NOT_APPLICABLE
context.trace.report(diagnostic.on(expression, expression.operationReference, leftType, rightType))
} else {
checkEnumsForCompatibility(context, expression, leftType, rightType)
}
@@ -48,6 +48,7 @@ import org.jetbrains.kotlin.resolve.bindingContextUtil.BindingContextUtilsKt;
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver;
import org.jetbrains.kotlin.resolve.calls.CallExpressionResolver;
import org.jetbrains.kotlin.resolve.calls.checkers.*;
import org.jetbrains.kotlin.resolve.calls.inference.BuilderInferenceSession;
import org.jetbrains.kotlin.resolve.calls.model.DataFlowInfoForArgumentsImpl;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCallImpl;
@@ -1181,6 +1182,16 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
}
}
KotlinTypeInfo rightTypeInfo = facade.getTypeInfo(right, contextWithDataFlow);
KotlinType leftType = leftTypeInfo.getType();
KotlinType rightType = rightTypeInfo.getType();
boolean isBuilderInferenceContext = context.inferenceSession instanceof BuilderInferenceSession;
if (leftType != null && rightType != null && !TypeIntersector.isIntersectionEmpty(leftType, rightType) && isBuilderInferenceContext) {
context.trace.record(MARKED_EQUALIY_CALL_PROPER_IN_BUILDER_INFERENCE, expression);
}
return rightTypeInfo.replaceType(components.builtIns.getBooleanType());
}
@@ -0,0 +1,20 @@
// !LANGUAGE: -ProperEqualityChecksInBuilderInferenceCalls
// WITH_STDLIB
fun main(x: Long, y: Int) {
sequence {
<!EQUALITY_NOT_APPLICABLE_WARNING!>1L == 3<!>
<!EQUALITY_NOT_APPLICABLE_WARNING!>x == 3<!>
<!EQUALITY_NOT_APPLICABLE_WARNING!>3 == 1L<!>
<!EQUALITY_NOT_APPLICABLE_WARNING!>3 == x<!>
<!EQUALITY_NOT_APPLICABLE_WARNING!>y == x<!>
<!EQUALITY_NOT_APPLICABLE_WARNING!>1L === 3<!>
<!EQUALITY_NOT_APPLICABLE_WARNING!>x === 3<!>
<!EQUALITY_NOT_APPLICABLE_WARNING!>3 === 1L<!>
<!EQUALITY_NOT_APPLICABLE_WARNING!>3 === x<!>
<!EQUALITY_NOT_APPLICABLE_WARNING!>y === x<!>
yield("")
}
}
@@ -0,0 +1,20 @@
// !LANGUAGE: -ProperEqualityChecksInBuilderInferenceCalls
// WITH_STDLIB
fun main(x: Long, y: Int) {
sequence {
<!EQUALITY_NOT_APPLICABLE_WARNING("==; Long; Int")!>1L == 3<!>
<!EQUALITY_NOT_APPLICABLE_WARNING("==; Long; Int")!>x == 3<!>
<!EQUALITY_NOT_APPLICABLE("==; Int; Long")!>3 == 1L<!>
<!EQUALITY_NOT_APPLICABLE("==; Int; Long")!>3 == x<!>
<!EQUALITY_NOT_APPLICABLE("==; Int; Long")!>y == x<!>
<!EQUALITY_NOT_APPLICABLE("===; Long; Int")!>1L === 3<!>
<!EQUALITY_NOT_APPLICABLE("===; Long; Int")!>x === 3<!>
<!EQUALITY_NOT_APPLICABLE("===; Int; Long")!>3 === 1L<!>
<!EQUALITY_NOT_APPLICABLE("===; Int; Long")!>3 === x<!>
<!EQUALITY_NOT_APPLICABLE("===; Int; Long")!>y === x<!>
yield("")
}
}
@@ -0,0 +1,20 @@
// !LANGUAGE: +ProperEqualityChecksInBuilderInferenceCalls
// WITH_STDLIB
fun main(x: Long, y: Int) {
sequence {
<!EQUALITY_NOT_APPLICABLE_WARNING!>1L == 3<!>
<!EQUALITY_NOT_APPLICABLE_WARNING!>x == 3<!>
<!EQUALITY_NOT_APPLICABLE_WARNING!>3 == 1L<!>
<!EQUALITY_NOT_APPLICABLE_WARNING!>3 == x<!>
<!EQUALITY_NOT_APPLICABLE_WARNING!>y == x<!>
<!EQUALITY_NOT_APPLICABLE_WARNING!>1L === 3<!>
<!EQUALITY_NOT_APPLICABLE_WARNING!>x === 3<!>
<!EQUALITY_NOT_APPLICABLE_WARNING!>3 === 1L<!>
<!EQUALITY_NOT_APPLICABLE_WARNING!>3 === x<!>
<!EQUALITY_NOT_APPLICABLE_WARNING!>y === x<!>
yield("")
}
}
@@ -1,4 +1,5 @@
// WITH_RUNTIME
// !LANGUAGE: +ProperEqualityChecksInBuilderInferenceCalls
// WITH_STDLIB
fun main(x: Long, y: Int) {
sequence {
@@ -0,0 +1,3 @@
package
public fun main(/*0*/ x: kotlin.Long, /*1*/ y: kotlin.Int): kotlin.Unit
@@ -1,19 +0,0 @@
// WITH_RUNTIME
fun main(x: Long, y: Int) {
sequence {
1L == 3
x == 3
3 == 1L
3 == x
y == x
1L === 3
x === 3
3 === 1L
3 === x
y === x
yield("")
}
}
@@ -14017,6 +14017,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/inference/builderInference/changingResolveIfDontUseBuilderInference.kt");
}
@Test
@TestMetadata("equalityChecksOnIntegerTypes.kt")
public void testEqualityChecksOnIntegerTypes() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/builderInference/equalityChecksOnIntegerTypes.kt");
}
@Test
@TestMetadata("equalityChecksOnIntegerTypesProgressive.kt")
public void testEqualityChecksOnIntegerTypesProgressive() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/builderInference/equalityChecksOnIntegerTypesProgressive.kt");
}
@Test
@TestMetadata("kt47744.kt")
public void testKt47744() throws Exception {
@@ -255,6 +255,7 @@ enum class LanguageFeature(
ProgressionsChangingResolve(KOTLIN_1_8), // KT-49276
ForbidSuperDelegationToAbstractFakeOverride(KOTLIN_1_8), // KT-49017
ForbidSuperDelegationToAbstractAnyMethod(KOTLIN_1_8), // KT-38078
ProperEqualityChecksInBuilderInferenceCalls(KOTLIN_1_8, kind = BUG_FIX),
// 1.9