Add error-level OptIn on safeAs, cast and assertedCast functions in addToStdlib

Usage of this function is unsafe because it does not have native compiler
  support. This means that compiler won't report UNCHECKED_CAST,
  CAST_NEVER_SUCCEED or similar diagnostics in case of error cast
  (which can happen immediately or after some refactoring of class hierarchy)
This commit is contained in:
Dmitriy Novozhilov
2022-10-03 13:59:11 +03:00
committed by teamcity
parent 1cd4f3ad2f
commit 9b63dde1c3
5 changed files with 74 additions and 0 deletions
+51
View File
@@ -373,6 +373,57 @@ val projectsWithEnabledContextReceivers by extra {
)
}
val projectsWithOptInToUnsafeCastFunctionsFromAddToStdLib by extra {
listOf(
":analysis:analysis-api-fe10",
":analysis:analysis-api-fir",
":analysis:decompiled:light-classes-for-decompiled",
":analysis:symbol-light-classes",
":compiler",
":compiler:backend",
":compiler:backend.js",
":compiler:backend.jvm",
":compiler:backend.jvm.codegen",
":compiler:backend.jvm.entrypoint",
":compiler:backend.jvm.lower",
":compiler:cli",
":compiler:frontend:cfg",
":compiler:frontend.common.jvm",
":compiler:frontend.java",
":compiler:frontend",
":compiler:ir.backend.common",
":compiler:ir.psi2ir",
":compiler:ir.serialization.jvm",
":compiler:ir.tree",
":compiler:light-classes",
":compiler:psi",
":compiler:resolution.common.jvm",
":compiler:resolution.common",
":compiler:resolution",
":core:descriptors.jvm",
":core:descriptors",
":core:deserialization",
":core:reflection.jvm",
":kotlin-reflect-api",
":jps:jps-common",
":jps:jps-common",
":js:js.tests",
":kotlin-build-common",
":kotlin-gradle-plugin",
":kotlin-native:backend.native",
":kotlin-reflect-api",
":kotlin-scripting-jvm-host-test",
":native:frontend.native",
":native:kotlin-klib-commonizer",
":native:native.tests",
":plugins:android-extensions-compiler",
":plugins:jvm-abi-gen",
":plugins:parcelize:parcelize-compiler:parcelize.k1",
":plugins:parcelize:parcelize-compiler:parcelize.backend",
":kotlinx-serialization-compiler-plugin.backend",
)
}
val gradlePluginProjects = listOf(
":kotlin-gradle-plugin",
":kotlin-gradle-plugin-api",
@@ -171,6 +171,7 @@ fun Project.configureKotlinCompilationOptions() {
)
val projectsWithEnabledContextReceivers: List<String> by rootProject.extra
val projectsWithOptInToUnsafeCastFunctionsFromAddToStdLib: List<String> by rootProject.extra
@Suppress("SuspiciousCollectionReassignment", "DEPRECATION")
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile>().configureEach {
@@ -196,6 +197,9 @@ fun Project.configureKotlinCompilationOptions() {
if (project.path in projectsWithEnabledContextReceivers) {
freeCompilerArgs += "-Xcontext-receivers"
}
if (project.path in projectsWithOptInToUnsafeCastFunctionsFromAddToStdLib) {
freeCompilerArgs += "-opt-in=org.jetbrains.kotlin.utils.addToStdlib.UnsafeCastFunction"
}
if (project.path == ":kotlin-util-klib") {
// This is a temporary workaround for a configuration problem in kotlin-native. Namely, module `:kotlin-native-shared`
@@ -91,9 +91,26 @@ fun <T> sequenceOfLazyValues(vararg elements: () -> T): Sequence<T> = elements.a
fun <T1, T2> Pair<T1, T2>.swap(): Pair<T2, T1> = Pair(second, first)
@RequiresOptIn(
message ="""
Usage of this function is unsafe because it does not have native compiler support
This means that compiler won't report UNCHECKED_CAST, CAST_NEVER_SUCCEED or similar
diagnostics in case of error cast (which can happen immediately or after some
refactoring of class hierarchy)
Consider using regular `as` and `as?`
""",
level = RequiresOptIn.Level.ERROR
)
annotation class UnsafeCastFunction
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
@UnsafeCastFunction
inline fun <reified T : Any> Any?.safeAs(): @kotlin.internal.NoInfer T? = this as? T
@UnsafeCastFunction
inline fun <reified T : Any> Any?.cast(): T = this as T
@UnsafeCastFunction
inline fun <reified T : Any> Any?.assertedCast(message: () -> String): T = this as? T ?: throw AssertionError(message())
fun <T : Any> constant(calculator: () -> T): T {
+1
View File
@@ -52,6 +52,7 @@ compileKotlin {
"-Xno-optimized-callable-references",
"-Xno-kotlin-nothing-value-exception",
"-opt-in=kotlin.RequiresOptIn",
"-opt-in=org.jetbrains.kotlin.utils.addToStdlib.UnsafeCastFunction",
"-Xno-new-java-annotation-targets",
]
moduleName = "kotlin-reflection"
@@ -86,6 +86,7 @@
<arg>-Xjvm-default=enable</arg>
<arg>-opt-in=org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI</arg>
<arg>-opt-in=org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi</arg>
<arg>-opt-in=org.jetbrains.kotlin.utils.addToStdlib.UnsafeCastFunction</arg>
<arg>-Xcontext-receivers</arg>
</args>
</configuration>