[K/N][FIR] Do not emit CAST_NEVER_SUCCEEDS when casting to forward declarations

^KT-61841 Fixed
This commit is contained in:
Vladimir Sukharev
2024-01-04 23:21:24 +01:00
committed by Space Team
parent 050d74a22e
commit 35b83a1225
7 changed files with 60 additions and 8 deletions
@@ -0,0 +1,25 @@
/*
* Copyright 2010-2024 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.native.checkers
import org.jetbrains.kotlin.fir.FirPlatformSpecificCastChecker
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
object FirNativeCastChecker : FirPlatformSpecificCastChecker() {
override fun shouldSuppressImpossibleCast(session: FirSession, fromType: ConeKotlinType, toType: ConeKotlinType): Boolean {
return isCastToAForwardDeclaration(session, toType)
}
/**
* Here, we only check that we are casting to a forward declaration to suppress a CAST_NEVER_SUCCEEDS warning.
* The cast would be further checked with FirNativeForwardDeclarationTypeOperatorChecker and FirNativeForwardDeclarationGetClassCallChecker.
*/
private fun isCastToAForwardDeclaration(session: FirSession, forwardDeclarationType: ConeKotlinType): Boolean {
return forwardDeclarationType.toRegularClassSymbol(session)?.forwardDeclarationKindOrNull() != null
}
}
@@ -16,10 +16,9 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.expressions.FirOperation
import org.jetbrains.kotlin.fir.expressions.FirTypeOperatorCall
import org.jetbrains.kotlin.fir.expressions.unwrapSmartcastExpression
import org.jetbrains.kotlin.fir.firPlatformSpecificCastChecker
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.types.ConeDynamicType
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.fir.types.*
object FirCastOperatorsChecker : FirTypeOperatorCallChecker() {
override fun check(expression: FirTypeOperatorCall, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -38,7 +37,9 @@ object FirCastOperatorsChecker : FirTypeOperatorCallChecker() {
val castType = checkCasting(actualType, targetType, isSafeAs, context)
if (castType == CastingType.Impossible) {
if (context.languageVersionSettings.supportsFeature(LanguageFeature.EnableDfaWarningsInK2)) {
reporter.reportOn(expression.source, FirErrors.CAST_NEVER_SUCCEEDS, context)
if (!session.firPlatformSpecificCastChecker.shouldSuppressImpossibleCast(session, actualType, targetType)) {
reporter.reportOn(expression.source, FirErrors.CAST_NEVER_SUCCEEDS, context)
}
}
} else if (castType == CastingType.Always) {
if (context.languageVersionSettings.supportsFeature(LanguageFeature.EnableDfaWarningsInK2)) {
@@ -95,6 +95,7 @@ fun FirSession.registerCommonComponents(languageVersionSettings: LanguageVersion
register(FirPrimaryConstructorSuperTypeCheckerPlatformComponent::class, FirPrimaryConstructorSuperTypeCheckerPlatformComponent.Default)
register(FirGenericArrayClassLiteralSupport::class, FirGenericArrayClassLiteralSupport.Disabled)
register(FirMissingDependencyStorage::class, FirMissingDependencyStorage(this))
register(FirPlatformSpecificCastChecker::class, FirPlatformSpecificCastChecker.Default)
}
@OptIn(SessionConfiguration::class)
@@ -6,10 +6,8 @@
package org.jetbrains.kotlin.fir.session
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.fir.BinaryModuleData
import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.SessionConfiguration
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.analysis.native.checkers.FirNativeCastChecker
import org.jetbrains.kotlin.fir.backend.native.FirNativeClassMapper
import org.jetbrains.kotlin.fir.checkers.registerNativeCheckers
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
@@ -44,6 +42,7 @@ object FirNativeSessionFactory : FirAbstractSessionFactory() {
registerExtraComponents = { session ->
session.registerDefaultComponents()
session.register(FirPlatformClassMapper::class, FirNativeClassMapper())
session.register(FirPlatformSpecificCastChecker::class, FirNativeCastChecker)
registerExtraComponents(session)
},
createKotlinScopeProvider = { FirKotlinScopeProvider() },
@@ -90,6 +89,7 @@ object FirNativeSessionFactory : FirAbstractSessionFactory() {
registerExtraComponents = {
it.registerDefaultComponents()
it.register(FirPlatformClassMapper::class, FirNativeClassMapper())
it.register(FirPlatformSpecificCastChecker::class, FirNativeCastChecker)
registerExtraComponents(it)
},
registerExtraCheckers = { it.registerNativeCheckers() },
@@ -140,5 +140,6 @@ object FirSessionFactoryHelper {
register(FirPlatformClassMapper::class, FirPlatformClassMapper.Default)
register(FirOverridesBackwardCompatibilityHelper::class, FirDefaultOverridesBackwardCompatibilityHelper)
register(FirDelegatedMembersFilter::class, FirDelegatedMembersFilter.Default)
register(FirPlatformSpecificCastChecker::class, FirPlatformSpecificCastChecker.Default)
}
}
@@ -0,0 +1,20 @@
/*
* Copyright 2010-2024 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
import org.jetbrains.kotlin.fir.types.ConeKotlinType
abstract class FirPlatformSpecificCastChecker : FirSessionComponent {
abstract fun shouldSuppressImpossibleCast(session: FirSession, fromType: ConeKotlinType, toType: ConeKotlinType): Boolean
object Default : FirPlatformSpecificCastChecker() {
override fun shouldSuppressImpossibleCast(session: FirSession, fromType: ConeKotlinType, toType: ConeKotlinType): Boolean {
return false
}
}
}
val FirSession.firPlatformSpecificCastChecker: FirPlatformSpecificCastChecker by FirSession.sessionComponentAccessor()
@@ -115,6 +115,10 @@ abstract class AbstractFirNativeDiagnosticsTestBase(val parser: FirParser) : Abs
forTestsMatching("compiler/testData/diagnostics/*") {
configurationForClassicAndFirTestsAlongside()
}
defaultDirectives {
LanguageSettingsDirectives.LANGUAGE + "+EnableDfaWarningsInK2"
}
}
}
}