[FIR] Fix K2 behavior according to RULES1
The compiler should only report diagnostics for
comparisons over builtins and identity-less types,
other incompatibilities should be reported
via inspections.
It's ok that in `equalityChecksOnIntegerTypes`
instead of `EQUALITY_NOT_APPLICABLE_WARNING` we get
`EQUALITY_NOT_APPLICABLE`, because
`ProperEqualityChecksInBuilderInferenceCalls`
is already active by default.
This change also replaces the notion of a representative superclass
with the least upper bound.
This makes complex types like
intersection/flexible transparent to
RULES1-based compatibility checks.
One way to look at it is to think
that this is an automatic way of handling
type parameters: automatic picking of
"interesting" bounds, and checking them against one another.
Note that `TypeIntersector.intersectTypes`
for `Int` and `T` where `T` is a type parameter
may return both `{Int & T}` or `null`
depending on `T`-s bounds. At the same time,
for type parameters `T` and `K` it will
always return `{T & K}`.
`ConeTypeIntersector.intersectTypes`, on the
other hand, will always return `{Int & T}`
irrespectively of the bounds. Meaning, the two
intersectors differ in corner cases.
`lowerBoundIfFlexible` call in `isLiterallyTypeParameter` is backed by
the `equalityOfFlexibleTypeParameters` test.
^KT-35134 #fixed-in-k2
^KT-22499 #fixed-in-k2
^KT-46383 #fixed-in-k2
This commit is contained in:
committed by
Space Team
parent
06e687addd
commit
f0720c1d12
+40
@@ -3848,6 +3848,46 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.INCOMPATIBLE_ENUM_COMPARISON) { firDiagnostic ->
|
||||
IncompatibleEnumComparisonImpl(
|
||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b),
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.FORBIDDEN_IDENTITY_EQUALS) { firDiagnostic ->
|
||||
ForbiddenIdentityEqualsImpl(
|
||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b),
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.FORBIDDEN_IDENTITY_EQUALS_WARNING) { firDiagnostic ->
|
||||
ForbiddenIdentityEqualsWarningImpl(
|
||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b),
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.DEPRECATED_IDENTITY_EQUALS) { firDiagnostic ->
|
||||
DeprecatedIdentityEqualsImpl(
|
||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b),
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.IMPLICIT_BOXING_IN_IDENTITY_EQUALS) { firDiagnostic ->
|
||||
ImplicitBoxingInIdentityEqualsImpl(
|
||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b),
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.INC_DEC_SHOULD_NOT_RETURN_UNIT) { firDiagnostic ->
|
||||
IncDecShouldNotReturnUnitImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
|
||||
+30
@@ -2684,6 +2684,36 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
abstract val rightType: KtType
|
||||
}
|
||||
|
||||
abstract class IncompatibleEnumComparison : KtFirDiagnostic<KtElement>() {
|
||||
override val diagnosticClass get() = IncompatibleEnumComparison::class
|
||||
abstract val leftType: KtType
|
||||
abstract val rightType: KtType
|
||||
}
|
||||
|
||||
abstract class ForbiddenIdentityEquals : KtFirDiagnostic<KtElement>() {
|
||||
override val diagnosticClass get() = ForbiddenIdentityEquals::class
|
||||
abstract val leftType: KtType
|
||||
abstract val rightType: KtType
|
||||
}
|
||||
|
||||
abstract class ForbiddenIdentityEqualsWarning : KtFirDiagnostic<KtElement>() {
|
||||
override val diagnosticClass get() = ForbiddenIdentityEqualsWarning::class
|
||||
abstract val leftType: KtType
|
||||
abstract val rightType: KtType
|
||||
}
|
||||
|
||||
abstract class DeprecatedIdentityEquals : KtFirDiagnostic<KtElement>() {
|
||||
override val diagnosticClass get() = DeprecatedIdentityEquals::class
|
||||
abstract val leftType: KtType
|
||||
abstract val rightType: KtType
|
||||
}
|
||||
|
||||
abstract class ImplicitBoxingInIdentityEquals : KtFirDiagnostic<KtElement>() {
|
||||
override val diagnosticClass get() = ImplicitBoxingInIdentityEquals::class
|
||||
abstract val leftType: KtType
|
||||
abstract val rightType: KtType
|
||||
}
|
||||
|
||||
abstract class IncDecShouldNotReturnUnit : KtFirDiagnostic<KtExpression>() {
|
||||
override val diagnosticClass get() = IncDecShouldNotReturnUnit::class
|
||||
}
|
||||
|
||||
+35
@@ -3235,6 +3235,41 @@ internal class IncompatibleEnumComparisonErrorImpl(
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.IncompatibleEnumComparisonError(), KtAbstractFirDiagnostic<KtElement>
|
||||
|
||||
internal class IncompatibleEnumComparisonImpl(
|
||||
override val leftType: KtType,
|
||||
override val rightType: KtType,
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.IncompatibleEnumComparison(), KtAbstractFirDiagnostic<KtElement>
|
||||
|
||||
internal class ForbiddenIdentityEqualsImpl(
|
||||
override val leftType: KtType,
|
||||
override val rightType: KtType,
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.ForbiddenIdentityEquals(), KtAbstractFirDiagnostic<KtElement>
|
||||
|
||||
internal class ForbiddenIdentityEqualsWarningImpl(
|
||||
override val leftType: KtType,
|
||||
override val rightType: KtType,
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.ForbiddenIdentityEqualsWarning(), KtAbstractFirDiagnostic<KtElement>
|
||||
|
||||
internal class DeprecatedIdentityEqualsImpl(
|
||||
override val leftType: KtType,
|
||||
override val rightType: KtType,
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.DeprecatedIdentityEquals(), KtAbstractFirDiagnostic<KtElement>
|
||||
|
||||
internal class ImplicitBoxingInIdentityEqualsImpl(
|
||||
override val leftType: KtType,
|
||||
override val rightType: KtType,
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.ImplicitBoxingInIdentityEquals(), KtAbstractFirDiagnostic<KtElement>
|
||||
|
||||
internal class IncDecShouldNotReturnUnitImpl(
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
|
||||
+90
@@ -159,6 +159,24 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
||||
runTest("compiler/testData/diagnostics/tests/CompareToWithErrorType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingArbitraryClasses.kt")
|
||||
public void testComparingArbitraryClasses() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/comparingArbitraryClasses.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingCallableReferencesWithInstanceOfJavaClass.kt")
|
||||
public void testComparingCallableReferencesWithInstanceOfJavaClass() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/comparingCallableReferencesWithInstanceOfJavaClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparisonOfGenericInterfaceWithGenericClass.kt")
|
||||
public void testComparisonOfGenericInterfaceWithGenericClass() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/comparisonOfGenericInterfaceWithGenericClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("Constants.kt")
|
||||
public void testConstants() throws Exception {
|
||||
@@ -243,6 +261,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
||||
runTest("compiler/testData/diagnostics/tests/DiamondProperty.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("differentNumericTypesFromSmartCast.kt")
|
||||
public void testDifferentNumericTypesFromSmartCast() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/differentNumericTypesFromSmartCast.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("Dollar.kt")
|
||||
public void testDollar() throws Exception {
|
||||
@@ -255,6 +279,18 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
||||
runTest("compiler/testData/diagnostics/tests/EnumEntryAsType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityComparisonToSelf.kt")
|
||||
public void testEqualityComparisonToSelf() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/equalityComparisonToSelf.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityWithSmartCastInIfBlock.kt")
|
||||
public void testEqualityWithSmartCastInIfBlock() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/equalityWithSmartCastInIfBlock.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("ExtensionCallInvoke.kt")
|
||||
public void testExtensionCallInvoke() throws Exception {
|
||||
@@ -10392,6 +10428,18 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
||||
runTest("compiler/testData/diagnostics/tests/enum/enumWithEmptyName.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityOfEnumAndParameter.kt")
|
||||
public void testEqualityOfEnumAndParameter() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/enum/equalityOfEnumAndParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityOfFlexibleTypeParameters.kt")
|
||||
public void testEqualityOfFlexibleTypeParameters() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/enum/equalityOfFlexibleTypeParameters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("ExplicitConstructorCall.kt")
|
||||
public void testExplicitConstructorCall() throws Exception {
|
||||
@@ -35359,6 +35407,30 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/commonCollections.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingDifferentSubclassesCommonInterface.kt")
|
||||
public void testComparingDifferentSubclassesCommonInterface() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/comparingDifferentSubclassesCommonInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingPlatformTypes.kt")
|
||||
public void testComparingPlatformTypes() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/comparingPlatformTypes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingSmartCastValueToBoolean.kt")
|
||||
public void testComparingSmartCastValueToBoolean() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/comparingSmartCastValueToBoolean.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingTripleWithPair.kt")
|
||||
public void testComparingTripleWithPair() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/comparingTripleWithPair.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("compileTimeUnsignedArray.kt")
|
||||
public void testCompileTimeUnsignedArray() throws Exception {
|
||||
@@ -35383,6 +35455,24 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/enumEntryInitialization.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityCompatibilityCommonCases.kt")
|
||||
public void testEqualityCompatibilityCommonCases() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/equalityCompatibilityCommonCases.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityCompatibilityOldBehavior_Off.kt")
|
||||
public void testEqualityCompatibilityOldBehavior_Off() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/equalityCompatibilityOldBehavior_Off.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityCompatibilityOldBehavior_On.kt")
|
||||
public void testEqualityCompatibilityOldBehavior_On() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/equalityCompatibilityOldBehavior_On.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("exitProcess.kt")
|
||||
public void testExitProcess() throws Exception {
|
||||
|
||||
+90
@@ -159,6 +159,24 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
||||
runTest("compiler/testData/diagnostics/tests/CompareToWithErrorType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingArbitraryClasses.kt")
|
||||
public void testComparingArbitraryClasses() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/comparingArbitraryClasses.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingCallableReferencesWithInstanceOfJavaClass.kt")
|
||||
public void testComparingCallableReferencesWithInstanceOfJavaClass() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/comparingCallableReferencesWithInstanceOfJavaClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparisonOfGenericInterfaceWithGenericClass.kt")
|
||||
public void testComparisonOfGenericInterfaceWithGenericClass() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/comparisonOfGenericInterfaceWithGenericClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("Constants.kt")
|
||||
public void testConstants() throws Exception {
|
||||
@@ -243,6 +261,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
||||
runTest("compiler/testData/diagnostics/tests/DiamondProperty.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("differentNumericTypesFromSmartCast.kt")
|
||||
public void testDifferentNumericTypesFromSmartCast() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/differentNumericTypesFromSmartCast.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("Dollar.kt")
|
||||
public void testDollar() throws Exception {
|
||||
@@ -255,6 +279,18 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
||||
runTest("compiler/testData/diagnostics/tests/EnumEntryAsType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityComparisonToSelf.kt")
|
||||
public void testEqualityComparisonToSelf() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/equalityComparisonToSelf.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityWithSmartCastInIfBlock.kt")
|
||||
public void testEqualityWithSmartCastInIfBlock() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/equalityWithSmartCastInIfBlock.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("ExtensionCallInvoke.kt")
|
||||
public void testExtensionCallInvoke() throws Exception {
|
||||
@@ -10392,6 +10428,18 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
||||
runTest("compiler/testData/diagnostics/tests/enum/enumWithEmptyName.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityOfEnumAndParameter.kt")
|
||||
public void testEqualityOfEnumAndParameter() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/enum/equalityOfEnumAndParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityOfFlexibleTypeParameters.kt")
|
||||
public void testEqualityOfFlexibleTypeParameters() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/enum/equalityOfFlexibleTypeParameters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("ExplicitConstructorCall.kt")
|
||||
public void testExplicitConstructorCall() throws Exception {
|
||||
@@ -35359,6 +35407,30 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/commonCollections.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingDifferentSubclassesCommonInterface.kt")
|
||||
public void testComparingDifferentSubclassesCommonInterface() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/comparingDifferentSubclassesCommonInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingPlatformTypes.kt")
|
||||
public void testComparingPlatformTypes() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/comparingPlatformTypes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingSmartCastValueToBoolean.kt")
|
||||
public void testComparingSmartCastValueToBoolean() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/comparingSmartCastValueToBoolean.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingTripleWithPair.kt")
|
||||
public void testComparingTripleWithPair() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/comparingTripleWithPair.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("compileTimeUnsignedArray.kt")
|
||||
public void testCompileTimeUnsignedArray() throws Exception {
|
||||
@@ -35383,6 +35455,24 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/enumEntryInitialization.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityCompatibilityCommonCases.kt")
|
||||
public void testEqualityCompatibilityCommonCases() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/equalityCompatibilityCommonCases.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityCompatibilityOldBehavior_Off.kt")
|
||||
public void testEqualityCompatibilityOldBehavior_Off() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/equalityCompatibilityOldBehavior_Off.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityCompatibilityOldBehavior_On.kt")
|
||||
public void testEqualityCompatibilityOldBehavior_On() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/equalityCompatibilityOldBehavior_On.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("exitProcess.kt")
|
||||
public void testExitProcess() throws Exception {
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ fun case1(javaClass: JavaClass?) {
|
||||
}
|
||||
|
||||
class Case1(val javaClass: JavaClass?) {
|
||||
val x = if (javaClass != null) { it -> <!EQUALITY_NOT_APPLICABLE_WARNING!>it == javaClass<!> } else BooCase2.FILTER
|
||||
val x = if (javaClass != null) { it -> it == javaClass } else BooCase2.FILTER
|
||||
}
|
||||
|
||||
class BooCase1() {
|
||||
|
||||
@@ -101,7 +101,7 @@ fun test_9(a: Int, b: Int?) {
|
||||
}
|
||||
b<!UNSAFE_CALL!>.<!>inc()
|
||||
|
||||
if (a === b) {
|
||||
if (<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a === b<!>) {
|
||||
b.inc()
|
||||
}
|
||||
b<!UNSAFE_CALL!>.<!>inc()
|
||||
@@ -111,7 +111,7 @@ fun test_9(a: Int, b: Int?) {
|
||||
}
|
||||
b<!UNSAFE_CALL!>.<!>inc()
|
||||
|
||||
if (b === a) {
|
||||
if (<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>b === a<!>) {
|
||||
b.inc()
|
||||
}
|
||||
b<!UNSAFE_CALL!>.<!>inc()
|
||||
|
||||
@@ -22,12 +22,12 @@ enum class Second {
|
||||
val ONE = Second.THREE
|
||||
|
||||
fun foo(f: First) = <!NO_ELSE_IN_WHEN!>when<!> (f) {
|
||||
<!INCOMPATIBLE_TYPES!>ONE<!> -> 1
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON_ERROR!>ONE<!> -> 1
|
||||
TWO -> 2
|
||||
}
|
||||
|
||||
fun bar(s: Second) = <!NO_ELSE_IN_WHEN!>when<!> (s) {
|
||||
<!INCOMPATIBLE_TYPES!>THREE<!> -> 3
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON_ERROR!>THREE<!> -> 3
|
||||
FOUR -> 4
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
/*
|
||||
* UNEXPECTED BEHAVIOUR
|
||||
* ISSUES: KT-37081
|
||||
|
||||
Vendored
+2
-1
@@ -1,8 +1,9 @@
|
||||
// FULL_JDK
|
||||
// ISSUE: KT-48113
|
||||
// STATUS: On a K2 technical meeting on Mar-27-2023 it was decided to report a warning
|
||||
// WITH_EXTENDED_CHECKERS
|
||||
|
||||
fun collapse(path: String) {
|
||||
val result = (path as <!PLATFORM_CLASS_MAPPED_TO_KOTLIN!>java.lang.String<!>).replace("123", "456")
|
||||
if (result !== path) {}
|
||||
if (<!EQUALITY_NOT_APPLICABLE_WARNING!>result !== path<!>) {}
|
||||
}
|
||||
|
||||
+90
@@ -159,6 +159,24 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
||||
runTest("compiler/testData/diagnostics/tests/CompareToWithErrorType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingArbitraryClasses.kt")
|
||||
public void testComparingArbitraryClasses() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/comparingArbitraryClasses.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingCallableReferencesWithInstanceOfJavaClass.kt")
|
||||
public void testComparingCallableReferencesWithInstanceOfJavaClass() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/comparingCallableReferencesWithInstanceOfJavaClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparisonOfGenericInterfaceWithGenericClass.kt")
|
||||
public void testComparisonOfGenericInterfaceWithGenericClass() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/comparisonOfGenericInterfaceWithGenericClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("Constants.kt")
|
||||
public void testConstants() throws Exception {
|
||||
@@ -243,6 +261,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
||||
runTest("compiler/testData/diagnostics/tests/DiamondProperty.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("differentNumericTypesFromSmartCast.kt")
|
||||
public void testDifferentNumericTypesFromSmartCast() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/differentNumericTypesFromSmartCast.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("Dollar.kt")
|
||||
public void testDollar() throws Exception {
|
||||
@@ -255,6 +279,18 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
||||
runTest("compiler/testData/diagnostics/tests/EnumEntryAsType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityComparisonToSelf.kt")
|
||||
public void testEqualityComparisonToSelf() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/equalityComparisonToSelf.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityWithSmartCastInIfBlock.kt")
|
||||
public void testEqualityWithSmartCastInIfBlock() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/equalityWithSmartCastInIfBlock.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("ExtensionCallInvoke.kt")
|
||||
public void testExtensionCallInvoke() throws Exception {
|
||||
@@ -10392,6 +10428,18 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
||||
runTest("compiler/testData/diagnostics/tests/enum/enumWithEmptyName.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityOfEnumAndParameter.kt")
|
||||
public void testEqualityOfEnumAndParameter() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/enum/equalityOfEnumAndParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityOfFlexibleTypeParameters.kt")
|
||||
public void testEqualityOfFlexibleTypeParameters() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/enum/equalityOfFlexibleTypeParameters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("ExplicitConstructorCall.kt")
|
||||
public void testExplicitConstructorCall() throws Exception {
|
||||
@@ -35359,6 +35407,30 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/commonCollections.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingDifferentSubclassesCommonInterface.kt")
|
||||
public void testComparingDifferentSubclassesCommonInterface() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/comparingDifferentSubclassesCommonInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingPlatformTypes.kt")
|
||||
public void testComparingPlatformTypes() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/comparingPlatformTypes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingSmartCastValueToBoolean.kt")
|
||||
public void testComparingSmartCastValueToBoolean() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/comparingSmartCastValueToBoolean.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingTripleWithPair.kt")
|
||||
public void testComparingTripleWithPair() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/comparingTripleWithPair.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("compileTimeUnsignedArray.kt")
|
||||
public void testCompileTimeUnsignedArray() throws Exception {
|
||||
@@ -35383,6 +35455,24 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/enumEntryInitialization.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityCompatibilityCommonCases.kt")
|
||||
public void testEqualityCompatibilityCommonCases() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/equalityCompatibilityCommonCases.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityCompatibilityOldBehavior_Off.kt")
|
||||
public void testEqualityCompatibilityOldBehavior_Off() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/equalityCompatibilityOldBehavior_Off.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityCompatibilityOldBehavior_On.kt")
|
||||
public void testEqualityCompatibilityOldBehavior_On() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/equalityCompatibilityOldBehavior_On.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("exitProcess.kt")
|
||||
public void testExitProcess() throws Exception {
|
||||
|
||||
+90
@@ -159,6 +159,24 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
||||
runTest("compiler/testData/diagnostics/tests/CompareToWithErrorType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingArbitraryClasses.kt")
|
||||
public void testComparingArbitraryClasses() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/comparingArbitraryClasses.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingCallableReferencesWithInstanceOfJavaClass.kt")
|
||||
public void testComparingCallableReferencesWithInstanceOfJavaClass() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/comparingCallableReferencesWithInstanceOfJavaClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparisonOfGenericInterfaceWithGenericClass.kt")
|
||||
public void testComparisonOfGenericInterfaceWithGenericClass() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/comparisonOfGenericInterfaceWithGenericClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("Constants.kt")
|
||||
public void testConstants() throws Exception {
|
||||
@@ -243,6 +261,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
||||
runTest("compiler/testData/diagnostics/tests/DiamondProperty.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("differentNumericTypesFromSmartCast.kt")
|
||||
public void testDifferentNumericTypesFromSmartCast() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/differentNumericTypesFromSmartCast.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("Dollar.kt")
|
||||
public void testDollar() throws Exception {
|
||||
@@ -255,6 +279,18 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
||||
runTest("compiler/testData/diagnostics/tests/EnumEntryAsType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityComparisonToSelf.kt")
|
||||
public void testEqualityComparisonToSelf() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/equalityComparisonToSelf.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityWithSmartCastInIfBlock.kt")
|
||||
public void testEqualityWithSmartCastInIfBlock() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/equalityWithSmartCastInIfBlock.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("ExtensionCallInvoke.kt")
|
||||
public void testExtensionCallInvoke() throws Exception {
|
||||
@@ -10398,6 +10434,18 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
||||
runTest("compiler/testData/diagnostics/tests/enum/enumWithEmptyName.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityOfEnumAndParameter.kt")
|
||||
public void testEqualityOfEnumAndParameter() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/enum/equalityOfEnumAndParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityOfFlexibleTypeParameters.kt")
|
||||
public void testEqualityOfFlexibleTypeParameters() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/enum/equalityOfFlexibleTypeParameters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("ExplicitConstructorCall.kt")
|
||||
public void testExplicitConstructorCall() throws Exception {
|
||||
@@ -35455,6 +35503,30 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/commonCollections.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingDifferentSubclassesCommonInterface.kt")
|
||||
public void testComparingDifferentSubclassesCommonInterface() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/comparingDifferentSubclassesCommonInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingPlatformTypes.kt")
|
||||
public void testComparingPlatformTypes() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/comparingPlatformTypes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingSmartCastValueToBoolean.kt")
|
||||
public void testComparingSmartCastValueToBoolean() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/comparingSmartCastValueToBoolean.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingTripleWithPair.kt")
|
||||
public void testComparingTripleWithPair() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/comparingTripleWithPair.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("compileTimeUnsignedArray.kt")
|
||||
public void testCompileTimeUnsignedArray() throws Exception {
|
||||
@@ -35479,6 +35551,24 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/enumEntryInitialization.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityCompatibilityCommonCases.kt")
|
||||
public void testEqualityCompatibilityCommonCases() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/equalityCompatibilityCommonCases.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityCompatibilityOldBehavior_Off.kt")
|
||||
public void testEqualityCompatibilityOldBehavior_Off() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/equalityCompatibilityOldBehavior_Off.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityCompatibilityOldBehavior_On.kt")
|
||||
public void testEqualityCompatibilityOldBehavior_On() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/equalityCompatibilityOldBehavior_On.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("exitProcess.kt")
|
||||
public void testExitProcess() throws Exception {
|
||||
|
||||
+20
@@ -1338,6 +1338,26 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
parameter<ConeKotlinType>("leftType")
|
||||
parameter<ConeKotlinType>("rightType")
|
||||
}
|
||||
val INCOMPATIBLE_ENUM_COMPARISON by warning<KtElement> {
|
||||
parameter<ConeKotlinType>("leftType")
|
||||
parameter<ConeKotlinType>("rightType")
|
||||
}
|
||||
val FORBIDDEN_IDENTITY_EQUALS by error<KtElement> {
|
||||
parameter<ConeKotlinType>("leftType")
|
||||
parameter<ConeKotlinType>("rightType")
|
||||
}
|
||||
val FORBIDDEN_IDENTITY_EQUALS_WARNING by warning<KtElement> {
|
||||
parameter<ConeKotlinType>("leftType")
|
||||
parameter<ConeKotlinType>("rightType")
|
||||
}
|
||||
val DEPRECATED_IDENTITY_EQUALS by warning<KtElement> {
|
||||
parameter<ConeKotlinType>("leftType")
|
||||
parameter<ConeKotlinType>("rightType")
|
||||
}
|
||||
val IMPLICIT_BOXING_IN_IDENTITY_EQUALS by warning<KtElement> {
|
||||
parameter<ConeKotlinType>("leftType")
|
||||
parameter<ConeKotlinType>("rightType")
|
||||
}
|
||||
val INC_DEC_SHOULD_NOT_RETURN_UNIT by error<KtExpression>(PositioningStrategy.OPERATOR)
|
||||
val ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT by error<KtExpression>(PositioningStrategy.OPERATOR) {
|
||||
parameter<FirNamedFunctionSymbol>("functionSymbol")
|
||||
|
||||
@@ -693,6 +693,11 @@ object FirErrors {
|
||||
val EQUALITY_NOT_APPLICABLE by error3<KtBinaryExpression, String, ConeKotlinType, ConeKotlinType>()
|
||||
val EQUALITY_NOT_APPLICABLE_WARNING by warning3<KtBinaryExpression, String, ConeKotlinType, ConeKotlinType>()
|
||||
val INCOMPATIBLE_ENUM_COMPARISON_ERROR by error2<KtElement, ConeKotlinType, ConeKotlinType>()
|
||||
val INCOMPATIBLE_ENUM_COMPARISON by warning2<KtElement, ConeKotlinType, ConeKotlinType>()
|
||||
val FORBIDDEN_IDENTITY_EQUALS by error2<KtElement, ConeKotlinType, ConeKotlinType>()
|
||||
val FORBIDDEN_IDENTITY_EQUALS_WARNING by warning2<KtElement, ConeKotlinType, ConeKotlinType>()
|
||||
val DEPRECATED_IDENTITY_EQUALS by warning2<KtElement, ConeKotlinType, ConeKotlinType>()
|
||||
val IMPLICIT_BOXING_IN_IDENTITY_EQUALS by warning2<KtElement, ConeKotlinType, ConeKotlinType>()
|
||||
val INC_DEC_SHOULD_NOT_RETURN_UNIT by error0<KtExpression>(SourceElementPositioningStrategies.OPERATOR)
|
||||
val ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT by error2<KtExpression, FirNamedFunctionSymbol, String>(SourceElementPositioningStrategies.OPERATOR)
|
||||
val PROPERTY_AS_OPERATOR by error1<PsiElement, FirPropertySymbol>(SourceElementPositioningStrategies.OPERATOR)
|
||||
|
||||
+299
-81
@@ -5,109 +5,247 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
||||
|
||||
import org.jetbrains.kotlin.KtRealSourceElementKind
|
||||
import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.ConeTypeCompatibilityChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.ConeTypeCompatibilityChecker.isCompatible
|
||||
import org.jetbrains.kotlin.KtRealSourceElementKind
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory2
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.collectUpperBounds
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isEnumClass
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isFinal
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isInline
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isInterface
|
||||
import org.jetbrains.kotlin.fir.expressions.FirEqualityOperatorCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirOperation
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.expressions.FirSmartCastExpression
|
||||
import org.jetbrains.kotlin.fir.isPrimitiveType
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
import org.jetbrains.kotlin.text
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
|
||||
|
||||
object FirEqualityCompatibilityChecker : FirEqualityOperatorCallChecker() {
|
||||
override fun check(expression: FirEqualityOperatorCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val arguments = expression.argumentList.arguments
|
||||
if (arguments.size != 2) return
|
||||
val lType = arguments[0].typeRef.coneType
|
||||
val rType = arguments[1].typeRef.coneType
|
||||
checkCompatibility(lType, rType, context, expression, reporter)
|
||||
checkSensibleness(lType, rType, context, expression, reporter)
|
||||
}
|
||||
require(arguments.size == 2) { "Equality operator call with non-2 arguments" }
|
||||
|
||||
private fun checkCompatibility(
|
||||
lType: ConeKotlinType,
|
||||
rType: ConeKotlinType,
|
||||
context: CheckerContext,
|
||||
expression: FirEqualityOperatorCall,
|
||||
reporter: DiagnosticReporter
|
||||
) {
|
||||
// If one of the type is already `Nothing?`, we skip reporting further comparison. This is to allow comparing with `null`, which has
|
||||
// type `Nothing?`
|
||||
if (lType.isNullableNothing || rType.isNullableNothing) return
|
||||
val inferenceContext = context.session.typeContext
|
||||
val l = arguments[0].toArgumentInfo(context)
|
||||
val r = arguments[1].toArgumentInfo(context)
|
||||
|
||||
val compatibility = try {
|
||||
inferenceContext.isCompatible(lType, rType)
|
||||
} catch (e: Throwable) {
|
||||
throw IllegalStateException(
|
||||
"Exception while determining type compatibility: lType: $lType, rType: $rType, " +
|
||||
"equality ${expression.render()}, " +
|
||||
"file ${context.containingFile?.name}",
|
||||
e
|
||||
checkSenselessness(l.smartCastType, r.smartCastType, context, expression, reporter)
|
||||
|
||||
val checkApplicability = when (expression.operation) {
|
||||
FirOperation.EQ, FirOperation.NOT_EQ -> ::checkEqualityApplicability
|
||||
FirOperation.IDENTITY, FirOperation.NOT_IDENTITY -> ::checkIdentityApplicability
|
||||
else -> error("Invalid operator of FirEqualityOperatorCall")
|
||||
}
|
||||
|
||||
checkApplicability(l.originalTypeInfo, r.originalTypeInfo, context).ifInapplicable {
|
||||
// Ideally this should match cases when K1
|
||||
// sees a non-empty intersection and none of the
|
||||
// types is an enum, but intersections in K1
|
||||
// work differently from intersections in K2.
|
||||
val isCaseMissedByK1 = it != Applicability.INAPPLICABLE_AS_ENUMS
|
||||
&& l.originalTypeInfo.isLiterallyTypeParameter
|
||||
&& r.originalTypeInfo.isLiterallyTypeParameter
|
||||
val replicateK1Behavior = !context.languageVersionSettings.supportsFeature(LanguageFeature.ReportErrorsForComparisonOperators)
|
||||
|
||||
return reporter.reportInapplicabilityDiagnostic(
|
||||
expression, it, expression.operation, forceWarning = isCaseMissedByK1 && replicateK1Behavior,
|
||||
l.originalTypeInfo, r.originalTypeInfo,
|
||||
l.userType, r.userType, context,
|
||||
)
|
||||
}
|
||||
if (compatibility != ConeTypeCompatibilityChecker.Compatibility.COMPATIBLE) {
|
||||
when (expression.source?.kind) {
|
||||
KtRealSourceElementKind -> {
|
||||
// Note: FE1.0 reports INCOMPATIBLE_ENUM_COMPARISON_ERROR only when TypeIntersector.isIntersectionEmpty() thinks the
|
||||
// given types are compatible. Exactly mimicking the behavior of FE1.0 is difficult and does not seem to provide any
|
||||
// value. So instead, we deterministically output INCOMPATIBLE_ENUM_COMPARISON_ERROR if at least one of the value is an
|
||||
// enum.
|
||||
if (compatibility == ConeTypeCompatibilityChecker.Compatibility.HARD_INCOMPATIBLE &&
|
||||
(lType.isEnumType(context) || rType.isEnumType(context))
|
||||
) {
|
||||
reporter.reportOn(
|
||||
expression.source,
|
||||
FirErrors.INCOMPATIBLE_ENUM_COMPARISON_ERROR,
|
||||
lType,
|
||||
rType,
|
||||
context
|
||||
)
|
||||
} else {
|
||||
reporter.reportOn(
|
||||
expression.source,
|
||||
if (compatibility == ConeTypeCompatibilityChecker.Compatibility.HARD_INCOMPATIBLE) {
|
||||
FirErrors.EQUALITY_NOT_APPLICABLE
|
||||
} else {
|
||||
FirErrors.EQUALITY_NOT_APPLICABLE_WARNING
|
||||
},
|
||||
expression.operation.operator,
|
||||
lType,
|
||||
rType,
|
||||
context
|
||||
)
|
||||
}
|
||||
}
|
||||
else -> reporter.reportOn(
|
||||
expression.source,
|
||||
if (compatibility == ConeTypeCompatibilityChecker.Compatibility.HARD_INCOMPATIBLE) {
|
||||
FirErrors.INCOMPATIBLE_TYPES
|
||||
} else {
|
||||
FirErrors.INCOMPATIBLE_TYPES_WARNING
|
||||
},
|
||||
lType,
|
||||
rType,
|
||||
context
|
||||
)
|
||||
}
|
||||
|
||||
if (l.argument !is FirSmartCastExpression && r.argument !is FirSmartCastExpression) {
|
||||
return
|
||||
}
|
||||
|
||||
checkApplicability(l.smartCastTypeInfo, r.smartCastTypeInfo, context).ifInapplicable {
|
||||
return reporter.reportInapplicabilityDiagnostic(
|
||||
expression, it, expression.operation, forceWarning = true,
|
||||
l.smartCastTypeInfo, r.smartCastTypeInfo,
|
||||
l.userType, r.userType, context,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun ConeKotlinType.isEnumType(
|
||||
context: CheckerContext
|
||||
): Boolean {
|
||||
if (isEnum) return true
|
||||
val firRegularClassSymbol = (this as? ConeClassLikeType)?.lookupTag?.toFirRegularClassSymbol(context.session) ?: return false
|
||||
return firRegularClassSymbol.isEnumClass
|
||||
private fun checkEqualityApplicability(l: TypeInfo, r: TypeInfo, context: CheckerContext): Applicability {
|
||||
val oneIsBuiltin = l.isBuiltin || r.isBuiltin
|
||||
|
||||
// The compiler should only check comparisons
|
||||
// when builtins are involved.
|
||||
// Builtins' supertypes must not be present in
|
||||
// the list of special fqNames described in RULES1
|
||||
|
||||
return when {
|
||||
oneIsBuiltin && shouldReportAsPerRules1(l, r, context) -> getInapplicabilityFor(l, r)
|
||||
else -> Applicability.APPLICABLE
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSensibleness(
|
||||
private fun checkIdentityApplicability(l: TypeInfo, r: TypeInfo, context: CheckerContext): Applicability {
|
||||
// The compiler should only check comparisons
|
||||
// when identity-less types or builtins are involved.
|
||||
|
||||
val oneIsBuiltin = l.isBuiltin || r.isBuiltin
|
||||
val oneIsNotNull = !l.type.isNullable || !r.type.isNullable
|
||||
|
||||
return when {
|
||||
l.isIdentityLess || r.isIdentityLess -> Applicability.INAPPLICABLE_AS_IDENTITY_LESS
|
||||
oneIsBuiltin && oneIsNotNull && shouldReportAsPerRules1(l, r, context) -> getInapplicabilityFor(l, r)
|
||||
else -> Applicability.APPLICABLE
|
||||
}
|
||||
}
|
||||
|
||||
private fun getInapplicabilityFor(l: TypeInfo, r: TypeInfo): Applicability {
|
||||
val isIntersectionEmpty = l.enforcesEmptyIntersection || r.enforcesEmptyIntersection
|
||||
val isOneEnum = l.isEnumClass || r.isEnumClass
|
||||
|
||||
return when {
|
||||
!isIntersectionEmpty && isOneEnum -> Applicability.INAPPLICABLE_AS_ENUMS
|
||||
else -> Applicability.GENERALLY_INAPPLICABLE
|
||||
}
|
||||
}
|
||||
|
||||
private fun shouldReportAsPerRules1(l: TypeInfo, r: TypeInfo, context: CheckerContext): Boolean {
|
||||
// Builtins are always final classes, so
|
||||
// we only need to check if one is related
|
||||
// to the other
|
||||
|
||||
fun TypeInfo.isSubclassOf(other: TypeInfo) = when {
|
||||
other.enforcesEmptyIntersection -> type.classId == other.type.classId
|
||||
else -> notNullType.isSubtypeOf(other.notNullType, context.session)
|
||||
}
|
||||
|
||||
return when {
|
||||
l.type.isNothingOrNullableNothing || r.type.isNothingOrNullableNothing -> false
|
||||
else -> !l.isSubclassOf(r) && !r.isSubclassOf(l)
|
||||
}
|
||||
}
|
||||
|
||||
private enum class Applicability {
|
||||
APPLICABLE,
|
||||
GENERALLY_INAPPLICABLE,
|
||||
INAPPLICABLE_AS_ENUMS,
|
||||
INAPPLICABLE_AS_IDENTITY_LESS,
|
||||
}
|
||||
|
||||
private inline fun Applicability.ifInapplicable(block: (Applicability) -> Unit) = when (this) {
|
||||
Applicability.APPLICABLE -> {}
|
||||
else -> block(this)
|
||||
}
|
||||
|
||||
private fun getGeneralInapplicabilityDiagnostic(forceWarning: Boolean) = when {
|
||||
forceWarning -> FirErrors.EQUALITY_NOT_APPLICABLE_WARNING
|
||||
else -> FirErrors.EQUALITY_NOT_APPLICABLE
|
||||
}
|
||||
|
||||
private fun getIdentityLessInapplicabilityDiagnostic(
|
||||
l: TypeInfo,
|
||||
r: TypeInfo,
|
||||
forceWarning: Boolean,
|
||||
context: CheckerContext,
|
||||
): KtDiagnosticFactory2<ConeKotlinType, ConeKotlinType> {
|
||||
val areBothPrimitives = l.isPrimitive && r.isPrimitive
|
||||
val areSameTypes = l.type.classId == r.type.classId
|
||||
val shouldProperlyReportError = context.languageVersionSettings.supportsFeature(LanguageFeature.ReportErrorsForComparisonOperators)
|
||||
|
||||
// In this case K1 reports nothing
|
||||
val shouldRelaxDiagnostic = (l.type.isNullableNothing || r.type.isNullableNothing) && !shouldProperlyReportError
|
||||
|
||||
return when {
|
||||
// See: KT-28252
|
||||
areSameTypes && areBothPrimitives -> FirErrors.DEPRECATED_IDENTITY_EQUALS
|
||||
// The same reason as above
|
||||
isIdentityComparedWithImplicitBoxing(l, r, context.session) -> FirErrors.IMPLICIT_BOXING_IN_IDENTITY_EQUALS
|
||||
forceWarning || shouldRelaxDiagnostic -> FirErrors.FORBIDDEN_IDENTITY_EQUALS_WARNING
|
||||
else -> FirErrors.FORBIDDEN_IDENTITY_EQUALS
|
||||
}
|
||||
}
|
||||
|
||||
private fun isIdentityComparedWithImplicitBoxing(l: TypeInfo, r: TypeInfo, session: FirSession) =
|
||||
isPrimitiveWithNonPrimitiveSupertype(l, r, session) || isPrimitiveWithNonPrimitiveSupertype(r, l, session)
|
||||
|
||||
private fun isPrimitiveWithNonPrimitiveSupertype(l: TypeInfo, r: TypeInfo, session: FirSession) =
|
||||
l.isPrimitive && !r.isPrimitive && l.type.isSubtypeOf(r.type, session)
|
||||
|
||||
private fun getSourceLessInapplicabilityDiagnostic(forceWarning: Boolean) = when {
|
||||
forceWarning -> FirErrors.INCOMPATIBLE_TYPES_WARNING
|
||||
else -> FirErrors.INCOMPATIBLE_TYPES
|
||||
}
|
||||
|
||||
private fun getEnumInapplicabilityDiagnostic(
|
||||
l: TypeInfo,
|
||||
r: TypeInfo,
|
||||
forceWarning: Boolean,
|
||||
context: CheckerContext,
|
||||
): KtDiagnosticFactory2<ConeKotlinType, ConeKotlinType> {
|
||||
// Preserving the behavior on the old test data
|
||||
// simplifies detecting fir-differences,
|
||||
// which is crucial for this checker
|
||||
val isOldTestData = !context.languageVersionSettings.supportsFeature(
|
||||
LanguageFeature.ProhibitComparisonOfIncompatibleEnums,
|
||||
)
|
||||
|
||||
// In this corner case K1 reports nothing
|
||||
val bothNullableEnums = l.isNullableEnum && r.isNullableEnum
|
||||
// When comparing enums, for type parameters K1
|
||||
// tries to pick the "representative" superclass
|
||||
// instead of the proper intersection.
|
||||
// We can't guarantee that in such cases
|
||||
// K2 reports the same as K1
|
||||
val areIntersectionsInvolved = l.type is ConeIntersectionType || r.type is ConeIntersectionType
|
||||
|
||||
val shouldProperlyReportError = context.languageVersionSettings.supportsFeature(LanguageFeature.ReportErrorsForComparisonOperators)
|
||||
val shouldRelaxDiagnostic = (bothNullableEnums || areIntersectionsInvolved) && !shouldProperlyReportError
|
||||
|
||||
return when {
|
||||
forceWarning || isOldTestData || shouldRelaxDiagnostic -> FirErrors.INCOMPATIBLE_ENUM_COMPARISON
|
||||
else -> FirErrors.INCOMPATIBLE_ENUM_COMPARISON_ERROR
|
||||
}
|
||||
}
|
||||
|
||||
private fun DiagnosticReporter.reportInapplicabilityDiagnostic(
|
||||
expression: FirEqualityOperatorCall,
|
||||
applicability: Applicability,
|
||||
operation: FirOperation,
|
||||
forceWarning: Boolean,
|
||||
l: TypeInfo,
|
||||
r: TypeInfo,
|
||||
lUserType: ConeKotlinType,
|
||||
rUserType: ConeKotlinType,
|
||||
context: CheckerContext,
|
||||
): Unit = when {
|
||||
applicability == Applicability.INAPPLICABLE_AS_IDENTITY_LESS -> reportOn(
|
||||
expression.source, getIdentityLessInapplicabilityDiagnostic(l, r, forceWarning, context),
|
||||
lUserType, rUserType, context,
|
||||
)
|
||||
applicability == Applicability.INAPPLICABLE_AS_ENUMS -> reportOn(
|
||||
expression.source, getEnumInapplicabilityDiagnostic(l, r, forceWarning, context),
|
||||
lUserType, rUserType, context,
|
||||
)
|
||||
// This check ensures K2 reports the same diagnostics as K1 used to.
|
||||
expression.source?.kind !is KtRealSourceElementKind -> reportOn(
|
||||
expression.source, getSourceLessInapplicabilityDiagnostic(forceWarning),
|
||||
lUserType, rUserType, context,
|
||||
)
|
||||
applicability == Applicability.GENERALLY_INAPPLICABLE -> reportOn(
|
||||
expression.source, getGeneralInapplicabilityDiagnostic(forceWarning),
|
||||
operation.operator, lUserType, rUserType, context,
|
||||
)
|
||||
else -> error("Shouldn't be here")
|
||||
}
|
||||
|
||||
private fun checkSenselessness(
|
||||
lType: ConeKotlinType,
|
||||
rType: ConeKotlinType,
|
||||
context: CheckerContext,
|
||||
@@ -139,3 +277,83 @@ object FirEqualityCompatibilityChecker : FirEqualityOperatorCallChecker() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class TypeInfo(
|
||||
val type: ConeKotlinType,
|
||||
val notNullType: ConeKotlinType,
|
||||
val isFinalClass: Boolean,
|
||||
val isEnumClass: Boolean,
|
||||
val isPrimitive: Boolean,
|
||||
val isBuiltin: Boolean,
|
||||
val isValueClass: Boolean,
|
||||
val isLiterallyTypeParameter: Boolean,
|
||||
) {
|
||||
override fun toString() = "$type"
|
||||
}
|
||||
|
||||
private val FirClassSymbol<*>.isBuiltin get() = isPrimitiveType() || classId == StandardClassIds.String || isEnumClass
|
||||
|
||||
// This property is used to replicate K1 behavior, and it
|
||||
// tries to predict empty intersections from the K1 point-of-view.
|
||||
// Enum classes are final, but enum entries are their subclasses.
|
||||
private val TypeInfo.enforcesEmptyIntersection get() = isFinalClass && !isEnumClass
|
||||
|
||||
private val TypeInfo.isNullableEnum get() = isEnumClass && type.isNullable
|
||||
|
||||
private val TypeInfo.isIdentityLess get() = isPrimitive || !type.isNullable && isValueClass
|
||||
|
||||
private val FirClassSymbol<*>.isFinalClass get() = isClass && isFinal
|
||||
|
||||
// NB: This is what RULES1 means then it says "class".
|
||||
private val FirClassSymbol<*>.isClass get() = !isInterface
|
||||
|
||||
private fun ConeKotlinType.toTypeInfo(session: FirSession): TypeInfo {
|
||||
val bounds = collectUpperBounds().map { type -> toKotlinType(type).replaceArgumentsWithStarProjections() }
|
||||
val type = bounds.ifNotEmpty { ConeTypeIntersector.intersectTypes(session.typeContext, this) }
|
||||
?: session.builtinTypes.nullableAnyType.type
|
||||
val notNullType = type.withNullability(ConeNullability.NOT_NULL, session.typeContext)
|
||||
|
||||
return TypeInfo(
|
||||
type, notNullType,
|
||||
isFinalClass = bounds.any { it.toClassSymbol(session)?.isFinalClass == true },
|
||||
isEnumClass = bounds.any { it.toClassSymbol(session)?.isEnumClass == true },
|
||||
isPrimitive = bounds.any { it.isPrimitive },
|
||||
isBuiltin = bounds.any { it.toClassSymbol(session)?.isBuiltin == true },
|
||||
isValueClass = bounds.any { it.toClassSymbol(session)?.isInline == true },
|
||||
isLiterallyTypeParameter = this.lowerBoundIfFlexible() is ConeTypeParameterType,
|
||||
)
|
||||
}
|
||||
|
||||
private fun toKotlinType(type: ConeClassLikeType): ConeClassLikeType {
|
||||
// Type arguments are ignored by design
|
||||
return ConeClassLikeTypeImpl(type.lookupTag, type.typeArguments, type.isNullable)
|
||||
}
|
||||
|
||||
private class ArgumentInfo(
|
||||
val argument: FirExpression,
|
||||
val userType: ConeKotlinType,
|
||||
val originalType: ConeKotlinType,
|
||||
val session: FirSession,
|
||||
) {
|
||||
val smartCastType: ConeKotlinType by lazy {
|
||||
if (argument !is FirSmartCastExpression) originalType else userType.fullyExpandedType(session)
|
||||
}
|
||||
|
||||
val originalTypeInfo get() = originalType.toTypeInfo(session)
|
||||
|
||||
val smartCastTypeInfo get() = smartCastType.toTypeInfo(session)
|
||||
|
||||
override fun toString() = "${argument.source?.text} :: $userType"
|
||||
}
|
||||
|
||||
@Suppress("RecursivePropertyAccessor")
|
||||
private val FirExpression.mostOriginalTypeIfSmartCast: ConeKotlinType
|
||||
get() = when (this) {
|
||||
is FirSmartCastExpression -> originalExpression.mostOriginalTypeIfSmartCast
|
||||
else -> typeRef.coneType
|
||||
}
|
||||
|
||||
private fun FirExpression.toArgumentInfo(context: CheckerContext) =
|
||||
ArgumentInfo(
|
||||
this, typeRef.coneType, mostOriginalTypeIfSmartCast.fullyExpandedType(context.session), context.session,
|
||||
)
|
||||
|
||||
+35
@@ -221,7 +221,10 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FINAL_UPPER_BOUND
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FLOAT_LITERAL_OUT_OF_RANGE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATED_BINARY_MOD
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATED_IDENTITY_EQUALS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FORBIDDEN_BINARY_MOD
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FORBIDDEN_IDENTITY_EQUALS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FORBIDDEN_IDENTITY_EQUALS_WARNING
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FORBIDDEN_VARARG_PARAMETER_TYPE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUNCTION_CALL_EXPECTED
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUNCTION_DECLARATION_WITH_NO_NAME
|
||||
@@ -249,6 +252,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_SUSPEND_F
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_SUSPEND_PROPERTY_ACCESS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_UNDERSCORE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.IMPLEMENTATION_BY_DELEGATION_IN_EXPECT_CLASS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.IMPLICIT_BOXING_IN_IDENTITY_EQUALS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.IMPLICIT_NOTHING_PROPERTY_TYPE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.IMPLICIT_NOTHING_RETURN_TYPE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_CANDIDATE
|
||||
@@ -262,6 +266,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_TARG
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_TARGET_PROPERTY_HAS_NO_BACKING_FIELD
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_TARGET_PROPERTY_HAS_NO_DELEGATE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_TARGET_PROPERTY_IMMUTABLE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INCOMPATIBLE_ENUM_COMPARISON
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INCOMPATIBLE_ENUM_COMPARISON_ERROR
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INCOMPATIBLE_MODIFIERS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INCOMPATIBLE_TYPES
|
||||
@@ -2002,6 +2007,36 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
||||
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(
|
||||
FORBIDDEN_IDENTITY_EQUALS,
|
||||
"Identity equality for arguments of types {0} and {1} is forbidden",
|
||||
RENDER_TYPE,
|
||||
RENDER_TYPE
|
||||
)
|
||||
map.put(
|
||||
FORBIDDEN_IDENTITY_EQUALS_WARNING,
|
||||
"Identity equality for arguments of types {0} and {1} is forbidden",
|
||||
RENDER_TYPE,
|
||||
RENDER_TYPE
|
||||
)
|
||||
map.put(
|
||||
DEPRECATED_IDENTITY_EQUALS,
|
||||
"Identity equality for arguments of types {0} and {1} is deprecated",
|
||||
RENDER_TYPE,
|
||||
RENDER_TYPE
|
||||
)
|
||||
map.put(
|
||||
IMPLICIT_BOXING_IN_IDENTITY_EQUALS,
|
||||
"Identity equality for arguments of types {0} and {1} can be unstable because of implicit boxing",
|
||||
RENDER_TYPE,
|
||||
RENDER_TYPE
|
||||
)
|
||||
map.put(INC_DEC_SHOULD_NOT_RETURN_UNIT, "Functions inc(), dec() shouldn't return Unit to be used by operators ++, --")
|
||||
map.put(
|
||||
ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT,
|
||||
|
||||
@@ -23,10 +23,7 @@ import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
@@ -607,6 +604,10 @@ fun ConeKotlinType.toRegularClassSymbol(session: FirSession): FirRegularClassSym
|
||||
return (this as? ConeClassLikeType)?.toRegularClassSymbol(session)
|
||||
}
|
||||
|
||||
fun ConeClassLikeType.toClassSymbol(session: FirSession): FirClassSymbol<*>? {
|
||||
return fullyExpandedType(session).toSymbol(session) as? FirClassSymbol<*>
|
||||
}
|
||||
|
||||
private fun lowerThanBound(context: ConeInferenceContext, argument: ConeKotlinType, typeParameterSymbol: FirTypeParameterSymbol): Boolean {
|
||||
typeParameterSymbol.resolvedBounds.forEach { boundTypeRef ->
|
||||
if (argument != boundTypeRef.coneType && argument.isSubtypeOf(context, boundTypeRef.coneType)) {
|
||||
|
||||
+6
@@ -83,12 +83,18 @@ inline val FirClassSymbol<*>.isLocalClassOrAnonymousObject: Boolean
|
||||
get() = classId.isLocal || this is FirAnonymousObjectSymbol
|
||||
|
||||
|
||||
inline val FirClassSymbol<*>.isClass: Boolean
|
||||
get() = classKind.isClass
|
||||
|
||||
inline val FirClassSymbol<*>.isInterface: Boolean
|
||||
get() = classKind.isInterface
|
||||
|
||||
inline val FirClassSymbol<*>.isEnumClass: Boolean
|
||||
get() = classKind.isEnumClass
|
||||
|
||||
inline val FirClassSymbol<*>.isEnumEntry: Boolean
|
||||
get() = classKind.isEnumEntry
|
||||
|
||||
// ---------------------- specific callables ----------------------
|
||||
|
||||
inline val FirPropertyAccessorSymbol.allowsToHaveFakeOverride: Boolean get() = visibility.allowsToHaveFakeOverride
|
||||
|
||||
+10
-10
@@ -1,7 +1,7 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// TARGET_BACKEND: JS_IR
|
||||
// IGNORE_BACKEND_K1: JVM_IR, NATIVE, JS_IR, JS_IR_ES6
|
||||
// IGNORE_BACKEND_K1: NATIVE
|
||||
|
||||
const val minusOneVal = (-1).toByte()
|
||||
const val oneVal = 1.toByte()
|
||||
@@ -106,16 +106,16 @@ fun box(): String {
|
||||
if (plus3 != 5) return "Fail 2.3"
|
||||
if (plus4 != 4) return "Fail 2.4"
|
||||
if (plus5 != 4) return "Fail 2.5"
|
||||
if (plus6 != 4) return "Fail 2.6"
|
||||
if (plus6 != 4L) return "Fail 2.6"
|
||||
if (plus7 != 4.0f) return "Fail 2.7"
|
||||
if (plus8 != 4.0f) return "Fail 2.8"
|
||||
if (plus8 != 4.0) return "Fail 2.8"
|
||||
|
||||
if (minus1 != -1) return "Fail 3.1"
|
||||
if (minus2 != 0) return "Fail 3.2"
|
||||
if (minus3 != 1) return "Fail 3.3"
|
||||
if (minus4 != 0) return "Fail 3.4"
|
||||
if (minus5 != 0) return "Fail 3.5"
|
||||
if (minus6 != 0) return "Fail 3.6"
|
||||
if (minus6 != 0L) return "Fail 3.6"
|
||||
if (minus7 != 0.0f) return "Fail 3.7"
|
||||
if (minus8 != 0.0) return "Fail 3.8"
|
||||
|
||||
@@ -124,7 +124,7 @@ fun box(): String {
|
||||
if (times3 != 6) return "Fail 4.3"
|
||||
if (times4 != 4) return "Fail 4.4"
|
||||
if (times5 != 4) return "Fail 4.5"
|
||||
if (times6 != 4) return "Fail 4.6"
|
||||
if (times6 != 4L) return "Fail 4.6"
|
||||
if (times7 != 4.0f) return "Fail 4.7"
|
||||
if (times8 != 4.0) return "Fail 4.8"
|
||||
|
||||
@@ -133,7 +133,7 @@ fun box(): String {
|
||||
if (div3 != 1) return "Fail 5.3"
|
||||
if (div4 != 1) return "Fail 5.4"
|
||||
if (div5 != 1) return "Fail 5.5"
|
||||
if (div6 != 1) return "Fail 5.6"
|
||||
if (div6 != 1L) return "Fail 5.6"
|
||||
if (div7 != 1.0f) return "Fail 5.7"
|
||||
if (div8 != 1.0) return "Fail 5.8"
|
||||
|
||||
@@ -142,7 +142,7 @@ fun box(): String {
|
||||
if (rem3 != 1) return "Fail 6.3"
|
||||
if (rem4 != 0) return "Fail 6.4"
|
||||
if (rem5 != 0) return "Fail 6.5"
|
||||
if (rem6 != 0) return "Fail 6.6"
|
||||
if (rem6 != 0L) return "Fail 6.6"
|
||||
if (rem7 != 0.0f) return "Fail 6.7"
|
||||
if (rem8 != 0.0) return "Fail 6.8"
|
||||
|
||||
@@ -151,11 +151,11 @@ fun box(): String {
|
||||
if (unaryMinus1 != -1) return "Fail 7.3"
|
||||
if (unaryMinus2 != 1) return "Fail 7.4"
|
||||
|
||||
if (convert1 != 1) return "Fail 8.1"
|
||||
if (convert1 != 1.toByte()) return "Fail 8.1"
|
||||
if (convert2 != '') return "Fail 8.2"
|
||||
if (convert3 != 1) return "Fail 8.3"
|
||||
if (convert3 != 1.toShort()) return "Fail 8.3"
|
||||
if (convert4 != 1) return "Fail 8.4"
|
||||
if (convert5 != 1) return "Fail 8.5"
|
||||
if (convert5 != 1L) return "Fail 8.5"
|
||||
if (convert6 != 1.0f) return "Fail 8.6"
|
||||
if (convert7 != 1.0) return "Fail 8.7"
|
||||
|
||||
|
||||
+38
-38
@@ -1,7 +1,7 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// TARGET_BACKEND: JS_IR
|
||||
// IGNORE_BACKEND_K1: JVM_IR, NATIVE, JS_IR, JS_IR_ES6
|
||||
// IGNORE_BACKEND_K1: NATIVE
|
||||
|
||||
const val minusOneVal = -1.0
|
||||
const val oneVal = 1.0
|
||||
@@ -101,59 +101,59 @@ fun box(): String {
|
||||
if (compareTo7 != 0) return "Fail 1.7"
|
||||
if (compareTo8 != 0) return "Fail 1.8"
|
||||
|
||||
if (plus1 != 3) return "Fail 2.1"
|
||||
if (plus2 != 4) return "Fail 2.2"
|
||||
if (plus3 != 5) return "Fail 2.3"
|
||||
if (plus4 != 4) return "Fail 2.4"
|
||||
if (plus5 != 4) return "Fail 2.5"
|
||||
if (plus6 != 4) return "Fail 2.6"
|
||||
if (plus7 != 4.0f) return "Fail 2.7"
|
||||
if (plus1 != 3.0) return "Fail 2.1"
|
||||
if (plus2 != 4.0) return "Fail 2.2"
|
||||
if (plus3 != 5.0) return "Fail 2.3"
|
||||
if (plus4 != 4.0) return "Fail 2.4"
|
||||
if (plus5 != 4.0) return "Fail 2.5"
|
||||
if (plus6 != 4.0) return "Fail 2.6"
|
||||
if (plus7 != 4.0) return "Fail 2.7"
|
||||
if (plus8 != 4.0) return "Fail 2.8"
|
||||
|
||||
if (minus1 != -1) return "Fail 3.1"
|
||||
if (minus2 != 0) return "Fail 3.2"
|
||||
if (minus3 != 1) return "Fail 3.3"
|
||||
if (minus4 != 0) return "Fail 3.4"
|
||||
if (minus5 != 0) return "Fail 3.5"
|
||||
if (minus6 != 0) return "Fail 3.6"
|
||||
if (minus7 != 0.0f) return "Fail 3.7"
|
||||
if (minus1 != -1.0) return "Fail 3.1"
|
||||
if (minus2 != 0.0) return "Fail 3.2"
|
||||
if (minus3 != 1.0) return "Fail 3.3"
|
||||
if (minus4 != 0.0) return "Fail 3.4"
|
||||
if (minus5 != 0.0) return "Fail 3.5"
|
||||
if (minus6 != 0.0) return "Fail 3.6"
|
||||
if (minus7 != 0.0) return "Fail 3.7"
|
||||
if (minus8 != 0.0) return "Fail 3.8"
|
||||
|
||||
if (times1 != 2) return "Fail 4.1"
|
||||
if (times2 != 4) return "Fail 4.2"
|
||||
if (times3 != 6) return "Fail 4.3"
|
||||
if (times4 != 4) return "Fail 4.4"
|
||||
if (times5 != 4) return "Fail 4.5"
|
||||
if (times6 != 4) return "Fail 4.6"
|
||||
if (times7 != 4.0f) return "Fail 4.7"
|
||||
if (times1 != 2.0) return "Fail 4.1"
|
||||
if (times2 != 4.0) return "Fail 4.2"
|
||||
if (times3 != 6.0) return "Fail 4.3"
|
||||
if (times4 != 4.0) return "Fail 4.4"
|
||||
if (times5 != 4.0) return "Fail 4.5"
|
||||
if (times6 != 4.0) return "Fail 4.6"
|
||||
if (times7 != 4.0) return "Fail 4.7"
|
||||
if (times8 != 4.0) return "Fail 4.8"
|
||||
|
||||
if (div1 != 0.5) return "Fail 5.1"
|
||||
if (div2 != 1.0) return "Fail 5.2"
|
||||
if (div3 != 1.5) return "Fail 5.3"
|
||||
if (div4 != 1) return "Fail 5.4"
|
||||
if (div5 != 1) return "Fail 5.5"
|
||||
if (div6 != 1) return "Fail 5.6"
|
||||
if (div7 != 1.0f) return "Fail 5.7"
|
||||
if (div4 != 1.0) return "Fail 5.4"
|
||||
if (div5 != 1.0) return "Fail 5.5"
|
||||
if (div6 != 1.0) return "Fail 5.6"
|
||||
if (div7 != 1.0) return "Fail 5.7"
|
||||
if (div8 != 1.0) return "Fail 5.8"
|
||||
|
||||
if (rem1 != 1) return "Fail 6.1"
|
||||
if (rem2 != 0) return "Fail 6.2"
|
||||
if (rem3 != 1) return "Fail 6.3"
|
||||
if (rem4 != 0) return "Fail 6.4"
|
||||
if (rem5 != 0) return "Fail 6.5"
|
||||
if (rem6 != 0) return "Fail 6.6"
|
||||
if (rem7 != 0.0f) return "Fail 6.7"
|
||||
if (rem1 != 1.0) return "Fail 6.1"
|
||||
if (rem2 != 0.0) return "Fail 6.2"
|
||||
if (rem3 != 1.0) return "Fail 6.3"
|
||||
if (rem4 != 0.0) return "Fail 6.4"
|
||||
if (rem5 != 0.0) return "Fail 6.5"
|
||||
if (rem6 != 0.0) return "Fail 6.6"
|
||||
if (rem7 != 0.0) return "Fail 6.7"
|
||||
if (rem8 != 0.0) return "Fail 6.8"
|
||||
|
||||
if (unaryPlus1 != 1) return "Fail 7.1"
|
||||
if (unaryPlus2 != -1) return "Fail 7.2"
|
||||
if (unaryMinus1 != -1) return "Fail 7.3"
|
||||
if (unaryMinus2 != 1) return "Fail 7.4"
|
||||
if (unaryPlus1 != 1.0) return "Fail 7.1"
|
||||
if (unaryPlus2 != -1.0) return "Fail 7.2"
|
||||
if (unaryMinus1 != -1.0) return "Fail 7.3"
|
||||
if (unaryMinus2 != 1.0) return "Fail 7.4"
|
||||
|
||||
if (convert1 != '') return "Fail 8.1"
|
||||
if (convert2 != 1) return "Fail 8.2"
|
||||
if (convert3 != 1) return "Fail 8.3"
|
||||
if (convert3 != 1L) return "Fail 8.3"
|
||||
if (convert4 != 1.0f) return "Fail 8.4"
|
||||
if (convert5 != 1.0) return "Fail 8.5"
|
||||
|
||||
|
||||
+33
-33
@@ -1,7 +1,7 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// TARGET_BACKEND: JS_IR
|
||||
// IGNORE_BACKEND_K1: JVM_IR, NATIVE, JS_IR, JS_IR_ES6
|
||||
// IGNORE_BACKEND_K1: NATIVE
|
||||
|
||||
const val minusOneVal = -1.0f
|
||||
const val oneVal = 1.0f
|
||||
@@ -101,59 +101,59 @@ fun box(): String {
|
||||
if (compareTo7 != 0) return "Fail 1.7"
|
||||
if (compareTo8 != 0) return "Fail 1.8"
|
||||
|
||||
if (plus1 != 3) return "Fail 2.1"
|
||||
if (plus2 != 4) return "Fail 2.2"
|
||||
if (plus3 != 5) return "Fail 2.3"
|
||||
if (plus4 != 4) return "Fail 2.4"
|
||||
if (plus5 != 4) return "Fail 2.5"
|
||||
if (plus6 != 4) return "Fail 2.6"
|
||||
if (plus1 != 3f) return "Fail 2.1"
|
||||
if (plus2 != 4f) return "Fail 2.2"
|
||||
if (plus3 != 5f) return "Fail 2.3"
|
||||
if (plus4 != 4f) return "Fail 2.4"
|
||||
if (plus5 != 4f) return "Fail 2.5"
|
||||
if (plus6 != 4f) return "Fail 2.6"
|
||||
if (plus7 != 4.0f) return "Fail 2.7"
|
||||
if (plus8 != 4.0) return "Fail 2.8"
|
||||
|
||||
if (minus1 != -1) return "Fail 3.1"
|
||||
if (minus2 != 0) return "Fail 3.2"
|
||||
if (minus3 != 1) return "Fail 3.3"
|
||||
if (minus4 != 0) return "Fail 3.4"
|
||||
if (minus5 != 0) return "Fail 3.5"
|
||||
if (minus6 != 0) return "Fail 3.6"
|
||||
if (minus1 != -1f) return "Fail 3.1"
|
||||
if (minus2 != 0f) return "Fail 3.2"
|
||||
if (minus3 != 1f) return "Fail 3.3"
|
||||
if (minus4 != 0f) return "Fail 3.4"
|
||||
if (minus5 != 0f) return "Fail 3.5"
|
||||
if (minus6 != 0f) return "Fail 3.6"
|
||||
if (minus7 != 0.0f) return "Fail 3.7"
|
||||
if (minus8 != 0.0) return "Fail 3.8"
|
||||
|
||||
if (times1 != 2) return "Fail 4.1"
|
||||
if (times2 != 4) return "Fail 4.2"
|
||||
if (times3 != 6) return "Fail 4.3"
|
||||
if (times4 != 4) return "Fail 4.4"
|
||||
if (times5 != 4) return "Fail 4.5"
|
||||
if (times6 != 4) return "Fail 4.6"
|
||||
if (times1 != 2f) return "Fail 4.1"
|
||||
if (times2 != 4f) return "Fail 4.2"
|
||||
if (times3 != 6f) return "Fail 4.3"
|
||||
if (times4 != 4f) return "Fail 4.4"
|
||||
if (times5 != 4f) return "Fail 4.5"
|
||||
if (times6 != 4f) return "Fail 4.6"
|
||||
if (times7 != 4.0f) return "Fail 4.7"
|
||||
if (times8 != 4.0) return "Fail 4.8"
|
||||
|
||||
if (div1 != 0.5f) return "Fail 5.1"
|
||||
if (div2 != 1.0f) return "Fail 5.2"
|
||||
if (div3 != 1.5f) return "Fail 5.3"
|
||||
if (div4 != 1) return "Fail 5.4"
|
||||
if (div5 != 1) return "Fail 5.5"
|
||||
if (div6 != 1) return "Fail 5.6"
|
||||
if (div4 != 1f) return "Fail 5.4"
|
||||
if (div5 != 1f) return "Fail 5.5"
|
||||
if (div6 != 1f) return "Fail 5.6"
|
||||
if (div7 != 1.0f) return "Fail 5.7"
|
||||
if (div8 != 1.0) return "Fail 5.8"
|
||||
|
||||
if (rem1 != 1) return "Fail 6.1"
|
||||
if (rem2 != 0) return "Fail 6.2"
|
||||
if (rem3 != 1) return "Fail 6.3"
|
||||
if (rem4 != 0) return "Fail 6.4"
|
||||
if (rem5 != 0) return "Fail 6.5"
|
||||
if (rem6 != 0) return "Fail 6.6"
|
||||
if (rem1 != 1f) return "Fail 6.1"
|
||||
if (rem2 != 0f) return "Fail 6.2"
|
||||
if (rem3 != 1f) return "Fail 6.3"
|
||||
if (rem4 != 0f) return "Fail 6.4"
|
||||
if (rem5 != 0f) return "Fail 6.5"
|
||||
if (rem6 != 0f) return "Fail 6.6"
|
||||
if (rem7 != 0.0f) return "Fail 6.7"
|
||||
if (rem8 != 0.0) return "Fail 6.8"
|
||||
|
||||
if (unaryPlus1 != 1) return "Fail 7.1"
|
||||
if (unaryPlus2 != -1) return "Fail 7.2"
|
||||
if (unaryMinus1 != -1) return "Fail 7.3"
|
||||
if (unaryMinus2 != 1) return "Fail 7.4"
|
||||
if (unaryPlus1 != 1f) return "Fail 7.1"
|
||||
if (unaryPlus2 != -1f) return "Fail 7.2"
|
||||
if (unaryMinus1 != -1f) return "Fail 7.3"
|
||||
if (unaryMinus2 != 1f) return "Fail 7.4"
|
||||
|
||||
if (convert1 != '') return "Fail 8.1"
|
||||
if (convert2 != 1) return "Fail 8.2"
|
||||
if (convert3 != 1) return "Fail 8.3"
|
||||
if (convert3 != 1L) return "Fail 8.3"
|
||||
if (convert4 != 1.0f) return "Fail 8.4"
|
||||
if (convert5 != 1.0) return "Fail 8.5"
|
||||
|
||||
|
||||
+9
-9
@@ -1,7 +1,7 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// TARGET_BACKEND: JS_IR
|
||||
// IGNORE_BACKEND_K1: JVM_IR, NATIVE, JS_IR, JS_IR_ES6
|
||||
// IGNORE_BACKEND_K1: NATIVE
|
||||
|
||||
const val minusOneVal = -1
|
||||
const val oneVal = 1
|
||||
@@ -106,7 +106,7 @@ fun box(): String {
|
||||
if (plus3 != 5) return "Fail 2.3"
|
||||
if (plus4 != 4) return "Fail 2.4"
|
||||
if (plus5 != 4) return "Fail 2.5"
|
||||
if (plus6 != 4) return "Fail 2.6"
|
||||
if (plus6 != 4L) return "Fail 2.6"
|
||||
if (plus7 != 4.0f) return "Fail 2.7"
|
||||
if (plus8 != 4.0) return "Fail 2.8"
|
||||
|
||||
@@ -115,7 +115,7 @@ fun box(): String {
|
||||
if (minus3 != 1) return "Fail 3.3"
|
||||
if (minus4 != 0) return "Fail 3.4"
|
||||
if (minus5 != 0) return "Fail 3.5"
|
||||
if (minus6 != 0) return "Fail 3.6"
|
||||
if (minus6 != 0L) return "Fail 3.6"
|
||||
if (minus7 != 0.0f) return "Fail 3.7"
|
||||
if (minus8 != 0.0) return "Fail 3.8"
|
||||
|
||||
@@ -124,7 +124,7 @@ fun box(): String {
|
||||
if (times3 != 6) return "Fail 4.3"
|
||||
if (times4 != 4) return "Fail 4.4"
|
||||
if (times5 != 4) return "Fail 4.5"
|
||||
if (times6 != 4) return "Fail 4.6"
|
||||
if (times6 != 4L) return "Fail 4.6"
|
||||
if (times7 != 4.0f) return "Fail 4.7"
|
||||
if (times8 != 4.0) return "Fail 4.8"
|
||||
|
||||
@@ -133,7 +133,7 @@ fun box(): String {
|
||||
if (div3 != 1) return "Fail 5.3"
|
||||
if (div4 != 1) return "Fail 5.4"
|
||||
if (div5 != 1) return "Fail 5.5"
|
||||
if (div6 != 1) return "Fail 5.6"
|
||||
if (div6 != 1L) return "Fail 5.6"
|
||||
if (div7 != 1.0f) return "Fail 5.7"
|
||||
if (div8 != 1.0) return "Fail 5.8"
|
||||
|
||||
@@ -142,7 +142,7 @@ fun box(): String {
|
||||
if (rem3 != 1) return "Fail 6.3"
|
||||
if (rem4 != 0) return "Fail 6.4"
|
||||
if (rem5 != 0) return "Fail 6.5"
|
||||
if (rem6 != 0) return "Fail 6.6"
|
||||
if (rem6 != 0L) return "Fail 6.6"
|
||||
if (rem7 != 0.0f) return "Fail 6.7"
|
||||
if (rem8 != 0.0) return "Fail 6.8"
|
||||
|
||||
@@ -151,11 +151,11 @@ fun box(): String {
|
||||
if (unaryMinus1 != -1) return "Fail 7.3"
|
||||
if (unaryMinus2 != 1) return "Fail 7.4"
|
||||
|
||||
if (convert1 != 1) return "Fail 8.1"
|
||||
if (convert1 != 1.toByte()) return "Fail 8.1"
|
||||
if (convert2 != '') return "Fail 8.2"
|
||||
if (convert3 != 1) return "Fail 8.3"
|
||||
if (convert3 != 1.toShort()) return "Fail 8.3"
|
||||
if (convert4 != 1) return "Fail 8.4"
|
||||
if (convert5 != 1) return "Fail 8.5"
|
||||
if (convert5 != 1L) return "Fail 8.5"
|
||||
if (convert6 != 1.0f) return "Fail 8.6"
|
||||
if (convert7 != 1.0) return "Fail 8.7"
|
||||
|
||||
|
||||
+38
-38
@@ -1,7 +1,7 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// TARGET_BACKEND: JS_IR
|
||||
// IGNORE_BACKEND_K1: JVM_IR, NATIVE, JS_IR, JS_IR_ES6
|
||||
// IGNORE_BACKEND_K1: NATIVE
|
||||
|
||||
const val minusOneVal = -1L
|
||||
const val oneVal = 1L
|
||||
@@ -101,61 +101,61 @@ fun box(): String {
|
||||
if (compareTo7 != 0) return "Fail 1.7"
|
||||
if (compareTo8 != 0) return "Fail 1.8"
|
||||
|
||||
if (plus1 != 3) return "Fail 2.1"
|
||||
if (plus2 != 4) return "Fail 2.2"
|
||||
if (plus3 != 5) return "Fail 2.3"
|
||||
if (plus4 != 4) return "Fail 2.4"
|
||||
if (plus5 != 4) return "Fail 2.5"
|
||||
if (plus6 != 4) return "Fail 2.6"
|
||||
if (plus1 != 3L) return "Fail 2.1"
|
||||
if (plus2 != 4L) return "Fail 2.2"
|
||||
if (plus3 != 5L) return "Fail 2.3"
|
||||
if (plus4 != 4L) return "Fail 2.4"
|
||||
if (plus5 != 4L) return "Fail 2.5"
|
||||
if (plus6 != 4L) return "Fail 2.6"
|
||||
if (plus7 != 4.0f) return "Fail 2.7"
|
||||
if (plus8 != 4.0) return "Fail 2.8"
|
||||
|
||||
if (minus1 != -1) return "Fail 3.1"
|
||||
if (minus2 != 0) return "Fail 3.2"
|
||||
if (minus3 != 1) return "Fail 3.3"
|
||||
if (minus4 != 0) return "Fail 3.4"
|
||||
if (minus5 != 0) return "Fail 3.5"
|
||||
if (minus6 != 0) return "Fail 3.6"
|
||||
if (minus1 != -1L) return "Fail 3.1"
|
||||
if (minus2 != 0L) return "Fail 3.2"
|
||||
if (minus3 != 1L) return "Fail 3.3"
|
||||
if (minus4 != 0L) return "Fail 3.4"
|
||||
if (minus5 != 0L) return "Fail 3.5"
|
||||
if (minus6 != 0L) return "Fail 3.6"
|
||||
if (minus7 != 0.0f) return "Fail 3.7"
|
||||
if (minus8 != 0.0) return "Fail 3.8"
|
||||
|
||||
if (times1 != 2) return "Fail 4.1"
|
||||
if (times2 != 4) return "Fail 4.2"
|
||||
if (times3 != 6) return "Fail 4.3"
|
||||
if (times4 != 4) return "Fail 4.4"
|
||||
if (times5 != 4) return "Fail 4.5"
|
||||
if (times6 != 4) return "Fail 4.6"
|
||||
if (times1 != 2L) return "Fail 4.1"
|
||||
if (times2 != 4L) return "Fail 4.2"
|
||||
if (times3 != 6L) return "Fail 4.3"
|
||||
if (times4 != 4L) return "Fail 4.4"
|
||||
if (times5 != 4L) return "Fail 4.5"
|
||||
if (times6 != 4L) return "Fail 4.6"
|
||||
if (times7 != 4.0f) return "Fail 4.7"
|
||||
if (times8 != 4.0) return "Fail 4.8"
|
||||
|
||||
if (div1 != 0) return "Fail 5.1"
|
||||
if (div2 != 1) return "Fail 5.2"
|
||||
if (div3 != 1) return "Fail 5.3"
|
||||
if (div4 != 1) return "Fail 5.4"
|
||||
if (div5 != 1) return "Fail 5.5"
|
||||
if (div6 != 1) return "Fail 5.6"
|
||||
if (div1 != 0L) return "Fail 5.1"
|
||||
if (div2 != 1L) return "Fail 5.2"
|
||||
if (div3 != 1L) return "Fail 5.3"
|
||||
if (div4 != 1L) return "Fail 5.4"
|
||||
if (div5 != 1L) return "Fail 5.5"
|
||||
if (div6 != 1L) return "Fail 5.6"
|
||||
if (div7 != 1.0f) return "Fail 5.7"
|
||||
if (div8 != 1.0) return "Fail 5.8"
|
||||
|
||||
if (rem1 != 1) return "Fail 6.1"
|
||||
if (rem2 != 0) return "Fail 6.2"
|
||||
if (rem3 != 1) return "Fail 6.3"
|
||||
if (rem4 != 0) return "Fail 6.4"
|
||||
if (rem5 != 0) return "Fail 6.5"
|
||||
if (rem6 != 0) return "Fail 6.6"
|
||||
if (rem1 != 1L) return "Fail 6.1"
|
||||
if (rem2 != 0L) return "Fail 6.2"
|
||||
if (rem3 != 1L) return "Fail 6.3"
|
||||
if (rem4 != 0L) return "Fail 6.4"
|
||||
if (rem5 != 0L) return "Fail 6.5"
|
||||
if (rem6 != 0L) return "Fail 6.6"
|
||||
if (rem7 != 0.0f) return "Fail 6.7"
|
||||
if (rem8 != 0.0) return "Fail 6.8"
|
||||
|
||||
if (unaryPlus1 != 1) return "Fail 7.1"
|
||||
if (unaryPlus2 != -1) return "Fail 7.2"
|
||||
if (unaryMinus1 != -1) return "Fail 7.3"
|
||||
if (unaryMinus2 != 1) return "Fail 7.4"
|
||||
if (unaryPlus1 != 1L) return "Fail 7.1"
|
||||
if (unaryPlus2 != -1L) return "Fail 7.2"
|
||||
if (unaryMinus1 != -1L) return "Fail 7.3"
|
||||
if (unaryMinus2 != 1L) return "Fail 7.4"
|
||||
|
||||
if (convert1 != 1) return "Fail 8.1"
|
||||
if (convert1 != 1.toByte()) return "Fail 8.1"
|
||||
if (convert2 != '') return "Fail 8.2"
|
||||
if (convert3 != 1) return "Fail 8.3"
|
||||
if (convert3 != 1.toShort()) return "Fail 8.3"
|
||||
if (convert4 != 1) return "Fail 8.4"
|
||||
if (convert5 != 1) return "Fail 8.5"
|
||||
if (convert5 != 1L) return "Fail 8.5"
|
||||
if (convert6 != 1.0f) return "Fail 8.6"
|
||||
if (convert7 != 1.0) return "Fail 8.7"
|
||||
|
||||
|
||||
+9
-9
@@ -1,7 +1,7 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// TARGET_BACKEND: JS_IR
|
||||
// IGNORE_BACKEND_K1: JVM_IR, NATIVE, JS_IR, JS_IR_ES6
|
||||
// IGNORE_BACKEND_K1: NATIVE
|
||||
|
||||
const val minusOneVal = (-1).toShort()
|
||||
const val oneVal = 1.toShort()
|
||||
@@ -106,7 +106,7 @@ fun box(): String {
|
||||
if (plus3 != 5) return "Fail 2.3"
|
||||
if (plus4 != 4) return "Fail 2.4"
|
||||
if (plus5 != 4) return "Fail 2.5"
|
||||
if (plus6 != 4) return "Fail 2.6"
|
||||
if (plus6 != 4L) return "Fail 2.6"
|
||||
if (plus7 != 4.0f) return "Fail 2.7"
|
||||
if (plus8 != 4.0) return "Fail 2.8"
|
||||
|
||||
@@ -115,7 +115,7 @@ fun box(): String {
|
||||
if (minus3 != 1) return "Fail 3.3"
|
||||
if (minus4 != 0) return "Fail 3.4"
|
||||
if (minus5 != 0) return "Fail 3.5"
|
||||
if (minus6 != 0) return "Fail 3.6"
|
||||
if (minus6 != 0L) return "Fail 3.6"
|
||||
if (minus7 != 0.0f) return "Fail 3.7"
|
||||
if (minus8 != 0.0) return "Fail 3.8"
|
||||
|
||||
@@ -124,7 +124,7 @@ fun box(): String {
|
||||
if (times3 != 6) return "Fail 4.3"
|
||||
if (times4 != 4) return "Fail 4.4"
|
||||
if (times5 != 4) return "Fail 4.5"
|
||||
if (times6 != 4) return "Fail 4.6"
|
||||
if (times6 != 4L) return "Fail 4.6"
|
||||
if (times7 != 4.0f) return "Fail 4.7"
|
||||
if (times8 != 4.0) return "Fail 4.8"
|
||||
|
||||
@@ -133,7 +133,7 @@ fun box(): String {
|
||||
if (div3 != 1) return "Fail 5.3"
|
||||
if (div4 != 1) return "Fail 5.4"
|
||||
if (div5 != 1) return "Fail 5.5"
|
||||
if (div6 != 1) return "Fail 5.6"
|
||||
if (div6 != 1L) return "Fail 5.6"
|
||||
if (div7 != 1.0f) return "Fail 5.7"
|
||||
if (div8 != 1.0) return "Fail 5.8"
|
||||
|
||||
@@ -142,7 +142,7 @@ fun box(): String {
|
||||
if (rem3 != 1) return "Fail 6.3"
|
||||
if (rem4 != 0) return "Fail 6.4"
|
||||
if (rem5 != 0) return "Fail 6.5"
|
||||
if (rem6 != 0) return "Fail 6.6"
|
||||
if (rem6 != 0L) return "Fail 6.6"
|
||||
if (rem7 != 0.0f) return "Fail 6.7"
|
||||
if (rem8 != 0.0) return "Fail 6.8"
|
||||
|
||||
@@ -151,11 +151,11 @@ fun box(): String {
|
||||
if (unaryMinus1 != -1) return "Fail 7.3"
|
||||
if (unaryMinus2 != 1) return "Fail 7.4"
|
||||
|
||||
if (convert1 != 1) return "Fail 8.1"
|
||||
if (convert1 != 1.toByte()) return "Fail 8.1"
|
||||
if (convert2 != '') return "Fail 8.2"
|
||||
if (convert3 != 1) return "Fail 8.3"
|
||||
if (convert3 != 1.toShort()) return "Fail 8.3"
|
||||
if (convert4 != 1) return "Fail 8.4"
|
||||
if (convert5 != 1) return "Fail 8.5"
|
||||
if (convert5 != 1L) return "Fail 8.5"
|
||||
if (convert6 != 1.0f) return "Fail 8.6"
|
||||
if (convert7 != 1.0) return "Fail 8.7"
|
||||
|
||||
|
||||
@@ -10,16 +10,16 @@ fun f(): Unit {
|
||||
x <!UNSAFE_OPERATOR_CALL!><<!> 1
|
||||
<!ASSIGNMENT_TYPE_MISMATCH!>x += 1<!>
|
||||
|
||||
x == 1
|
||||
x != 1
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>x == 1<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>x != 1<!>
|
||||
|
||||
<!EQUALITY_NOT_APPLICABLE!>A() == 1<!>
|
||||
|
||||
x === "1"
|
||||
x !== "1"
|
||||
<!EQUALITY_NOT_APPLICABLE!>x === "1"<!>
|
||||
<!EQUALITY_NOT_APPLICABLE!>x !== "1"<!>
|
||||
|
||||
x === 1
|
||||
x !== 1
|
||||
<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>x === 1<!>
|
||||
<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>x !== 1<!>
|
||||
|
||||
x..2
|
||||
x in 1..2
|
||||
|
||||
+45
-45
@@ -22,60 +22,60 @@ val a: Any = 0
|
||||
val na: Any? = 0
|
||||
|
||||
// Identity for primitive values of same type
|
||||
val test_zz = z === z || z !== z
|
||||
val test_bb = b === b || b !== b
|
||||
val test_ss = s === s || s !== s
|
||||
val test_ii = i === i || i !== i
|
||||
val test_jj = j === j || j !== j
|
||||
val test_ff = f === f || f !== f
|
||||
val test_dd = d === d || d !== d
|
||||
val test_cc = c === c || c !== c
|
||||
val test_zz = <!DEPRECATED_IDENTITY_EQUALS!>z === z<!> || <!DEPRECATED_IDENTITY_EQUALS!>z !== z<!>
|
||||
val test_bb = <!DEPRECATED_IDENTITY_EQUALS!>b === b<!> || <!DEPRECATED_IDENTITY_EQUALS!>b !== b<!>
|
||||
val test_ss = <!DEPRECATED_IDENTITY_EQUALS!>s === s<!> || <!DEPRECATED_IDENTITY_EQUALS!>s !== s<!>
|
||||
val test_ii = <!DEPRECATED_IDENTITY_EQUALS!>i === i<!> || <!DEPRECATED_IDENTITY_EQUALS!>i !== i<!>
|
||||
val test_jj = <!DEPRECATED_IDENTITY_EQUALS!>j === j<!> || <!DEPRECATED_IDENTITY_EQUALS!>j !== j<!>
|
||||
val test_ff = <!DEPRECATED_IDENTITY_EQUALS!>f === f<!> || <!DEPRECATED_IDENTITY_EQUALS!>f !== f<!>
|
||||
val test_dd = <!DEPRECATED_IDENTITY_EQUALS!>d === d<!> || <!DEPRECATED_IDENTITY_EQUALS!>d !== d<!>
|
||||
val test_cc = <!DEPRECATED_IDENTITY_EQUALS!>c === c<!> || <!DEPRECATED_IDENTITY_EQUALS!>c !== c<!>
|
||||
|
||||
// Identity for primitive values of different types (no extra error)
|
||||
val test_zb = <!EQUALITY_NOT_APPLICABLE_WARNING!>z === b<!> || <!EQUALITY_NOT_APPLICABLE_WARNING!>z !== b<!>
|
||||
val test_zb = <!FORBIDDEN_IDENTITY_EQUALS!>z === b<!> || <!FORBIDDEN_IDENTITY_EQUALS!>z !== b<!>
|
||||
|
||||
// Primitive vs nullable
|
||||
val test_znz = z === nz || nz === z || z !== nz || nz !== z
|
||||
val test_bnb = b === nb || nb === b || b !== nb || nb !== b
|
||||
val test_sns = s === ns || ns === s || s !== ns || ns !== s
|
||||
val test_ini = i === ni || ni === i || i !== ni || ni !== i
|
||||
val test_jnj = j === nj || nj === j || j !== nj || nj !== j
|
||||
val test_fnf = f === nf || nf === f || f !== nf || nf !== f
|
||||
val test_dnd = d === nd || nd === d || d !== nd || nd !== d
|
||||
val test_cnc = c === nc || nc === c || c !== nc || nc !== c
|
||||
val test_znz = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>z === nz<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>nz === z<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>z !== nz<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>nz !== z<!>
|
||||
val test_bnb = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>b === nb<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>nb === b<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>b !== nb<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>nb !== b<!>
|
||||
val test_sns = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>s === ns<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>ns === s<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>s !== ns<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>ns !== s<!>
|
||||
val test_ini = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>i === ni<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>ni === i<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>i !== ni<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>ni !== i<!>
|
||||
val test_jnj = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>j === nj<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>nj === j<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>j !== nj<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>nj !== j<!>
|
||||
val test_fnf = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>f === nf<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>nf === f<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>f !== nf<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>nf !== f<!>
|
||||
val test_dnd = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>d === nd<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>nd === d<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>d !== nd<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>nd !== d<!>
|
||||
val test_cnc = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>c === nc<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>nc === c<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>c !== nc<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>nc !== c<!>
|
||||
|
||||
// Primitive number vs Number
|
||||
val test_bn = b === n || n === b || b !== n || n !== b
|
||||
val test_sn = s === n || n === s || s !== n || n !== s
|
||||
val test_in = i === n || n === i || i !== n || n !== i
|
||||
val test_jn = j === n || n === j || j !== n || n !== j
|
||||
val test_fn = f === n || n === f || f !== n || n !== f
|
||||
val test_dn = d === n || n === d || d !== n || n !== d
|
||||
val test_bn = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>b === n<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>n === b<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>b !== n<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>n !== b<!>
|
||||
val test_sn = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>s === n<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>n === s<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>s !== n<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>n !== s<!>
|
||||
val test_in = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>i === n<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>n === i<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>i !== n<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>n !== i<!>
|
||||
val test_jn = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>j === n<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>n === j<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>j !== n<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>n !== j<!>
|
||||
val test_fn = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>f === n<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>n === f<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>f !== n<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>n !== f<!>
|
||||
val test_dn = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>d === n<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>n === d<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>d !== n<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>n !== d<!>
|
||||
|
||||
// Primitive number vs Number?
|
||||
val test_bnn = b === nn || nn === b || b !== nn || nn !== b
|
||||
val test_snn = s === nn || nn === s || s !== nn || nn !== s
|
||||
val test_inn = i === nn || nn === i || i !== nn || nn !== i
|
||||
val test_jnn = j === nn || nn === j || j !== nn || nn !== j
|
||||
val test_fnn = f === nn || nn === f || f !== nn || nn !== f
|
||||
val test_dnn = d === nn || nn === d || d !== nn || nn !== d
|
||||
val test_bnn = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>b === nn<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>nn === b<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>b !== nn<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>nn !== b<!>
|
||||
val test_snn = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>s === nn<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>nn === s<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>s !== nn<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>nn !== s<!>
|
||||
val test_inn = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>i === nn<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>nn === i<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>i !== nn<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>nn !== i<!>
|
||||
val test_jnn = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>j === nn<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>nn === j<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>j !== nn<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>nn !== j<!>
|
||||
val test_fnn = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>f === nn<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>nn === f<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>f !== nn<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>nn !== f<!>
|
||||
val test_dnn = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>d === nn<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>nn === d<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>d !== nn<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>nn !== d<!>
|
||||
|
||||
// Primitive vs Any
|
||||
val test_za = z === a || a === z || z !== a || a !== z
|
||||
val test_ba = b === a || a === b || b !== a || a !== b
|
||||
val test_sa = s === a || a === s || s !== a || a !== s
|
||||
val test_ia = i === a || a === i || i !== a || a !== i
|
||||
val test_ja = j === a || a === j || j !== a || a !== j
|
||||
val test_fa = f === a || a === f || f !== a || a !== f
|
||||
val test_da = d === a || a === d || d !== a || a !== d
|
||||
val test_ca = c === a || a === c || c !== a || a !== c
|
||||
val test_za = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>z === a<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a === z<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>z !== a<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a !== z<!>
|
||||
val test_ba = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>b === a<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a === b<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>b !== a<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a !== b<!>
|
||||
val test_sa = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>s === a<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a === s<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>s !== a<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a !== s<!>
|
||||
val test_ia = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>i === a<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a === i<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>i !== a<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a !== i<!>
|
||||
val test_ja = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>j === a<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a === j<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>j !== a<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a !== j<!>
|
||||
val test_fa = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>f === a<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a === f<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>f !== a<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a !== f<!>
|
||||
val test_da = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>d === a<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a === d<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>d !== a<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a !== d<!>
|
||||
val test_ca = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>c === a<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a === c<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>c !== a<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a !== c<!>
|
||||
|
||||
// Primitive vs Any?
|
||||
val test_zna = z === na || na === z || z !== na || na !== z
|
||||
val test_bna = b === na || na === b || b !== na || na !== b
|
||||
val test_sna = s === na || na === s || s !== na || na !== s
|
||||
val test_ina = i === na || na === i || i !== na || na !== i
|
||||
val test_jna = j === na || na === j || j !== na || na !== j
|
||||
val test_fna = f === na || na === f || f !== na || na !== f
|
||||
val test_dna = d === na || na === d || d !== na || na !== d
|
||||
val test_cna = c === na || na === c || c !== na || na !== c
|
||||
val test_zna = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>z === na<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>na === z<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>z !== na<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>na !== z<!>
|
||||
val test_bna = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>b === na<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>na === b<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>b !== na<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>na !== b<!>
|
||||
val test_sna = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>s === na<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>na === s<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>s !== na<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>na !== s<!>
|
||||
val test_ina = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>i === na<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>na === i<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>i !== na<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>na !== i<!>
|
||||
val test_jna = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>j === na<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>na === j<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>j !== na<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>na !== j<!>
|
||||
val test_fna = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>f === na<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>na === f<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>f !== na<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>na !== f<!>
|
||||
val test_dna = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>d === na<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>na === d<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>d !== na<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>na !== d<!>
|
||||
val test_cna = <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>c === na<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>na === c<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>c !== na<!> || <!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>na !== c<!>
|
||||
|
||||
+1
-1
@@ -5,5 +5,5 @@ class Bar3 : Foo<Bar3>
|
||||
|
||||
fun test(b1: Bar1, b2: Bar2, b3: Bar3) {
|
||||
b1 == b2
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>b1 == b3<!>
|
||||
b1 == b3
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
// ISSUE: KT-29316
|
||||
// ISSUE: KT-24284
|
||||
|
||||
class A
|
||||
class B
|
||||
fun main() {
|
||||
A() == B()
|
||||
A() === B()
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// ISSUE: KT-29316
|
||||
// ISSUE: KT-24284
|
||||
|
||||
class A
|
||||
class B
|
||||
fun main() {
|
||||
<!EQUALITY_NOT_APPLICABLE!>A() == B()<!>
|
||||
<!EQUALITY_NOT_APPLICABLE!>A() === B()<!>
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
// FIR_IDENTICAL
|
||||
// ISSUE: KT-13451
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
public class J {
|
||||
}
|
||||
|
||||
// FILE: Main.kt
|
||||
|
||||
class K {
|
||||
fun f() {}
|
||||
}
|
||||
|
||||
fun test (j: J, k: K) {
|
||||
j == K::f
|
||||
j == k::f
|
||||
|
||||
when (j) {
|
||||
k::f -> ""
|
||||
K::f -> ""
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// FIR_IDENTICAL
|
||||
// ISSUE: KT-47884
|
||||
|
||||
interface A<X>
|
||||
class B<T>
|
||||
|
||||
fun foo(a: A<*>, b: B<*>): Boolean = a == b
|
||||
@@ -0,0 +1,7 @@
|
||||
// ISSUE: KT-22499
|
||||
|
||||
fun test(x: Any, y: Any) =
|
||||
x is Float && y is Double && <!EQUALITY_NOT_APPLICABLE_WARNING!>x == y<!>
|
||||
|
||||
fun test(x: Float, y: Double) =
|
||||
<!EQUALITY_NOT_APPLICABLE!>x == y<!>
|
||||
@@ -0,0 +1,7 @@
|
||||
// ISSUE: KT-22499
|
||||
|
||||
fun test(x: Any, y: Any) =
|
||||
x is Float && y is Double && x == y
|
||||
|
||||
fun test(x: Float, y: Double) =
|
||||
<!EQUALITY_NOT_APPLICABLE!>x == y<!>
|
||||
@@ -1,17 +0,0 @@
|
||||
// !LANGUAGE: -ProhibitComparisonOfIncompatibleEnums
|
||||
// FILE: JavaEnumA.java
|
||||
|
||||
public enum JavaEnumA {}
|
||||
|
||||
// FILE: JavaEnumB.java
|
||||
|
||||
public enum JavaEnumB {}
|
||||
|
||||
// FILE: test.kt
|
||||
|
||||
enum class KotlinEnumA
|
||||
enum class KotlinEnumB
|
||||
|
||||
fun jj(a: JavaEnumA, b: JavaEnumB) = <!EQUALITY_NOT_APPLICABLE_WARNING!>a == b<!>
|
||||
fun jk(a: JavaEnumA, b: KotlinEnumB) = <!EQUALITY_NOT_APPLICABLE_WARNING!>a == b<!>
|
||||
fun kk(a: KotlinEnumA, b: KotlinEnumB) = <!EQUALITY_NOT_APPLICABLE_WARNING!>a == b<!>
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: -ProhibitComparisonOfIncompatibleEnums
|
||||
// FILE: JavaEnumA.java
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
interface Buffered {
|
||||
fun flush()
|
||||
}
|
||||
|
||||
interface AIPowered {
|
||||
fun getAvatarReleaseYear(): Int
|
||||
}
|
||||
|
||||
enum class BufferedEnum : Buffered {
|
||||
A, B;
|
||||
override fun flush() {}
|
||||
}
|
||||
|
||||
enum class UsualEnum {
|
||||
C, D;
|
||||
}
|
||||
|
||||
enum class CleverEnum : Buffered, AIPowered {
|
||||
E, F;
|
||||
override fun flush() {}
|
||||
override fun getAvatarReleaseYear() = 2022
|
||||
}
|
||||
|
||||
fun <P> processInfo1(info: String, printer: P) where P: Buffered, P: AIPowered {
|
||||
<!EQUALITY_NOT_APPLICABLE!>printer == 20<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>printer == BufferedEnum.A<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>printer == UsualEnum.C<!>
|
||||
printer == CleverEnum.E
|
||||
}
|
||||
|
||||
fun <P> processInfo2(info: String, printer: P) where P: AIPowered, P: Buffered {
|
||||
<!EQUALITY_NOT_APPLICABLE!>printer == 20<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>printer == BufferedEnum.A<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>printer == UsualEnum.C<!>
|
||||
printer == CleverEnum.E
|
||||
}
|
||||
|
||||
abstract class Printer {
|
||||
abstract fun print(command: String)
|
||||
}
|
||||
|
||||
fun <P> processInfo3(info: String, printer: P) where P: Buffered, P: Printer {
|
||||
<!EQUALITY_NOT_APPLICABLE!>printer == 20<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>printer == BufferedEnum.A<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>printer == UsualEnum.C<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>printer == CleverEnum.E<!>
|
||||
}
|
||||
|
||||
fun test(a: Int, b: Any?) {
|
||||
<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a === b<!>
|
||||
}
|
||||
|
||||
fun <<!CONFLICTING_UPPER_BOUNDS, INCONSISTENT_TYPE_PARAMETER_BOUNDS, MISPLACED_TYPE_PARAMETER_CONSTRAINTS!>T: <!FINAL_UPPER_BOUND!>Int<!><!>> rest(a: T, b: Any?) where T : <!FINAL_UPPER_BOUND, ONLY_ONE_CLASS_BOUND_ALLOWED!>String<!> {
|
||||
<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a === b<!>
|
||||
}
|
||||
|
||||
fun <<!MISPLACED_TYPE_PARAMETER_CONSTRAINTS!>T: Any?<!>> nest(a: Int, b: T) where T : <!FINAL_UPPER_BOUND, ONLY_ONE_CLASS_BOUND_ALLOWED!>String<!> {
|
||||
<!FORBIDDEN_IDENTITY_EQUALS!>a === b<!>
|
||||
}
|
||||
|
||||
fun <<!CONFLICTING_UPPER_BOUNDS, INCONSISTENT_TYPE_PARAMETER_BOUNDS, MISPLACED_TYPE_PARAMETER_CONSTRAINTS!>T: <!FINAL_UPPER_BOUND!>Int<!><!>, <!MISPLACED_TYPE_PARAMETER_CONSTRAINTS!>K: Any?<!>> mest(a: T, b: K) where T : <!FINAL_UPPER_BOUND, ONLY_ONE_CLASS_BOUND_ALLOWED!>String<!>, K: <!FINAL_UPPER_BOUND, ONLY_ONE_CLASS_BOUND_ALLOWED!>Boolean<!> {
|
||||
<!FORBIDDEN_IDENTITY_EQUALS_WARNING!>a === b<!>
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
interface Buffered {
|
||||
fun flush()
|
||||
}
|
||||
|
||||
interface AIPowered {
|
||||
fun getAvatarReleaseYear(): Int
|
||||
}
|
||||
|
||||
enum class BufferedEnum : Buffered {
|
||||
A, B;
|
||||
override fun flush() {}
|
||||
}
|
||||
|
||||
enum class UsualEnum {
|
||||
C, D;
|
||||
}
|
||||
|
||||
enum class CleverEnum : Buffered, AIPowered {
|
||||
E, F;
|
||||
override fun flush() {}
|
||||
override fun getAvatarReleaseYear() = 2022
|
||||
}
|
||||
|
||||
fun <P> processInfo1(info: String, printer: P) where P: Buffered, P: AIPowered {
|
||||
<!EQUALITY_NOT_APPLICABLE!>printer == 20<!>
|
||||
printer == BufferedEnum.A
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON_ERROR!>printer == UsualEnum.C<!>
|
||||
printer == CleverEnum.E
|
||||
}
|
||||
|
||||
fun <P> processInfo2(info: String, printer: P) where P: AIPowered, P: Buffered {
|
||||
<!EQUALITY_NOT_APPLICABLE!>printer == 20<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON_ERROR!>printer == BufferedEnum.A<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON_ERROR!>printer == UsualEnum.C<!>
|
||||
printer == CleverEnum.E
|
||||
}
|
||||
|
||||
abstract class Printer {
|
||||
abstract fun print(command: String)
|
||||
}
|
||||
|
||||
fun <P> processInfo3(info: String, printer: P) where P: Buffered, P: Printer {
|
||||
<!EQUALITY_NOT_APPLICABLE!>printer == 20<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON_ERROR!>printer == BufferedEnum.A<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON_ERROR!>printer == UsualEnum.C<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON_ERROR!>printer == CleverEnum.E<!>
|
||||
}
|
||||
|
||||
fun test(a: Int, b: Any?) {
|
||||
<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a === b<!>
|
||||
}
|
||||
|
||||
fun <<!INCONSISTENT_TYPE_PARAMETER_BOUNDS, MISPLACED_TYPE_PARAMETER_CONSTRAINTS!><!CONFLICTING_UPPER_BOUNDS!>T<!>: <!FINAL_UPPER_BOUND!>Int<!><!>> rest(a: T, b: Any?) where T : <!FINAL_UPPER_BOUND, ONLY_ONE_CLASS_BOUND_ALLOWED!>String<!> {
|
||||
a === b
|
||||
}
|
||||
|
||||
fun <<!MISPLACED_TYPE_PARAMETER_CONSTRAINTS!>T: Any?<!>> nest(a: Int, b: T) where T : <!FINAL_UPPER_BOUND, ONLY_ONE_CLASS_BOUND_ALLOWED!>String<!> {
|
||||
<!EQUALITY_NOT_APPLICABLE!>a === b<!>
|
||||
}
|
||||
|
||||
fun <<!INCONSISTENT_TYPE_PARAMETER_BOUNDS, MISPLACED_TYPE_PARAMETER_CONSTRAINTS!><!CONFLICTING_UPPER_BOUNDS!>T<!>: <!FINAL_UPPER_BOUND!>Int<!><!>, <!MISPLACED_TYPE_PARAMETER_CONSTRAINTS!>K: Any?<!>> mest(a: T, b: K) where T : <!FINAL_UPPER_BOUND, ONLY_ONE_CLASS_BOUND_ALLOWED!>String<!>, K: <!FINAL_UPPER_BOUND, ONLY_ONE_CLASS_BOUND_ALLOWED!>Boolean<!> {
|
||||
a === b
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// FILE: A.java
|
||||
|
||||
class MyHelpers {
|
||||
public static <T> T id(T it) {
|
||||
return it;
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: B.kt
|
||||
|
||||
fun <<!CONFLICTING_UPPER_BOUNDS, INCONSISTENT_TYPE_PARAMETER_BOUNDS, MISPLACED_TYPE_PARAMETER_CONSTRAINTS!>T: <!FINAL_UPPER_BOUND!>Int<!><!>, <!MISPLACED_TYPE_PARAMETER_CONSTRAINTS!>K: Any?<!>> mest(a: T, b: K) where T : <!FINAL_UPPER_BOUND, ONLY_ONE_CLASS_BOUND_ALLOWED!>String<!>, K: <!FINAL_UPPER_BOUND, ONLY_ONE_CLASS_BOUND_ALLOWED!>Boolean<!> {
|
||||
<!FORBIDDEN_IDENTITY_EQUALS_WARNING!>MyHelpers.id(a) === MyHelpers.id(b)<!>
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// FILE: A.java
|
||||
|
||||
class MyHelpers {
|
||||
public static <T> T id(T it) {
|
||||
return it;
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: B.kt
|
||||
|
||||
fun <<!INCONSISTENT_TYPE_PARAMETER_BOUNDS, MISPLACED_TYPE_PARAMETER_CONSTRAINTS!><!CONFLICTING_UPPER_BOUNDS!>T<!>: <!FINAL_UPPER_BOUND!>Int<!><!>, <!MISPLACED_TYPE_PARAMETER_CONSTRAINTS!>K: Any?<!>> mest(a: T, b: K) where T : <!FINAL_UPPER_BOUND, ONLY_ONE_CLASS_BOUND_ALLOWED!>String<!>, K: <!FINAL_UPPER_BOUND, ONLY_ONE_CLASS_BOUND_ALLOWED!>Boolean<!> {
|
||||
MyHelpers.id(a) === MyHelpers.id(b)
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
// !LANGUAGE: -ProhibitComparisonOfIncompatibleEnums
|
||||
|
||||
interface I {
|
||||
fun foo()
|
||||
}
|
||||
|
||||
enum class E1 : I {
|
||||
A {
|
||||
override fun foo() {
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>this == E2.A<!>
|
||||
|
||||
val q = this
|
||||
when (q) {
|
||||
this -> {}
|
||||
E1.A -> {}
|
||||
E1.B -> {}
|
||||
<!INCOMPATIBLE_TYPES_WARNING!>E2.A<!> -> {}
|
||||
<!INCOMPATIBLE_TYPES_WARNING!>E2.B<!> -> {}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
},
|
||||
B {
|
||||
override fun foo() {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum class E2 : I {
|
||||
A {
|
||||
override fun foo() {
|
||||
|
||||
}
|
||||
},
|
||||
B {
|
||||
override fun foo() {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun foo1(e1: E1, e2: E2) {
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>e1 == e2<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>e1 != e2<!>
|
||||
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>e1 == E2.A<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>E1.B == e2<!>
|
||||
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>E1.A == E2.B<!>
|
||||
|
||||
e1 == E1.A
|
||||
E1.A == e1
|
||||
e2 == E2.B
|
||||
E2.B == e2
|
||||
}
|
||||
|
||||
fun foo2(e1: E1, e2: E2) {
|
||||
when (e1) {
|
||||
E1.A -> {}
|
||||
<!INCOMPATIBLE_TYPES_WARNING!>E2.A<!> -> {}
|
||||
<!INCOMPATIBLE_TYPES_WARNING!>E2.B<!> -> {}
|
||||
e1 -> {}
|
||||
<!INCOMPATIBLE_TYPES_WARNING!>e2<!> -> {}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
fun foo3(e1: Enum<E1>, e2: Enum<E2>, e: Enum<*>) {
|
||||
e1 == e
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>e1 == e2<!>
|
||||
|
||||
e1 == E1.A
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>e1 == E2.A<!>
|
||||
|
||||
when (e1) {
|
||||
e1 -> {}
|
||||
<!INCOMPATIBLE_TYPES_WARNING!>e2<!> -> {}
|
||||
e -> {}
|
||||
E1.A -> {}
|
||||
<!INCOMPATIBLE_TYPES_WARNING!>E2.A<!> -> {}
|
||||
else -> {}
|
||||
}
|
||||
|
||||
when (e) {
|
||||
e -> {}
|
||||
e2 -> {}
|
||||
E1.A -> {}
|
||||
E2.A -> {}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: -ProhibitComparisonOfIncompatibleEnums
|
||||
|
||||
interface I {
|
||||
|
||||
@@ -9,13 +9,13 @@ enum class E2 {
|
||||
}
|
||||
|
||||
fun foo1(e1: E1, e2: E2) {
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>e1 == e2<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>e1 != e2<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>e1 == e2<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>e1 != e2<!>
|
||||
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>e1 == E2.A<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>E1.B == e2<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>e1 == E2.A<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>E1.B == e2<!>
|
||||
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>E1.A == E2.B<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>E1.A == E2.B<!>
|
||||
|
||||
e1 == E1.A
|
||||
E1.A == e1
|
||||
@@ -26,27 +26,27 @@ fun foo1(e1: E1, e2: E2) {
|
||||
fun foo2(e1: E1, e2: E2) {
|
||||
when (e1) {
|
||||
E1.A -> {}
|
||||
<!INCOMPATIBLE_TYPES_WARNING!>E2.A<!> -> {}
|
||||
<!INCOMPATIBLE_TYPES_WARNING!>E2.B<!> -> {}
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>E2.A<!> -> {}
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>E2.B<!> -> {}
|
||||
e1 -> {}
|
||||
<!INCOMPATIBLE_TYPES_WARNING!>e2<!> -> {}
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>e2<!> -> {}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
fun foo3(e1: Enum<E1>, e2: Enum<E2>, e: Enum<*>) {
|
||||
e1 == e
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>e1 == e2<!>
|
||||
e1 == e2
|
||||
|
||||
e1 == E1.A
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>e1 == E2.A<!>
|
||||
e1 == E2.A
|
||||
|
||||
when (e1) {
|
||||
e1 -> {}
|
||||
<!INCOMPATIBLE_TYPES_WARNING!>e2<!> -> {}
|
||||
e2 -> {}
|
||||
e -> {}
|
||||
E1.A -> {}
|
||||
<!INCOMPATIBLE_TYPES_WARNING!>E2.A<!> -> {}
|
||||
E2.A -> {}
|
||||
else -> {}
|
||||
}
|
||||
|
||||
@@ -63,15 +63,15 @@ interface MyInterface
|
||||
open class MyOpenClass
|
||||
|
||||
fun foo4(e1: E1, i: MyInterface, c: MyOpenClass) {
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>e1 == i<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>i == e1<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>e1 == i<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>i == e1<!>
|
||||
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>e1 == c<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>c == e1<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>e1 == c<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>c == e1<!>
|
||||
|
||||
when (e1) {
|
||||
<!INCOMPATIBLE_TYPES_WARNING!>i<!> -> {}
|
||||
<!INCOMPATIBLE_TYPES_WARNING!>c<!> -> {}
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>i<!> -> {}
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>c<!> -> {}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
@@ -90,10 +90,10 @@ fun foo6(e1: E1?, e2: E2) {
|
||||
e1 == null
|
||||
null == e1
|
||||
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>e1 == E2.A<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>E2.A == e1<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>e1 == e2<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>e2 == e1<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>e1 == E2.A<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>E2.A == e1<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>e1 == e2<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>e2 == e1<!>
|
||||
|
||||
<!SENSELESS_COMPARISON!>e2 == null<!>
|
||||
<!SENSELESS_COMPARISON!>null == e2<!>
|
||||
@@ -102,7 +102,7 @@ fun foo6(e1: E1?, e2: E2) {
|
||||
}
|
||||
|
||||
fun foo7(e1: E1?, e2: E2?) {
|
||||
e1 == e2 // There should be an IDE-inspection for such cases
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>e1 == e2<!> // There should be an IDE-inspection for such cases
|
||||
}
|
||||
|
||||
fun <T> foo8(e1: E1?, e2: E2, t: T) {
|
||||
@@ -117,16 +117,16 @@ fun <T> foo8(e1: E1?, e2: E2, t: T) {
|
||||
}
|
||||
|
||||
fun <T, K> foo9(e1: E1?, e2: E2, t: T, k: K) where T : MyInterface, T : MyOpenClass, K : MyInterface {
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>e1 == t<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>t == e1<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>e1 == t<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>t == e1<!>
|
||||
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>e2 == t<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>t == e2<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>e2 == t<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>t == e2<!>
|
||||
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>E1.A == t<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>t == E1.A<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>E1.A == t<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>t == E1.A<!>
|
||||
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>E3.X == t<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>E3.X == t<!>
|
||||
|
||||
E3.X == k
|
||||
k == E3.X
|
||||
@@ -137,9 +137,9 @@ interface Inv<T>
|
||||
enum class E4 : Inv<Int> { A }
|
||||
|
||||
fun foo10(e4: E4, invString: Inv<String>) {
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>e4 == invString<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>invString == e4<!>
|
||||
e4 == invString
|
||||
invString == e4
|
||||
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>E4.A == invString<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>invString == E4.A<!>
|
||||
E4.A == invString
|
||||
invString == E4.A
|
||||
}
|
||||
|
||||
@@ -26,27 +26,27 @@ fun foo1(e1: E1, e2: E2) {
|
||||
fun foo2(e1: E1, e2: E2) {
|
||||
when (e1) {
|
||||
E1.A -> {}
|
||||
<!INCOMPATIBLE_TYPES!>E2.A<!> -> {}
|
||||
<!INCOMPATIBLE_TYPES!>E2.B<!> -> {}
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON_ERROR!>E2.A<!> -> {}
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON_ERROR!>E2.B<!> -> {}
|
||||
e1 -> {}
|
||||
<!INCOMPATIBLE_TYPES!>e2<!> -> {}
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON_ERROR!>e2<!> -> {}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
fun foo3(e1: Enum<E1>, e2: Enum<E2>, e: Enum<*>) {
|
||||
e1 == e
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON_ERROR!>e1 == e2<!>
|
||||
e1 == e2
|
||||
|
||||
e1 == E1.A
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON_ERROR!>e1 == E2.A<!>
|
||||
e1 == E2.A
|
||||
|
||||
when (e1) {
|
||||
e1 -> {}
|
||||
<!INCOMPATIBLE_TYPES!>e2<!> -> {}
|
||||
e2 -> {}
|
||||
e -> {}
|
||||
E1.A -> {}
|
||||
<!INCOMPATIBLE_TYPES!>E2.A<!> -> {}
|
||||
E2.A -> {}
|
||||
else -> {}
|
||||
}
|
||||
|
||||
@@ -70,8 +70,8 @@ fun foo4(e1: E1, i: MyInterface, c: MyOpenClass) {
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON_ERROR!>c == e1<!>
|
||||
|
||||
when (e1) {
|
||||
<!INCOMPATIBLE_TYPES!>i<!> -> {}
|
||||
<!INCOMPATIBLE_TYPES!>c<!> -> {}
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON_ERROR!>i<!> -> {}
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON_ERROR!>c<!> -> {}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
@@ -102,7 +102,7 @@ fun foo6(e1: E1?, e2: E2) {
|
||||
}
|
||||
|
||||
fun foo7(e1: E1?, e2: E2?) {
|
||||
e1 == e2 // There should be an IDE-inspection for such cases
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>e1 == e2<!> // There should be an IDE-inspection for such cases
|
||||
}
|
||||
|
||||
fun <T> foo8(e1: E1?, e2: E2, t: T) {
|
||||
@@ -117,16 +117,16 @@ fun <T> foo8(e1: E1?, e2: E2, t: T) {
|
||||
}
|
||||
|
||||
fun <T, K> foo9(e1: E1?, e2: E2, t: T, k: K) where T : MyInterface, T : MyOpenClass, K : MyInterface {
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>e1 == t<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>t == e1<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>e1 == t<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>t == e1<!>
|
||||
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>e2 == t<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>t == e2<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>e2 == t<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>t == e2<!>
|
||||
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>E1.A == t<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>t == E1.A<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>E1.A == t<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>t == E1.A<!>
|
||||
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>E3.X == t<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>E3.X == t<!>
|
||||
|
||||
E3.X == k
|
||||
k == E3.X
|
||||
@@ -137,9 +137,9 @@ interface Inv<T>
|
||||
enum class E4 : Inv<Int> { A }
|
||||
|
||||
fun foo10(e4: E4, invString: Inv<String>) {
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>e4 == invString<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>invString == e4<!>
|
||||
e4 == invString
|
||||
invString == e4
|
||||
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>E4.A == invString<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>invString == E4.A<!>
|
||||
E4.A == invString
|
||||
invString == E4.A
|
||||
}
|
||||
|
||||
@@ -56,47 +56,47 @@ fun foo(
|
||||
<!EQUALITY_NOT_APPLICABLE!>"" == 2<!>
|
||||
|
||||
<!EQUALITY_NOT_APPLICABLE!>string == int<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>strings == ints<!>
|
||||
strings == ints
|
||||
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>aString == aInt<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>aOutString == aOutInt<!>
|
||||
aString == aInt
|
||||
aOutString == aOutInt
|
||||
aInString == aInInt
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>aOutString == aInInt<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>aInString == aOutInt<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>aOutString == aInt<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>aInString == aInt<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>aOutString2 == aOutInt2<!>
|
||||
aOutString == aInInt
|
||||
aInString == aOutInt
|
||||
aOutString == aInt
|
||||
aInString == aInt
|
||||
aOutString2 == aOutInt2
|
||||
aInString2 == aInInt2
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>aOutString2 == aInInt2<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>aInString2 == aOutInt2<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>aString == a2<!>
|
||||
aOutString2 == aInInt2
|
||||
aInString2 == aOutInt2
|
||||
aString == a2
|
||||
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>bString == bInt<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>bOutString == bOutInt<!>
|
||||
bString == bInt
|
||||
bOutString == bOutInt
|
||||
bInString == bInInt
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>bOutString == bInInt<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>bInString == bOutInt<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>bOutString == bInt<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>bInString == bInt<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>bOutString2 == bOutInt2<!>
|
||||
bOutString == bInInt
|
||||
bInString == bOutInt
|
||||
bOutString == bInt
|
||||
bInString == bInt
|
||||
bOutString2 == bOutInt2
|
||||
bInString2 == bInInt2
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>bOutString2 == bInInt2<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>bInString2 == bOutInt2<!>
|
||||
bOutString2 == bInInt2
|
||||
bInString2 == bOutInt2
|
||||
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON_ERROR!>e == i<!>
|
||||
<!EQUALITY_NOT_APPLICABLE!>"" == i<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>ac == ad<!>
|
||||
ac == ad
|
||||
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>tSub1 == tSub2<!>
|
||||
tSub1 == tSub2
|
||||
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>aString == bString<!>
|
||||
aString == bString
|
||||
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>aListInt == aSetInt<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>aSetInt == aListString<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>aListString == aListInt<!>
|
||||
aListInt == aSetInt
|
||||
aSetInt == aListString
|
||||
aListString == aListInt
|
||||
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>aString == aListString<!>
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>bString == aListString<!>
|
||||
aString == aListString
|
||||
bString == aListString
|
||||
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>mutableListAny == listString<!>
|
||||
mutableListAny == listString
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
// FIR_IDENTICAL
|
||||
// ISSUE: KTIJ-15380
|
||||
|
||||
fun test() {
|
||||
var x = 0
|
||||
if (x == x) {}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// ISSUE: KT-46383
|
||||
|
||||
fun test(a: Any, b: Any, s: String, i: Int) {
|
||||
if (a is String && b is Int) {
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>a == b<!>
|
||||
}
|
||||
<!EQUALITY_NOT_APPLICABLE!>s == i<!>
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// ISSUE: KT-46383
|
||||
|
||||
fun test(a: Any, b: Any, s: String, i: Int) {
|
||||
if (a is String && b is Int) {
|
||||
a == b
|
||||
}
|
||||
<!EQUALITY_NOT_APPLICABLE!>s == i<!>
|
||||
}
|
||||
Vendored
+11
-11
@@ -3,18 +3,18 @@
|
||||
|
||||
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!>1L == 3<!>
|
||||
<!EQUALITY_NOT_APPLICABLE!>x == 3<!>
|
||||
<!EQUALITY_NOT_APPLICABLE!>3 == 1L<!>
|
||||
<!EQUALITY_NOT_APPLICABLE!>3 == x<!>
|
||||
<!EQUALITY_NOT_APPLICABLE!>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<!>
|
||||
<!FORBIDDEN_IDENTITY_EQUALS!>1L === 3<!>
|
||||
<!FORBIDDEN_IDENTITY_EQUALS!>x === 3<!>
|
||||
<!FORBIDDEN_IDENTITY_EQUALS!>3 === 1L<!>
|
||||
<!FORBIDDEN_IDENTITY_EQUALS!>3 === x<!>
|
||||
<!FORBIDDEN_IDENTITY_EQUALS!>y === x<!>
|
||||
|
||||
yield("")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
-11
@@ -3,18 +3,18 @@
|
||||
|
||||
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!>1L == 3<!>
|
||||
<!EQUALITY_NOT_APPLICABLE!>x == 3<!>
|
||||
<!EQUALITY_NOT_APPLICABLE!>3 == 1L<!>
|
||||
<!EQUALITY_NOT_APPLICABLE!>3 == x<!>
|
||||
<!EQUALITY_NOT_APPLICABLE!>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<!>
|
||||
<!FORBIDDEN_IDENTITY_EQUALS!>1L === 3<!>
|
||||
<!FORBIDDEN_IDENTITY_EQUALS!>x === 3<!>
|
||||
<!FORBIDDEN_IDENTITY_EQUALS!>3 === 1L<!>
|
||||
<!FORBIDDEN_IDENTITY_EQUALS!>3 === x<!>
|
||||
<!FORBIDDEN_IDENTITY_EQUALS!>y === x<!>
|
||||
|
||||
yield("")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+7
-7
@@ -5,18 +5,18 @@ inline class Foo(val x: Int)
|
||||
inline class Bar(val y: String)
|
||||
|
||||
fun test(f1: Foo, f2: Foo, b1: Bar, fn1: Foo?, fn2: Foo?) {
|
||||
val a1 = f1 === f2 || f1 !== f2
|
||||
val a2 = f1 === f1
|
||||
val a3 = <!EQUALITY_NOT_APPLICABLE!>f1 === b1<!> || <!EQUALITY_NOT_APPLICABLE!>f1 !== b1<!>
|
||||
val a1 = <!FORBIDDEN_IDENTITY_EQUALS!>f1 === f2<!> || <!FORBIDDEN_IDENTITY_EQUALS!>f1 !== f2<!>
|
||||
val a2 = <!FORBIDDEN_IDENTITY_EQUALS!>f1 === f1<!>
|
||||
val a3 = <!FORBIDDEN_IDENTITY_EQUALS!>f1 === b1<!> || <!FORBIDDEN_IDENTITY_EQUALS!>f1 !== b1<!>
|
||||
|
||||
val c1 = fn1 === fn2 || fn1 !== fn2
|
||||
val c2 = f1 === fn1 || f1 !== fn1
|
||||
val c3 = <!EQUALITY_NOT_APPLICABLE!>b1 === fn1<!> || <!EQUALITY_NOT_APPLICABLE!>b1 !== fn1<!>
|
||||
val c2 = <!FORBIDDEN_IDENTITY_EQUALS!>f1 === fn1<!> || <!FORBIDDEN_IDENTITY_EQUALS!>f1 !== fn1<!>
|
||||
val c3 = <!FORBIDDEN_IDENTITY_EQUALS!>b1 === fn1<!> || <!FORBIDDEN_IDENTITY_EQUALS!>b1 !== fn1<!>
|
||||
|
||||
val any = Any()
|
||||
|
||||
val d1 = any === f1 || any !== f1
|
||||
val d2 = f1 === any || f1 !== any
|
||||
val d1 = <!FORBIDDEN_IDENTITY_EQUALS!>any === f1<!> || <!FORBIDDEN_IDENTITY_EQUALS!>any !== f1<!>
|
||||
val d2 = <!FORBIDDEN_IDENTITY_EQUALS!>f1 === any<!> || <!FORBIDDEN_IDENTITY_EQUALS!>f1 !== any<!>
|
||||
val d3 = any === fn1 || any !== fn1
|
||||
val d4 = fn1 === any || fn1 !== any
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
const val equalsBoolean1 = true.equals(true)
|
||||
const val equalsBoolean2 = false != true
|
||||
const val equalsBoolean3 = false.equals(1)
|
||||
const val equalsBoolean4 = <!EQUALITY_NOT_APPLICABLE_WARNING!>false == 1<!>
|
||||
const val equalsBoolean4 = <!EQUALITY_NOT_APPLICABLE!>false == 1<!>
|
||||
|
||||
const val equalsChar1 = '1'.equals('2')
|
||||
const val equalsChar2 = '2' == '2'
|
||||
const val equalsChar3 = '1'.equals(1)
|
||||
const val equalsChar4 = <!EQUALITY_NOT_APPLICABLE_WARNING!>'1' == 1<!>
|
||||
const val equalsChar4 = <!EQUALITY_NOT_APPLICABLE!>'1' == 1<!>
|
||||
|
||||
const val equalsByte1 = 1.toByte().equals(2.toByte())
|
||||
const val equalsByte2 = 2.toByte() == 2.toByte()
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
const val equalsBoolean1 = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>true.equals(true)<!>
|
||||
const val equalsBoolean2 = false != true
|
||||
const val equalsBoolean3 = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>false.equals(1)<!>
|
||||
const val equalsBoolean4 = <!EQUALITY_NOT_APPLICABLE_WARNING!>false == 1<!>
|
||||
const val equalsBoolean4 = <!EQUALITY_NOT_APPLICABLE!>false == 1<!>
|
||||
|
||||
const val equalsChar1 = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>'1'.equals('2')<!>
|
||||
const val equalsChar2 = '2' == '2'
|
||||
const val equalsChar3 = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>'1'.equals(1)<!>
|
||||
const val equalsChar4 = <!EQUALITY_NOT_APPLICABLE_WARNING!>'1' == 1<!>
|
||||
const val equalsChar4 = <!EQUALITY_NOT_APPLICABLE!>'1' == 1<!>
|
||||
|
||||
const val equalsByte1 = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>1.toByte().equals(2.toByte())<!>
|
||||
const val equalsByte2 = 2.toByte() == 2.toByte()
|
||||
|
||||
@@ -8,8 +8,8 @@ import checkSubtype
|
||||
fun main(args : Array<String>) {
|
||||
val x = checkSubtype<Any>(args[0])
|
||||
if(x is <!PLATFORM_CLASS_MAPPED_TO_KOTLIN!>java.lang.CharSequence<!>) {
|
||||
if (<!EQUALITY_NOT_APPLICABLE!>"a" == x<!>) x.<!FUNCTION_CALL_EXPECTED!>length<!> else x.length() // OK
|
||||
if (<!EQUALITY_NOT_APPLICABLE!>"a" == x<!> || <!EQUALITY_NOT_APPLICABLE!>"b" == x<!>) x.<!FUNCTION_CALL_EXPECTED!>length<!> else x.length() // <– THEN ERROR
|
||||
if (<!EQUALITY_NOT_APPLICABLE!>"a" == x<!> && <!EQUALITY_NOT_APPLICABLE!>"a" == x<!>) x.<!FUNCTION_CALL_EXPECTED!>length<!> else x.length() // <– ELSE ERROR
|
||||
if (<!EQUALITY_NOT_APPLICABLE_WARNING!>"a" == x<!>) x.<!FUNCTION_CALL_EXPECTED!>length<!> else x.length() // OK
|
||||
if (<!EQUALITY_NOT_APPLICABLE_WARNING!>"a" == x<!> || <!EQUALITY_NOT_APPLICABLE_WARNING!>"b" == x<!>) x.<!FUNCTION_CALL_EXPECTED!>length<!> else x.length() // <– THEN ERROR
|
||||
if (<!EQUALITY_NOT_APPLICABLE_WARNING!>"a" == x<!> && <!EQUALITY_NOT_APPLICABLE_WARNING!>"a" == x<!>) x.<!FUNCTION_CALL_EXPECTED!>length<!> else x.length() // <– ELSE ERROR
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ sealed class Tree {
|
||||
|
||||
fun maxIsClass(): Int = <!NO_ELSE_IN_WHEN!>when<!>(this) {
|
||||
Empty -> -1
|
||||
<!INCOMPATIBLE_TYPES, NO_COMPANION_OBJECT!>Leaf<!> -> 0
|
||||
<!NO_COMPANION_OBJECT!>Leaf<!> -> 0
|
||||
is Node -> this.left.max()
|
||||
}
|
||||
|
||||
|
||||
+8
-8
@@ -6,18 +6,18 @@ fun test(
|
||||
ui1: UInt, ui2: UInt,
|
||||
ul1: ULong, ul2: ULong
|
||||
) {
|
||||
val ub = ub1 === ub2 || ub1 !== ub2
|
||||
val us = us1 === us2 || us1 !== us2
|
||||
val ui = ui1 === ui2 || ui1 !== ui2
|
||||
val ul = ul1 === ul2 || ul1 !== ul2
|
||||
val ub = <!FORBIDDEN_IDENTITY_EQUALS!>ub1 === ub2<!> || <!FORBIDDEN_IDENTITY_EQUALS!>ub1 !== ub2<!>
|
||||
val us = <!FORBIDDEN_IDENTITY_EQUALS!>us1 === us2<!> || <!FORBIDDEN_IDENTITY_EQUALS!>us1 !== us2<!>
|
||||
val ui = <!FORBIDDEN_IDENTITY_EQUALS!>ui1 === ui2<!> || <!FORBIDDEN_IDENTITY_EQUALS!>ui1 !== ui2<!>
|
||||
val ul = <!FORBIDDEN_IDENTITY_EQUALS!>ul1 === ul2<!> || <!FORBIDDEN_IDENTITY_EQUALS!>ul1 !== ul2<!>
|
||||
|
||||
val u = <!EQUALITY_NOT_APPLICABLE!>ub1 === ul1<!>
|
||||
val u = <!FORBIDDEN_IDENTITY_EQUALS!>ub1 === ul1<!>
|
||||
|
||||
val a1 = 1u === 2u || 1u !== 2u
|
||||
val a2 = 0xFFFF_FFFF_FFFF_FFFFu === 0xFFFF_FFFF_FFFF_FFFFu
|
||||
val a1 = <!FORBIDDEN_IDENTITY_EQUALS!>1u === 2u<!> || <!FORBIDDEN_IDENTITY_EQUALS!>1u !== 2u<!>
|
||||
val a2 = <!FORBIDDEN_IDENTITY_EQUALS!>0xFFFF_FFFF_FFFF_FFFFu === 0xFFFF_FFFF_FFFF_FFFFu<!>
|
||||
|
||||
val bu1 = 1u
|
||||
val bu2 = 1u
|
||||
|
||||
val c1 = bu1 === bu2 || bu1 !== bu2
|
||||
val c1 = <!FORBIDDEN_IDENTITY_EQUALS!>bu1 === bu2<!> || <!FORBIDDEN_IDENTITY_EQUALS!>bu1 !== bu2<!>
|
||||
}
|
||||
|
||||
+7
-7
@@ -13,18 +13,18 @@ value class Foo(val x: Int)
|
||||
value class Bar(val y: String)
|
||||
|
||||
fun test(f1: Foo, f2: Foo, b1: Bar, fn1: Foo?, fn2: Foo?) {
|
||||
val a1 = f1 === f2 || f1 !== f2
|
||||
val a2 = f1 === f1
|
||||
val a3 = <!EQUALITY_NOT_APPLICABLE!>f1 === b1<!> || <!EQUALITY_NOT_APPLICABLE!>f1 !== b1<!>
|
||||
val a1 = <!FORBIDDEN_IDENTITY_EQUALS!>f1 === f2<!> || <!FORBIDDEN_IDENTITY_EQUALS!>f1 !== f2<!>
|
||||
val a2 = <!FORBIDDEN_IDENTITY_EQUALS!>f1 === f1<!>
|
||||
val a3 = <!FORBIDDEN_IDENTITY_EQUALS!>f1 === b1<!> || <!FORBIDDEN_IDENTITY_EQUALS!>f1 !== b1<!>
|
||||
|
||||
val c1 = fn1 === fn2 || fn1 !== fn2
|
||||
val c2 = f1 === fn1 || f1 !== fn1
|
||||
val c3 = <!EQUALITY_NOT_APPLICABLE!>b1 === fn1<!> || <!EQUALITY_NOT_APPLICABLE!>b1 !== fn1<!>
|
||||
val c2 = <!FORBIDDEN_IDENTITY_EQUALS!>f1 === fn1<!> || <!FORBIDDEN_IDENTITY_EQUALS!>f1 !== fn1<!>
|
||||
val c3 = <!FORBIDDEN_IDENTITY_EQUALS!>b1 === fn1<!> || <!FORBIDDEN_IDENTITY_EQUALS!>b1 !== fn1<!>
|
||||
|
||||
val any = Any()
|
||||
|
||||
val d1 = any === f1 || any !== f1
|
||||
val d2 = f1 === any || f1 !== any
|
||||
val d1 = <!FORBIDDEN_IDENTITY_EQUALS!>any === f1<!> || <!FORBIDDEN_IDENTITY_EQUALS!>any !== f1<!>
|
||||
val d2 = <!FORBIDDEN_IDENTITY_EQUALS!>f1 === any<!> || <!FORBIDDEN_IDENTITY_EQUALS!>f1 !== any<!>
|
||||
val d3 = any === fn1 || any !== fn1
|
||||
val d4 = fn1 === any || fn1 !== any
|
||||
}
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ fun foo() : Int {
|
||||
<!USELESS_IS_CHECK!>!is Int<!> -> 1
|
||||
<!USELESS_IS_CHECK!>is Any?<!> -> 1
|
||||
<!USELESS_IS_CHECK!>is Any<!> -> 1
|
||||
s -> 1
|
||||
<!INCOMPATIBLE_TYPES!>s<!> -> 1
|
||||
1 -> 1
|
||||
1 <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>a<!> -> 1
|
||||
in 1..<!UNRESOLVED_REFERENCE!>a<!> -> 1
|
||||
|
||||
+2
-2
@@ -47,8 +47,8 @@ fun testWithSubject_ok(x: Boolean, y: Boolean?, any: Any, z: Boolean) {
|
||||
x <!OVERLOAD_RESOLUTION_AMBIGUITY!>>=<!> x -> {}
|
||||
x == x -> {}
|
||||
x != x -> {}
|
||||
x === x -> {}
|
||||
x !== x -> {}
|
||||
<!DEPRECATED_IDENTITY_EQUALS!>x === x<!> -> {}
|
||||
<!DEPRECATED_IDENTITY_EQUALS!>x !== x<!> -> {}
|
||||
x && x -> {}
|
||||
x || x -> {}
|
||||
}
|
||||
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
// ISSUE: KT-54473
|
||||
|
||||
interface I
|
||||
class A : I
|
||||
class B : I
|
||||
|
||||
fun test(a: A, b: B) {
|
||||
a == b
|
||||
a == b as I
|
||||
}
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
// ISSUE: KT-54473
|
||||
|
||||
interface I
|
||||
class A : I
|
||||
class B : I
|
||||
|
||||
fun test(a: A, b: B) {
|
||||
<!EQUALITY_NOT_APPLICABLE!>a == b<!>
|
||||
a == b as I
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// ISSUE: KT-25808
|
||||
// WITH_STDLIB
|
||||
|
||||
// B.java
|
||||
public class B {
|
||||
}
|
||||
|
||||
// test.kt
|
||||
class A
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
(1 to A()) == A()
|
||||
(1 to B()) == B()
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// ISSUE: KT-25808
|
||||
// WITH_STDLIB
|
||||
|
||||
// B.java
|
||||
public class B {
|
||||
}
|
||||
|
||||
// test.kt
|
||||
class A
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
<!EQUALITY_NOT_APPLICABLE!>(1 to A()) == A()<!>
|
||||
<!EQUALITY_NOT_APPLICABLE!>(1 to B()) == B()<!>
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
// ISSUE: KT-35134
|
||||
|
||||
interface A
|
||||
|
||||
fun foo(a: Any) {
|
||||
if (a is A) {
|
||||
if (<!EQUALITY_NOT_APPLICABLE_WARNING!>a == (<!EQUALITY_NOT_APPLICABLE_WARNING!>a == 1<!>)<!>) {
|
||||
println(1)
|
||||
}
|
||||
|
||||
when (a) {
|
||||
<!CONFUSING_BRANCH_CONDITION_ERROR, EQUALITY_NOT_APPLICABLE_WARNING, INCOMPATIBLE_TYPES!>a == 1<!> -> print("1")
|
||||
}
|
||||
|
||||
if (<!EQUALITY_NOT_APPLICABLE!>(a <!USELESS_CAST!>as A<!>) == (<!EQUALITY_NOT_APPLICABLE_WARNING!>a == 1<!>)<!>) {
|
||||
println(1)
|
||||
}
|
||||
|
||||
when (a <!USELESS_CAST!>as A<!>) {
|
||||
<!CONFUSING_BRANCH_CONDITION_ERROR, EQUALITY_NOT_APPLICABLE_WARNING, INCOMPATIBLE_TYPES!>a == 1<!> -> print("1")
|
||||
}
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
// ISSUE: KT-35134
|
||||
|
||||
interface A
|
||||
|
||||
fun foo(a: Any) {
|
||||
if (a is A) {
|
||||
if (a == (a == 1)) {
|
||||
println(1)
|
||||
}
|
||||
|
||||
when (a) {
|
||||
<!CONFUSING_BRANCH_CONDITION_ERROR!>a == 1<!> -> print("1")
|
||||
}
|
||||
|
||||
if (<!EQUALITY_NOT_APPLICABLE!>(a <!USELESS_CAST!>as A<!>) == (a == 1)<!>) {
|
||||
println(1)
|
||||
}
|
||||
|
||||
when (a <!USELESS_CAST!>as A<!>) {
|
||||
<!CONFUSING_BRANCH_CONDITION_ERROR, INCOMPATIBLE_TYPES!>a == 1<!> -> print("1")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// ISSUE: KT-47979
|
||||
|
||||
enum class Foo { A, B }
|
||||
|
||||
fun test() {
|
||||
if (Triple(Foo.A, 1, 2) == Pair("a", "b")) println("Doesn't compile")
|
||||
if (Triple(0, 1, 2) == Pair(Foo.A, "a")) println("Doesn't compile")
|
||||
if (Triple(0, 1, 2) == Pair("a", "b")) println("Doesn't compile")
|
||||
if (Triple(Foo.A, 1, 2) == Pair(Foo.A, "a")) println("Compiles, but why?")
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// ISSUE: KT-47979
|
||||
|
||||
enum class Foo { A, B }
|
||||
|
||||
fun test() {
|
||||
if (<!EQUALITY_NOT_APPLICABLE!>Triple(Foo.A, 1, 2) == Pair("a", "b")<!>) println("Doesn't compile")
|
||||
if (<!EQUALITY_NOT_APPLICABLE!>Triple(0, 1, 2) == Pair(Foo.A, "a")<!>) println("Doesn't compile")
|
||||
if (<!EQUALITY_NOT_APPLICABLE!>Triple(0, 1, 2) == Pair("a", "b")<!>) println("Doesn't compile")
|
||||
if (Triple(Foo.A, 1, 2) == Pair(Foo.A, "a")) println("Compiles, but why?")
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
interface B
|
||||
|
||||
fun equalityNotApplicable(a: Int, b: B) {
|
||||
<!EQUALITY_NOT_APPLICABLE!>a == b<!>
|
||||
}
|
||||
|
||||
fun equalityNotApplicableSmartCast(a: Any?, b: Any?) {
|
||||
if (a is Int && b is B) {
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>a == b<!>
|
||||
}
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class C(val int: Int)
|
||||
@JvmInline
|
||||
value class D(val bool: Boolean)
|
||||
|
||||
fun forbiddenIdentityEquals(c: C, d: D) {
|
||||
<!FORBIDDEN_IDENTITY_EQUALS!>c === d<!>
|
||||
}
|
||||
|
||||
fun forbiddenIdentityEqualsSmartCast(c: Any?, d: Any?) {
|
||||
if (c is C && d is D) {
|
||||
<!FORBIDDEN_IDENTITY_EQUALS_WARNING!>c === d<!>
|
||||
}
|
||||
}
|
||||
|
||||
fun implicitBoxingInIdentityEquals(i: Int, a: Any?) {
|
||||
<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>i === a<!>
|
||||
}
|
||||
|
||||
fun implicitBoxingInIdentityEqualsSmartCast(i: Any?, a: Any?) {
|
||||
if (i is Int) {
|
||||
<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>i === a<!>
|
||||
}
|
||||
}
|
||||
|
||||
fun deprecatedIdentityEquals(a: Int, b: Int) {
|
||||
<!DEPRECATED_IDENTITY_EQUALS!>a === b<!>
|
||||
}
|
||||
|
||||
fun deprecatedIdentityEqualsSmartCast(a: Any?, b: Any?) {
|
||||
if (a is Int && b is Int) {
|
||||
<!DEPRECATED_IDENTITY_EQUALS!>a === b<!>
|
||||
}
|
||||
}
|
||||
|
||||
fun incompatibleTypes(a: Int) = when(a) {
|
||||
<!INCOMPATIBLE_TYPES!>C(10)<!> -> 1
|
||||
else -> 2
|
||||
}
|
||||
|
||||
fun incompatibleTypesSmartCast(a: Any?) {
|
||||
if (a is Int) {
|
||||
when(a) {
|
||||
<!INCOMPATIBLE_TYPES!>C(10)<!> -> 1
|
||||
else -> 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum class E {
|
||||
A, B
|
||||
}
|
||||
|
||||
fun incompatibleEnumComparison(c: B, e: E) {
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON_ERROR!>c == e<!>
|
||||
}
|
||||
|
||||
fun incompatibleEnumComparisonSmartCast(c: Any?, e: Any?) {
|
||||
if (c is B && e is E) {
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>c == e<!>
|
||||
}
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
interface B
|
||||
|
||||
fun equalityNotApplicable(a: Int, b: B) {
|
||||
<!EQUALITY_NOT_APPLICABLE!>a == b<!>
|
||||
}
|
||||
|
||||
fun equalityNotApplicableSmartCast(a: Any?, b: Any?) {
|
||||
if (a is Int && b is B) {
|
||||
a == b
|
||||
}
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class C(val int: Int)
|
||||
@JvmInline
|
||||
value class D(val bool: Boolean)
|
||||
|
||||
fun forbiddenIdentityEquals(c: C, d: D) {
|
||||
<!EQUALITY_NOT_APPLICABLE, FORBIDDEN_IDENTITY_EQUALS!>c === d<!>
|
||||
}
|
||||
|
||||
fun forbiddenIdentityEqualsSmartCast(c: Any?, d: Any?) {
|
||||
if (c is C && d is D) {
|
||||
c === d
|
||||
}
|
||||
}
|
||||
|
||||
fun implicitBoxingInIdentityEquals(i: Int, a: Any?) {
|
||||
<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>i === a<!>
|
||||
}
|
||||
|
||||
fun implicitBoxingInIdentityEqualsSmartCast(i: Any?, a: Any?) {
|
||||
if (i is Int) {
|
||||
i === a
|
||||
}
|
||||
}
|
||||
|
||||
fun deprecatedIdentityEquals(a: Int, b: Int) {
|
||||
<!DEPRECATED_IDENTITY_EQUALS!>a === b<!>
|
||||
}
|
||||
|
||||
fun deprecatedIdentityEqualsSmartCast(a: Any?, b: Any?) {
|
||||
if (a is Int && b is Int) {
|
||||
a === b
|
||||
}
|
||||
}
|
||||
|
||||
fun incompatibleTypes(a: Int) = when(a) {
|
||||
<!INCOMPATIBLE_TYPES!>C(10)<!> -> 1
|
||||
else -> 2
|
||||
}
|
||||
|
||||
fun incompatibleTypesSmartCast(a: Any?) {
|
||||
if (a is Int) {
|
||||
when(<!DEBUG_INFO_SMARTCAST!>a<!>) {
|
||||
C(10) -> 1
|
||||
else -> 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum class E {
|
||||
A, B
|
||||
}
|
||||
|
||||
fun incompatibleEnumComparison(c: B, e: E) {
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON_ERROR!>c == e<!>
|
||||
}
|
||||
|
||||
fun incompatibleEnumComparisonSmartCast(c: Any?, e: Any?) {
|
||||
if (c is B && e is E) {
|
||||
c == e
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
// LANGUAGE: +ReportErrorsForComparisonOperators
|
||||
|
||||
fun nullableNothingIdentity(a: Int, b: Nothing?) {
|
||||
<!FORBIDDEN_IDENTITY_EQUALS, SENSELESS_COMPARISON!>a === b<!>
|
||||
}
|
||||
|
||||
fun samePrimitiveIdentity(a: Int, b: Int) {
|
||||
<!DEPRECATED_IDENTITY_EQUALS!>a === b<!>
|
||||
}
|
||||
|
||||
fun identityWithImplicitBoxing(a: Int, b: Any?) {
|
||||
<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a === b<!>
|
||||
}
|
||||
|
||||
enum class E1 { A, B }
|
||||
enum class E2 { C, D }
|
||||
|
||||
fun nullableEnums(a: E1?, b: E2?) {
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON_ERROR!>a == b<!>
|
||||
}
|
||||
|
||||
fun <T> enumAsTypeParameterBound(a: T, b: Int) where T : Any, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>E1<!> {
|
||||
<!EQUALITY_NOT_APPLICABLE!>a == b<!>
|
||||
}
|
||||
|
||||
fun <T, K> twoTypeParameters(a: T, b: K) where T : Number, K : <!FINAL_UPPER_BOUND!>String<!> {
|
||||
<!EQUALITY_NOT_APPLICABLE!>a == b<!>
|
||||
}
|
||||
|
||||
interface I1
|
||||
interface I2
|
||||
|
||||
enum class E3 : I1 { A, B }
|
||||
|
||||
fun <A> compareTypeParameterWithEnum(a: A) where A: I1, A: I2 {
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON_ERROR!>a == E1.A<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON_ERROR!>a == E3.A<!>
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
// LANGUAGE: +ReportErrorsForComparisonOperators
|
||||
|
||||
fun nullableNothingIdentity(a: Int, b: Nothing?) {
|
||||
a === <!DEBUG_INFO_CONSTANT!>b<!>
|
||||
}
|
||||
|
||||
fun samePrimitiveIdentity(a: Int, b: Int) {
|
||||
<!DEPRECATED_IDENTITY_EQUALS!>a === b<!>
|
||||
}
|
||||
|
||||
fun identityWithImplicitBoxing(a: Int, b: Any?) {
|
||||
<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a === b<!>
|
||||
}
|
||||
|
||||
enum class E1 { A, B }
|
||||
enum class E2 { C, D }
|
||||
|
||||
fun nullableEnums(a: E1?, b: E2?) {
|
||||
a == b
|
||||
}
|
||||
|
||||
fun <T> enumAsTypeParameterBound(a: T, b: Int) where T : Any, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>E1<!> {
|
||||
<!EQUALITY_NOT_APPLICABLE!>a == b<!>
|
||||
}
|
||||
|
||||
fun <T, K> twoTypeParameters(a: T, b: K) where T : Number, K : <!FINAL_UPPER_BOUND!>String<!> {
|
||||
a == b
|
||||
}
|
||||
|
||||
interface I1
|
||||
interface I2
|
||||
|
||||
enum class E3 : I1 { A, B }
|
||||
|
||||
fun <A> compareTypeParameterWithEnum(a: A) where A: I1, A: I2 {
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON_ERROR!>a == E1.A<!>
|
||||
a == E3.A
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
// LANGUAGE: -ReportErrorsForComparisonOperators
|
||||
|
||||
fun nullableNothingIdentity(a: Int, b: Nothing?) {
|
||||
<!FORBIDDEN_IDENTITY_EQUALS_WARNING, SENSELESS_COMPARISON!>a === b<!>
|
||||
}
|
||||
|
||||
fun samePrimitiveIdentity(a: Int, b: Int) {
|
||||
<!DEPRECATED_IDENTITY_EQUALS!>a === b<!>
|
||||
}
|
||||
|
||||
fun identityWithImplicitBoxing(a: Int, b: Any?) {
|
||||
<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a === b<!>
|
||||
}
|
||||
|
||||
enum class E1 { A, B }
|
||||
enum class E2 { C, D }
|
||||
|
||||
fun nullableEnums(a: E1?, b: E2?) {
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>a == b<!>
|
||||
}
|
||||
|
||||
fun <T> enumAsTypeParameterBound(a: T, b: Int) where T : Any, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>E1<!> {
|
||||
<!EQUALITY_NOT_APPLICABLE!>a == b<!>
|
||||
}
|
||||
|
||||
fun <T, K> twoTypeParameters(a: T, b: K) where T : Number, K : <!FINAL_UPPER_BOUND!>String<!> {
|
||||
<!EQUALITY_NOT_APPLICABLE_WARNING!>a == b<!>
|
||||
}
|
||||
|
||||
interface I1
|
||||
interface I2
|
||||
|
||||
enum class E3 : I1 { A, B }
|
||||
|
||||
fun <A> compareTypeParameterWithEnum(a: A) where A: I1, A: I2 {
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>a == E1.A<!>
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON!>a == E3.A<!>
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
// LANGUAGE: -ReportErrorsForComparisonOperators
|
||||
|
||||
fun nullableNothingIdentity(a: Int, b: Nothing?) {
|
||||
a === <!DEBUG_INFO_CONSTANT!>b<!>
|
||||
}
|
||||
|
||||
fun samePrimitiveIdentity(a: Int, b: Int) {
|
||||
<!DEPRECATED_IDENTITY_EQUALS!>a === b<!>
|
||||
}
|
||||
|
||||
fun identityWithImplicitBoxing(a: Int, b: Any?) {
|
||||
<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a === b<!>
|
||||
}
|
||||
|
||||
enum class E1 { A, B }
|
||||
enum class E2 { C, D }
|
||||
|
||||
fun nullableEnums(a: E1?, b: E2?) {
|
||||
a == b
|
||||
}
|
||||
|
||||
fun <T> enumAsTypeParameterBound(a: T, b: Int) where T : Any, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>E1<!> {
|
||||
<!EQUALITY_NOT_APPLICABLE!>a == b<!>
|
||||
}
|
||||
|
||||
fun <T, K> twoTypeParameters(a: T, b: K) where T : Number, K : <!FINAL_UPPER_BOUND!>String<!> {
|
||||
a == b
|
||||
}
|
||||
|
||||
interface I1
|
||||
interface I2
|
||||
|
||||
enum class E3 : I1 { A, B }
|
||||
|
||||
fun <A> compareTypeParameterWithEnum(a: A) where A: I1, A: I2 {
|
||||
<!INCOMPATIBLE_ENUM_COMPARISON_ERROR!>a == E1.A<!>
|
||||
a == E3.A
|
||||
}
|
||||
Generated
+90
@@ -159,6 +159,24 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/CompareToWithErrorType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingArbitraryClasses.kt")
|
||||
public void testComparingArbitraryClasses() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/comparingArbitraryClasses.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingCallableReferencesWithInstanceOfJavaClass.kt")
|
||||
public void testComparingCallableReferencesWithInstanceOfJavaClass() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/comparingCallableReferencesWithInstanceOfJavaClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparisonOfGenericInterfaceWithGenericClass.kt")
|
||||
public void testComparisonOfGenericInterfaceWithGenericClass() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/comparisonOfGenericInterfaceWithGenericClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("Constants.kt")
|
||||
public void testConstants() throws Exception {
|
||||
@@ -243,6 +261,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/DiamondProperty.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("differentNumericTypesFromSmartCast.kt")
|
||||
public void testDifferentNumericTypesFromSmartCast() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/differentNumericTypesFromSmartCast.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("Dollar.kt")
|
||||
public void testDollar() throws Exception {
|
||||
@@ -255,6 +279,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/EnumEntryAsType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityComparisonToSelf.kt")
|
||||
public void testEqualityComparisonToSelf() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/equalityComparisonToSelf.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityWithSmartCastInIfBlock.kt")
|
||||
public void testEqualityWithSmartCastInIfBlock() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/equalityWithSmartCastInIfBlock.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("ExtensionCallInvoke.kt")
|
||||
public void testExtensionCallInvoke() throws Exception {
|
||||
@@ -10398,6 +10434,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/enum/enumWithEmptyName.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityOfEnumAndParameter.kt")
|
||||
public void testEqualityOfEnumAndParameter() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/enum/equalityOfEnumAndParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityOfFlexibleTypeParameters.kt")
|
||||
public void testEqualityOfFlexibleTypeParameters() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/enum/equalityOfFlexibleTypeParameters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("ExplicitConstructorCall.kt")
|
||||
public void testExplicitConstructorCall() throws Exception {
|
||||
@@ -36203,6 +36251,30 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/commonCollections.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingDifferentSubclassesCommonInterface.kt")
|
||||
public void testComparingDifferentSubclassesCommonInterface() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/comparingDifferentSubclassesCommonInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingPlatformTypes.kt")
|
||||
public void testComparingPlatformTypes() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/comparingPlatformTypes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingSmartCastValueToBoolean.kt")
|
||||
public void testComparingSmartCastValueToBoolean() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/comparingSmartCastValueToBoolean.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("comparingTripleWithPair.kt")
|
||||
public void testComparingTripleWithPair() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/comparingTripleWithPair.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("compileTimeUnsignedArray.kt")
|
||||
public void testCompileTimeUnsignedArray() throws Exception {
|
||||
@@ -36227,6 +36299,24 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/enumEntryInitialization.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityCompatibilityCommonCases.kt")
|
||||
public void testEqualityCompatibilityCommonCases() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/equalityCompatibilityCommonCases.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityCompatibilityOldBehavior_Off.kt")
|
||||
public void testEqualityCompatibilityOldBehavior_Off() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/equalityCompatibilityOldBehavior_Off.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalityCompatibilityOldBehavior_On.kt")
|
||||
public void testEqualityCompatibilityOldBehavior_On() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/equalityCompatibilityOldBehavior_On.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("exitProcess.kt")
|
||||
public void testExitProcess() throws Exception {
|
||||
|
||||
@@ -21,7 +21,7 @@ fun case_1(x: Any?) {
|
||||
|
||||
// TESTCASE NUMBER: 3
|
||||
fun case_3() {
|
||||
if (<!SENSELESS_COMPARISON!>Object.prop_1 == null !== null<!>)
|
||||
if (<!FORBIDDEN_IDENTITY_EQUALS_WARNING, SENSELESS_COMPARISON!>Object.prop_1 == null !== null<!>)
|
||||
else {
|
||||
Object.prop_1
|
||||
Object.prop_1<!UNSAFE_CALL!>.<!>equals(null)
|
||||
@@ -56,7 +56,7 @@ fun case_4(x: Char?) {
|
||||
fun case_5() {
|
||||
val x: Unit? = null
|
||||
|
||||
if (<!EQUALITY_NOT_APPLICABLE!>x !== <!USELESS_IS_CHECK!>null is Boolean?<!><!>) <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit?")!>x<!>
|
||||
if (<!FORBIDDEN_IDENTITY_EQUALS!>x !== <!USELESS_IS_CHECK!>null is Boolean?<!><!>) <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit?")!>x<!>
|
||||
if (<!SENSELESS_COMPARISON!>x !== null == null<!>) <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit?")!>x<!><!UNSAFE_CALL!>.<!>equals(null)
|
||||
if (<!SENSELESS_COMPARISON!>x !== null == null<!>) <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit?")!>x<!>.propT
|
||||
if (<!SENSELESS_COMPARISON!>x !== null == null<!>) <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit?")!>x<!><!UNSAFE_CALL!>.<!>propAny
|
||||
@@ -88,7 +88,7 @@ fun case_6(x: EmptyClass?) {
|
||||
|
||||
// TESTCASE NUMBER: 7
|
||||
fun case_7() {
|
||||
if (nullableNumberProperty != null || <!SENSELESS_COMPARISON!><!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Nothing?")!>nullableNumberProperty<!> != null is Boolean<!>) {
|
||||
if (nullableNumberProperty != null || <!EQUALITY_NOT_APPLICABLE, SENSELESS_COMPARISON!><!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Nothing?")!>nullableNumberProperty<!> != null is Boolean<!>) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number?")!>nullableNumberProperty<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number?")!>nullableNumberProperty<!><!UNSAFE_CALL!>.<!>equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number?")!>nullableNumberProperty<!>.propT
|
||||
@@ -104,13 +104,13 @@ fun case_7() {
|
||||
|
||||
// TESTCASE NUMBER: 8
|
||||
fun case_8(x: TypealiasNullableString) {
|
||||
if (<!SENSELESS_COMPARISON!>x !== null === null<!> && <!SENSELESS_COMPARISON!><!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString")!>x<!> != null != null<!>) <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString")!>x<!><!UNSAFE_CALL!>.<!>get(0)
|
||||
if (<!SENSELESS_COMPARISON!>x !== null != null<!> && <!SENSELESS_COMPARISON!><!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString")!>x<!> != null === null<!>) <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString")!>x<!><!UNSAFE_CALL!>.<!>get(0)
|
||||
if (<!FORBIDDEN_IDENTITY_EQUALS_WARNING, SENSELESS_COMPARISON!>x !== null === null<!> && <!SENSELESS_COMPARISON!><!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString")!>x<!> != null != null<!>) <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString")!>x<!><!UNSAFE_CALL!>.<!>get(0)
|
||||
if (<!SENSELESS_COMPARISON!>x !== null != null<!> && <!FORBIDDEN_IDENTITY_EQUALS_WARNING, SENSELESS_COMPARISON!><!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString")!>x<!> != null === null<!>) <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString")!>x<!><!UNSAFE_CALL!>.<!>get(0)
|
||||
}
|
||||
|
||||
// TESTCASE NUMBER: 9
|
||||
fun case_9(x: TypealiasNullableString<!REDUNDANT_NULLABLE!>?<!>) {
|
||||
if (<!SENSELESS_COMPARISON!>x === null === null<!>) {
|
||||
if (<!FORBIDDEN_IDENTITY_EQUALS_WARNING, SENSELESS_COMPARISON!>x === null === null<!>) {
|
||||
|
||||
} else if (<!USELESS_IS_CHECK!>false is Boolean<!>) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString?")!>x<!>
|
||||
@@ -123,7 +123,7 @@ fun case_10() {
|
||||
val a = Class()
|
||||
|
||||
if (a.prop_4 === null || <!USELESS_IS_CHECK!>true is Boolean<!>) {
|
||||
if (<!SENSELESS_COMPARISON!>a.prop_4 != null !== null<!>) {
|
||||
if (<!FORBIDDEN_IDENTITY_EQUALS_WARNING, SENSELESS_COMPARISON!>a.prop_4 != null !== null<!>) {
|
||||
a.prop_4
|
||||
a.prop_4<!UNSAFE_CALL!>.<!>equals(null)
|
||||
a.prop_4.propT
|
||||
@@ -166,8 +166,8 @@ fun case_11(x: TypealiasNullableStringIndirect<!REDUNDANT_NULLABLE!>?<!>, y: Typ
|
||||
|
||||
// TESTCASE NUMBER: 12
|
||||
fun case_12(x: TypealiasNullableStringIndirect, y: TypealiasNullableStringIndirect) =
|
||||
if (<!USELESS_IS_CHECK!>(x == null) !is Boolean<!> === false) "1"
|
||||
else if (<!USELESS_IS_CHECK!>(<!SENSELESS_COMPARISON!>y === null !== null<!>) is Boolean<!>) <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableStringIndirect")!>x<!>
|
||||
if (<!DEPRECATED_IDENTITY_EQUALS!><!USELESS_IS_CHECK!>(x == null) !is Boolean<!> === false<!>) "1"
|
||||
else if (<!USELESS_IS_CHECK!>(<!FORBIDDEN_IDENTITY_EQUALS_WARNING, SENSELESS_COMPARISON!>y === null !== null<!>) is Boolean<!>) <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableStringIndirect")!>x<!>
|
||||
else if (<!SENSELESS_COMPARISON!>y === null != null<!>) <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableStringIndirect")!>x<!>.equals(null)
|
||||
else if (<!SENSELESS_COMPARISON!>y === null != null<!>) <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableStringIndirect")!>x<!>.propT
|
||||
else if (<!SENSELESS_COMPARISON!>y === null != null<!>) <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableStringIndirect")!>x<!><!UNSAFE_CALL!>.<!>propAny
|
||||
@@ -181,7 +181,7 @@ fun case_12(x: TypealiasNullableStringIndirect, y: TypealiasNullableStringIndire
|
||||
|
||||
// TESTCASE NUMBER: 13
|
||||
fun case_13(x: <!UNRESOLVED_REFERENCE!>otherpackage.Case13<!>?) =
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Boolean")!>if ((x == null !is Boolean) !== true) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Boolean")!>if (<!DEPRECATED_IDENTITY_EQUALS!>(x == null !is Boolean) !== true<!>) {
|
||||
throw Exception()
|
||||
} else {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("ERROR CLASS: Symbol not found for otherpackage.Case13? & kotlin.Boolean")!>x<!>
|
||||
@@ -204,18 +204,18 @@ fun case_14() {
|
||||
if (a.x != null == true) {
|
||||
if (<!SENSELESS_COMPARISON!>a.x !== null<!> == false) {
|
||||
if (<!SENSELESS_COMPARISON!><!SENSELESS_COMPARISON!>a.x != null<!> == null<!>) {
|
||||
if (<!SENSELESS_COMPARISON!><!SENSELESS_COMPARISON!>a.x != null<!> !== null<!>) {
|
||||
if (<!SENSELESS_COMPARISON!>a.x != null<!> === true) {
|
||||
if (<!SENSELESS_COMPARISON!>a.x !== null<!> === <!USELESS_IS_CHECK!>true !is Boolean<!> == true) {
|
||||
if (<!SENSELESS_COMPARISON!>a.x != null<!> !== false) {
|
||||
if (<!SENSELESS_COMPARISON!>a.x != null<!> === false) {
|
||||
if (<!SENSELESS_COMPARISON!>a.x !== null<!> === true) {
|
||||
if (<!FORBIDDEN_IDENTITY_EQUALS_WARNING, SENSELESS_COMPARISON!><!SENSELESS_COMPARISON!>a.x != null<!> !== null<!>) {
|
||||
if (<!DEPRECATED_IDENTITY_EQUALS!><!SENSELESS_COMPARISON!>a.x != null<!> === true<!>) {
|
||||
if (<!DEPRECATED_IDENTITY_EQUALS!><!SENSELESS_COMPARISON!>a.x !== null<!> === <!USELESS_IS_CHECK!>true !is Boolean<!><!> == true) {
|
||||
if (<!DEPRECATED_IDENTITY_EQUALS!><!SENSELESS_COMPARISON!>a.x != null<!> !== false<!>) {
|
||||
if (<!DEPRECATED_IDENTITY_EQUALS!><!SENSELESS_COMPARISON!>a.x != null<!> === false<!>) {
|
||||
if (<!DEPRECATED_IDENTITY_EQUALS!><!SENSELESS_COMPARISON!>a.x !== null<!> === true<!>) {
|
||||
if (<!USELESS_IS_CHECK!>(<!SENSELESS_COMPARISON!>a.x != null<!> != true) !is Boolean<!>) {
|
||||
if (a.x != null is Boolean) {
|
||||
if (a.x != <!USELESS_IS_CHECK!>null is Boolean is Boolean<!>) {
|
||||
if (a.x !== null is Boolean) {
|
||||
if (<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a.x !== null is Boolean<!>) {
|
||||
if (a.x != null is Boolean) {
|
||||
if ((a.x !== null !is Boolean) == false) {
|
||||
if ((<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>a.x !== null !is Boolean<!>) == false) {
|
||||
a.x
|
||||
a.x.equals(a.x)
|
||||
}
|
||||
@@ -238,7 +238,7 @@ fun case_14() {
|
||||
|
||||
// TESTCASE NUMBER: 15
|
||||
fun case_15(x: EmptyObject) {
|
||||
val t = if (<!EQUALITY_NOT_APPLICABLE!>x === <!USELESS_IS_CHECK!><!USELESS_IS_CHECK!>null is Boolean is Boolean<!> is Boolean<!><!>) "" else {
|
||||
val t = if (<!FORBIDDEN_IDENTITY_EQUALS!>x === <!USELESS_IS_CHECK!><!USELESS_IS_CHECK!>null is Boolean is Boolean<!> is Boolean<!><!>) "" else {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("EmptyObject")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("EmptyObject")!>x<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("EmptyObject")!>x<!>.propT
|
||||
@@ -256,7 +256,7 @@ fun case_15(x: EmptyObject) {
|
||||
fun case_16() {
|
||||
val x: TypealiasNullableNothing = null
|
||||
|
||||
if (<!EQUALITY_NOT_APPLICABLE!>x != <!USELESS_IS_CHECK!><!USELESS_IS_CHECK!><!USELESS_IS_CHECK!><!USELESS_IS_CHECK!>null !is Boolean !is Boolean<!> !is Boolean<!> !is Boolean<!> !is Boolean<!><!>) {
|
||||
if (<!SENSELESS_COMPARISON!>x != <!USELESS_IS_CHECK!><!USELESS_IS_CHECK!><!USELESS_IS_CHECK!><!USELESS_IS_CHECK!>null !is Boolean !is Boolean<!> !is Boolean<!> !is Boolean<!> !is Boolean<!><!>) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableNothing")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableNothing")!>x<!><!UNSAFE_CALL!>.<!>java
|
||||
}
|
||||
@@ -270,7 +270,7 @@ val case_17 = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>if (nullableIntPrope
|
||||
|
||||
//TESTCASE NUMBER: 18
|
||||
fun case_18(a: DeepObject.A.B.C.D.E.F.G.J?) {
|
||||
if (<!SENSELESS_COMPARISON!>a != null !== null<!>) {
|
||||
if (<!FORBIDDEN_IDENTITY_EQUALS_WARNING, SENSELESS_COMPARISON!>a != null !== null<!>) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("DeepObject.A.B.C.D.E.F.G.J?")!>a<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("DeepObject.A.B.C.D.E.F.G.J?")!>a<!><!UNSAFE_CALL!>.<!>equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("DeepObject.A.B.C.D.E.F.G.J?")!>a<!>.propT
|
||||
@@ -304,7 +304,7 @@ fun case_19(b: Boolean) {
|
||||
}
|
||||
} else null
|
||||
|
||||
if (<!EQUALITY_NOT_APPLICABLE!>a != null !is Boolean<!> && <!EQUALITY_NOT_APPLICABLE!>a<!UNSAFE_CALL!>.<!>B19 != null is Boolean<!> && <!EQUALITY_NOT_APPLICABLE!>a<!UNSAFE_CALL!>.<!>B19<!UNSAFE_CALL!>.<!>C19 != null is Boolean<!> && <!SENSELESS_COMPARISON!>a<!UNSAFE_CALL!>.<!>B19<!UNSAFE_CALL!>.<!>C19<!UNSAFE_CALL!>.<!>D19 != null == null<!> && <!SENSELESS_COMPARISON!>a<!UNSAFE_CALL!>.<!>B19<!UNSAFE_CALL!>.<!>C19<!UNSAFE_CALL!>.<!>D19<!UNSAFE_CALL!>.<!>x != null !== null<!>) {
|
||||
if (<!EQUALITY_NOT_APPLICABLE!>a != null !is Boolean<!> && <!EQUALITY_NOT_APPLICABLE!>a<!UNSAFE_CALL!>.<!>B19 != null is Boolean<!> && <!EQUALITY_NOT_APPLICABLE!>a<!UNSAFE_CALL!>.<!>B19<!UNSAFE_CALL!>.<!>C19 != null is Boolean<!> && <!SENSELESS_COMPARISON!>a<!UNSAFE_CALL!>.<!>B19<!UNSAFE_CALL!>.<!>C19<!UNSAFE_CALL!>.<!>D19 != null == null<!> && <!FORBIDDEN_IDENTITY_EQUALS_WARNING, SENSELESS_COMPARISON!>a<!UNSAFE_CALL!>.<!>B19<!UNSAFE_CALL!>.<!>C19<!UNSAFE_CALL!>.<!>D19<!UNSAFE_CALL!>.<!>x != null !== null<!>) {
|
||||
a<!UNSAFE_CALL!>.<!>B19<!UNSAFE_CALL!>.<!>C19<!UNSAFE_CALL!>.<!>D19<!UNSAFE_CALL!>.<!>x
|
||||
a<!UNSAFE_CALL!>.<!>B19<!UNSAFE_CALL!>.<!>C19<!UNSAFE_CALL!>.<!>D19<!UNSAFE_CALL!>.<!>x<!UNSAFE_CALL!>.<!>equals(null)
|
||||
a<!UNSAFE_CALL!>.<!>B19<!UNSAFE_CALL!>.<!>C19<!UNSAFE_CALL!>.<!>D19<!UNSAFE_CALL!>.<!>x.propT
|
||||
@@ -330,7 +330,7 @@ fun case_20(b: Boolean) {
|
||||
}
|
||||
}
|
||||
|
||||
if (<!EQUALITY_NOT_APPLICABLE!>a.B19.C19.D19 !== null !is Boolean<!>) {
|
||||
if (<!FORBIDDEN_IDENTITY_EQUALS!>a.B19.C19.D19 !== null !is Boolean<!>) {
|
||||
a.B19.C19.D19
|
||||
a.B19.C19.D19<!UNSAFE_CALL!>.<!>equals(null)
|
||||
a.B19.C19.D19.propT
|
||||
@@ -346,7 +346,7 @@ fun case_20(b: Boolean) {
|
||||
|
||||
// TESTCASE NUMBER: 21
|
||||
fun case_21() {
|
||||
if (<!EQUALITY_NOT_APPLICABLE_WARNING!>EnumClassWithNullableProperty.B.prop_1 !== null is Boolean<!> == <!USELESS_IS_CHECK!>true !is Boolean<!> != true) {
|
||||
if (<!FORBIDDEN_IDENTITY_EQUALS!>EnumClassWithNullableProperty.B.prop_1 !== null is Boolean<!> == <!USELESS_IS_CHECK!>true !is Boolean<!> != true) {
|
||||
EnumClassWithNullableProperty.B.prop_1
|
||||
EnumClassWithNullableProperty.B.prop_1<!UNSAFE_CALL!>.<!>equals(null)
|
||||
EnumClassWithNullableProperty.B.prop_1.propT
|
||||
@@ -378,7 +378,7 @@ fun case_22(a: (() -> Unit)?) {
|
||||
|
||||
// TESTCASE NUMBER: 23
|
||||
fun case_23(a: ((Float) -> Int?)?, b: Float?) {
|
||||
if (<!EQUALITY_NOT_APPLICABLE!>a != null !is Boolean<!> && <!EQUALITY_NOT_APPLICABLE_WARNING!>b !== null is Boolean<!>) {
|
||||
if (<!EQUALITY_NOT_APPLICABLE!>a != null !is Boolean<!> && <!FORBIDDEN_IDENTITY_EQUALS!>b !== null is Boolean<!>) {
|
||||
val x = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int?")!><!UNSAFE_IMPLICIT_INVOKE_CALL!>a<!>(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Float?")!>b<!>)<!>
|
||||
if (x != null) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int? & kotlin.Int")!>x<!>
|
||||
@@ -397,7 +397,7 @@ fun case_23(a: ((Float) -> Int?)?, b: Float?) {
|
||||
|
||||
// TESTCASE NUMBER: 24
|
||||
fun case_24(a: ((() -> Unit) -> Unit)?, b: (() -> Unit)?) =
|
||||
if (<!EQUALITY_NOT_APPLICABLE!>a !== null is Boolean<!> && <!EQUALITY_NOT_APPLICABLE!>b !== null !is Boolean<!>) {
|
||||
if (<!FORBIDDEN_IDENTITY_EQUALS!>a !== null is Boolean<!> && <!FORBIDDEN_IDENTITY_EQUALS!>b !== null !is Boolean<!>) {
|
||||
<!UNSAFE_IMPLICIT_INVOKE_CALL!>a<!>(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function0<kotlin.Unit>?")!>b<!>)
|
||||
<!UNSAFE_IMPLICIT_INVOKE_CALL!>a<!>(b)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function0<kotlin.Unit>?")!>b<!><!UNSAFE_CALL!>.<!>equals(null)
|
||||
@@ -421,10 +421,10 @@ fun case_25(b: Boolean) {
|
||||
|
||||
val y = if (b) x else null
|
||||
|
||||
if (y !== null === true) {
|
||||
if (<!DEPRECATED_IDENTITY_EQUALS!>y !== null === true<!>) {
|
||||
val z = <!DEBUG_INFO_EXPRESSION_TYPE("<anonymous>?")!>y()<!>
|
||||
|
||||
if (z != null !== false) {
|
||||
if (<!DEPRECATED_IDENTITY_EQUALS!>z != null !== false<!>) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("<anonymous>? & <anonymous>")!>z<!>.a
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("<anonymous>? & <anonymous>")!>z<!>.a.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("<anonymous>? & <anonymous>")!>z<!>.a.propT
|
||||
@@ -443,7 +443,7 @@ fun case_25(b: Boolean) {
|
||||
fun case_26(a: ((Float) -> Int?)?, b: Float?) {
|
||||
if (a != null == true == false && b != null == true == false) {
|
||||
val x = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int?")!><!UNSAFE_IMPLICIT_INVOKE_CALL!>a<!>(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Float? & kotlin.Nothing?")!>b<!>)<!>
|
||||
if (x != null == true === false) {
|
||||
if (<!DEPRECATED_IDENTITY_EQUALS!>x != null == true === false<!>) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int? & kotlin.Nothing?")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int? & kotlin.Nothing?")!>x<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int? & kotlin.Nothing?")!>x<!>.propT
|
||||
|
||||
@@ -322,7 +322,7 @@ fun case_15(x: EmptyObject) {
|
||||
fun case_16() {
|
||||
val x: TypealiasNullableNothing = null
|
||||
|
||||
if (x != null) {
|
||||
if (<!SENSELESS_COMPARISON!>x != null<!>) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableNothing & kotlin.Nothing")!>x<!>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ fun case_1(x: Any?) {
|
||||
* ISSUES: KT-28329
|
||||
*/
|
||||
fun case_2(x: Any) {
|
||||
if (x is Int === true) {
|
||||
if (<!DEPRECATED_IDENTITY_EQUALS!>x is Int === true<!>) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any & kotlin.Int")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any & kotlin.Int")!>x<!>.inv()
|
||||
}
|
||||
@@ -60,7 +60,7 @@ fun case_6(x: Any?) {
|
||||
* ISSUES: KT-28329
|
||||
*/
|
||||
fun case_7(x: Any) {
|
||||
if (!(x is DeepObject.A.B.C.D.E.F.G.J) !== false) else {
|
||||
if (<!DEPRECATED_IDENTITY_EQUALS!>!(x is DeepObject.A.B.C.D.E.F.G.J) !== false<!>) else {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any & DeepObject.A.B.C.D.E.F.G.J")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any & DeepObject.A.B.C.D.E.F.G.J")!>x<!>.prop_1
|
||||
}
|
||||
@@ -72,7 +72,7 @@ fun case_7(x: Any) {
|
||||
* ISSUES: KT-28329
|
||||
*/
|
||||
fun case_8(x: Any?) {
|
||||
if (!(x is Int?) !== false !== false !== false) else {
|
||||
if (<!DEPRECATED_IDENTITY_EQUALS!><!DEPRECATED_IDENTITY_EQUALS!><!DEPRECATED_IDENTITY_EQUALS!>!(x is Int?) !== false<!> !== false<!> !== false<!>) else {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Int?")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Int?")!>x<!>?.inv()
|
||||
}
|
||||
@@ -84,7 +84,7 @@ fun case_8(x: Any?) {
|
||||
* ISSUES: KT-28329
|
||||
*/
|
||||
fun case_9(x: Any?) {
|
||||
if (!!(x !is TypealiasNullableStringIndirect<!REDUNDANT_NULLABLE!>?<!>) !== false === true) else {
|
||||
if (<!DEPRECATED_IDENTITY_EQUALS!><!DEPRECATED_IDENTITY_EQUALS!>!!(x !is TypealiasNullableStringIndirect<!REDUNDANT_NULLABLE!>?<!>) !== false<!> === true<!>) else {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & TypealiasNullableStringIndirect?")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & TypealiasNullableStringIndirect?")!>x<!>?.get(0)
|
||||
}
|
||||
@@ -96,7 +96,7 @@ fun case_9(x: Any?) {
|
||||
* ISSUES: KT-28329
|
||||
*/
|
||||
fun case_10(x: Any?) {
|
||||
if (!!(x !is Interface3) === true && true) else {
|
||||
if (<!DEPRECATED_IDENTITY_EQUALS!>!!(x !is Interface3) === true<!> && true) else {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any?")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any?")!>x<!>.<!UNRESOLVED_REFERENCE!>itest<!>()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any?")!>x<!>.<!UNRESOLVED_REFERENCE!>itest3<!>()
|
||||
|
||||
@@ -161,7 +161,7 @@ inline fun <reified T>case_17(x: Any?) {
|
||||
* ISSUES: KT-30369, KT-28262, KT-29878
|
||||
*/
|
||||
inline fun <reified T>case_18(x: Any?) {
|
||||
if (x?.equals(10) === null === true) else {
|
||||
if (<!DEPRECATED_IDENTITY_EQUALS!>x?.equals(10) === null === true<!>) else {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Any")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Any")!>x<!>.equals(10)
|
||||
}
|
||||
@@ -173,7 +173,7 @@ inline fun <reified T>case_18(x: Any?) {
|
||||
* ISSUES: KT-30369, KT-28262, KT-29878
|
||||
*/
|
||||
inline fun <reified T>case_19(x: Any?) {
|
||||
if (x?.equals(10) !== null === true) {
|
||||
if (<!DEPRECATED_IDENTITY_EQUALS!>x?.equals(10) !== null === true<!>) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Any")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Any")!>x<!>.equals(10)
|
||||
}
|
||||
@@ -185,7 +185,7 @@ inline fun <reified T>case_19(x: Any?) {
|
||||
* ISSUES: KT-30369, KT-28262, KT-29878
|
||||
*/
|
||||
inline fun <reified T>case_20(x: Any?) {
|
||||
if (x?.equals(10) === null !== false) else {
|
||||
if (<!DEPRECATED_IDENTITY_EQUALS!>x?.equals(10) === null !== false<!>) else {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Any")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Any")!>x<!>.equals(10)
|
||||
}
|
||||
@@ -197,7 +197,7 @@ inline fun <reified T>case_20(x: Any?) {
|
||||
* ISSUES: KT-30369, KT-28262, KT-29878
|
||||
*/
|
||||
inline fun <reified T>case_21(x: Any?) {
|
||||
if (x?.equals(10) !== null !== false) {
|
||||
if (<!DEPRECATED_IDENTITY_EQUALS!>x?.equals(10) !== null !== false<!>) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Any")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Any")!>x<!>.equals(10)
|
||||
}
|
||||
@@ -209,7 +209,7 @@ inline fun <reified T>case_21(x: Any?) {
|
||||
* ISSUES: KT-30369, KT-28262, KT-29878
|
||||
*/
|
||||
inline fun <reified T>case_22(x: Any?) {
|
||||
if (x?.equals(10) !== null !== true) else {
|
||||
if (<!DEPRECATED_IDENTITY_EQUALS!>x?.equals(10) !== null !== true<!>) else {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Any")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Any")!>x<!>.equals(10)
|
||||
}
|
||||
@@ -221,7 +221,7 @@ inline fun <reified T>case_22(x: Any?) {
|
||||
* ISSUES: KT-30369, KT-28262, KT-29878
|
||||
*/
|
||||
inline fun <reified T>case_23(x: Any?) {
|
||||
if (x?.equals(10) === null === false) {
|
||||
if (<!DEPRECATED_IDENTITY_EQUALS!>x?.equals(10) === null === false<!>) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Any")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Any")!>x<!>.equals(10)
|
||||
}
|
||||
@@ -257,7 +257,7 @@ inline fun <reified T>case_25(x: Any?) {
|
||||
* ISSUES: KT-30369, KT-29878
|
||||
*/
|
||||
inline fun <reified T>case_26(x: Any?) {
|
||||
if (x?.equals(10) != null === false) else {
|
||||
if (<!DEPRECATED_IDENTITY_EQUALS!>x?.equals(10) != null === false<!>) else {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Any")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Any")!>x<!>.equals(10)
|
||||
}
|
||||
@@ -269,7 +269,7 @@ inline fun <reified T>case_26(x: Any?) {
|
||||
* ISSUES: KT-30369, KT-29878
|
||||
*/
|
||||
inline fun <reified T>case_27(x: Any?) {
|
||||
if (x?.equals(10) == null === false) {
|
||||
if (<!DEPRECATED_IDENTITY_EQUALS!>x?.equals(10) == null === false<!>) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Any")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Any")!>x<!>.equals(10)
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ fun case_15(x: TypealiasNullableString) {
|
||||
fun case_16() {
|
||||
val x: TypealiasNullableNothing = null
|
||||
|
||||
if (x == null || false || false || false) {
|
||||
if (<!SENSELESS_COMPARISON!>x == null<!> || false || false || false) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableNothing")!>x<!>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ fun case_10(x: Any?, z: Any, b: Boolean?) {
|
||||
false -> return
|
||||
null -> throw Exception()
|
||||
}
|
||||
z === y || if (b == true) return else if (b === false) null!! else throw Exception()
|
||||
z === y || if (b == true) return else if (<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>b === false<!>) null!! else throw Exception()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Any")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>y<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>y<!>.equals(10)
|
||||
@@ -137,7 +137,7 @@ fun case_10(x: Any?, z: Any, b: Boolean?) {
|
||||
fun case_11(x: Any?, z: Any, b: Boolean?) {
|
||||
while (true) {
|
||||
var y = x ?: if (b == true) continue<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!> else if (!(b != false)) return else break <!USELESS_ELVIS!>?: break::class<!>
|
||||
z !== y && if (b == true) return else if (b === false) null!!else throw Exception()
|
||||
z !== y && if (b == true) return else if (<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>b === false<!>) null!!else throw Exception()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Any")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>y<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>y<!>.equals(10)
|
||||
@@ -148,7 +148,7 @@ fun case_11(x: Any?, z: Any, b: Boolean?) {
|
||||
fun case_12(x: Any?, z: Any, b: Boolean?) {
|
||||
while (true) {
|
||||
var y = select(x) ?: if (b == true) continue<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!> else if (!(b != false)) return else break <!USELESS_ELVIS!>?: break::class<!>
|
||||
select(z) !== y && if (b == true) return else if (b === false) null!!else throw Exception()
|
||||
select(z) !== y && if (b == true) return else if (<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>b === false<!>) null!!else throw Exception()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any?")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>y<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>y<!>.equals(10)
|
||||
|
||||
@@ -77,7 +77,7 @@ fun case_6(x: Boolean?) {
|
||||
// TESTCASE NUMBER: 7
|
||||
fun case_7(x: Boolean?) {
|
||||
while (true) {
|
||||
if (!(x === false)) return
|
||||
if (!(<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>x === false<!>)) return
|
||||
}
|
||||
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Boolean?")!>x<!>
|
||||
|
||||
@@ -257,7 +257,7 @@ fun case_22(a: (() -> Unit)) {
|
||||
fun case_23(a: ((Float) -> Int), b: Float) {
|
||||
if (<!SENSELESS_COMPARISON!>a == null<!> && <!SENSELESS_COMPARISON!>b == null<!>) {
|
||||
val x = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>a(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Float & kotlin.Nothing")!>b<!>)<!>
|
||||
if (<!SENSELESS_COMPARISON!>x !== null<!>) {
|
||||
if (<!FORBIDDEN_IDENTITY_EQUALS_WARNING, SENSELESS_COMPARISON!>x !== null<!>) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>x<!>
|
||||
}
|
||||
}
|
||||
@@ -282,7 +282,7 @@ fun case_25(a: (() -> Unit) -> Unit, b: (() -> Unit) -> Unit = if (<!SENSELESS_C
|
||||
}
|
||||
|
||||
// TESTCASE NUMBER: 26
|
||||
fun case_26(a: Int, b: Int = if (<!SENSELESS_COMPARISON!>a === null<!>) <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int & kotlin.Nothing")!>a<!> else 0) {
|
||||
fun case_26(a: Int, b: Int = if (<!FORBIDDEN_IDENTITY_EQUALS_WARNING, SENSELESS_COMPARISON!>a === null<!>) <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int & kotlin.Nothing")!>a<!> else 0) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>a<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>b<!>
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ fun case_1(x: Any?, y: Any?) {
|
||||
* ISSUES: KT-30317
|
||||
*/
|
||||
fun case_2(x: Any?, y: Any?) {
|
||||
if (x as Int === y) {
|
||||
if (<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>x as Int === y<!>) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Int")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Int")!>x<!>.inv(<!TOO_MANY_ARGUMENTS!>10<!>)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Int")!>y<!>
|
||||
@@ -49,7 +49,7 @@ fun case_3(x: Any?, y: Any?) {
|
||||
* ISSUES: KT-30317
|
||||
*/
|
||||
fun case_4(x: Any?, y: Any?) {
|
||||
if (y === x as Int) {
|
||||
if (<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!>y === x as Int<!>) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Int")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Int")!>x<!>.inv(<!TOO_MANY_ARGUMENTS!>10<!>)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Int")!>y<!>
|
||||
|
||||
@@ -26,7 +26,7 @@ fun case_2() {
|
||||
do {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any?")!>x<!>
|
||||
x = x<!UNSAFE_CALL!>.<!>equals(10)
|
||||
} while (<!SENSELESS_COMPARISON!>x !== null<!>)
|
||||
} while (<!FORBIDDEN_IDENTITY_EQUALS_WARNING, SENSELESS_COMPARISON!>x !== null<!>)
|
||||
}
|
||||
|
||||
// TESTCASE NUMBER: 3
|
||||
@@ -58,7 +58,7 @@ fun case_5() {
|
||||
do {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any?")!>x<!>
|
||||
x = x<!UNSAFE_CALL!>.<!>equals(10)
|
||||
} while (<!SENSELESS_COMPARISON!>x !== null<!>)
|
||||
} while (<!FORBIDDEN_IDENTITY_EQUALS_WARNING, SENSELESS_COMPARISON!>x !== null<!>)
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -86,7 +86,7 @@ fun case_7() {
|
||||
do {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any?")!>x<!>
|
||||
x = x<!UNSAFE_CALL!>.<!>equals(10)
|
||||
} while (<!SENSELESS_COMPARISON!>x !== null<!>)
|
||||
} while (<!FORBIDDEN_IDENTITY_EQUALS_WARNING, SENSELESS_COMPARISON!>x !== null<!>)
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -114,7 +114,7 @@ fun case_9() {
|
||||
do {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any?")!>x<!>
|
||||
x = x<!UNSAFE_CALL!>.<!>equals(10)
|
||||
} while (<!SENSELESS_COMPARISON!>x !== null<!>)
|
||||
} while (<!FORBIDDEN_IDENTITY_EQUALS_WARNING, SENSELESS_COMPARISON!>x !== null<!>)
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -300,7 +300,7 @@ fun case_16() {
|
||||
val x: TypealiasNullableNothing = null
|
||||
val y: Nothing? = null
|
||||
|
||||
if (x !== y) {
|
||||
if (<!SENSELESS_COMPARISON!>x !== y<!>) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableNothing & kotlin.Nothing")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableNothing & kotlin.Nothing")!>x<!>.hashCode()
|
||||
}
|
||||
@@ -437,7 +437,7 @@ fun case_22(a: (() -> Unit)?) {
|
||||
|
||||
// TESTCASE NUMBER: 23
|
||||
fun case_23(a: ((Float) -> Int?)?, b: Float?, z: Nothing?) {
|
||||
if (a != z && b !== z && <!SENSELESS_COMPARISON!>b !== z<!>) {
|
||||
if (a != z && b !== z && <!FORBIDDEN_IDENTITY_EQUALS_WARNING, SENSELESS_COMPARISON!>b !== z<!>) {
|
||||
val x = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int?")!>a(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Float? & kotlin.Float")!>b<!>)<!>
|
||||
if (x != z || <!SENSELESS_COMPARISON!>x !== implicitNullableNothingProperty<!>) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int?")!>x<!>
|
||||
@@ -577,7 +577,7 @@ fun case_29(x: Boolean) {
|
||||
if (false || false || false || false || y !== v) {
|
||||
val t = <!DEBUG_INFO_EXPRESSION_TYPE("<anonymous>?")!><!UNSAFE_IMPLICIT_INVOKE_CALL!>y<!>()<!>
|
||||
|
||||
if (<!EQUALITY_NOT_APPLICABLE_WARNING!>z !== t<!> || false) {
|
||||
if (z !== t || false) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("<anonymous>?")!>t<!><!UNSAFE_CALL!>.<!>a
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("<anonymous>?")!>t<!><!UNSAFE_CALL!>.<!>equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("<anonymous>?")!>t<!>.propT
|
||||
@@ -677,7 +677,7 @@ fun case_33(a: ((Float) -> Int?)?, b: Float?, c: Boolean?) {
|
||||
fun case_34(z1: Boolean?) {
|
||||
var z = null
|
||||
|
||||
if (true && true && true && true && EnumClassWithNullableProperty.A.prop_1 != implicitNullableNothingProperty && <!SENSELESS_COMPARISON!>EnumClassWithNullableProperty.A.prop_1 !== null<!> && <!SENSELESS_COMPARISON!>EnumClassWithNullableProperty.A.prop_1 !== z<!> || z1 != implicitNullableNothingProperty || z1!! && true && true) {
|
||||
if (true && true && true && true && EnumClassWithNullableProperty.A.prop_1 != implicitNullableNothingProperty && <!FORBIDDEN_IDENTITY_EQUALS_WARNING, SENSELESS_COMPARISON!>EnumClassWithNullableProperty.A.prop_1 !== null<!> && <!FORBIDDEN_IDENTITY_EQUALS_WARNING, SENSELESS_COMPARISON!>EnumClassWithNullableProperty.A.prop_1 !== z<!> || z1 != implicitNullableNothingProperty || z1!! && true && true) {
|
||||
|
||||
} else {
|
||||
EnumClassWithNullableProperty.A.prop_1
|
||||
@@ -910,7 +910,7 @@ fun case_51() {
|
||||
val x: TypealiasNullableNothing = null
|
||||
val z: Nothing? = null
|
||||
|
||||
if (x === z || <!SENSELESS_COMPARISON!>z == x<!> && <!SENSELESS_COMPARISON!>x == z<!> || false || false || false) {
|
||||
if (<!SENSELESS_COMPARISON!>x === z<!> || <!SENSELESS_COMPARISON!>z == x<!> && <!SENSELESS_COMPARISON!>x == z<!> || false || false || false) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableNothing")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableNothing")!>x<!>.hashCode()
|
||||
}
|
||||
@@ -1401,7 +1401,7 @@ fun case_75(t: Any?, z: Nothing?) {
|
||||
}
|
||||
|
||||
// TESTCASE NUMBER: 76
|
||||
fun case_76(a: Any?, b: Int = if (a !is Number? === true || a !is Int? == true || a != null == false == true) 0 else <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Int")!>a<!>) {
|
||||
fun case_76(a: Any?, b: Int = if (<!DEPRECATED_IDENTITY_EQUALS!>a !is Number? === true<!> || a !is Int? == true || a != null == false == true) 0 else <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Int")!>a<!>) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any?")!>a<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>b<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>b<!>.equals(null)
|
||||
|
||||
@@ -168,7 +168,7 @@ fun case_9(x: TypealiasNullableString<!REDUNDANT_NULLABLE!>?<!>) {
|
||||
fun case_10() {
|
||||
val a = Class()
|
||||
|
||||
if (a.prop_4 === null || <!SENSELESS_COMPARISON!>a.prop_4 === null<!> || true) {
|
||||
if (a.prop_4 === null || <!FORBIDDEN_IDENTITY_EQUALS_WARNING, SENSELESS_COMPARISON!>a.prop_4 === null<!> || true) {
|
||||
if (a.prop_4 != null) {
|
||||
a.prop_4
|
||||
a.prop_4.equals(null)
|
||||
@@ -283,14 +283,14 @@ fun case_16() {
|
||||
val x: TypealiasNothing? = null
|
||||
val y: Nothing? = null
|
||||
|
||||
if (x != null || x !== null || x != y) {
|
||||
if (<!SENSELESS_COMPARISON!>x != null<!> || <!SENSELESS_COMPARISON!>x !== null<!> || <!SENSELESS_COMPARISON!>x != y<!>) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNothing? & kotlin.Nothing")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNothing? & kotlin.Nothing")!>x<!>.hashCode()
|
||||
}
|
||||
}
|
||||
|
||||
// TESTCASE NUMBER: 17
|
||||
val case_17 = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>if (nullableIntProperty == null || <!SENSELESS_COMPARISON!>nullableNothingProperty === nullableIntProperty<!>) 0 else {
|
||||
val case_17 = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>if (nullableIntProperty == null || <!FORBIDDEN_IDENTITY_EQUALS_WARNING, SENSELESS_COMPARISON!>nullableNothingProperty === nullableIntProperty<!>) 0 else {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int? & kotlin.Int")!>nullableIntProperty<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int? & kotlin.Int")!>nullableIntProperty<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int? & kotlin.Int")!>nullableIntProperty<!>.propAny
|
||||
|
||||
@@ -307,6 +307,10 @@ enum class LanguageFeature(
|
||||
// When this feature is enabled, no such errors are reported.
|
||||
NoBuilderInferenceWithoutAnnotationRestriction(sinceVersion = null, kind = OTHER),
|
||||
|
||||
// Disabled for indefinite time. Forces K2 report errors (instead of warnings) for incompatible
|
||||
// equality & identity operators in cases where K1 would report warnings or would not report anything.
|
||||
ReportErrorsForComparisonOperators(sinceVersion = null, kind = BUG_FIX),
|
||||
|
||||
// Experimental features
|
||||
|
||||
BreakContinueInInlineLambdas(null), // KT-1436
|
||||
|
||||
Reference in New Issue
Block a user