From e2dc21da909319f2d43272c493996f91cf430024 Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Wed, 28 Apr 2021 22:32:51 -0700 Subject: [PATCH] FIR checker: warn useless as and is --- .../testData/resolve/cfg/when.kt | 2 +- .../positive/exhaustiveness_sealedSubClass.kt | 2 +- .../testData/resolve/expresssions/when.kt | 2 +- .../testData/resolve/typesInLocalFunctions.kt | 2 +- .../problems/receiverResolutionInLambda.kt | 6 +- .../kotlin/fir/checkers/generator/Main.kt | 1 + .../generator/diagnostics/DiagnosticData.kt | 1 + .../diagnostics/FirDiagnosticsList.kt | 7 ++ .../expression/ComposedExpressionCheckers.kt | 4 + .../checkers/expression/ExpressionCheckers.kt | 2 + .../expression/FirExpressionCheckerAliases.kt | 2 + .../fir/analysis/diagnostics/FirErrors.kt | 5 + .../FirUselessTypeOperationCallChecker.kt | 91 +++++++++++++++++++ .../ExpressionCheckersDiagnosticComponent.kt | 2 +- .../diagnostics/FirDefaultErrorMessages.kt | 6 ++ .../LightTreePositioningStrategies.kt | 6 +- .../SourceElementPositioningStrategies.kt | 6 +- .../fir/checkers/CommonExpressionCheckers.kt | 5 + .../testData/diagnostics/tests/Casts.fir.kt | 2 +- .../diagnostics/tests/Constants.fir.kt | 2 +- .../diagnostics/tests/IsExpressions.fir.kt | 8 +- .../tests/NumberPrefixAndSuffix.fir.kt | 6 +- .../tests/StringPrefixAndSuffix.fir.kt | 4 +- .../tests/annotations/ConstructorCall.fir.kt | 2 +- .../tests/cast/AsInBlockWithReturnType.fir.kt | 4 +- .../AsInPropertyAndPropertyAccessor.fir.kt | 4 +- .../tests/cast/FlexibleTargetType.fir.kt | 8 +- ...IsErasedAllowForExactSupertypeCheck.fir.kt | 5 - .../IsErasedAllowForExactSupertypeCheck.kt | 1 + ...wForSupertypeCheckWithContrvariance.fir.kt | 8 -- ...AllowForSupertypeCheckWithContrvariance.kt | 1 + ...llowForSupertypeCheckWithCovariance.fir.kt | 8 -- ...sedAllowForSupertypeCheckWithCovariance.kt | 1 + .../tests/cast/IsErasedAllowFromOut.fir.kt | 1 - .../tests/cast/IsErasedAllowFromOut.kt | 1 + .../tests/cast/IsErasedAllowFromOut2.fir.kt | 1 - .../tests/cast/IsErasedAllowFromOut2.kt | 1 + .../cast/IsErasedAllowFromOutAtClass.fir.kt | 1 - .../tests/cast/IsErasedAllowFromOutAtClass.kt | 1 + .../tests/cast/IsErasedTasT.fir.kt | 1 - .../diagnostics/tests/cast/IsErasedTasT.kt | 1 + .../cast/IsErasedUpcastToNonReified.fir.kt | 18 ++-- .../tests/cast/UselessSafeCast.fir.kt | 10 +- .../tests/cast/checkCastToNullableType.fir.kt | 14 +-- .../diagnostics/tests/cast/constants.fir.kt | 8 +- .../tests/classObjects/kt3866.fir.kt | 20 ---- .../diagnostics/tests/classObjects/kt3866.kt | 1 + .../typeParametersInAnnonymousObject.fir.kt | 12 ++- .../typeParametersInAnnonymousObject.kt | 10 ++ ...eParametersInAnnonymousObject_after.fir.kt | 12 ++- .../typeParametersInAnnonymousObject_after.kt | 10 ++ .../UninitializedOrReassignedVariables.fir.kt | 2 +- .../controlStructures/when.kt234.kt973.fir.kt | 2 +- .../diagnostics/tests/dataFlow/EmptyIf.fir.kt | 2 +- .../tests/dataFlow/assignment/kt6118.fir.kt | 4 +- .../dataFlowInfoTraversal/IsExpression.fir.kt | 2 +- .../dataFlowInfoTraversal/ManyIfs.fir.kt | 10 +- .../tests/enum/enumSubjectTypeCheck.fir.kt | 6 +- .../expectedTypeAdditionalTest.fir.kt | 2 +- .../inference/expectedTypeFromCast.fir.kt | 4 +- .../tests/inference/findViewById.fir.kt | 59 ------------ .../tests/inference/findViewById.kt | 1 + .../diagnostics/tests/infos/SmartCasts.fir.kt | 10 +- .../diagnostics/tests/inline/isCheck.fir.kt | 10 -- .../diagnostics/tests/inline/isCheck.kt | 1 + .../diagnostics/tests/inline/when.fir.kt | 11 --- .../testData/diagnostics/tests/inline/when.kt | 1 + .../tests/regressions/kt7804.fir.kt | 6 +- .../tests/sealed/ExhaustiveOnRoot.fir.kt | 23 ----- .../tests/sealed/ExhaustiveOnRoot.kt | 1 + .../NonExhaustiveWhenWithAnyCase.fir.kt | 15 --- .../sealed/NonExhaustiveWhenWithAnyCase.kt | 1 + .../tests/smartCasts/alwaysNull.fir.kt | 4 +- .../smartCasts/castchecks/basicOff.fir.kt | 6 +- .../smartCasts/castchecks/basicOn.fir.kt | 6 +- .../smartCasts/castchecks/impossible.fir.kt | 25 ----- .../tests/smartCasts/castchecks/impossible.kt | 1 + .../tests/smartCasts/extensionSafeCall.fir.kt | 4 +- .../tests/smartCasts/kt10232.fir.kt | 15 --- .../diagnostics/tests/smartCasts/kt10232.kt | 1 + .../tests/smartCasts/kt27221.fir.kt | 4 +- .../tests/smartCasts/kt27221_2.fir.kt | 6 +- .../tests/smartCasts/kt5455.fir.kt | 28 ------ .../diagnostics/tests/smartCasts/kt5455.kt | 1 + .../tests/smartCasts/safeAs.fir.kt | 4 +- .../tests/suppress/oneWarning/onClass.fir.kt | 4 - .../tests/suppress/oneWarning/onClass.kt | 1 + .../suppress/oneWarning/onClassObject.fir.kt | 6 -- .../suppress/oneWarning/onClassObject.kt | 1 + .../suppress/oneWarning/onExpression.fir.kt | 4 - .../tests/suppress/oneWarning/onExpression.kt | 1 + .../suppress/oneWarning/onFunction.fir.kt | 4 - .../tests/suppress/oneWarning/onFunction.kt | 1 + .../oneWarning/onLocalVariable.fir.kt | 7 -- .../suppress/oneWarning/onLocalVariable.kt | 1 + .../tests/suppress/oneWarning/onObject.fir.kt | 4 - .../tests/suppress/oneWarning/onObject.kt | 1 + .../suppress/oneWarning/onParameter.fir.kt | 3 - .../tests/suppress/oneWarning/onParameter.kt | 1 + .../suppress/oneWarning/onProperty.fir.kt | 4 - .../tests/suppress/oneWarning/onProperty.kt | 1 + .../oneWarning/onPropertyAccessor.fir.kt | 5 - .../suppress/oneWarning/onPropertyAccessor.kt | 1 + .../diagnostics/tests/when/When.fir.kt | 6 +- .../tests/when/WhenTypeDisjunctions.fir.kt | 2 +- .../testsWithStdLib/cast/IsArray.fir.kt | 4 +- .../contracts/smartcasts/deeplyNested.fir.kt | 2 +- .../valueOfContractedFunctionIngored.fir.kt | 11 --- .../valueOfContractedFunctionIngored.kt | 1 + .../type-checking-expression/p-4/pos/1.1.kt | 2 +- .../p-2/neg/9.1.fir.kt | 83 ----------------- .../p-2/neg/9.1.kt | 1 + .../p-2/pos/1.3.fir.kt | 2 +- .../p-2/pos/7.1.fir.kt | 2 +- .../when-expression/p-2/pos/2.1.fir.kt | 6 +- .../when-expression/p-6/pos/1.1.fir.kt | 2 +- .../p-1/pos/1.3.fir.kt | 2 +- .../analysis/smartcasts/neg/15.fir.kt | 2 +- .../analysis/smartcasts/pos/2.fir.kt | 2 +- .../effects/returns/neg/7.fir.kt | 2 +- .../contractFunction/neg/2.fir.kt | 6 +- .../diagnostics/notLinked/dfa/neg/1.fir.kt | 32 +++---- .../diagnostics/notLinked/dfa/neg/3.fir.kt | 14 +-- .../diagnostics/notLinked/dfa/neg/4.fir.kt | 10 +- .../diagnostics/notLinked/dfa/neg/6.fir.kt | 10 +- .../diagnostics/notLinked/dfa/pos/22.fir.kt | 12 +-- .../diagnostics/notLinked/dfa/pos/25.fir.kt | 4 +- .../diagnostics/notLinked/dfa/pos/26.fir.kt | 4 +- .../diagnostics/notLinked/dfa/pos/27.fir.kt | 4 +- .../diagnostics/notLinked/dfa/pos/31.fir.kt | 2 +- .../diagnostics/notLinked/dfa/pos/34.fir.kt | 2 +- .../diagnostics/notLinked/dfa/pos/5.fir.kt | 2 +- .../diagnostics/notLinked/dfa/pos/51.fir.kt | 4 +- .../diagnostics/notLinked/dfa/pos/54.fir.kt | 4 +- .../diagnostics/notLinked/dfa/pos/59.fir.kt | 6 +- .../diagnostics/notLinked/dfa/pos/6.fir.kt | 2 +- .../diagnostics/notLinked/dfa/pos/66.fir.kt | 2 +- .../fir/generator/HLDiagnosticConverter.kt | 1 + .../diagnostics/KtFirDataClassConverters.kt | 14 +++ .../api/fir/diagnostics/KtFirDiagnostics.kt | 10 ++ .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 16 ++++ 141 files changed, 417 insertions(+), 543 deletions(-) create mode 100644 compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUselessTypeOperationCallChecker.kt delete mode 100644 compiler/testData/diagnostics/tests/cast/IsErasedAllowForExactSupertypeCheck.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/cast/IsErasedAllowForSupertypeCheckWithContrvariance.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/cast/IsErasedAllowForSupertypeCheckWithCovariance.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut2.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOutAtClass.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/cast/IsErasedTasT.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/classObjects/kt3866.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/inference/findViewById.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/inline/isCheck.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/inline/when.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/sealed/ExhaustiveOnRoot.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenWithAnyCase.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/smartCasts/castchecks/impossible.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/smartCasts/kt10232.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/smartCasts/kt5455.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/suppress/oneWarning/onClass.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/suppress/oneWarning/onClassObject.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/suppress/oneWarning/onExpression.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/suppress/oneWarning/onFunction.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/suppress/oneWarning/onLocalVariable.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/suppress/oneWarning/onObject.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/suppress/oneWarning/onParameter.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/suppress/oneWarning/onProperty.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/suppress/oneWarning/onPropertyAccessor.fir.kt delete mode 100644 compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/valueOfContractedFunctionIngored.fir.kt delete mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/9.1.fir.kt diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/when.kt b/compiler/fir/analysis-tests/testData/resolve/cfg/when.kt index fe5b1fcfbb7..1264fd69cf0 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/when.kt +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/when.kt @@ -13,6 +13,6 @@ interface B fun test_2(x: Any?) { if (x is A && x is B) { - x is A + x is A } } diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedSubClass.kt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedSubClass.kt index e7c9a2027b2..0e3762dfeb1 100644 --- a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedSubClass.kt +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedSubClass.kt @@ -27,7 +27,7 @@ fun test_1(e: A) { val d = when (e) { is E -> 1 - is A -> 2 + is A -> 2 }.plus(0) } diff --git a/compiler/fir/analysis-tests/testData/resolve/expresssions/when.kt b/compiler/fir/analysis-tests/testData/resolve/expresssions/when.kt index 9947275b9b9..7e5a00052de 100644 --- a/compiler/fir/analysis-tests/testData/resolve/expresssions/when.kt +++ b/compiler/fir/analysis-tests/testData/resolve/expresssions/when.kt @@ -1,6 +1,6 @@ fun foo() = if (true) 1 else 0 fun bar(arg: Any?) = when (arg) { - is Int -> arg as Int + is Int -> arg as Int else -> 42 } diff --git a/compiler/fir/analysis-tests/testData/resolve/typesInLocalFunctions.kt b/compiler/fir/analysis-tests/testData/resolve/typesInLocalFunctions.kt index 2dbee247b04..270558549fe 100644 --- a/compiler/fir/analysis-tests/testData/resolve/typesInLocalFunctions.kt +++ b/compiler/fir/analysis-tests/testData/resolve/typesInLocalFunctions.kt @@ -3,7 +3,7 @@ class Some fun foo(): () -> Boolean { val s = Some() if (true) { - return { if (s is Some) true else false } + return { if (s is Some) true else false } } else { return { true } } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/receiverResolutionInLambda.kt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/receiverResolutionInLambda.kt index 62aaa928a89..004168479ec 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/receiverResolutionInLambda.kt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/receiverResolutionInLambda.kt @@ -14,7 +14,7 @@ class Case1() { this.yield("") //UNRESOLVED_REFERENCE - this as SequenceScope + this as SequenceScope yield("") // resolved to SequenceScope.yield @@ -31,10 +31,10 @@ fun case2() { this.yield("") //UNRESOLVED_REFERENCE - this as SequenceScope + this as SequenceScope yield("") // UNRESOLVED_REFERENCE this.yield("") // UNRESOLVED_REFERENCE } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/Main.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/Main.kt index fc14480eeb6..204d1d84ae4 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/Main.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/Main.kt @@ -38,6 +38,7 @@ fun main(args: Array) { alias("EqualityOperatorCallChecker") alias("AnonymousFunctionAsExpressionChecker") alias("StringConcatenationCallChecker") + alias("TypeOperatorCallChecker") alias("ResolvedQualifierChecker") } diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/DiagnosticData.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/DiagnosticData.kt index b763933bd81..ad213f6fa80 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/DiagnosticData.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/DiagnosticData.kt @@ -52,6 +52,7 @@ enum class PositioningStrategy(private val strategy: String? = null) { CONST_MODIFIER, ARRAY_ACCESS, SAFE_ACCESS, + AS_TYPE, USELESS_ELVIS, NAME_OF_NAMED_ARGUMENT, VALUE_ARGUMENTS, diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index f6433564d0d..b8918c20cae 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -654,6 +654,13 @@ object DIAGNOSTICS_LIST : DiagnosticList() { val USELESS_ELVIS_RIGHT_IS_NULL by warning(PositioningStrategy.USELESS_ELVIS) } + val CASTS_AND_IS_CHECKS by object : DiagnosticGroup("Casts and is-checks") { + val USELESS_CAST by warning(PositioningStrategy.AS_TYPE) + val USELESS_IS_CHECK by warning { + parameter("compileTimeCheckResult") + } + } + val WHEN_EXPRESSIONS by object : DiagnosticGroup("When expressions") { val NO_ELSE_IN_WHEN by error(PositioningStrategy.WHEN_EXPRESSION) { parameter>("missingWhenCases") diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/expression/ComposedExpressionCheckers.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/expression/ComposedExpressionCheckers.kt index 17fbfb51bd1..494a6aea306 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/expression/ComposedExpressionCheckers.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/expression/ComposedExpressionCheckers.kt @@ -45,6 +45,8 @@ class ComposedExpressionCheckers : ExpressionCheckers() { get() = _anonymousFunctionAsExpressionCheckers override val stringConcatenationCallCheckers: Set get() = _stringConcatenationCallCheckers + override val typeOperatorCallCheckers: Set + get() = _typeOperatorCallCheckers override val resolvedQualifierCheckers: Set get() = _resolvedQualifierCheckers @@ -64,6 +66,7 @@ class ComposedExpressionCheckers : ExpressionCheckers() { private val _equalityOperatorCallCheckers: MutableSet = mutableSetOf() private val _anonymousFunctionAsExpressionCheckers: MutableSet = mutableSetOf() private val _stringConcatenationCallCheckers: MutableSet = mutableSetOf() + private val _typeOperatorCallCheckers: MutableSet = mutableSetOf() private val _resolvedQualifierCheckers: MutableSet = mutableSetOf() @CheckersComponentInternal @@ -84,6 +87,7 @@ class ComposedExpressionCheckers : ExpressionCheckers() { _equalityOperatorCallCheckers += checkers.equalityOperatorCallCheckers _anonymousFunctionAsExpressionCheckers += checkers.anonymousFunctionAsExpressionCheckers _stringConcatenationCallCheckers += checkers.stringConcatenationCallCheckers + _typeOperatorCallCheckers += checkers.typeOperatorCallCheckers _resolvedQualifierCheckers += checkers.resolvedQualifierCheckers } } diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/expression/ExpressionCheckers.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/expression/ExpressionCheckers.kt index 788334c72b0..db1cb7eb3a5 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/expression/ExpressionCheckers.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/expression/ExpressionCheckers.kt @@ -33,6 +33,7 @@ abstract class ExpressionCheckers { open val equalityOperatorCallCheckers: Set = emptySet() open val anonymousFunctionAsExpressionCheckers: Set = emptySet() open val stringConcatenationCallCheckers: Set = emptySet() + open val typeOperatorCallCheckers: Set = emptySet() open val resolvedQualifierCheckers: Set = emptySet() @CheckersComponentInternal internal val allBasicExpressionCheckers: Set get() = basicExpressionCheckers @@ -51,5 +52,6 @@ abstract class ExpressionCheckers { @CheckersComponentInternal internal val allEqualityOperatorCallCheckers: Set get() = equalityOperatorCallCheckers + basicExpressionCheckers @CheckersComponentInternal internal val allAnonymousFunctionAsExpressionCheckers: Set get() = anonymousFunctionAsExpressionCheckers + basicExpressionCheckers @CheckersComponentInternal internal val allStringConcatenationCallCheckers: Set get() = stringConcatenationCallCheckers + basicExpressionCheckers + @CheckersComponentInternal internal val allTypeOperatorCallCheckers: Set get() = typeOperatorCallCheckers + basicExpressionCheckers @CheckersComponentInternal internal val allResolvedQualifierCheckers: Set get() = resolvedQualifierCheckers + basicExpressionCheckers } diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirExpressionCheckerAliases.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirExpressionCheckerAliases.kt index b2bc160ba0f..18a4fba256d 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirExpressionCheckerAliases.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirExpressionCheckerAliases.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.expressions.FirSafeCallExpression import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.expressions.FirStringConcatenationCall import org.jetbrains.kotlin.fir.expressions.FirTryExpression +import org.jetbrains.kotlin.fir.expressions.FirTypeOperatorCall import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment import org.jetbrains.kotlin.fir.expressions.FirWhenExpression @@ -44,4 +45,5 @@ typealias FirSafeCallExpressionChecker = FirExpressionChecker typealias FirAnonymousFunctionAsExpressionChecker = FirExpressionChecker typealias FirStringConcatenationCallChecker = FirExpressionChecker +typealias FirTypeOperatorCallChecker = FirExpressionChecker typealias FirResolvedQualifierChecker = FirExpressionChecker diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index a8961a8a3db..19802569ed8 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -35,6 +35,7 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtAnnotation import org.jetbrains.kotlin.psi.KtArrayAccessExpression import org.jetbrains.kotlin.psi.KtBinaryExpression +import org.jetbrains.kotlin.psi.KtBinaryExpressionWithTypeRHS import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtDeclaration @@ -390,6 +391,10 @@ object FirErrors { val USELESS_ELVIS by warning1(SourceElementPositioningStrategies.USELESS_ELVIS) val USELESS_ELVIS_RIGHT_IS_NULL by warning0(SourceElementPositioningStrategies.USELESS_ELVIS) + // Casts and is-checks + val USELESS_CAST by warning0(SourceElementPositioningStrategies.AS_TYPE) + val USELESS_IS_CHECK by warning1() + // When expressions val NO_ELSE_IN_WHEN by error1>(SourceElementPositioningStrategies.WHEN_EXPRESSION) val INVALID_IF_AS_EXPRESSION by error0(SourceElementPositioningStrategies.IF_EXPRESSION) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUselessTypeOperationCallChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUselessTypeOperationCallChecker.kt new file mode 100644 index 00000000000..ed1343ef196 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUselessTypeOperationCallChecker.kt @@ -0,0 +1,91 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.analysis.checkers.expression + +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn +import org.jetbrains.kotlin.fir.expressions.* +import org.jetbrains.kotlin.fir.resolve.fullyExpandedType +import org.jetbrains.kotlin.fir.typeContext +import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.types.AbstractTypeChecker + +// See .../types/CastDiagnosticsUtil.kt for counterparts, including isRefinementUseless, isExactTypeCast, isUpcast. +object FirUselessTypeOperationCallChecker : FirTypeOperatorCallChecker() { + override fun check(expression: FirTypeOperatorCall, context: CheckerContext, reporter: DiagnosticReporter) { + if (expression.operation !in FirOperation.TYPES) return + val arg = expression.argument + + val candidateType = arg.typeRef.coneType.upperBoundIfFlexible().fullyExpandedType(context.session) + if (candidateType is ConeKotlinErrorType) return + + val targetType = expression.conversionTypeRef.coneType.fullyExpandedType(context.session) + if (targetType is ConeKotlinErrorType) return + + // x as? Type <=> x as Type? + val refinedTargetType = + if (expression.operation == FirOperation.SAFE_AS) { + targetType.withNullability(ConeNullability.NULLABLE, context.session.typeContext) + } else { + targetType + } + if (isRefinementUseless(context, candidateType, refinedTargetType, shouldCheckForExactType(expression, context))) { + when (expression.operation) { + FirOperation.IS -> reporter.reportOn(expression.source, FirErrors.USELESS_IS_CHECK, true, context) + FirOperation.NOT_IS -> reporter.reportOn(expression.source, FirErrors.USELESS_IS_CHECK, false, context) + FirOperation.AS, FirOperation.SAFE_AS -> reporter.reportOn(expression.source, FirErrors.USELESS_CAST, context) + else -> throw AssertionError("Should not be here: ${expression.operation}") + } + } + } + + @Suppress("UNUSED_PARAMETER") + private fun shouldCheckForExactType(expression: FirTypeOperatorCall, context: CheckerContext): Boolean { + return when (expression.operation) { + FirOperation.IS, FirOperation.NOT_IS -> false + // TODO: differentiate if this expression defines the enclosing thing's type + // e.g., + // val c1 get() = 1 as Number + // val c2: Number get() = 1 as Number + FirOperation.AS, FirOperation.SAFE_AS -> true + else -> throw AssertionError("Should not be here: ${expression.operation}") + } + } + + private fun isRefinementUseless( + context: CheckerContext, + candidateType: ConeKotlinType, + targetType: ConeKotlinType, + shouldCheckForExactType: Boolean, + ): Boolean { + return if (shouldCheckForExactType) { + isExactTypeCast(context, candidateType, targetType) + } else { + isUpcast(context, candidateType, targetType) + } + } + + private fun isExactTypeCast(context: CheckerContext, candidateType: ConeKotlinType, targetType: ConeKotlinType): Boolean { + if (!AbstractTypeChecker.equalTypes(context.session.typeContext, candidateType, targetType, stubTypesEqualToAnything = false)) + return false + // See comments at [isUpcast] why we need to check the existence of @ExtensionFunctionType + return candidateType.isExtensionFunctionType == targetType.isExtensionFunctionType + } + + private fun isUpcast(context: CheckerContext, candidateType: ConeKotlinType, targetType: ConeKotlinType): Boolean { + if (!AbstractTypeChecker.isSubtypeOf(context.session.typeContext, candidateType, targetType, stubTypesEqualToAnything = false)) + return false + + // E.g., foo(p1: (X) -> Y), where p1 has a functional type whose receiver type is X and return type is Y. + // For bar(p2: X.() -> Y), p2 has the same functional type (with same receiver and return types). + // The only difference is the existence of type annotation, @ExtensionFunctionType, + // which indicates that the annotated type represents an extension function. + // If one casts p1 to p2 (or vice versa), it is _not_ up cast, i.e., not redundant, yet meaningful. + return candidateType.isExtensionFunctionType == targetType.isExtensionFunctionType + } +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ExpressionCheckersDiagnosticComponent.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ExpressionCheckersDiagnosticComponent.kt index 18e5b84144d..34aa3c91655 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ExpressionCheckersDiagnosticComponent.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ExpressionCheckersDiagnosticComponent.kt @@ -28,7 +28,7 @@ class ExpressionCheckersDiagnosticComponent( } override fun visitTypeOperatorCall(typeOperatorCall: FirTypeOperatorCall, data: CheckerContext) { - checkers.allBasicExpressionCheckers.check(typeOperatorCall, data, reporter) + checkers.allTypeOperatorCallCheckers.check(typeOperatorCall, data, reporter) } override fun visitConstExpression(constExpression: FirConstExpression, data: CheckerContext) { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index 385ca0d36d3..61b3c6affed 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -282,8 +282,10 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNUSED_VARIABLE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UPPER_BOUND_IS_EXTENSION_FUNCTION_TYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UPPER_BOUND_VIOLATED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USAGE_IS_NOT_INLINABLE +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_CAST import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_ELVIS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_ELVIS_RIGHT_IS_NULL +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_IS_CHECK import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_VARARG_ON_PARAMETER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNOT_BE_CLONEABLE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION @@ -871,6 +873,10 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension { map.put(USELESS_ELVIS, "Elvis operator (?:) always returns the left operand of non-nullable type {0}", RENDER_TYPE) map.put(USELESS_ELVIS_RIGHT_IS_NULL, "Right operand of elvis operator (?:) is useless if it is null") + // Casts and is-checks + map.put(USELESS_CAST, "No cast needed") + map.put(USELESS_IS_CHECK, "Check for instance is always ''{0}''", TO_STRING) + // When expressions map.put(NO_ELSE_IN_WHEN, "''when'' expression must be exhaustive, add necessary {0}", WHEN_MISSING_CASES) map.put(INVALID_IF_AS_EXPRESSION, "'if' must have both main and 'else' branches if used as an expression") diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt index 2a9902efd7c..892c24ce5b7 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt @@ -594,7 +594,7 @@ object LightTreePositioningStrategies { } } - val USELESS_ELVIS = object : LightTreePositioningStrategy() { + private val OPERATION_TO_END = object : LightTreePositioningStrategy() { override fun mark( node: LighterASTNode, startOffset: Int, @@ -605,6 +605,10 @@ object LightTreePositioningStrategies { } } + val AS_TYPE = OPERATION_TO_END + + val USELESS_ELVIS = OPERATION_TO_END + val RETURN_WITH_LABEL = object : LightTreePositioningStrategy() { override fun mark( node: LighterASTNode, diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt index 9e9f562d220..a04f08242f1 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt @@ -118,7 +118,6 @@ object SourceElementPositioningStrategies { PositioningStrategies.SUSPEND_MODIFIER ) - val OPERATOR = SourceElementPositioningStrategy( LightTreePositioningStrategies.OPERATOR, PositioningStrategies.OPERATOR @@ -194,6 +193,11 @@ object SourceElementPositioningStrategies { PositioningStrategies.SAFE_ACCESS ) + val AS_TYPE = SourceElementPositioningStrategy( + LightTreePositioningStrategies.AS_TYPE, + PositioningStrategies.AS_TYPE + ) + val USELESS_ELVIS = SourceElementPositioningStrategy( LightTreePositioningStrategies.USELESS_ELVIS, PositioningStrategies.USELESS_ELVIS diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonExpressionCheckers.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonExpressionCheckers.kt index 36382fad35e..2edda7ccb3c 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonExpressionCheckers.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonExpressionCheckers.kt @@ -94,6 +94,11 @@ object CommonExpressionCheckers : ExpressionCheckers() { FirAnonymousFunctionChecker, ) + override val typeOperatorCallCheckers: Set + get() = setOf( + FirUselessTypeOperationCallChecker, + ) + override val resolvedQualifierCheckers: Set get() = setOf( FirStandaloneQualifierChecker, diff --git a/compiler/testData/diagnostics/tests/Casts.fir.kt b/compiler/testData/diagnostics/tests/Casts.fir.kt index 54d6ee2d330..eb6615ef52c 100644 --- a/compiler/testData/diagnostics/tests/Casts.fir.kt +++ b/compiler/testData/diagnostics/tests/Casts.fir.kt @@ -7,7 +7,7 @@ fun test() : Unit { checkSubtype(x) checkSubtype(y) checkSubtype(x as Int) - checkSubtype(y as Int) + checkSubtype(y as Int) checkSubtype(x as Int?) checkSubtype(y as Int?) checkSubtype(x as? Int) diff --git a/compiler/testData/diagnostics/tests/Constants.fir.kt b/compiler/testData/diagnostics/tests/Constants.fir.kt index e925d1b8252..3621eb86263 100644 --- a/compiler/testData/diagnostics/tests/Constants.fir.kt +++ b/compiler/testData/diagnostics/tests/Constants.fir.kt @@ -33,7 +33,7 @@ fun test() { checkSubtype(1) 1 as Byte - 1 as Int + 1 as Int 0xff as Long 1.1 as Int diff --git a/compiler/testData/diagnostics/tests/IsExpressions.fir.kt b/compiler/testData/diagnostics/tests/IsExpressions.fir.kt index a12b3ef9fe4..f6899b7253e 100644 --- a/compiler/testData/diagnostics/tests/IsExpressions.fir.kt +++ b/compiler/testData/diagnostics/tests/IsExpressions.fir.kt @@ -1,21 +1,21 @@ // FILE: KotlinFile.kt fun test() { - if (1 is Int) { + if (1 is Int) { if (1 is Boolean) { } } A.create() is A - A.create() is A? + A.create() is A? unresolved is A unresolved is A? val x = foo() x as String - x is String + x is String } fun foo(): Any = "" @@ -23,4 +23,4 @@ fun foo(): Any = "" // FILE: A.java class A { static A create() { return null; } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/NumberPrefixAndSuffix.fir.kt b/compiler/testData/diagnostics/tests/NumberPrefixAndSuffix.fir.kt index 7301b10cf92..fc1b01a4940 100644 --- a/compiler/testData/diagnostics/tests/NumberPrefixAndSuffix.fir.kt +++ b/compiler/testData/diagnostics/tests/NumberPrefixAndSuffix.fir.kt @@ -45,10 +45,10 @@ fun test(a: Any) { .0fin a .0din a - 1is Any + 1is Any 1as Any 1as? Any - 1!is Any + 1!is Any 1!in a -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/StringPrefixAndSuffix.fir.kt b/compiler/testData/diagnostics/tests/StringPrefixAndSuffix.fir.kt index 5133b2c0c33..330d1f5c868 100644 --- a/compiler/testData/diagnostics/tests/StringPrefixAndSuffix.fir.kt +++ b/compiler/testData/diagnostics/tests/StringPrefixAndSuffix.fir.kt @@ -31,8 +31,8 @@ fun test(a: Any) { a !in's' a !in'' - if("s"is Any) {} - if("s"is Any) {} + if("s"is Any) {} + if("s"is Any) {} test("s"as Any) a foo""1 diff --git a/compiler/testData/diagnostics/tests/annotations/ConstructorCall.fir.kt b/compiler/testData/diagnostics/tests/annotations/ConstructorCall.fir.kt index fa66da3ee58..01a9f87e4d9 100644 --- a/compiler/testData/diagnostics/tests/annotations/ConstructorCall.fir.kt +++ b/compiler/testData/diagnostics/tests/annotations/ConstructorCall.fir.kt @@ -26,7 +26,7 @@ fun foo() { } fun bar(a: Ann = Ann()) { - if (a is Ann) {} + if (a is Ann) {} } operator fun String.invoke() {} diff --git a/compiler/testData/diagnostics/tests/cast/AsInBlockWithReturnType.fir.kt b/compiler/testData/diagnostics/tests/cast/AsInBlockWithReturnType.fir.kt index 51416c8e083..d1501325a99 100644 --- a/compiler/testData/diagnostics/tests/cast/AsInBlockWithReturnType.fir.kt +++ b/compiler/testData/diagnostics/tests/cast/AsInBlockWithReturnType.fir.kt @@ -25,8 +25,8 @@ fun testRun() { } run { - 1 as Int - 1 as Int + 1 as Int + 1 as Int } runWithoutReturn { diff --git a/compiler/testData/diagnostics/tests/cast/AsInPropertyAndPropertyAccessor.fir.kt b/compiler/testData/diagnostics/tests/cast/AsInPropertyAndPropertyAccessor.fir.kt index 27cdb37c820..f467a3e3ab3 100644 --- a/compiler/testData/diagnostics/tests/cast/AsInPropertyAndPropertyAccessor.fir.kt +++ b/compiler/testData/diagnostics/tests/cast/AsInPropertyAndPropertyAccessor.fir.kt @@ -4,7 +4,7 @@ fun test() { val a = 1 as Any? val b: Number = 1 as Number val c = null as String? - val d: Number = 1 as Int + val d: Number = 1 as Int } val c1 get() = 1 as Number @@ -14,4 +14,4 @@ val d: Number get() { 1 as Number return 1 as Number - } \ No newline at end of file + } diff --git a/compiler/testData/diagnostics/tests/cast/FlexibleTargetType.fir.kt b/compiler/testData/diagnostics/tests/cast/FlexibleTargetType.fir.kt index 8041cb1ef69..e864b1d21b6 100644 --- a/compiler/testData/diagnostics/tests/cast/FlexibleTargetType.fir.kt +++ b/compiler/testData/diagnostics/tests/cast/FlexibleTargetType.fir.kt @@ -18,9 +18,9 @@ public class Foo { fun test() { Foo.create() as Foo Foo.createN() as Foo - Foo.createNN() as Foo + Foo.createNN() as Foo - Foo.create() as Foo? - Foo.createN() as Foo? + Foo.create() as Foo? + Foo.createN() as Foo? Foo.createNN() as Foo? -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/cast/IsErasedAllowForExactSupertypeCheck.fir.kt b/compiler/testData/diagnostics/tests/cast/IsErasedAllowForExactSupertypeCheck.fir.kt deleted file mode 100644 index 51c6eab4642..00000000000 --- a/compiler/testData/diagnostics/tests/cast/IsErasedAllowForExactSupertypeCheck.fir.kt +++ /dev/null @@ -1,5 +0,0 @@ -open class Base -class Some: Base() - -// a is Some => a is Base -fun f(a: Some) = a is Base \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/cast/IsErasedAllowForExactSupertypeCheck.kt b/compiler/testData/diagnostics/tests/cast/IsErasedAllowForExactSupertypeCheck.kt index f4e4c9a8453..f731756bd95 100644 --- a/compiler/testData/diagnostics/tests/cast/IsErasedAllowForExactSupertypeCheck.kt +++ b/compiler/testData/diagnostics/tests/cast/IsErasedAllowForExactSupertypeCheck.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL open class Base class Some: Base() diff --git a/compiler/testData/diagnostics/tests/cast/IsErasedAllowForSupertypeCheckWithContrvariance.fir.kt b/compiler/testData/diagnostics/tests/cast/IsErasedAllowForSupertypeCheckWithContrvariance.fir.kt deleted file mode 100644 index db875931272..00000000000 --- a/compiler/testData/diagnostics/tests/cast/IsErasedAllowForSupertypeCheckWithContrvariance.fir.kt +++ /dev/null @@ -1,8 +0,0 @@ -open class A -open class B: A() - -open class Base -class SubBase: Base() - -// f is SubBase => f is Base => (Base, B <: A) f is Base -fun test(f: SubBase) = f is Base \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/cast/IsErasedAllowForSupertypeCheckWithContrvariance.kt b/compiler/testData/diagnostics/tests/cast/IsErasedAllowForSupertypeCheckWithContrvariance.kt index eafc428eeb5..160e578b82b 100644 --- a/compiler/testData/diagnostics/tests/cast/IsErasedAllowForSupertypeCheckWithContrvariance.kt +++ b/compiler/testData/diagnostics/tests/cast/IsErasedAllowForSupertypeCheckWithContrvariance.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL open class A open class B: A() diff --git a/compiler/testData/diagnostics/tests/cast/IsErasedAllowForSupertypeCheckWithCovariance.fir.kt b/compiler/testData/diagnostics/tests/cast/IsErasedAllowForSupertypeCheckWithCovariance.fir.kt deleted file mode 100644 index a7ca5876259..00000000000 --- a/compiler/testData/diagnostics/tests/cast/IsErasedAllowForSupertypeCheckWithCovariance.fir.kt +++ /dev/null @@ -1,8 +0,0 @@ -open class A -open class B: A() - -open class Base -class SubBase: Base() - -// f is SubBase => (SubBase <: Base) f is Base => (B <: A, Base => SubBase <: Base) f is Base -fun test(f: SubBase) = f is Base \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/cast/IsErasedAllowForSupertypeCheckWithCovariance.kt b/compiler/testData/diagnostics/tests/cast/IsErasedAllowForSupertypeCheckWithCovariance.kt index aa50f251377..640c6279060 100644 --- a/compiler/testData/diagnostics/tests/cast/IsErasedAllowForSupertypeCheckWithCovariance.kt +++ b/compiler/testData/diagnostics/tests/cast/IsErasedAllowForSupertypeCheckWithCovariance.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL open class A open class B: A() diff --git a/compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut.fir.kt b/compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut.fir.kt deleted file mode 100644 index 29ac268ad0f..00000000000 --- a/compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut.fir.kt +++ /dev/null @@ -1 +0,0 @@ -fun f(a: MutableList) = a is MutableList diff --git a/compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut.kt b/compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut.kt index 7000a879e06..6e907734829 100644 --- a/compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut.kt +++ b/compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut.kt @@ -1 +1,2 @@ +// FIR_IDENTICAL fun f(a: MutableList) = a is MutableList diff --git a/compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut2.fir.kt b/compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut2.fir.kt deleted file mode 100644 index 6f7bc4f981a..00000000000 --- a/compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut2.fir.kt +++ /dev/null @@ -1 +0,0 @@ -fun f(a: MutableList) = a is MutableList diff --git a/compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut2.kt b/compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut2.kt index 1ad94336466..921c2d08608 100644 --- a/compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut2.kt +++ b/compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut2.kt @@ -1 +1,2 @@ +// FIR_IDENTICAL fun f(a: MutableList) = a is MutableList diff --git a/compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOutAtClass.fir.kt b/compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOutAtClass.fir.kt deleted file mode 100644 index f1ba3800c08..00000000000 --- a/compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOutAtClass.fir.kt +++ /dev/null @@ -1 +0,0 @@ -fun f(a: List) = a is List diff --git a/compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOutAtClass.kt b/compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOutAtClass.kt index 3b47296763c..92f2c6a0144 100644 --- a/compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOutAtClass.kt +++ b/compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOutAtClass.kt @@ -1 +1,2 @@ +// FIR_IDENTICAL fun f(a: List) = a is List diff --git a/compiler/testData/diagnostics/tests/cast/IsErasedTasT.fir.kt b/compiler/testData/diagnostics/tests/cast/IsErasedTasT.fir.kt deleted file mode 100644 index ae1fa33c9f8..00000000000 --- a/compiler/testData/diagnostics/tests/cast/IsErasedTasT.fir.kt +++ /dev/null @@ -1 +0,0 @@ -fun testing(a: T) = a is T diff --git a/compiler/testData/diagnostics/tests/cast/IsErasedTasT.kt b/compiler/testData/diagnostics/tests/cast/IsErasedTasT.kt index 03c602a643d..aa84c2a2271 100644 --- a/compiler/testData/diagnostics/tests/cast/IsErasedTasT.kt +++ b/compiler/testData/diagnostics/tests/cast/IsErasedTasT.kt @@ -1 +1,2 @@ +// FIR_IDENTICAL fun testing(a: T) = a is T diff --git a/compiler/testData/diagnostics/tests/cast/IsErasedUpcastToNonReified.fir.kt b/compiler/testData/diagnostics/tests/cast/IsErasedUpcastToNonReified.fir.kt index 84d2d5ea5f2..9edec42d143 100644 --- a/compiler/testData/diagnostics/tests/cast/IsErasedUpcastToNonReified.fir.kt +++ b/compiler/testData/diagnostics/tests/cast/IsErasedUpcastToNonReified.fir.kt @@ -1,14 +1,14 @@ fun test(x: T?, y: S, z: T) { x is T - x is T? + x is T? - y is T - y is S - y is T? - y is S? + y is T + y is S + y is T? + y is S? - z is T - z is T? + z is T + z is T? null as T null as T? @@ -22,6 +22,6 @@ inline fun test(x: T?) { } fun foo(x: List, y: List?) { - x is List + x is List y is List -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/cast/UselessSafeCast.fir.kt b/compiler/testData/diagnostics/tests/cast/UselessSafeCast.fir.kt index 6e2725448d4..42e1df9622b 100644 --- a/compiler/testData/diagnostics/tests/cast/UselessSafeCast.fir.kt +++ b/compiler/testData/diagnostics/tests/cast/UselessSafeCast.fir.kt @@ -2,15 +2,15 @@ // !DIAGNOSTICS: -UNUSED_PARAMETER, -UNUSED_VARIABLE fun test(x: Int?) { - val a1 = x as? Int - val a2 = x as? Int? + val a1 = x as? Int + val a2 = x as? Int? val a3 = x as? Number val a4 = x as? Number? - val a5: Int? = x as? Int - val a6: Number? = x as? Int + val a5: Int? = x as? Int + val a6: Number? = x as? Int val a7: Number? = 1 as? Number - run { x as? Int } + run { x as? Int } run { x as? Number } foo(x as? Number) diff --git a/compiler/testData/diagnostics/tests/cast/checkCastToNullableType.fir.kt b/compiler/testData/diagnostics/tests/cast/checkCastToNullableType.fir.kt index 1b4e9c59bc3..130f3f79bef 100644 --- a/compiler/testData/diagnostics/tests/cast/checkCastToNullableType.fir.kt +++ b/compiler/testData/diagnostics/tests/cast/checkCastToNullableType.fir.kt @@ -22,17 +22,17 @@ public class JavaClass { // FILE: test.kt fun test(x1: T, x2: T?, y1: S, y2: S?) { - x1 is T? - x2 is T? - y1 is S? - y2 is S? + x1 is T? + x2 is T? + y1 is S? + y2 is S? val f1 = JavaClass.foo() - f1 is Int? + f1 is Int? val f2 = JavaClass.fooN() - f2 is Int? + f2 is Int? val f3 = JavaClass.fooNN() - f3 is Int? + f3 is Int? } diff --git a/compiler/testData/diagnostics/tests/cast/constants.fir.kt b/compiler/testData/diagnostics/tests/cast/constants.fir.kt index 26ebc7dc2bf..0b04399ea45 100644 --- a/compiler/testData/diagnostics/tests/cast/constants.fir.kt +++ b/compiler/testData/diagnostics/tests/cast/constants.fir.kt @@ -1,5 +1,5 @@ fun asCall() { - 1 as Int + 1 as Int 1 as Byte 1 as Short 1 as Long @@ -12,7 +12,7 @@ fun asCall() { 1.0 as Short 1.0 as Long 1.0 as Char - 1.0 as Double + 1.0 as Double 1.0 as Float 1f as Int @@ -21,7 +21,7 @@ fun asCall() { 1f as Long 1f as Char 1f as Double - 1f as Float + 1f as Float } fun asSafe() { @@ -48,4 +48,4 @@ fun asSafe() { 1f as? Char 1f as? Double 1f as? Float -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/classObjects/kt3866.fir.kt b/compiler/testData/diagnostics/tests/classObjects/kt3866.fir.kt deleted file mode 100644 index 5a0f25e02f1..00000000000 --- a/compiler/testData/diagnostics/tests/classObjects/kt3866.fir.kt +++ /dev/null @@ -1,20 +0,0 @@ -open class C { -} - -fun C.foo() {} - -open class X { - companion object : C() {} -} - -open class Y { - companion object : C() {} -} - -fun bar() { - val x = X - x.foo() - X.foo() - (X as C).foo() - ((if (1<2) X else Y) as C).foo() -} diff --git a/compiler/testData/diagnostics/tests/classObjects/kt3866.kt b/compiler/testData/diagnostics/tests/classObjects/kt3866.kt index 8f90fc5307a..c49024f6bab 100644 --- a/compiler/testData/diagnostics/tests/classObjects/kt3866.kt +++ b/compiler/testData/diagnostics/tests/classObjects/kt3866.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL open class C { } diff --git a/compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject.fir.kt b/compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject.fir.kt index e2eb8b5226b..c12c992f922 100644 --- a/compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject.fir.kt +++ b/compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject.fir.kt @@ -33,8 +33,18 @@ inline fun case_5() { val z = x.test() - if (z is T) { + if (z is T) { // z is {T!! & T!!} (smart cast from T) println(z) } + + val a = object { + fun test() = 42 as A + } + + val b = a.test() + + if (a is T) { + println(a) + } } diff --git a/compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject.kt b/compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject.kt index 002ce8da2e0..866ac189628 100644 --- a/compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject.kt +++ b/compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject.kt @@ -37,4 +37,14 @@ inline fun case_5() { // z is {T!! & T!!} (smart cast from T) println(z) } + + val a = object { + fun test() = 42 as A + } + + val b = a.test() + + if (a is T) { + println(a) + } } diff --git a/compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject_after.fir.kt b/compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject_after.fir.kt index e7f7ba14ef1..c9f10467812 100644 --- a/compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject_after.fir.kt +++ b/compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject_after.fir.kt @@ -33,8 +33,18 @@ inline fun case_5() { val z = x.test() - if (z is T) { + if (z is T) { // z is {T!! & T!!} (smart cast from T) println(z) } + + val a = object { + fun test() = 42 as A + } + + val b = a.test() + + if (a is T) { + println(a) + } } diff --git a/compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject_after.kt b/compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject_after.kt index c49a042b252..245cdcca70c 100644 --- a/compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject_after.kt +++ b/compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject_after.kt @@ -37,4 +37,14 @@ inline fun case_5() { // z is {T!! & T!!} (smart cast from T) println(z) } + + val a = object { + fun test() = 42 as A + } + + val b = a.test() + + if (a is T) { + println(a) + } } diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/UninitializedOrReassignedVariables.fir.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/UninitializedOrReassignedVariables.fir.kt index a22219c35a3..361a995e876 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/UninitializedOrReassignedVariables.fir.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/UninitializedOrReassignedVariables.fir.kt @@ -39,7 +39,7 @@ fun t1(b : Boolean) { return; } doSmth(i) - if (i is Int) { + if (i is Int) { return; } } diff --git a/compiler/testData/diagnostics/tests/controlStructures/when.kt234.kt973.fir.kt b/compiler/testData/diagnostics/tests/controlStructures/when.kt234.kt973.fir.kt index 33c1afbc435..f9d48fe7db3 100644 --- a/compiler/testData/diagnostics/tests/controlStructures/when.kt234.kt973.fir.kt +++ b/compiler/testData/diagnostics/tests/controlStructures/when.kt234.kt973.fir.kt @@ -26,7 +26,7 @@ fun t1(x: Int) = when(x) { } fun t5(x: Int) = when (x) { - is Int -> 1 + is Int -> 1 2 -> 2 } diff --git a/compiler/testData/diagnostics/tests/dataFlow/EmptyIf.fir.kt b/compiler/testData/diagnostics/tests/dataFlow/EmptyIf.fir.kt index cb03e48686e..659f0b04a5e 100644 --- a/compiler/testData/diagnostics/tests/dataFlow/EmptyIf.fir.kt +++ b/compiler/testData/diagnostics/tests/dataFlow/EmptyIf.fir.kt @@ -13,7 +13,7 @@ fun f2(s: Number?) { } fun f3(s: Number?) { - if (s is Int && s as Int == 42); + if (s is Int && s as Int == 42); checkSubtype(s) } diff --git a/compiler/testData/diagnostics/tests/dataFlow/assignment/kt6118.fir.kt b/compiler/testData/diagnostics/tests/dataFlow/assignment/kt6118.fir.kt index c16bb040bcf..bd3cb1f1b22 100644 --- a/compiler/testData/diagnostics/tests/dataFlow/assignment/kt6118.fir.kt +++ b/compiler/testData/diagnostics/tests/dataFlow/assignment/kt6118.fir.kt @@ -2,7 +2,7 @@ fun foo(o: Any) { if (o is String) { - val s = o as String + val s = o as String s.length } } @@ -13,4 +13,4 @@ fun foo1(o: Any) { val s = o s.length } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/dataFlowInfoTraversal/IsExpression.fir.kt b/compiler/testData/diagnostics/tests/dataFlowInfoTraversal/IsExpression.fir.kt index 565ded5a2b8..326501f5165 100644 --- a/compiler/testData/diagnostics/tests/dataFlowInfoTraversal/IsExpression.fir.kt +++ b/compiler/testData/diagnostics/tests/dataFlowInfoTraversal/IsExpression.fir.kt @@ -1,7 +1,7 @@ // !CHECK_TYPE fun foo(x: Number) { - if ((x as Int) is Int) { + if ((x as Int) is Int) { checkSubtype(x) } checkSubtype(x) diff --git a/compiler/testData/diagnostics/tests/dataFlowInfoTraversal/ManyIfs.fir.kt b/compiler/testData/diagnostics/tests/dataFlowInfoTraversal/ManyIfs.fir.kt index 4f0f723d8e8..fea7d38197c 100644 --- a/compiler/testData/diagnostics/tests/dataFlowInfoTraversal/ManyIfs.fir.kt +++ b/compiler/testData/diagnostics/tests/dataFlowInfoTraversal/ManyIfs.fir.kt @@ -1,11 +1,11 @@ // !CHECK_TYPE fun noUselessDataFlowInfoCreation(x: Number) { - if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) { - if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) { - if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) { - if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) { - if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) { + if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) { + if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) { + if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) { + if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) { + if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) { } } } } } } } } } } } } } } } } } } } } } } } } } } diff --git a/compiler/testData/diagnostics/tests/enum/enumSubjectTypeCheck.fir.kt b/compiler/testData/diagnostics/tests/enum/enumSubjectTypeCheck.fir.kt index c1e21b2b41d..de45682c62d 100644 --- a/compiler/testData/diagnostics/tests/enum/enumSubjectTypeCheck.fir.kt +++ b/compiler/testData/diagnostics/tests/enum/enumSubjectTypeCheck.fir.kt @@ -5,7 +5,7 @@ enum class En { A, B, ะก } fun foo() { // nullable variable val en2: Any? = En.A - if (en2 is En) { + if (en2 is En) { when (en2) { En.A -> {} En.B -> {} @@ -15,7 +15,7 @@ fun foo() { // not nullable variable val en1: Any = En.A - if (en1 is En) { + if (en1 is En) { when (en1) { En.A -> {} En.B -> {} @@ -37,4 +37,4 @@ fun bar(x: Any) { else -> {} } } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/inference/expectedTypeAdditionalTest.fir.kt b/compiler/testData/diagnostics/tests/inference/expectedTypeAdditionalTest.fir.kt index d7e5f529abb..a946ec1bcd7 100644 --- a/compiler/testData/diagnostics/tests/inference/expectedTypeAdditionalTest.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/expectedTypeAdditionalTest.fir.kt @@ -7,7 +7,7 @@ fun foo() = foo() as T fun foo2(): T = TODO() -val test = foo2().plus("") as String +val test = foo2().plus("") as String fun T.bar() = this val barTest = "".bar() as Number diff --git a/compiler/testData/diagnostics/tests/inference/expectedTypeFromCast.fir.kt b/compiler/testData/diagnostics/tests/inference/expectedTypeFromCast.fir.kt index ba4bafed1a4..cb72542a16c 100644 --- a/compiler/testData/diagnostics/tests/inference/expectedTypeFromCast.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/expectedTypeFromCast.fir.kt @@ -17,5 +17,5 @@ val asStarList = foo() as List<*> val safeAs = foo() as? String -val fromIs = foo() is String -val fromNoIs = foo() !is String +val fromIs = foo() is String +val fromNoIs = foo() !is String diff --git a/compiler/testData/diagnostics/tests/inference/findViewById.fir.kt b/compiler/testData/diagnostics/tests/inference/findViewById.fir.kt deleted file mode 100644 index dd62ae8ab67..00000000000 --- a/compiler/testData/diagnostics/tests/inference/findViewById.fir.kt +++ /dev/null @@ -1,59 +0,0 @@ -// !WITH_NEW_INFERENCE -// !LANGUAGE: +ExpectedTypeFromCast -// !DIAGNOSTICS: -UNUSED_VARIABLE -DEBUG_INFO_LEAKING_THIS - -// FILE: a/View.java -package a; - -public class View { - -} - -// FILE: a/Test.java -package a; - -public class Test { - public T findViewById(int id); -} - -// FILE: 1.kt -package a - - -class X : View() - -class Y : View() - -val xExplicit: X = Test().findViewById(0) -val xCast = Test().findViewById(0) as X - -val xCastExplicitType = Test().findViewById(0) as X -val xSafeCastExplicitType = Test().findViewById(0) as? X - -val yExplicit: Y = Test().findViewById(0) -val yCast = Test().findViewById(0) as Y - - -class TestChild : Test() { - val xExplicit: X = findViewById(0) - val xCast = findViewById(0) as X - - val yExplicit: Y = findViewById(0) - val yCast = findViewById(0) as Y -} - -fun test(t: Test) { - val xExplicit: X = t.findViewById(0) - val xCast = t.findViewById(0) as X - - val yExplicit: Y = t.findViewById(0) - val yCast = t.findViewById(0) as Y -} - -fun test2(t: Test?) { - val xSafeCallSafeCast = t?.findViewById(0) as? X - val xSafeCallSafeCastExplicitType = t?.findViewById(0) as? X - - val xSafeCallCast = t?.findViewById(0) as X - val xSafeCallCastExplicitType = t?.findViewById(0) as X -} diff --git a/compiler/testData/diagnostics/tests/inference/findViewById.kt b/compiler/testData/diagnostics/tests/inference/findViewById.kt index f6b623dc3c1..620781ae011 100644 --- a/compiler/testData/diagnostics/tests/inference/findViewById.kt +++ b/compiler/testData/diagnostics/tests/inference/findViewById.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !WITH_NEW_INFERENCE // !LANGUAGE: +ExpectedTypeFromCast // !DIAGNOSTICS: -UNUSED_VARIABLE -DEBUG_INFO_LEAKING_THIS diff --git a/compiler/testData/diagnostics/tests/infos/SmartCasts.fir.kt b/compiler/testData/diagnostics/tests/infos/SmartCasts.fir.kt index 7aeffc88755..d5655efe5c9 100644 --- a/compiler/testData/diagnostics/tests/infos/SmartCasts.fir.kt +++ b/compiler/testData/diagnostics/tests/infos/SmartCasts.fir.kt @@ -36,7 +36,7 @@ fun f10(init : A?) { if (!(a is B)) { return; } - if (!(a is B)) { + if (!(a is B)) { return; } } @@ -58,7 +58,7 @@ fun f11(a : A?) { is B -> a.bar() is A -> a.foo() is Any -> a.foo() - is Any? -> a.bar() + is Any? -> a.bar() else -> a?.foo() } } @@ -68,12 +68,12 @@ fun f12(a : A?) { is B -> a.bar() is A -> a.foo() is Any -> a.foo(); - is Any? -> a.bar() + is Any? -> a.bar() is C -> a.bar() else -> a?.foo() } - if (a is Any?) { + if (a is Any?) { a?.bar() } if (a is B) { @@ -198,7 +198,7 @@ fun mergeSmartCasts(a: Any?) { when (a) { is String, is Any -> a.compareTo("") } - if (a is String && a is Any) { + if (a is String && a is Any) { val i: Int = a.compareTo("") } if (a is String && a.compareTo("") == 0) {} diff --git a/compiler/testData/diagnostics/tests/inline/isCheck.fir.kt b/compiler/testData/diagnostics/tests/inline/isCheck.fir.kt deleted file mode 100644 index 4ea8d43784e..00000000000 --- a/compiler/testData/diagnostics/tests/inline/isCheck.fir.kt +++ /dev/null @@ -1,10 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_EXPRESSION -inline public fun reg(converter: (Any) -> Any, flag: Boolean) { - flag - converter("") -} - -public inline fun register(converter: (Any) -> Any) { - converter is (Any) -> Any - reg(converter, converter is (Any) -> Any) -} diff --git a/compiler/testData/diagnostics/tests/inline/isCheck.kt b/compiler/testData/diagnostics/tests/inline/isCheck.kt index 8eb5d081810..08ac4e222fb 100644 --- a/compiler/testData/diagnostics/tests/inline/isCheck.kt +++ b/compiler/testData/diagnostics/tests/inline/isCheck.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_EXPRESSION inline public fun reg(converter: (Any) -> Any, flag: Boolean) { flag diff --git a/compiler/testData/diagnostics/tests/inline/when.fir.kt b/compiler/testData/diagnostics/tests/inline/when.fir.kt deleted file mode 100644 index 47766cfdc04..00000000000 --- a/compiler/testData/diagnostics/tests/inline/when.fir.kt +++ /dev/null @@ -1,11 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_EXPRESSION -inline public fun reg(converter: (Any) -> Any) { - converter("") -} - -public inline fun register(converter: (Any) -> Any) { - reg(when(converter) { - is (Any) -> Any -> converter - else -> converter - }) -} diff --git a/compiler/testData/diagnostics/tests/inline/when.kt b/compiler/testData/diagnostics/tests/inline/when.kt index 26914fe0018..c456e2c795c 100644 --- a/compiler/testData/diagnostics/tests/inline/when.kt +++ b/compiler/testData/diagnostics/tests/inline/when.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_EXPRESSION inline public fun reg(converter: (Any) -> Any) { converter("") diff --git a/compiler/testData/diagnostics/tests/regressions/kt7804.fir.kt b/compiler/testData/diagnostics/tests/regressions/kt7804.fir.kt index c03b3af14a6..653d5ad4902 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt7804.fir.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt7804.fir.kt @@ -6,7 +6,7 @@ class A fun test(v: T): T { val a = if (v !is A) { - foo(v) as T + foo(v) as T } else { v @@ -18,7 +18,7 @@ fun test(v: T): T { fun test2(v: T): T { val a = if (v !is A) { - foo(v) as T + foo(v) as T } else { v as T @@ -42,7 +42,7 @@ fun test3(v: T): T { fun test4(v: T): T { val a: T = if (v !is A) { - foo(v) as T + foo(v) as T } else { v diff --git a/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnRoot.fir.kt b/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnRoot.fir.kt deleted file mode 100644 index 04b049c2dc3..00000000000 --- a/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnRoot.fir.kt +++ /dev/null @@ -1,23 +0,0 @@ -sealed class Stmt - -class ForStmt : Stmt() - -sealed class Expr : Stmt() { - object BinExpr : Expr() -} - -fun test(x: Stmt): String = - when (x) { - is Expr -> "expr" - is Stmt -> "stmt" - } - -fun test2(x: Stmt): String = - when (x) { - is Expr -> "expr" - } - -fun test3(x: Expr): String = - when (x) { - is Stmt -> "stmt" - } diff --git a/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnRoot.kt b/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnRoot.kt index a6e5d26fe91..220da33f2f2 100644 --- a/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnRoot.kt +++ b/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnRoot.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL sealed class Stmt class ForStmt : Stmt() diff --git a/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenWithAnyCase.fir.kt b/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenWithAnyCase.fir.kt deleted file mode 100644 index fc235670129..00000000000 --- a/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenWithAnyCase.fir.kt +++ /dev/null @@ -1,15 +0,0 @@ -sealed class Sealed { - object First: Sealed() - open class NonFirst: Sealed() { - object Second: NonFirst() - object Third: NonFirst() - } -} - -fun foo(s: Sealed): Int { - return when(s) { - is Sealed.First -> 1 - !is Any -> 0 - } -} - diff --git a/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenWithAnyCase.kt b/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenWithAnyCase.kt index f6cf690492c..b7f3dc565c5 100644 --- a/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenWithAnyCase.kt +++ b/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenWithAnyCase.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL sealed class Sealed { object First: Sealed() open class NonFirst: Sealed() { diff --git a/compiler/testData/diagnostics/tests/smartCasts/alwaysNull.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/alwaysNull.fir.kt index d900c519e42..b99e0b8be40 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/alwaysNull.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/alwaysNull.fir.kt @@ -17,7 +17,7 @@ fun String?.gav() {} fun bar(s: String?) { if (s != null) return s.gav() - s as? String - s as String? + s as? String + s as String? s as String } diff --git a/compiler/testData/diagnostics/tests/smartCasts/castchecks/basicOff.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/castchecks/basicOff.fir.kt index 48eba2309dd..41dea08871d 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/castchecks/basicOff.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/castchecks/basicOff.fir.kt @@ -14,7 +14,7 @@ fun g(a: SomeClass?) { a.hashCode() a.foo (a as? SomeSubClass).foo - (a as SomeSubClass).foo + (a as SomeSubClass).foo } val b = (a as? SomeSubClass)?.foo if (b != null) { @@ -22,7 +22,7 @@ fun g(a: SomeClass?) { a.hashCode() a.foo (a as? SomeSubClass).foo - (a as SomeSubClass).foo + (a as SomeSubClass).foo } val c = a as? SomeSubClass if (c != null) { @@ -33,4 +33,4 @@ fun g(a: SomeClass?) { c.hashCode() c.foo } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/smartCasts/castchecks/basicOn.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/castchecks/basicOn.fir.kt index 0a2f990344a..2c0f258bd37 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/castchecks/basicOn.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/castchecks/basicOn.fir.kt @@ -14,7 +14,7 @@ fun g(a: SomeClass?) { a.hashCode() a.foo (a as? SomeSubClass).foo - (a as SomeSubClass).foo + (a as SomeSubClass).foo } val b = (a as? SomeSubClass)?.foo if (b != null) { @@ -22,7 +22,7 @@ fun g(a: SomeClass?) { a.hashCode() a.foo (a as? SomeSubClass).foo - (a as SomeSubClass).foo + (a as SomeSubClass).foo } val c = a as? SomeSubClass if (c != null) { @@ -33,4 +33,4 @@ fun g(a: SomeClass?) { c.hashCode() c.foo } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/smartCasts/castchecks/impossible.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/castchecks/impossible.fir.kt deleted file mode 100644 index 0650f50ccb1..00000000000 --- a/compiler/testData/diagnostics/tests/smartCasts/castchecks/impossible.fir.kt +++ /dev/null @@ -1,25 +0,0 @@ -// !LANGUAGE: +SafeCastCheckBoundSmartCasts -// See KT-20752 - -class Unstable { - val first: String? get() = null -} - -class StringList { - fun remove(s: String) = s -} - -fun StringList.remove(s: String?) = s ?: "" - -fun foo(list: StringList, arg: Unstable) { - list.remove(arg.first) - if (arg.first as? String != null) { - // Should be still resolved to extension, without smart cast or smart cast impossible - list.remove(arg.first) - } - val s = arg.first as? String - if (s != null) { - // Should be still resolved to extension, without smart cast or smart cast impossible - list.remove(arg.first) - } -} diff --git a/compiler/testData/diagnostics/tests/smartCasts/castchecks/impossible.kt b/compiler/testData/diagnostics/tests/smartCasts/castchecks/impossible.kt index 7a7c420bb30..1989685169c 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/castchecks/impossible.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/castchecks/impossible.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !LANGUAGE: +SafeCastCheckBoundSmartCasts // See KT-20752 diff --git a/compiler/testData/diagnostics/tests/smartCasts/extensionSafeCall.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/extensionSafeCall.fir.kt index 33fc365b7a8..ecc8bc20159 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/extensionSafeCall.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/extensionSafeCall.fir.kt @@ -7,7 +7,7 @@ fun T?.let(f: (T) -> Unit) { } fun test(your: Your?) { - (your?.foo() as? Any)?.let {} + (your?.foo() as? Any)?.let {} // strange smart cast to 'Your' at this point your.hashCode() -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/smartCasts/kt10232.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/kt10232.fir.kt deleted file mode 100644 index 00840f11164..00000000000 --- a/compiler/testData/diagnostics/tests/smartCasts/kt10232.fir.kt +++ /dev/null @@ -1,15 +0,0 @@ -// Type inference failed after smart cast - -interface A -interface B : A - -fun foo(b: A) = b - -fun test(a: A) { - if (a is Any) { - // Error:(9, 9) Kotlin: Type inference failed: fun foo(b: A): kotlin.Unit - // cannot be applied to (A) - foo(a) - } - foo(a) // ok -} diff --git a/compiler/testData/diagnostics/tests/smartCasts/kt10232.kt b/compiler/testData/diagnostics/tests/smartCasts/kt10232.kt index 502d68c577b..79f8867cca5 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/kt10232.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/kt10232.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // Type inference failed after smart cast interface A diff --git a/compiler/testData/diagnostics/tests/smartCasts/kt27221.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/kt27221.fir.kt index 5ff5d106d13..d998091c17c 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/kt27221.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/kt27221.fir.kt @@ -19,10 +19,10 @@ fun foo(a: A) { fun foo2(a: A) { if (a is C) { - if (a is B) { + if (a is B) { val t = when (a) { is CC -> "CC" } } } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/smartCasts/kt27221_2.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/kt27221_2.fir.kt index 91d54894917..2e897c33be2 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/kt27221_2.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/kt27221_2.fir.kt @@ -12,7 +12,7 @@ object DD : D() fun foo1(a: A) { if (a is B) { if (a is D) { - if (a is C) { + if (a is C) { val t = when (a) { is DD -> "DD" @@ -25,7 +25,7 @@ fun foo1(a: A) { fun foo2(a: A) { if (a is B) { if (a is D) { - if (a is C) { + if (a is C) { val t = when (a) { is DD -> "DD" @@ -33,4 +33,4 @@ fun foo2(a: A) { } } } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/smartCasts/kt5455.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/kt5455.fir.kt deleted file mode 100644 index 64211fc04e9..00000000000 --- a/compiler/testData/diagnostics/tests/smartCasts/kt5455.fir.kt +++ /dev/null @@ -1,28 +0,0 @@ -//KT-5455 Need warning about redundant type cast -fun foo(o: Any): Int { - if (o is String) { - return (o as String).length - } - return -1 -} - -open class A { - fun foo() {} -} -class B: A() - -fun test(a: Any?) { - if (a is B) { - (a as A).foo() - } -} - -fun test1(a: B) { - (a as A?)?.foo() -} - -fun test2(b: B?) { - if (b != null) { - (b as A).foo() - } -} diff --git a/compiler/testData/diagnostics/tests/smartCasts/kt5455.kt b/compiler/testData/diagnostics/tests/smartCasts/kt5455.kt index 6543540d5f8..131f3a965bf 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/kt5455.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/kt5455.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL //KT-5455 Need warning about redundant type cast fun foo(o: Any): Int { if (o is String) { diff --git a/compiler/testData/diagnostics/tests/smartCasts/safeAs.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/safeAs.fir.kt index 814a65830bc..68f10de8e30 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/safeAs.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/safeAs.fir.kt @@ -1,13 +1,13 @@ // See also KT-10992: we should have no errors for all unsafe hashCode() calls fun foo(arg: Any?) { - val x = arg as? Any ?: return + val x = arg as? Any ?: return arg.hashCode() x.hashCode() } fun bar(arg: Any?) { - arg as? Any ?: return + arg as? Any ?: return arg.hashCode() } diff --git a/compiler/testData/diagnostics/tests/suppress/oneWarning/onClass.fir.kt b/compiler/testData/diagnostics/tests/suppress/oneWarning/onClass.fir.kt deleted file mode 100644 index bc71b4b2ecf..00000000000 --- a/compiler/testData/diagnostics/tests/suppress/oneWarning/onClass.fir.kt +++ /dev/null @@ -1,4 +0,0 @@ -@Suppress("REDUNDANT_NULLABLE") -class C { - fun foo(): String?? = null as Nothing?? -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/suppress/oneWarning/onClass.kt b/compiler/testData/diagnostics/tests/suppress/oneWarning/onClass.kt index 72177c8e373..30ed05b32d0 100644 --- a/compiler/testData/diagnostics/tests/suppress/oneWarning/onClass.kt +++ b/compiler/testData/diagnostics/tests/suppress/oneWarning/onClass.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL @Suppress("REDUNDANT_NULLABLE") class C { fun foo(): String?? = null as Nothing?? diff --git a/compiler/testData/diagnostics/tests/suppress/oneWarning/onClassObject.fir.kt b/compiler/testData/diagnostics/tests/suppress/oneWarning/onClassObject.fir.kt deleted file mode 100644 index 6ef18f496d1..00000000000 --- a/compiler/testData/diagnostics/tests/suppress/oneWarning/onClassObject.fir.kt +++ /dev/null @@ -1,6 +0,0 @@ -class C { - @Suppress("REDUNDANT_NULLABLE") - companion object { - val foo: String?? = null as Nothing?? - } -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/suppress/oneWarning/onClassObject.kt b/compiler/testData/diagnostics/tests/suppress/oneWarning/onClassObject.kt index 1aea6e8c797..649efa8caea 100644 --- a/compiler/testData/diagnostics/tests/suppress/oneWarning/onClassObject.kt +++ b/compiler/testData/diagnostics/tests/suppress/oneWarning/onClassObject.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL class C { @Suppress("REDUNDANT_NULLABLE") companion object { diff --git a/compiler/testData/diagnostics/tests/suppress/oneWarning/onExpression.fir.kt b/compiler/testData/diagnostics/tests/suppress/oneWarning/onExpression.fir.kt deleted file mode 100644 index 17c2f78894e..00000000000 --- a/compiler/testData/diagnostics/tests/suppress/oneWarning/onExpression.fir.kt +++ /dev/null @@ -1,4 +0,0 @@ -fun foo(): Any? { - @Suppress("REDUNDANT_NULLABLE") - return null as Nothing?? -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/suppress/oneWarning/onExpression.kt b/compiler/testData/diagnostics/tests/suppress/oneWarning/onExpression.kt index 3dffa173770..1b46a642037 100644 --- a/compiler/testData/diagnostics/tests/suppress/oneWarning/onExpression.kt +++ b/compiler/testData/diagnostics/tests/suppress/oneWarning/onExpression.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL fun foo(): Any? { @Suppress("REDUNDANT_NULLABLE") return null as Nothing?? diff --git a/compiler/testData/diagnostics/tests/suppress/oneWarning/onFunction.fir.kt b/compiler/testData/diagnostics/tests/suppress/oneWarning/onFunction.fir.kt deleted file mode 100644 index d8af00a55c7..00000000000 --- a/compiler/testData/diagnostics/tests/suppress/oneWarning/onFunction.fir.kt +++ /dev/null @@ -1,4 +0,0 @@ -class C { - @Suppress("REDUNDANT_NULLABLE") - fun foo(): String?? = null as Nothing?? -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/suppress/oneWarning/onFunction.kt b/compiler/testData/diagnostics/tests/suppress/oneWarning/onFunction.kt index ce50f76ce9b..a75a2f5d76d 100644 --- a/compiler/testData/diagnostics/tests/suppress/oneWarning/onFunction.kt +++ b/compiler/testData/diagnostics/tests/suppress/oneWarning/onFunction.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL class C { @Suppress("REDUNDANT_NULLABLE") fun foo(): String?? = null as Nothing?? diff --git a/compiler/testData/diagnostics/tests/suppress/oneWarning/onLocalVariable.fir.kt b/compiler/testData/diagnostics/tests/suppress/oneWarning/onLocalVariable.fir.kt deleted file mode 100644 index 36faabbcce5..00000000000 --- a/compiler/testData/diagnostics/tests/suppress/oneWarning/onLocalVariable.fir.kt +++ /dev/null @@ -1,7 +0,0 @@ -class C { - fun foo(): Any? { - @Suppress("REDUNDANT_NULLABLE") - val v: String?? = null as Nothing?? - return v - } -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/suppress/oneWarning/onLocalVariable.kt b/compiler/testData/diagnostics/tests/suppress/oneWarning/onLocalVariable.kt index 3861d420d7e..e78b3db54ab 100644 --- a/compiler/testData/diagnostics/tests/suppress/oneWarning/onLocalVariable.kt +++ b/compiler/testData/diagnostics/tests/suppress/oneWarning/onLocalVariable.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL class C { fun foo(): Any? { @Suppress("REDUNDANT_NULLABLE") diff --git a/compiler/testData/diagnostics/tests/suppress/oneWarning/onObject.fir.kt b/compiler/testData/diagnostics/tests/suppress/oneWarning/onObject.fir.kt deleted file mode 100644 index b23994c8df0..00000000000 --- a/compiler/testData/diagnostics/tests/suppress/oneWarning/onObject.fir.kt +++ /dev/null @@ -1,4 +0,0 @@ -@Suppress("REDUNDANT_NULLABLE") -object C { - fun foo(): String?? = null as Nothing?? -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/suppress/oneWarning/onObject.kt b/compiler/testData/diagnostics/tests/suppress/oneWarning/onObject.kt index dd00afa6f30..99f98796e7b 100644 --- a/compiler/testData/diagnostics/tests/suppress/oneWarning/onObject.kt +++ b/compiler/testData/diagnostics/tests/suppress/oneWarning/onObject.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL @Suppress("REDUNDANT_NULLABLE") object C { fun foo(): String?? = null as Nothing?? diff --git a/compiler/testData/diagnostics/tests/suppress/oneWarning/onParameter.fir.kt b/compiler/testData/diagnostics/tests/suppress/oneWarning/onParameter.fir.kt deleted file mode 100644 index d475ca24ef6..00000000000 --- a/compiler/testData/diagnostics/tests/suppress/oneWarning/onParameter.fir.kt +++ /dev/null @@ -1,3 +0,0 @@ -class C { - fun foo(@Suppress("REDUNDANT_NULLABLE") p: String?? = null as Nothing??) = p -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/suppress/oneWarning/onParameter.kt b/compiler/testData/diagnostics/tests/suppress/oneWarning/onParameter.kt index a99f04d0a75..87bbe26081f 100644 --- a/compiler/testData/diagnostics/tests/suppress/oneWarning/onParameter.kt +++ b/compiler/testData/diagnostics/tests/suppress/oneWarning/onParameter.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL class C { fun foo(@Suppress("REDUNDANT_NULLABLE") p: String?? = null as Nothing??) = p } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/suppress/oneWarning/onProperty.fir.kt b/compiler/testData/diagnostics/tests/suppress/oneWarning/onProperty.fir.kt deleted file mode 100644 index e34ce0bd122..00000000000 --- a/compiler/testData/diagnostics/tests/suppress/oneWarning/onProperty.fir.kt +++ /dev/null @@ -1,4 +0,0 @@ -class C { - @Suppress("REDUNDANT_NULLABLE") - val foo: String?? = null as Nothing? -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/suppress/oneWarning/onProperty.kt b/compiler/testData/diagnostics/tests/suppress/oneWarning/onProperty.kt index 306e804c290..d8700a3772d 100644 --- a/compiler/testData/diagnostics/tests/suppress/oneWarning/onProperty.kt +++ b/compiler/testData/diagnostics/tests/suppress/oneWarning/onProperty.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL class C { @Suppress("REDUNDANT_NULLABLE") val foo: String?? = null as Nothing? diff --git a/compiler/testData/diagnostics/tests/suppress/oneWarning/onPropertyAccessor.fir.kt b/compiler/testData/diagnostics/tests/suppress/oneWarning/onPropertyAccessor.fir.kt deleted file mode 100644 index 06b586d33d8..00000000000 --- a/compiler/testData/diagnostics/tests/suppress/oneWarning/onPropertyAccessor.fir.kt +++ /dev/null @@ -1,5 +0,0 @@ -class C { - val foo: String? - @Suppress("REDUNDANT_NULLABLE") - get(): String?? = null as Nothing?? -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/suppress/oneWarning/onPropertyAccessor.kt b/compiler/testData/diagnostics/tests/suppress/oneWarning/onPropertyAccessor.kt index 8c82baa6741..3fbdeff3eff 100644 --- a/compiler/testData/diagnostics/tests/suppress/oneWarning/onPropertyAccessor.kt +++ b/compiler/testData/diagnostics/tests/suppress/oneWarning/onPropertyAccessor.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL class C { val foo: String? @Suppress("REDUNDANT_NULLABLE") diff --git a/compiler/testData/diagnostics/tests/when/When.fir.kt b/compiler/testData/diagnostics/tests/when/When.fir.kt index ff304ab963e..6f885487511 100644 --- a/compiler/testData/diagnostics/tests/when/When.fir.kt +++ b/compiler/testData/diagnostics/tests/when/When.fir.kt @@ -20,9 +20,9 @@ fun foo() : Int { val x = 1 when (x) { is String -> 1 - !is Int -> 1 - is Any? -> 1 - is Any -> 1 + !is Int -> 1 + is Any? -> 1 + is Any -> 1 s -> 1 1 -> 1 1 + a -> 1 diff --git a/compiler/testData/diagnostics/tests/when/WhenTypeDisjunctions.fir.kt b/compiler/testData/diagnostics/tests/when/WhenTypeDisjunctions.fir.kt index 7233c101745..758d96de3d0 100644 --- a/compiler/testData/diagnostics/tests/when/WhenTypeDisjunctions.fir.kt +++ b/compiler/testData/diagnostics/tests/when/WhenTypeDisjunctions.fir.kt @@ -23,7 +23,7 @@ fun foo(s: Any): String { fun bar(s: Any): String { val x = when (s) { - is String -> s as String // meaningless + is String -> s as String // meaningless is Int -> "$s" else -> return "" } diff --git a/compiler/testData/diagnostics/testsWithStdLib/cast/IsArray.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/cast/IsArray.fir.kt index b2cfa383fc3..b8db0800695 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/cast/IsArray.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/cast/IsArray.fir.kt @@ -1,5 +1,5 @@ fun f(a: Array) = a.isArrayOf() -fun f1(a: Array) = a is Array<*> +fun f1(a: Array) = a is Array<*> -fun f2(a: Array) = a is Array \ No newline at end of file +fun f2(a: Array) = a is Array diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/deeplyNested.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/deeplyNested.fir.kt index 4a2354b4eaf..1f82b4ed9df 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/deeplyNested.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/deeplyNested.fir.kt @@ -95,7 +95,7 @@ fun branchedAndNestedWithNativeOperators(x: Any?, y: Any?) { equalsTrue(isInt(y) && isString(y)) // y is Int, String ) && - (1 == 2 || y is Int || isString(y)) + (1 == 2 || y is Int || isString(y)) ) x.length y.length diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/valueOfContractedFunctionIngored.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/valueOfContractedFunctionIngored.fir.kt deleted file mode 100644 index cc764056435..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/valueOfContractedFunctionIngored.fir.kt +++ /dev/null @@ -1,11 +0,0 @@ -// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect -// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts -// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER - -import kotlin.contracts.* - -fun f3(value: String?) { - if (!value.isNullOrEmpty() is Boolean) { - value.length - } -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/valueOfContractedFunctionIngored.kt b/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/valueOfContractedFunctionIngored.kt index 719b21a4480..60015281e60 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/valueOfContractedFunctionIngored.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/valueOfContractedFunctionIngored.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect // !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts // !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/type-checking-and-containment-checking-expressions/type-checking-expression/p-4/pos/1.1.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/type-checking-and-containment-checking-expressions/type-checking-expression/p-4/pos/1.1.kt index 5d617e0d00f..507d98fbe10 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/type-checking-and-containment-checking-expressions/type-checking-expression/p-4/pos/1.1.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/type-checking-and-containment-checking-expressions/type-checking-expression/p-4/pos/1.1.kt @@ -37,4 +37,4 @@ fun case4() { x checkType { check() } } -class A \ No newline at end of file +class A diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/9.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/9.1.fir.kt deleted file mode 100644 index 03a0b7bb732..00000000000 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/9.1.fir.kt +++ /dev/null @@ -1,83 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_EXPRESSION -// SKIP_TXT - -/* - * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) - * - * SPEC VERSION: 0.1-435 - * MAIN LINK: expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 9 - * NUMBER: 1 - * DESCRIPTION: Non-exhaustive when using subclasses of the sealed class. - * HELPERS: sealedClasses - */ - -// TESTCASE NUMBER: 1 -fun case_1(value_1: SealedClass): String = when(value_1) { - is SealedChild1 -> "" - is SealedChild2 -> "" -} - -// TESTCASE NUMBER: 2 -fun case_2(value_1: SealedClass): String = when(value_1) { - is SealedChild1, is SealedChild2 -> "" -} - -// TESTCASE NUMBER: 3 -fun case_3(value_1: SealedClassMixed): String = when(value_1) { - is SealedMixedChild1 -> "" - is SealedMixedChild2 -> "" - SealedMixedChildObject1 -> "" -} - -// TESTCASE NUMBER: 4 -fun case_4(value_1: SealedClassMixed): String = when(value_1) { - SealedMixedChildObject1, is SealedMixedChild2, is SealedMixedChild1 -> "" -} - -// TESTCASE NUMBER: 5 -fun case_5(value_1: SealedClassMixed): String = when(value_1) { - is SealedMixedChild1 -> "" - is SealedMixedChild2 -> "" - is SealedMixedChild3 -> "" -} - -// TESTCASE NUMBER: 6 -fun case_6(value_1: SealedClassMixed): Int = when(value_1) { } - -// TESTCASE NUMBER: 7 -fun case_7(value_1: SealedClassSingleWithObject): Int = when(value_1) { } - -// TESTCASE NUMBER: 8 -fun case_8(value_1: SealedClassEmpty): String = when (value_1) { } - -// TESTCASE NUMBER: 9 -fun case_9(value_1: Number): String = when (value_1) { - is Byte -> "" - is Double -> "" - is Float -> "" - is Int -> "" - is Long -> "" - is Short -> "" -} - -/* - * TESTCASE NUMBER: 10 - * DISCUSSION: maybe make exhaustive without else? - */ -fun case_10(value_1: Any): String = when (value_1) { - is Any -> "" -} - -// TESTCASE NUMBER: 11 -fun case_11(value_1: SealedClass): String = when { - value_1 is SealedChild1 -> "" - value_1 is SealedChild2 -> "" - value_1 is SealedChild3 -> "" -} - -// TESTCASE NUMBER: 12 -fun case_12(value_1: SealedClassMixed): String = when(value_1) { - is SealedMixedChild1 -> "" - is SealedMixedChild2 -> "" - is SealedMixedChild3 -> "" -} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/9.1.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/9.1.kt index b40e79ef1b0..adfb86ec3cd 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/9.1.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/9.1.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_EXPRESSION // SKIP_TXT diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/1.3.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/1.3.fir.kt index 4f5815ecd53..18bc60d3021 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/1.3.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/1.3.fir.kt @@ -53,7 +53,7 @@ fun case_6(value_1: SealedClass?): String = when (value_1) { // TESTCASE NUMBER: 7 fun case_7(value_1: SealedClassSingle): String = when (value_1) { - is SealedClassSingle -> "" + is SealedClassSingle -> "" else -> "" } diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/7.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/7.1.fir.kt index dda105c886d..679d7850567 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/7.1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/7.1.fir.kt @@ -11,7 +11,7 @@ fun case_1(value_1: SealedClass): Int = when (value_1) { // TESTCASE NUMBER: 2 fun case_2(value_1: SealedClass): String = when (value_1) { - is SealedClass -> "" + is SealedClass -> "" } // TESTCASE NUMBER: 3 diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/2.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/2.1.fir.kt index a375290a9c0..61813107bac 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/2.1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/2.1.fir.kt @@ -73,7 +73,7 @@ fun case_6(value_1: Any) { value_1 is String -> {} value_1 is Number -> {} value_1 is Float -> {} - value_1 is Any -> {} + value_1 is Any -> {} } } @@ -85,8 +85,8 @@ fun case_7(value_1: Any) { when { value_1 !is Number -> {} value_1 is Float -> {} - value_1 is Number -> {} - value_1 is Any -> {} + value_1 is Number -> {} + value_1 is Any -> {} } } diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/1.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/1.1.fir.kt index 35d1f0c79d9..738eb1f2cb7 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/1.1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/1.1.fir.kt @@ -29,7 +29,7 @@ fun case_3(value_1: Any?): String = when (value_1) { // TESTCASE NUMBER: 4 fun case_4(value_1: Any): String = when (value_1) { - is Any? -> "" + is Any? -> "" else -> "" } diff --git a/compiler/tests-spec/testData/diagnostics/linked/type-system/subtyping/subtyping-for-intersection-types/p-1/pos/1.3.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/type-system/subtyping/subtyping-for-intersection-types/p-1/pos/1.3.fir.kt index a77e14c3079..b9c07f93002 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/type-system/subtyping/subtyping-for-intersection-types/p-1/pos/1.3.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/type-system/subtyping/subtyping-for-intersection-types/p-1/pos/1.3.fir.kt @@ -70,7 +70,7 @@ interface A3 // TESTCASE NUMBER: 4 fun case4(x: C?) { - if (x is B4 && x is A4) { + if (x is B4 && x is A4) { x x x.foo() diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/15.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/15.fir.kt index 28e7c382409..ae077910249 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/15.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/15.fir.kt @@ -43,7 +43,7 @@ fun case_2(value: Any) { // TESTCASE NUMBER: 3 fun case_3(value: String?) { - if (!value.isNullOrEmpty() is Boolean) { + if (!value.isNullOrEmpty() is Boolean) { value.length } } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/2.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/2.fir.kt index a8b1adcedaa..2941017f8f6 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/2.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/2.fir.kt @@ -158,7 +158,7 @@ class case_10_class { * ISSUES: KT-26747 */ fun case_11(value_1: Any?, value_2: Any?, value_3: Any?) { - funWithReturnsAndInvertCondition(value_1 !is String || value_2 !is Number || value_3 !is Any?) + funWithReturnsAndInvertCondition(value_1 !is String || value_2 !is Number || value_3 !is Any?) println(value_1!!.length) println(value_2?.toByte()) } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/effects/returns/neg/7.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/effects/returns/neg/7.fir.kt index 44a67da46d3..f7638f0ad3c 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/effects/returns/neg/7.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/effects/returns/neg/7.fir.kt @@ -6,7 +6,7 @@ import kotlin.contracts.* // TESTCASE NUMBER: 1 fun T.case_1() { contract { returns() implies (this@case_1 is T) } - if (!(this@case_1 is T)) throw Exception() + if (!(this@case_1 is T)) throw Exception() } // TESTCASE NUMBER: 2 diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/neg/2.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/neg/2.fir.kt index e4e4de283a2..3030c239818 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/neg/2.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/neg/2.fir.kt @@ -43,7 +43,7 @@ class case_4 : ClassLevel3() { fun T.case_4_3_wrap() { fun case_4_3_contract() { - contract { returns() implies (this@case_4_3_wrap is ClassLevel1) } + contract { returns() implies (this@case_4_3_wrap is ClassLevel1) } if (this@case_4_3_wrap !is ClassLevel1) throw Exception() } case_4_3_contract() @@ -61,12 +61,12 @@ class case_5 : ClassLevel5() { inner class case_5_1 { fun K.case_5_1_1() { contract { returns() implies (this@case_5_1 !is ClassLevel1 && this@case_5_1 != null || this@case_5 is ClassLevel1 && this@case_5_1_1 is Float) } - if (!(this@case_5_1 !is ClassLevel1 && this@case_5_1 != null || this@case_5 is ClassLevel1 && this is Float)) throw Exception() + if (!(this@case_5_1 !is ClassLevel1 && this@case_5_1 != null || this@case_5 is ClassLevel1 && this is Float)) throw Exception() } fun case_5_1_2() { contract { returns() implies (this@case_5_1 !is ClassLevel1 || this@case_5 is ClassLevel1 || this@case_5_1 == null) } - if (!(this@case_5_1 !is ClassLevel1 || this@case_5 is ClassLevel1 || this@case_5_1 == null)) throw Exception() + if (!(this@case_5_1 !is ClassLevel1 || this@case_5 is ClassLevel1 || this@case_5_1 == null)) throw Exception() } } } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.fir.kt index da5939c25c9..6a11265b90e 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.fir.kt @@ -37,7 +37,7 @@ fun case_3() { // TESTCASE NUMBER: 4 fun case_4(x: Char?) { - if (x != null || false is Boolean) { + if (x != null || false is Boolean) { x x.equals(null) x.propT @@ -55,7 +55,7 @@ fun case_4(x: Char?) { fun case_5() { val x: Unit? = null - if (x !== null is Boolean?) x + if (x !== null is Boolean?) x if (x !== null == null) x.equals(null) if (x !== null == null) x.propT if (x !== null == null) x.propAny @@ -71,7 +71,7 @@ fun case_5() { fun case_6(x: EmptyClass?) { val y = true - if ((x != null && !y) is Boolean) { + if ((x != null && !y) is Boolean) { x x.equals(null) x.propT @@ -111,7 +111,7 @@ fun case_8(x: TypealiasNullableString) { fun case_9(x: TypealiasNullableString?) { if (x === null === null) { - } else if (false is Boolean) { + } else if (false is Boolean) { x x.get(0) } @@ -121,7 +121,7 @@ fun case_9(x: TypealiasNullableString?) { fun case_10() { val a = Class() - if (a.prop_4 === null || true is Boolean) { + if (a.prop_4 === null || true is Boolean) { if (a.prop_4 != null !== null) { a.prop_4 a.prop_4.equals(null) @@ -145,7 +145,7 @@ fun case_11(x: TypealiasNullableStringIndirect?, y: TypealiasNullableStringIndir } else { if (y != null is Boolean == true) { - if ((nullableStringProperty == null) !is Boolean) { + if ((nullableStringProperty == null) !is Boolean) { if (t != null is Boolean) { x x.equals(null) @@ -165,8 +165,8 @@ fun case_11(x: TypealiasNullableStringIndirect?, y: TypealiasNullableStringIndir // TESTCASE NUMBER: 12 fun case_12(x: TypealiasNullableStringIndirect, y: TypealiasNullableStringIndirect) = - if ((x == null) !is Boolean === false) "1" - else if ((y === null !== null) is Boolean) x + if ((x == null) !is Boolean === false) "1" + else if ((y === null !== null) is Boolean) x else if (y === null != null) x.equals(null) else if (y === null != null) x.propT else if (y === null != null) x.propAny @@ -198,19 +198,19 @@ class Case14 { fun case_14() { val a = Case14() - if (a.x != null !is Boolean !is Boolean) { + if (a.x != null !is Boolean !is Boolean) { if (a.x != null == true) { if (a.x !== null == false) { if (a.x != null == null) { if (a.x != null !== null) { if (a.x != null === true) { - if (a.x !== null === true !is Boolean == true) { + if (a.x !== null === true !is Boolean == true) { if (a.x != null !== false) { if (a.x != null === false) { if (a.x !== null === true) { - if ((a.x != null != true) !is Boolean) { + if ((a.x != null != true) !is Boolean) { if (a.x != null is Boolean) { - if (a.x != null is Boolean is Boolean) { + if (a.x != null is Boolean is Boolean) { if (a.x !== null is Boolean) { if (a.x != null is Boolean) { if ((a.x !== null !is Boolean) == false) { @@ -236,7 +236,7 @@ fun case_14() { // TESTCASE NUMBER: 15 fun case_15(x: EmptyObject) { - val t = if (x === null is Boolean is Boolean is Boolean) "" else { + val t = if (x === null is Boolean is Boolean is Boolean) "" else { x x.equals(null) x.propT @@ -254,7 +254,7 @@ fun case_15(x: EmptyObject) { fun case_16() { val x: TypealiasNullableNothing = null - if (x != null !is Boolean !is Boolean !is Boolean !is Boolean !is Boolean) { + if (x != null !is Boolean !is Boolean !is Boolean !is Boolean !is Boolean) { x x.java } @@ -344,7 +344,7 @@ fun case_20(b: Boolean) { // TESTCASE NUMBER: 21 fun case_21() { - if (EnumClassWithNullableProperty.B.prop_1 !== null is Boolean == true !is Boolean != true) { + if (EnumClassWithNullableProperty.B.prop_1 !== null is Boolean == true !is Boolean != true) { EnumClassWithNullableProperty.B.prop_1 EnumClassWithNullableProperty.B.prop_1.equals(null) EnumClassWithNullableProperty.B.prop_1.propT @@ -458,7 +458,7 @@ fun case_26(a: ((Float) -> Int?)?, b: Float?) { // TESTCASE NUMBER: 27 fun case_27() { - if (Object.prop_1 == null == true == true == true == true == true == true == true == true == true == true == true == true == true == true is Boolean) + if (Object.prop_1 == null == true == true == true == true == true == true == true == true == true == true == true == true == true == true is Boolean) else { Object.prop_1 Object.prop_1.equals(null) diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/3.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/3.fir.kt index ea8cef6a0d9..29fbca7e1d6 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/3.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/3.fir.kt @@ -12,7 +12,7 @@ fun case_1(x: Nothing?) { // TESTCASE NUMBER: 2 fun case_2(x: Nothing) { - if (x is Unit) { + if (x is Unit) { x x.inv() } @@ -28,7 +28,7 @@ fun case_3(x: Nothing?) { // TESTCASE NUMBER: 4 fun case_4(x: Nothing) { - if (x !is EnumClass) else { + if (x !is EnumClass) else { x x.fun_1() } @@ -36,7 +36,7 @@ fun case_4(x: Nothing) { // TESTCASE NUMBER: 5 fun case_5(x: Nothing?) { - if (!(x !is Class.NestedClass?)) { + if (!(x !is Class.NestedClass?)) { x x?.prop_4 } @@ -52,7 +52,7 @@ fun case_6(x: Nothing?) { // TESTCASE NUMBER: 7 fun case_7(x: Nothing) { - if (!(x is DeepObject.A.B.C.D.E.F.G.J)) else { + if (!(x is DeepObject.A.B.C.D.E.F.G.J)) else { x x.prop_1 } @@ -60,7 +60,7 @@ fun case_7(x: Nothing) { // TESTCASE NUMBER: 8 fun case_8(x: Nothing?) { - if (!(x is Int?)) else { + if (!(x is Int?)) else { x x?.inv() } @@ -68,7 +68,7 @@ fun case_8(x: Nothing?) { // TESTCASE NUMBER: 9 fun case_9(x: Nothing?) { - if (!!(x !is TypealiasNullableStringIndirect?)) else { + if (!!(x !is TypealiasNullableStringIndirect?)) else { x x?.length } @@ -85,7 +85,7 @@ fun case_10(x: Nothing?) { // TESTCASE NUMBER: 11 fun case_11(x: Nothing?) { - if (x is SealedMixedChildObject1?) { + if (x is SealedMixedChildObject1?) { x x?.prop_1 x?.prop_2 diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/4.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/4.fir.kt index 846cf0d2216..7707610932d 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/4.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/4.fir.kt @@ -4,7 +4,7 @@ // TESTCASE NUMBER: 1 fun case_1(x: Any?) { - if (x is Int is Boolean) { + if (x is Int is Boolean) { x x.inv() x.not() @@ -15,7 +15,7 @@ fun case_1(x: Any?) { // TESTCASE NUMBER: 2 fun case_2(x: Any?) { - if (x is Int is Any? is Boolean) { + if (x is Int is Any? is Boolean) { x x.inv() x.not() @@ -86,7 +86,7 @@ fun case_8(x: Any?) { // TESTCASE NUMBER: 9 fun case_9(x: Any?) { - if (x !is Int !is Any?) { + if (x !is Int !is Any?) { x x.inv() x.propAny @@ -132,7 +132,7 @@ inline fun case_13(x: Any?) { // TESTCASE NUMBER: 14 inline fun case_14(x: Any?) { - if (!(x !is T is Boolean)) { + if (!(x !is T is Boolean)) { x x.propAny x.funAny() @@ -141,7 +141,7 @@ inline fun case_14(x: Any?) { // TESTCASE NUMBER: 15 inline fun case_15(x: Any?) { - if (!(x !is T) is Boolean) { + if (!(x !is T) is Boolean) { x x.propAny x.funAny() diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/6.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/6.fir.kt index 3e56c9a480a..21c3b6ef2d7 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/6.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/6.fir.kt @@ -12,7 +12,7 @@ fun case_1(x: Any?) { // TESTCASE NUMBER: 2 fun case_2(x: Any) { - if (x is Number || x !is Number || x is Number) { + if (x is Number || x !is Number || x is Number) { x x.toByte() } @@ -20,7 +20,7 @@ fun case_2(x: Any) { // TESTCASE NUMBER: 3 fun case_3(x: Any?) { - if (x is Boolean || x !is Boolean is Boolean) { + if (x is Boolean || x !is Boolean is Boolean) { x x.prop_1 } @@ -28,7 +28,7 @@ fun case_3(x: Any?) { // TESTCASE NUMBER: 4 fun case_4(x: Any) { - if (x !is EnumClass || x !is EnumClass || x is EnumClass || x is EnumClass) { + if (x !is EnumClass || x !is EnumClass || x is EnumClass || x is EnumClass) { x x.fun_1() } @@ -46,7 +46,7 @@ fun case_5(x: Any?) { // TESTCASE NUMBER: 6 fun case_6(x: Any?) { - if (!(x is Object) || !!(x !is Object)) { + if (!(x is Object) || !!(x !is Object)) { x x.prop_1 } @@ -54,7 +54,7 @@ fun case_6(x: Any?) { // TESTCASE NUMBER: 7 fun case_7(x: Any) { - if (!(x is DeepObject.A.B.C.D.E.F.G.J) || !!!!!!(x is DeepObject.A.B.C.D.E.F.G.J)) { + if (!(x is DeepObject.A.B.C.D.E.F.G.J) || !!!!!!(x is DeepObject.A.B.C.D.E.F.G.J)) { x x.prop_1 } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/22.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/22.fir.kt index 581c261d041..1ebedfb4d7c 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/22.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/22.fir.kt @@ -5,7 +5,7 @@ // TESTCASE NUMBER: 1 fun case_1(x: Any?) { if (x is Int) { - if (x !is Int) { + if (x !is Int) { x x.inv() } @@ -35,7 +35,7 @@ fun case_3(x: Any?) { // TESTCASE NUMBER: 4 fun case_4(x: Any) { if (x !is EnumClass) else { - if (x !is EnumClass) { + if (x !is EnumClass) { x x.fun_1() } @@ -45,7 +45,7 @@ fun case_4(x: Any) { // TESTCASE NUMBER: 5 fun case_5(x: Any?) { if (!(x !is Class.NestedClass?)) { - if (!!(x !is Class.NestedClass?)) { + if (!!(x !is Class.NestedClass?)) { x x?.prop_4 } @@ -106,7 +106,7 @@ fun case_10(x: Any?) { // TESTCASE NUMBER: 11 fun case_11(x: Any?) { if (x is SealedMixedChildObject1?) { - if (x is SealedMixedChildObject1?) { + if (x is SealedMixedChildObject1?) { x x?.prop_1 x?.prop_2 @@ -117,7 +117,7 @@ fun case_11(x: Any?) { // TESTCASE NUMBER: 12 inline fun case_12(x: Any?) { if (x is T) { - if (x is T is K) { + if (x is T is K) { x } } @@ -135,7 +135,7 @@ inline fun case_13(x: Any?) { // TESTCASE NUMBER: 14 inline fun case_14(x: Any?) { if (x is T) { - if (x !is T) { + if (x !is T) { x } } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/25.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/25.fir.kt index fbcc4cc42e4..4106f420f65 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/25.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/25.fir.kt @@ -30,7 +30,7 @@ open class Case1 { // TESTCASE NUMBER: 2 inline fun case_2(x: Any?) { x as T - if (x !is T) { + if (x !is T) { x x.length x.get(0) @@ -60,7 +60,7 @@ inline fun case_4(x: Any?) { // TESTCASE NUMBER: 5 inline fun case_5(x: Any?) { if (x as? T != null) { - if (x is T?) { + if (x is T?) { x x.length x.get(0) diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/26.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/26.fir.kt index fbcc4cc42e4..4106f420f65 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/26.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/26.fir.kt @@ -30,7 +30,7 @@ open class Case1 { // TESTCASE NUMBER: 2 inline fun case_2(x: Any?) { x as T - if (x !is T) { + if (x !is T) { x x.length x.get(0) @@ -60,7 +60,7 @@ inline fun case_4(x: Any?) { // TESTCASE NUMBER: 5 inline fun case_5(x: Any?) { if (x as? T != null) { - if (x is T?) { + if (x is T?) { x x.length x.get(0) diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/27.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/27.fir.kt index fbcc4cc42e4..4106f420f65 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/27.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/27.fir.kt @@ -30,7 +30,7 @@ open class Case1 { // TESTCASE NUMBER: 2 inline fun case_2(x: Any?) { x as T - if (x !is T) { + if (x !is T) { x x.length x.get(0) @@ -60,7 +60,7 @@ inline fun case_4(x: Any?) { // TESTCASE NUMBER: 5 inline fun case_5(x: Any?) { if (x as? T != null) { - if (x is T?) { + if (x is T?) { x x.length x.get(0) diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/31.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/31.fir.kt index 8becfa46a9d..93ae62955b7 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/31.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/31.fir.kt @@ -83,7 +83,7 @@ fun case_5(x: Class?) { * ISSUES: KT-30376 */ fun case_6(x: Class?) { - if ((x?.prop_8?.prop_8?.prop_8 as Class?)?.prop_8 == null == true) else { + if ((x?.prop_8?.prop_8?.prop_8 as Class?)?.prop_8 == null == true) else { x x.prop_8 x.prop_8.prop_8 diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/34.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/34.fir.kt index 356c3d93f92..be41491807b 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/34.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/34.fir.kt @@ -73,7 +73,7 @@ fun case_5(a: Any?) { if ( a is ClassLevel1 && if (true) {b = a; false} else {b = a;true} - && b as ClassLevel2 is ClassLevel2 + && b as ClassLevel2 is ClassLevel2 && if (true) {c = b;false} else {c = b;false} && try {c as ClassLevel3;true} finally {c as ClassLevel3;false} && when (true) {else -> {d = c;true}} diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/5.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/5.fir.kt index 84b0a273a07..4a421fa6662 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/5.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/5.fir.kt @@ -338,7 +338,7 @@ fun case_14(x: Any?) { * ISSUES: KT-28362 */ fun case_15(x: Any?) { - if (x !is ClassLevel2? || x !is ClassLevel1?) else { + if (x !is ClassLevel2? || x !is ClassLevel1?) else { if (x === null || x !is Interface1?) else { if (x !is Interface2? || x !is Interface3?) {} else { x diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/51.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/51.fir.kt index 87e8c84541f..f50480df320 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/51.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/51.fir.kt @@ -264,7 +264,7 @@ fun case_23(z: Any?) { val y = z.run { when (this) { true -> this!! - 0.0 -> this as Any + 0.0 -> this as Any else -> this!! } } @@ -277,7 +277,7 @@ fun case_24(z: Any?) { val y = z.let { when (it) { true -> it!! - 0.0 -> it as Any + 0.0 -> it as Any else -> it!! } } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/54.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/54.fir.kt index 3d2ce654e6e..38bdee11f95 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/54.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/54.fir.kt @@ -13,7 +13,7 @@ fun case_1() { var b = a b b.length - while (a is String) { + while (a is String) { b = a b b.length @@ -119,7 +119,7 @@ fun case_6() { var b = a b b.length - if (a is String) { + if (a is String) { b = a b b.length diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/59.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/59.fir.kt index c781c9b3103..376a7a7f3f8 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/59.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/59.fir.kt @@ -139,7 +139,7 @@ fun case_10() { */ fun case_11() { var x: Any? = null - x as? Any ?: null!! + x as? Any ?: null!! do { x x = x.equals(10) @@ -187,7 +187,7 @@ fun case_14() { do { x x = x.equals(10) - } while (x is Any) + } while (x is Any) } /* @@ -201,6 +201,6 @@ fun case_15() { do { x x = x .equals(10) - } while (x is Any) + } while (x is Any) } } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/6.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/6.fir.kt index 7bce4c1a7f0..5802bfa7f61 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/6.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/6.fir.kt @@ -1386,7 +1386,7 @@ fun case_74(t: Any?) { * ISSUES: KT-28362 */ fun case_75(t: Any?, z: Nothing?) { - if (t !is ClassLevel2? || t !is ClassLevel1?) else { + if (t !is ClassLevel2? || t !is ClassLevel1?) else { if (t === ((((((z)))))) || t !is Interface1?) else { if (t !is Interface2? || t !is Interface3?) {} else { t.itest2() diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/66.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/66.fir.kt index 2fcf9954b1a..2496b391cdb 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/66.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/66.fir.kt @@ -78,7 +78,7 @@ fun case_5(x: Pair<*, *>?) { fun case_6(x: Any?) { when (x) { is Nothing? -> return - is Any? -> { + is Any? -> { x x.equals(10) } diff --git a/idea/idea-frontend-fir/idea-frontend-fir-generator/src/org/jetbrains/kotlin/idea/frontend/api/fir/generator/HLDiagnosticConverter.kt b/idea/idea-frontend-fir/idea-frontend-fir-generator/src/org/jetbrains/kotlin/idea/frontend/api/fir/generator/HLDiagnosticConverter.kt index 52a94c4d428..5b2ad83e52f 100644 --- a/idea/idea-frontend-fir/idea-frontend-fir-generator/src/org/jetbrains/kotlin/idea/frontend/api/fir/generator/HLDiagnosticConverter.kt +++ b/idea/idea-frontend-fir/idea-frontend-fir-generator/src/org/jetbrains/kotlin/idea/frontend/api/fir/generator/HLDiagnosticConverter.kt @@ -203,6 +203,7 @@ private object FirToKtConversionCreator { ) private val allowedTypesWithoutTypeParams = setOf( + Boolean::class, String::class, Int::class, Name::class, diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt index 607c697055a..5bb40066b42 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.psi.KtAnnotation import org.jetbrains.kotlin.psi.KtArrayAccessExpression import org.jetbrains.kotlin.psi.KtBinaryExpression +import org.jetbrains.kotlin.psi.KtBinaryExpressionWithTypeRHS import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtDeclaration @@ -1853,6 +1854,19 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.USELESS_CAST) { firDiagnostic -> + UselessCastImpl( + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } + add(FirErrors.USELESS_IS_CHECK) { firDiagnostic -> + UselessIsCheckImpl( + firDiagnostic.a, + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } add(FirErrors.NO_ELSE_IN_WHEN) { firDiagnostic -> NoElseInWhenImpl( firDiagnostic.a.map { whenMissingCase -> diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt index dfc8aa3ebe2..0901463252e 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtAnnotation import org.jetbrains.kotlin.psi.KtArrayAccessExpression import org.jetbrains.kotlin.psi.KtBinaryExpression +import org.jetbrains.kotlin.psi.KtBinaryExpressionWithTypeRHS import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtDeclaration @@ -1302,6 +1303,15 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = UselessElvisRightIsNull::class } + abstract class UselessCast : KtFirDiagnostic() { + override val diagnosticClass get() = UselessCast::class + } + + abstract class UselessIsCheck : KtFirDiagnostic() { + override val diagnosticClass get() = UselessIsCheck::class + abstract val compileTimeCheckResult: Boolean + } + abstract class NoElseInWhen : KtFirDiagnostic() { override val diagnosticClass get() = NoElseInWhen::class abstract val missingWhenCases: List diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index c5865980a6a..08095de306a 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -30,6 +30,7 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtAnnotation import org.jetbrains.kotlin.psi.KtArrayAccessExpression import org.jetbrains.kotlin.psi.KtBinaryExpression +import org.jetbrains.kotlin.psi.KtBinaryExpressionWithTypeRHS import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtDeclaration @@ -2113,6 +2114,21 @@ internal class UselessElvisRightIsNullImpl( override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) } +internal class UselessCastImpl( + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.UselessCast(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + +internal class UselessIsCheckImpl( + override val compileTimeCheckResult: Boolean, + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.UselessIsCheck(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + internal class NoElseInWhenImpl( override val missingWhenCases: List, firDiagnostic: FirPsiDiagnostic<*>,