Skip to content

Commit 46d9321

Browse files
vsukharevSpace Team
authored andcommitted
[IR] Add IR validation error on redundant implicit cast
^KT-80953
1 parent 978fb39 commit 46d9321

File tree

3 files changed

+81
-0
lines changed

3 files changed

+81
-0
lines changed

compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/IrValidationPhase.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.ir.validation.checkers.declaration.IrExpressionBodyI
1515
import org.jetbrains.kotlin.ir.validation.checkers.declaration.IrFieldVisibilityChecker
1616
import org.jetbrains.kotlin.ir.validation.checkers.expression.InlineFunctionUseSiteChecker
1717
import org.jetbrains.kotlin.ir.validation.checkers.expression.IrCrossFileFieldUsageChecker
18+
import org.jetbrains.kotlin.ir.validation.checkers.expression.IrTypeOperatorRedundancyChecker
1819
import org.jetbrains.kotlin.ir.validation.checkers.expression.IrValueAccessScopeChecker
1920
import org.jetbrains.kotlin.ir.validation.checkers.symbol.IrVisibilityChecker
2021
import org.jetbrains.kotlin.utils.addToStdlib.applyIf
@@ -106,6 +107,7 @@ class IrValidationAfterInliningAllFunctionsOnTheSecondStagePhase<Context : Lower
106107
withVarargChecks()
107108
}
108109
.withInlineFunctionCallsiteCheck(checkInlineFunctionCallSites)
110+
.withCheckers(IrTypeOperatorRedundancyChecker)
109111
}
110112

111113
class IrValidationAfterInliningAllFunctionsOnTheFirstStagePhase<Context : LoweringContext>(
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
3+
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
4+
*/
5+
6+
package org.jetbrains.kotlin.ir.validation.checkers.expression
7+
8+
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
9+
import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall
10+
import org.jetbrains.kotlin.ir.util.render
11+
import org.jetbrains.kotlin.ir.validation.checkers.IrElementChecker
12+
import org.jetbrains.kotlin.ir.validation.checkers.context.CheckerContext
13+
14+
object IrTypeOperatorRedundancyChecker : IrElementChecker<IrTypeOperatorCall>(IrTypeOperatorCall::class) {
15+
override fun check(element: IrTypeOperatorCall, context: CheckerContext) {
16+
if (element.operator == IrTypeOperator.IMPLICIT_CAST) {
17+
if (element.type == element.argument.type) {
18+
context.error(element, "Redundant IMPLICIT_CAST: ${element.render()}")
19+
}
20+
}
21+
}
22+
}

compiler/ir/ir.validation/test/org/jetbrains/kotlin/ir/validation/IrValidatorTest.kt

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.ir.types.*
3939
import org.jetbrains.kotlin.ir.types.impl.IrDynamicTypeImpl
4040
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
4141
import org.jetbrains.kotlin.ir.util.*
42+
import org.jetbrains.kotlin.ir.validation.checkers.expression.IrTypeOperatorRedundancyChecker
4243
import org.jetbrains.kotlin.name.FqName
4344
import org.jetbrains.kotlin.name.Name
4445
import org.jetbrains.kotlin.name.SpecialNames
@@ -2231,6 +2232,62 @@ class IrValidatorTest {
22312232
)
22322233
}
22332234

2235+
@Test
2236+
fun `redundant IMPLICIT_CAST is reported`() {
2237+
val file = createIrFile("test.kt")
2238+
val function = IrFactoryImpl.buildFun {
2239+
name = Name.identifier("foo")
2240+
returnType = TestIrBuiltins.unitType
2241+
}
2242+
val body = IrFactoryImpl.createBlockBody(
2243+
startOffset = UNDEFINED_OFFSET,
2244+
endOffset = UNDEFINED_OFFSET,
2245+
)
2246+
2247+
// Redundant: result type equals argument type
2248+
val redundantImplicitCast = IrTypeOperatorCallImpl(
2249+
startOffset = UNDEFINED_OFFSET,
2250+
endOffset = UNDEFINED_OFFSET,
2251+
type = TestIrBuiltins.booleanType,
2252+
operator = IrTypeOperator.IMPLICIT_CAST,
2253+
typeOperand = TestIrBuiltins.booleanType,
2254+
argument = createTrueConst()
2255+
)
2256+
2257+
// Non-redundant: argument type differs from result type
2258+
val nonRedundantImplicitCast = IrTypeOperatorCallImpl(
2259+
startOffset = UNDEFINED_OFFSET,
2260+
endOffset = UNDEFINED_OFFSET,
2261+
type = TestIrBuiltins.anyType,
2262+
operator = IrTypeOperator.IMPLICIT_CAST,
2263+
typeOperand = TestIrBuiltins.anyType,
2264+
argument = createTrueConst() // Boolean is a subtype of Any
2265+
)
2266+
2267+
body.statements.addAll(listOf(redundantImplicitCast, nonRedundantImplicitCast))
2268+
function.body = body
2269+
file.addChild(function)
2270+
2271+
testValidation(
2272+
IrVerificationMode.ERROR,
2273+
file,
2274+
listOf(
2275+
Message(
2276+
ERROR,
2277+
"""
2278+
[IR VALIDATION] IrValidatorTest: Redundant IMPLICIT_CAST: TYPE_OP type=kotlin.Boolean origin=IMPLICIT_CAST typeOperand=kotlin.Boolean
2279+
TYPE_OP type=kotlin.Boolean origin=IMPLICIT_CAST typeOperand=kotlin.Boolean
2280+
inside BLOCK_BODY
2281+
inside FUN name:foo visibility:public modality:FINAL <> () returnType:kotlin.Unit
2282+
inside FILE fqName:org.sample fileName:test.kt
2283+
""".trimIndent(),
2284+
CompilerMessageLocation.create("test.kt", 0, 0, null),
2285+
)
2286+
),
2287+
config = defaultValidationConfig.withCheckers(IrTypeOperatorRedundancyChecker)
2288+
)
2289+
}
2290+
22342291
@Test
22352292
fun `calls with incorrect type are reported`() {
22362293
val file = createIrFile("test.kt")

0 commit comments

Comments
 (0)