diff --git a/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java b/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java index 87dc3b96ecf..b2b66a3ecc5 100644 --- a/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java +++ b/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java @@ -3141,6 +3141,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/safeCalls/boundSafeCallAndIsCheck.kt"); } + @TestMetadata("complexIfWithOr.kt") + public void testComplexIfWithOr() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/safeCalls/complexIfWithOr.kt"); + } + @TestMetadata("safeCallAndEqualityToBool.kt") public void testSafeCallAndEqualityToBool() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/safeCalls/safeCallAndEqualityToBool.kt"); diff --git a/compiler/fir/analysis-tests/testData/resolve/smartcasts/safeCalls/complexIfWithOr.fir.txt b/compiler/fir/analysis-tests/testData/resolve/smartcasts/safeCalls/complexIfWithOr.fir.txt new file mode 100644 index 00000000000..9682b6315a7 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/smartcasts/safeCalls/complexIfWithOr.fir.txt @@ -0,0 +1,19 @@ +FILE: complexIfWithOr.kt + public abstract interface State : R|kotlin/Any| { + } + public abstract interface Complex : R|kotlin/Any| { + public abstract val superClass: R|Complex?| + public get(): R|Complex?| + + } + public abstract interface ExceptionState : R|State| { + } + public final fun test(qualifier: R|State?|): R|kotlin/Unit| { + when () { + ==(R|/qualifier|, Null(null)) || (R|/qualifier| is R|ExceptionState|) || ==((R|/qualifier| as? R|Complex|)?.{ $subj$.R|/Complex.superClass| }, Null(null)) -> { + ^test Unit + } + } + + R|/qualifier|.R|/Complex.superClass| + } diff --git a/compiler/fir/analysis-tests/testData/resolve/smartcasts/safeCalls/complexIfWithOr.kt b/compiler/fir/analysis-tests/testData/resolve/smartcasts/safeCalls/complexIfWithOr.kt new file mode 100644 index 00000000000..ac809c66c92 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/smartcasts/safeCalls/complexIfWithOr.kt @@ -0,0 +1,13 @@ +interface State +interface Complex { + val superClass: Complex? +} + +interface ExceptionState : State + +fun test(qualifier: State?) { + if (qualifier == null || qualifier is ExceptionState || (qualifier as? Complex)?.superClass == null) { + return + } + qualifier.superClass +} diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java index 2e8c5b5d8e8..4492e91c070 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java @@ -3520,6 +3520,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest { runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/safeCalls/boundSafeCallAndIsCheck.kt"); } + @Test + @TestMetadata("complexIfWithOr.kt") + public void testComplexIfWithOr() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/safeCalls/complexIfWithOr.kt"); + } + @Test @TestMetadata("safeCallAndEqualityToBool.kt") public void testSafeCallAndEqualityToBool() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java index 330d8501dfb..ead574e1fb4 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java @@ -3566,6 +3566,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/safeCalls/boundSafeCallAndIsCheck.kt"); } + @Test + @TestMetadata("complexIfWithOr.kt") + public void testComplexIfWithOr() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/safeCalls/complexIfWithOr.kt"); + } + @Test @TestMetadata("safeCallAndEqualityToBool.kt") public void testSafeCallAndEqualityToBool() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index ae540bfc9f9..f5d21564443 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -14946,6 +14946,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/fir/FakeOverrideBuilder.kt"); } + @Test + @TestMetadata("falsePositiveBoundSmartcast.kt") + public void testFalsePositiveBoundSmartcast() throws Exception { + runTest("compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt"); + } + @Test @TestMetadata("Fir2IrClassifierStorage.kt") public void testFir2IrClassifierStorage() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt index 2a850c269be..093c8da9aa2 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt @@ -49,6 +49,12 @@ class DataFlowAnalyzerContext( var variableStorage = variableStorage private set + private var assignmentCounter = 0 + + fun newAssignmentIndex(): Int { + return assignmentCounter++ + } + fun reset() { graphBuilder.reset() variablesForWhenConditions.clear() @@ -84,7 +90,6 @@ abstract class FirDataFlowAnalyzer( private val receiverStack: PersistentImplicitReceiverStack get() = components.implicitReceiverStack as PersistentImplicitReceiverStack - private val symbolProvider = components.session.symbolProvider private val visibilityChecker = components.session.visibilityChecker override val logicSystem: PersistentLogicSystem = @@ -673,7 +678,7 @@ abstract class FirDataFlowAnalyzer( if (possiblyChangedVariables.isEmpty()) return val flow = node.flow for (variable in possiblyChangedVariables) { - logicSystem.removeAllAboutVariableIncludingAliasInformation(flow, variable) + flow.removeAllAboutVariable(variable) } } @@ -946,6 +951,7 @@ abstract class FirDataFlowAnalyzer( if (isAssignment) { logicSystem.removeLocalVariableAlias(flow, propertyVariable) flow.removeAllAboutVariable(propertyVariable) + logicSystem.recordNewAssignment(flow, propertyVariable, context.newAssignmentIndex()) } variableStorage.getOrCreateRealVariable(flow, initializer.symbol, initializer)?.let { initializerVariable -> @@ -1256,7 +1262,9 @@ abstract class FirDataFlowAnalyzer( private fun FLOW.removeAllAboutVariable(variable: RealVariable?) { if (variable == null) return - logicSystem.removeAllAboutVariable(this, variable) + logicSystem.removeTypeStatementsAboutVariable(this, variable) + logicSystem.removeLogicStatementsAboutVariable(this, variable) + logicSystem.removeAliasInformationAboutVariable(this, variable) } private fun FLOW.fork(): FLOW { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/LogicSystem.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/LogicSystem.kt index 2516266317f..83d648e50b5 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/LogicSystem.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/LogicSystem.kt @@ -18,6 +18,7 @@ abstract class Flow { abstract val directAliasMap: Map abstract val backwardsAliasMap: Map> + abstract val assignmentIndex: Map } fun Flow.unwrapVariable(variable: RealVariable): RealVariable { @@ -36,8 +37,9 @@ abstract class LogicSystem(protected val context: ConeInferenceCont abstract fun addImplication(flow: FLOW, implication: Implication) - abstract fun removeAllAboutVariable(flow: FLOW, variable: RealVariable) - abstract fun removeAllAboutVariableIncludingAliasInformation(flow: FLOW, variable: RealVariable) + abstract fun removeTypeStatementsAboutVariable(flow: FLOW, variable: RealVariable) + abstract fun removeLogicStatementsAboutVariable(flow: FLOW, variable: DataFlowVariable) + abstract fun removeAliasInformationAboutVariable(flow: FLOW, variable: RealVariable) abstract fun translateVariableFromConditionInStatements( flow: FLOW, @@ -58,6 +60,8 @@ abstract class LogicSystem(protected val context: ConeInferenceCont abstract fun addLocalVariableAlias(flow: FLOW, alias: RealVariable, underlyingVariable: RealVariableAndType) abstract fun removeLocalVariableAlias(flow: FLOW, alias: RealVariable) + abstract fun recordNewAssignment(flow: FLOW, variable: RealVariable, index: Int) + protected abstract fun getImplicationsWithVariable(flow: FLOW, variable: DataFlowVariable): Collection protected abstract fun ConeKotlinType.isAcceptableForSmartcast(): Boolean diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/PersistentLogicSystem.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/PersistentLogicSystem.kt index 20ab32e00cb..991994c71ec 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/PersistentLogicSystem.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/PersistentLogicSystem.kt @@ -11,7 +11,6 @@ import org.jetbrains.kotlin.fir.types.ConeInferenceContext import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.utils.addIfNotNull import java.util.* -import kotlin.NoSuchElementException data class PersistentTypeStatement( override val variable: RealVariable, @@ -55,6 +54,8 @@ class PersistentFlow : Flow { override var directAliasMap: PersistentMap override var backwardsAliasMap: PersistentMap> + override var assignmentIndex: PersistentMap + constructor(previousFlow: PersistentFlow) { this.previousFlow = previousFlow approvedTypeStatements = previousFlow.approvedTypeStatements @@ -63,6 +64,7 @@ class PersistentFlow : Flow { directAliasMap = previousFlow.directAliasMap backwardsAliasMap = previousFlow.backwardsAliasMap + assignmentIndex = previousFlow.assignmentIndex } constructor() { @@ -73,6 +75,7 @@ class PersistentFlow : Flow { directAliasMap = persistentMapOf() backwardsAliasMap = persistentMapOf() + assignmentIndex = persistentMapOf() } override fun getTypeStatement(variable: RealVariable): TypeStatement? { @@ -133,7 +136,12 @@ abstract class PersistentLogicSystem(context: ConeInferenceContext) : LogicSyste val variables = flows.flatMap { it.approvedTypeStatements.keys }.toSet() for (variable in variables) { val info = mergeOperation(flows.map { it.getApprovedTypeStatements(variable, commonFlow) }) ?: continue - removeAllAboutVariable(commonFlow, variable) + removeTypeStatementsAboutVariable(commonFlow, variable) + val thereWereReassignments = variable.hasDifferentReassignments(flows) + if (thereWereReassignments) { + removeLogicStatementsAboutVariable(commonFlow, variable) + removeAliasInformationAboutVariable(commonFlow, variable) + } commonFlow.addApprovedStatements(info) } @@ -141,6 +149,15 @@ abstract class PersistentLogicSystem(context: ConeInferenceContext) : LogicSyste return commonFlow } + private fun RealVariable.hasDifferentReassignments(flows: Collection): Boolean { + val firstIndex = flows.first().assignmentIndex[this] ?: -1 + for (flow in flows) { + val index = flow.assignmentIndex[this] ?: -1 + if (index != firstIndex) return true + } + return false + } + private fun computeAliasesThatDontChange( flows: Collection ): MutableMap { @@ -247,15 +264,33 @@ abstract class PersistentLogicSystem(context: ConeInferenceContext) : LogicSyste } } - override fun removeAllAboutVariable(flow: PersistentFlow, variable: RealVariable) { - flow.logicStatements -= variable + override fun removeTypeStatementsAboutVariable(flow: PersistentFlow, variable: RealVariable) { flow.approvedTypeStatements -= variable flow.approvedTypeStatementsDiff -= variable - // TODO: should we search variable in all logic statements? } - override fun removeAllAboutVariableIncludingAliasInformation(flow: PersistentFlow, variable: RealVariable) { - removeAllAboutVariable(flow, variable) + override fun removeLogicStatementsAboutVariable(flow: PersistentFlow, variable: DataFlowVariable) { + flow.logicStatements -= variable + var newLogicStatements = flow.logicStatements + for ((key, implications) in flow.logicStatements) { + val implicationsToDelete = mutableListOf() + implications.forEach { implication -> + if (implication.effect.variable == variable) { + implicationsToDelete += implication + } + } + if (implicationsToDelete.isEmpty()) continue + val newImplications = implications.removeAll(implicationsToDelete) + newLogicStatements = if (newImplications.isNotEmpty()) { + newLogicStatements.put(key, newImplications) + } else { + newLogicStatements.remove(key) + } + } + flow.logicStatements = newLogicStatements + } + + override fun removeAliasInformationAboutVariable(flow: PersistentFlow, variable: RealVariable) { val existedAlias = flow.directAliasMap[variable]?.variable if (existedAlias != null) { flow.directAliasMap = flow.directAliasMap.remove(variable) @@ -408,6 +443,10 @@ abstract class PersistentLogicSystem(context: ConeInferenceContext) : LogicSyste return flow.logicStatements[variable] ?: emptyList() } + override fun recordNewAssignment(flow: PersistentFlow, variable: RealVariable, index: Int) { + flow.assignmentIndex = flow.assignmentIndex.put(variable, index) + } + // --------------------------------------------------------------------\ } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/model.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/model.kt index 46c99d2abc9..f7eaaef9ea2 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/model.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/model.kt @@ -128,6 +128,7 @@ private infix fun FirElement.isEqualsTo(other: FirElement): Boolean { sealed class Statement> { abstract fun invert(): T + abstract val variable: DataFlowVariable } /* @@ -137,7 +138,7 @@ sealed class Statement> { * d == True * d == False */ -data class OperationStatement(val variable: DataFlowVariable, val operation: Operation) : Statement() { +data class OperationStatement(override val variable: DataFlowVariable, val operation: Operation) : Statement() { override fun invert(): OperationStatement { return OperationStatement(variable, operation.invert()) } @@ -148,7 +149,7 @@ data class OperationStatement(val variable: DataFlowVariable, val operation: Ope } abstract class TypeStatement : Statement() { - abstract val variable: RealVariable + abstract override val variable: RealVariable abstract val exactType: Set abstract val exactNotType: Set @@ -209,6 +210,8 @@ fun Implication.invertCondition(): Implication = Implication(condition.invert(), typealias TypeStatements = Map typealias MutableTypeStatements = MutableMap +typealias MutableOperationStatements = MutableMap + fun MutableTypeStatements.addStatement(variable: RealVariable, statement: TypeStatement) { put(variable, statement.asMutableStatement()) { it.apply { this += statement } } } diff --git a/compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt b/compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt new file mode 100644 index 00000000000..aad188ed55e --- /dev/null +++ b/compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt @@ -0,0 +1,21 @@ +abstract class A { + abstract fun foo(): String +} + +class B : A() { + override fun foo() = "OK" +} + +class C : A() { + override fun foo() = "fail" +} + +fun test(c: C, cond: Boolean): String { + var x: A = c + if (cond) { + x = B() + } + return x.foo() +} + +fun box(): String = test(C(), true) diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/variables/kt7792.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/variables/kt7792.kt index a8b3e4940ff..8849e4c20a2 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/variables/kt7792.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/variables/kt7792.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // FILE: 1.kt package test diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index ed3ae9e79b2..261d14ecbf3 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -14946,6 +14946,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/fir/FakeOverrideBuilder.kt"); } + @Test + @TestMetadata("falsePositiveBoundSmartcast.kt") + public void testFalsePositiveBoundSmartcast() throws Exception { + runTest("compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt"); + } + @Test @TestMetadata("Fir2IrClassifierStorage.kt") public void testFir2IrClassifierStorage() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 77c6da7ab89..09e979a755f 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -14946,6 +14946,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/fir/FakeOverrideBuilder.kt"); } + @Test + @TestMetadata("falsePositiveBoundSmartcast.kt") + public void testFalsePositiveBoundSmartcast() throws Exception { + runTest("compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt"); + } + @Test @TestMetadata("Fir2IrClassifierStorage.kt") public void testFir2IrClassifierStorage() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 4f8d4ee9bff..bc3096b6fbf 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -12338,6 +12338,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/fir/FakeOverrideBuilder.kt"); } + @TestMetadata("falsePositiveBoundSmartcast.kt") + public void testFalsePositiveBoundSmartcast() throws Exception { + runTest("compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt"); + } + @TestMetadata("Fir2IrClassifierStorage.kt") public void testFir2IrClassifierStorage() throws Exception { runTest("compiler/testData/codegen/box/fir/Fir2IrClassifierStorage.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index 582c0430424..5aba055ee81 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -10945,6 +10945,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes public void testClassCanNotBeCastedToVoid() throws Exception { runTest("compiler/testData/codegen/box/fir/classCanNotBeCastedToVoid.kt"); } + + @TestMetadata("falsePositiveBoundSmartcast.kt") + public void testFalsePositiveBoundSmartcast() throws Exception { + runTest("compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt"); + } } @TestMetadata("compiler/testData/codegen/box/fullJdk") diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 1447565a8b0..1e484daddfb 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -10402,6 +10402,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { public void testClassCanNotBeCastedToVoid() throws Exception { runTest("compiler/testData/codegen/box/fir/classCanNotBeCastedToVoid.kt"); } + + @TestMetadata("falsePositiveBoundSmartcast.kt") + public void testFalsePositiveBoundSmartcast() throws Exception { + runTest("compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt"); + } } @TestMetadata("compiler/testData/codegen/box/fullJdk") diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 31f67c6f581..3663d8c57fd 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -10402,6 +10402,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { public void testClassCanNotBeCastedToVoid() throws Exception { runTest("compiler/testData/codegen/box/fir/classCanNotBeCastedToVoid.kt"); } + + @TestMetadata("falsePositiveBoundSmartcast.kt") + public void testFalsePositiveBoundSmartcast() throws Exception { + runTest("compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt"); + } } @TestMetadata("compiler/testData/codegen/box/fullJdk") diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index e7e2af7b7a7..9ab988dd23d 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -5233,6 +5233,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest public void testClassCanNotBeCastedToVoid() throws Exception { runTest("compiler/testData/codegen/box/fir/classCanNotBeCastedToVoid.kt"); } + + @TestMetadata("falsePositiveBoundSmartcast.kt") + public void testFalsePositiveBoundSmartcast() throws Exception { + runTest("compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt"); + } } @TestMetadata("compiler/testData/codegen/box/fullJdk")