Kotlin 1.7 的兼容性指南
Keeping the Language Modern and Comfortable Updates are among the fundamental principles in Kotlin Language Design. The former says that constructs which obstruct language evolution should be removed, and the latter says that this removal should be well-communicated beforehand to make code migration as smooth as possible.
While most of the language changes were already announced through other channels, like update changelogs or compiler warnings, this document summarizes them all, providing a complete reference for migration from Kotlin 1.6 to Kotlin 1.7.
Basic terms
In this document we introduce several kinds of compatibility:
- source: source-incompatible change stops code that used to compile fine (without errors or warnings) from compiling anymore
- binary: two binary artifacts are said to be binary-compatible if interchanging them doesn't lead to loading or linkage errors
- behavioral: a change is said to be behavioral-incompatible if the same program demonstrates different behavior before and after applying the change
Remember that those definitions are given only for pure Kotlin. Compatibility of Kotlin code from the other languages perspective (for example, from Java) is out of the scope of this document.
Language
Make safe call result always nullable
Issue: KT-46860
Component: Core language
Incompatible change type: source
Short summary: Kotlin 1.7 will consider the type of safe call result always nullable, even when the receiver of the safe call is non-nullable
Deprecation cycle:
- \<1.3: report a warning on an unnecessary safe call on non-nullable receivers
- 1.6.20: warn additionally that the result of an unnecessary safe call will change its type in the next version
- 1.7.0: change the type of safe call result to nullable,
-XXLanguage:-SafeCallsAreAlwaysNullable
can be used to temporarily revert to the pre-1.7 behavior
Prohibit the delegation of super calls to an abstract superclass member
Issues: KT-45508, KT-49017, KT-38078
Component: Core language
Incompatible change type: source
Short summary: Kotlin will report a compile error when an explicit or implicit super call is delegated to an abstract member of the superclass, even if there's a default implementation in a super interface
Deprecation cycle:
- 1.5.20: introduce a warning when non-abstract classes that do not override all abstract members are used
- 1.7.0: report an error if a super call, in fact, accesses an abstract member from a superclass
- 1.7.0: report an error if the
-Xjvm-default=all
or-Xjvm-default=all-compatibility
compatibility modes are enabled; report an error in the progressive mode- >=1.8.0: report an error in all cases
Prohibit exposing non-public types through public properties declared in a non-public primary constructor
Issue: KT-28078
Component: Core language
Incompatible change type: source
Short summary: Kotlin will prevent declaring public properties having non-public types in a private primary constructor. Accessing such properties from another package could lead to an
IllegalAccessError
Deprecation cycle:
- 1.3.20: report a warning on a public property that has a non-public type and is declared in a non-public constructor
- 1.6.20: raise this warning to an error in the progressive mode
- 1.7.0: raise this warning to an error
Prohibit access to uninitialized enum entries qualified with the enum name
Issue: KT-41124
Component: Core language
Incompatible change type: source
Short summary: Kotlin 1.7 will prohibit access to uninitialized enum entries from the enum static initializer block when these entries are qualified with the enum name
Deprecation cycle:
- 1.7.0: report an error when uninitialized enum entries are accessed from the enum static initializer block
Prohibit computing constant values of complex boolean expressions in when
condition branches and conditions of loops
Issue: KT-39883
Component: Core language
Incompatible change type: source
Short summary: Kotlin will no longer make exhaustiveness and control flow assumptions based on constant boolean expressions other than literal
true
andfalse
Deprecation cycle:
- 1.5.30: report a warning when exhaustiveness of
when
or control flow reachability is determined based on a complex constant boolean expression inwhen
branch or loop condition- 1.7.0: raise this warning to an error
Make when
statements with enum, sealed, and Boolean subjects exhaustive by default
Issue: KT-47709
Component: Core language
Incompatible change type: source
Short summary: Kotlin 1.7 will report an error about the
when
statement with an enum, sealed, or Boolean subject being non-exhaustiveDeprecation cycle:
- 1.6.0: introduce a warning when the
when
statement with an enum, sealed, or Boolean subject is non-exhaustive (error in the progressive mode)- 1.7.0: raise this warning to an error
Deprecate confusing grammar in when-with-subject
Issue: KT-48385
Component: Core language
Incompatible change type: source
Short summary: Kotlin 1.6 deprecated several confusing grammar constructs in
when
condition expressionsDeprecation cycle:
- 1.6.20: introduce a deprecation warning on the affected expressions
- 1.8.0: raise this warning to an error
- >= 1.8: repurpose some deprecated constructs for new language features
Type nullability enhancement improvements
Issue: KT-48623
Component: Kotlin/JVM
Incompatible change type: source
Short summary: Kotlin 1.7 will change how it loads and interprets type nullability annotations in Java code
Deprecation cycle:
- 1.4.30: introduce warnings for cases where more precise type nullability could lead to an error
- 1.7.0: infer more precise nullability of Java types,
-XXLanguage:-TypeEnhancementImprovementsInStrictMode
can be used to temporarily revert to the pre-1.7 behavior
Prevent implicit coercions between different numeric types
Issue: KT-48645
Component: Kotlin/JVM
Incompatible change type: behavioral
Short summary: Kotlin will avoid converting numeric values automatically to a primitive numeric type where only a downcast to that type was needed semantically
Deprecation cycle:
- < 1.5.30: the old behavior in all affected cases
- 1.5.30: fix the downcast behavior in generated property delegate accessors,
-Xuse-old-backend
can be used to temporarily revert to the pre-1.5.30 fix behavior- >= 1.7.20: fix the downcast behavior in other affected cases
Deprecate the enable
and the compatibility
modes of the compiler option -Xjvm-default
Issue: KT-46329
Component: Kotlin/JVM
Incompatible change type: source
Short summary: Kotlin 1.6.20 warns about the usage of
enable
andcompatibility
modes of the-Xjvm-default
compiler optionDeprecation cycle:
- 1.6.20: introduce a warning on the
enable
andcompatibility
modes of the-Xjvm-default
compiler option- >= 1.8.0: raise this warning to an error
Prohibit calls to functions named suspend
with a trailing lambda
Issue: KT-22562
Component: Core language
Incompatible change type: source
Short summary: Kotlin 1.6 no longer allows calling user functions named
suspend
that have the single argument of a functional type passed as a trailing lambdaDeprecation cycle:
- 1.3.0: introduce a warning on such function calls
- 1.6.0: raise this warning to an error
- 1.7.0: introduce changes to the language grammar so that
suspend
before{
is parsed as a keyword
Prohibit smart cast on a base class property if the base class is from another module
Issue: KT-52629
Component: Core language
Incompatible change type: source
Short summary: Kotlin 1.7 will no longer allow smart casts on properties of a superclass if that class is located in another module
Deprecation cycle:
- 1.6.0: report a warning on a smart cast on a property declared in the superclass located in another module
- 1.7.0: raise this warning to an error,
-XXLanguage:-ProhibitSmartcastsOnPropertyFromAlienBaseClass
can be used to temporarily revert to the pre-1.7 behavior
Do not neglect meaningful constraints during type inference
Issue: KT-52668
Component: Core language
Incompatible change type: source
Short summary: Kotlin 1.4−1.6 neglected some type constraints during type inference due to an incorrect optimization. It could allow writing unsound code, causing
ClassCastException
at runtime. Kotlin 1.7 takes these constraints into account, thus prohibiting the unsound codeDeprecation cycle:
- 1.5.20: report a warning on expressions where a type mismatch would happen if all the type inference constraints were taken into account
- 1.7.0: take all the constraints into account, thus raising this warning to an error,
-XXLanguage:-ProperTypeInferenceConstraintsProcessing
can be used to temporarily revert to the pre-1.7 behavior
Standard library
Gradually change the return type of collection min
and max
functions to non-nullable
Issue: KT-38854
Component: kotlin-stdlib
Incompatible change type: source
Short summary: the return type of collection
min
andmax
functions will be changed to non-nullable in Kotlin 1.7Deprecation cycle:
- 1.4.0: introduce
...OrNull
functions as synonyms and deprecate the affected API (see details in the issue)- 1.5.0: raise the deprecation level of the affected API to an error
- 1.6.0: hide the deprecated functions from the public API
- 1.7.0: reintroduce the affected API but with non-nullable return type
Deprecate floating-point array functions: contains
, indexOf
, lastIndexOf
Issue: KT-28753
Component: kotlin-stdlib
Incompatible change type: source
Short summary: Kotlin deprecates floating-point array functions
contains
,indexOf
,lastIndexOf
that compare values using the IEEE-754 order instead of the total orderDeprecation cycle:
- 1.4.0: deprecate the affected functions with a warning
- 1.6.0: raise the deprecation level to an error
- 1.7.0: hide the deprecated functions from the public API
Migrate declarations from kotlin.dom
and kotlin.browser
packages to kotlinx.*
Issue: KT-39330
Component: kotlin-stdlib (JS)
Incompatible change type: source
Short summary: declarations from the
kotlin.dom
andkotlin.browser
packages are moved to the correspondingkotlinx.*
packages to prepare for extracting them from stdlibDeprecation cycle:
- 1.4.0: introduce the replacement API in
kotlinx.dom
andkotlinx.browser
packages- 1.4.0: deprecate the API in
kotlin.dom
andkotlin.browser
packages and propose the new API above as a replacement- 1.6.0: raise the deprecation level to an error
- >= 1.8: remove the deprecated functions from stdlib
- >= 1.8: move the API in kotlinx.* packages to a separate library
Deprecate some JS-only API
Issue: KT-48587
Component: kotlin-stdlib (JS)
Incompatible change type: source
Short summary: a number of JS-only functions in stdlib are deprecated for removal. They include:
String.concat(String)
,String.match(regex: String)
,String.matches(regex: String)
, and thesort
functions on arrays taking a comparison function, for example,Array<out T>.sort(comparison: (a: T, b: T) -> Int)
Deprecation cycle:
- 1.6.0: deprecate the affected functions with a warning
- 1.8.0: raise the deprecation level to an error
- 1.9.0: remove the deprecated functions from the public API
Tools
Remove KotlinGradleSubplugin class
Issue: KT-48831
Component: Gradle
Incompatible change type: source
Short summary: remove the
KotlinGradleSubplugin
class. Use theKotlinCompilerPluginSupportPlugin
class insteadDeprecation cycle:
- 1.6.0: raise the deprecation level to an error
- 1.7.0: remove the deprecated class
Remove useIR compiler option
Issue: KT-48847
Component: Gradle
Incompatible change type: source
Short summary: remove the deprecated and hidden
useIR
compiler optionDeprecation cycle:
- 1.5.0: raise the deprecation level to a warning
- 1.6.0: hide the option
- 1.7.0: remove the deprecated option
Deprecate kapt.use.worker.api Gradle property
Issue: KT-48826
Component: Gradle
Incompatible change type: source
Short summary: deprecate the
kapt.use.worker.api
property that allowed to run kapt via Gradle Workers API (default: true)Deprecation cycle:
- 1.6.20: raise the deprecation level to a warning
- >= 1.8.0: remove this property
Remove kotlin.experimental.coroutines Gradle DSL option and kotlin.coroutines Gradle property
Issue: KT-50494
Component: Gradle
Incompatible change type: source
Short summary: remove the
kotlin.experimental.coroutines
Gradle DSL option and thekotlin.coroutines
propertyDeprecation cycle:
- 1.6.20: raise the deprecation level to a warning
- 1.7.0: remove the DSL option, its enclosing
experimental
block, and the property
Deprecate useExperimentalAnnotation compiler option
Issue: KT-47763
Component: Gradle
Incompatible change type: source
Short summary: remove the hidden
useExperimentalAnnotation()
Gradle function used to opt in to using an API in a module.optIn()
function can be used insteadDeprecation cycle:
- 1.6.0: hide the deprecation option
- 1.7.0: remove the deprecated option
Deprecate kotlin.compiler.execution.strategy system property
Issue: KT-51830
Component: Gradle
Incompatible change type: source
Short summary: deprecate the
kotlin.compiler.execution.strategy
system property used to choose a compiler execution strategy. Use the Gradle propertykotlin.compiler.execution.strategy
or the compile task propertycompilerExecutionStrategy
insteadDeprecation cycle:
- 1.7.0: raise the deprecation level to a warning
- > 1.7.0: remove the property
Remove kotlinOptions.jdkHome compiler option
Issue: KT-46541
Component: Gradle
Incompatible change type: source
Short summary: remove the
kotlinOptions.jdkHome
compiler option used to include a custom JDK from the specified location into the classpath instead of the defaultJAVA_HOME
. Use Java toolchains insteadDeprecation cycle:
- 1.5.30: raise the deprecation level to a warning
- > 1.7.0: remove the option
Remove noStdlib compiler option
Issue: KT-49011
Component: Gradle
Incompatible change type: source
Short summary: remove the
noStdlib
compiler option. The Gradle plugin uses thekotlin.stdlib.default.dependency=true
property to control whether the Kotlin standard library is presentDeprecation cycle:
- 1.5.0: raise the deprecation level to a warning
- 1.7.0: remove the option
Remove kotlin2js and kotlin-dce-plugin plugins
Issue: KT-48276
Component: Gradle
Incompatible change type: source
Short summary: remove the
kotlin2js
andkotlin-dce-plugin
plugins. Instead ofkotlin2js
, use the neworg.jetbrains.kotlin.js
plugin. Dead code elimination (DCE) works when the Kotlin/JS Gradle plugin is properly configured
>
Deprecation cycle:
- 1.4.0: raise the deprecation level to a warning
- 1.7.0: remove the plugins
Changes in compile tasks
Issue: KT-32805
Component: Gradle
Incompatible change type: source
Short summary: Kotlin compile tasks no longer inherit the Gradle
AbstractCompile
task and that's why thesourceCompatibility
andtargetCompatibility
inputs are no longer available in Kotlin users' scripts. TheSourceTask.stableSources
input is no longer available. ThesourceFilesExtensions
input was removed. The deprecatedGradle destinationDir: File
output was replaced with thedestinationDirectory: DirectoryProperty
output. Theclasspath
property of theKotlinCompile
task is deprecatedDeprecation cycle:
- 1.7.0: inputs are not available, the output is replaced, the
classpath
property is deprecated