Compatibility guide for Kotlin 2.1
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 2.0 to Kotlin 2.1.
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.
tip
Issue: KT-60521
Component: Core language
Incompatible change type: source
Short summary: Kotlin 2.1 introduces language version 2.1 and removes support for language versions 1.4 and 1.5. Language versions 1.6 and 1.7 are deprecated.
Deprecation cycle:
1.6.0: report a warning for language version 1.4
1.9.0: report a warning for language version 1.5
2.1.0: report a warning for language versions 1.6 and 1.7; raise the warning to an error for language versions 1.4 and 1.5
tip
Issue: KT-70754
Component: Core language
Incompatible change type: behavioral
Short summary: The behavior of the
typeOf()
function on Kotlin/Native is aligned with Kotlin/JVM to ensure consistency across platforms.Deprecation cycle:
2.1.0: align the
typeOf()
function behavior on Kotlin/Native
tip
Issue: KT-69653
Component: Core language
Incompatible change type: source
Short summary: Exposing types with lower visibility through type parameter bounds is now prohibited, addressing inconsistencies in type visibility rules. This change ensures that bounds on type parameters follow the same visibility rules as classes, preventing issues like IR validation errors in the JVM.
Deprecation cycle:
2.1.0: report a warning for exposing types via type parameter bounds with lower visibility
2.2.0: raise the warning to an error
tip
Issue: KT-58659
Component: Core language
Incompatible change type: source
Short summary: If a class inherits an abstract
var
property from an interface and aval
property with the same name from a superclass, it now triggers a compilation error. This resolves runtime crashes caused by missing setters in such cases.Deprecation cycle:
2.1.0: report a warning (or an error in progressive mode) when a class inherits an abstract
var
property from an interface and aval
property with the same name from a superclass2.2.0: raise the warning to an error
tip
Issue: KT-68451
Component: Core language
Incompatible change type: source
Short summary: The compiler now reports an error when uninitialized enum entries are accessed during enum class or entry initialization. This aligns the behavior with member property initialization rules, preventing runtime exceptions and ensuring consistent logic.
Deprecation cycle:
2.1.0: report an error when accessing uninitialized enum entries
tip
Issue: KTLC-34
Component: Core language
Incompatible change type: behavioral
Short summary: The K2 compiler changes its behavior for smart cast propagation by introducing bidirectional propagation of type information for inferred variables, like
val x = y
. Explicitly typed variables, such asval x: T = y
, no longer propagate type information, ensuring stricter adherence to declared types.Deprecation cycle:
2.1.0: enable the new behavior
tip
Issue: KTLC-35
Component: Core language
Incompatible change type: behavioral
Short summary: The getter for member-extension properties overridden by Java subclasses is now hidden in the subclass's scope, aligning its behavior with that of regular Kotlin properties.
Deprecation cycle:
2.1.0: enable the new behavior
tip
Issue: KTLC-36
Component: Core language
Incompatible change type: binary
Short summary: The visibility of getters and setters for
var
properties overriding aprotected val
property is now consistent, with both inheriting the visibility of the overriddenval
property.Deprecation cycle:
2.1.0: enforce consistent visibility for both getters and setters in K2; K1 remains unaffected
tip
Issue: KTLC-11
Component: Core language
Incompatible change type: source
Short summary: Nullability mismatches from
org.jspecify.annotations
, such as@NonNull
,@Nullable
, and@NullMarked
are now treated as errors instead of warnings, enforcing stricter type safety for Java interoperability. To adjust the severity of these diagnostics, use the-Xnullability-annotations
compiler option.Deprecation cycle:
1.6.0: report warnings for potential nullability mismatches
1.8.20: expand warnings to specific JSpecify annotations, including:
@Nullable
,@NullnessUnspecified
,@NullMarked
, and legacy annotations inorg.jspecify.nullness
(JSpecify 0.2 and earlier)2.0.0: add support for the
@NonNull
annotation2.1.0: change default mode to
strict
for JSpecify annotations, converting warnings into errors; use-Xnullability-annotations=@org.jspecify.annotations:warning
or-Xnullability-annotations=@org.jspecify.annotations:ignore
to override the default behavior
tip
Issue: KTLC-37
Component: Core language
Incompatible change type: behavioral
Short summary: Overload resolution now consistently prioritizes extension functions over invoke calls in ambiguous cases. This resolves inconsistencies in the resolution logic for local functions and properties. The change applies only after recompilation, without affecting precompiled binaries.
Deprecation cycle:
2.1.0: change overload resolution to consistently prioritize extension functions over
invoke
calls for extension functions with matching signatures; this change applies only after recompilation and does not affect precompiled binaries
tip
Issue: KTLC-42
Component: Core language
Incompatible change type: source
Short summary: Returning nullable values from lambdas in SAM constructors of JDK function interfaces now triggers a compilation error if the specified type argument is non-nullable. This resolves issues where nullability mismatches could lead to runtime exceptions, ensuring stricter type safety.
Deprecation cycle:
2.0.0: report a deprecation warning for nullable return values in SAM constructors of JDK function interfaces
2.1.0: enable the new behavior by default
tip
Issue: KTLC-43
Component: Core language
Incompatible change type: behavioral
Short summary: In Kotlin/Native, private members no longer override or conflict with public members in a superclass, aligning behavior with Kotlin/JVM. This resolves inconsistencies in override resolution and eliminates unexpected behavior caused by separate compilation.
Deprecation cycle:
2.1.0: private functions and properties in Kotlin/Native no longer override or affect public members in a superclass, aligning with JVM behavior
tip
Issue: KTLC-71
Component: Core language
Incompatible change type: source
Short summary: Private operator functions such as
getValue()
,setValue()
,provideDelegate()
,hasNext()
, andnext()
can no longer be accessed in public inline functions.Deprecation cycle:
2.0.0: report a deprecation warning for accessing private operator functions in public inline functions
2.1.0: raise the warning to an error
tip
Issue: KTLC-72
Component: Core language
Incompatible change type: source
Short summary: The compiler now ignores
@UnsafeVariance
annotations during type checks, enforcing stricter type safety for invariant type parameters. This prevents invalid calls that rely on@UnsafeVariance
to bypass expected type checks.Deprecation cycle:
2.1.0: activate the new behavior
tip
Issue: KTLC-100
Component: Core language
Incompatible change type: source
Short summary: The compiler now detects nullability mismatches in Java methods where a warning-level nullable type contains type arguments with stricter, error-level nullability. This ensures that previously ignored errors in type arguments are reported correctly.
Deprecation cycle:
2.0.0: report a deprecation warning for nullability mismatches in Java methods with stricter type arguments
2.1.0: raise the warning to an error
tip
Issue: KTLC-3
Component: Core language
Incompatible change type: source
Short summary: The compiler now reports usages of inaccessible types in function literals and type arguments, preventing compilation and runtime failures caused by incomplete type information.
Deprecation cycle:
2.0.0: report warnings for function literals with parameters or receivers of inaccessible non-generic types and for types with inaccessible type argument; report errors for function literals with parameters or receivers of inaccessible generic types and for types with inaccessible generic type arguments in specific scenarios
2.1.0: raise warnings to errors for function literals with parameters and receivers of inaccessible non-generic types
2.2.0: raise warnings to errors for types with inaccessible type arguments
tip
Issue: KT-43023
Component: kotlin-stdlib
Incompatible change type: source
Short summary: Among other Kotlin standard library APIs, locale-sensitive case conversion functions for
Char
andString
, such asChar.toUpperCase()
andString.toLowerCase()
, are deprecated. Replace them with locale-agnostic alternatives likeString.lowercase()
or explicitly specify the locale for locale-sensitive behavior, such asString.lowercase(Locale.getDefault())
.For a comprehensive list of deprecated Kotlin standard library APIs in Kotlin 2.1.0, see KT-71628.
Deprecation cycle:
1.4.30: introduce locale-agnostic alternatives as experimental API
1.5.0: deprecate locale-sensitive case conversion functions with a warning
2.1.0: raise the warning to an error
tip
Issue: KT-62159
Component: kotlin-stdlib
Incompatible change type: binary
Short summary: The
kotlin-stdlib-common.jar
artifact, previously used for legacy multiplatform declarations metadata, is deprecated and replaced by.klib
files as the standard format for common multiplatform declarations metadata. This change does not affect the mainkotlin-stdlib.jar
orkotlin-stdlib-all.jar
artifacts.Deprecation cycle:
2.1.0: deprecate and remove
kotlin-stdlib-common.jar
artifact
tip
Issue: KTLC-27
Component: kotlin-stdlib
Incompatible change type: source
Short summary:
StringBuilder.appendln()
is deprecated in favor ofStringBuilder.appendLine()
.Deprecation cycle:
1.4.0: the
appendln()
function is deprecated; report a warning on use2.1.0: raise the warning to an error
tip
Issue: KT-69545
Component: kotlin-stdlib
Incompatible change type: source
Short summary: Freezing-related APIs in Kotlin/Native, previously marked with the
@FreezingIsDeprecated
annotation, are now deprecated. This aligns with the introduction of the new memory manager that removes the need for freezing objects for thread sharing. For migration details, see the Kotlin/Native migration guide.Deprecation cycle:
1.7.20: deprecate freezing-related APIs with a warning
2.1.0: raise the warning to an error
tip
Issue: KTLC-23
Component: kotlin-stdlib
Incompatible change type: behavioral
Short summary: Accessing a
Map.Entry
key-value pair after its associated map has been structurally modified now throws aConcurrentModificationException
.Deprecation cycle:
2.1.0: throw an exception when a map structural modification is detected
tip
Issue: KT-69255
Component: Gradle
Incompatible change type: source
Short summary: The
KotlinCompilationOutput#resourcesDirProvider
field is deprecated. UseKotlinSourceSet.resources
in your Gradle build script instead to add additional resource directories.Deprecation cycle:
2.1.0:
KotlinCompilationOutput#resourcesDirProvider
is deprecated
tip
Issue: KT-69927
Component: Gradle
Incompatible change type: source
Short summary: The
registerKotlinJvmCompileTask(taskName, moduleName)
function is deprecated in favor of the newregisterKotlinJvmCompileTask(taskName, compilerOptions, explicitApiMode)
function, which now acceptsKotlinJvmCompilerOptions
. This allows you to pass acompilerOptions
instance, typically from an extension or target, with values used as conventions for the task's options.Deprecation cycle:
2.1.0: the
registerKotlinJvmCompileTask(taskName, moduleName)
function is deprecated
tip
Issue: KT-70383
Component: Gradle
Incompatible change type: source
Short summary: The
registerKaptGenerateStubsTask(taskName)
function is deprecated. Use the newregisterKaptGenerateStubsTask(compileTask, kaptExtension, explicitApiMode)
function instead. This new version allows you to link values as conventions from the relevantKotlinJvmCompile
task, ensuring both tasks are using the same set of options.Deprecation cycle:
2.1.0: the
registerKaptGenerateStubsTask(taskName)
function is deprecated
tip
Issue: KT-71602
Component: Gradle
Incompatible change type: behavioral
Short summary:
KotlinTopLevelExtension
andKotlinTopLevelExtensionConfig
interfaces are deprecated in favor of a newKotlinTopLevelExtension
interface. This interface mergesKotlinTopLevelExtensionConfig
,KotlinTopLevelExtension
, andKotlinProjectExtension
to streamline API hierarchy, and provide official access to the JVM toolchain and compiler properties.Deprecation cycle:
2.1.0: the
KotlinTopLevelExtension
andKotlinTopLevelExtensionConfig
interfaces are deprecated
tip
Issue: KT-61706
Component: Gradle
Incompatible change type: source
Short summary: The
kotlin-compiler-embeddable
dependency is removed from the runtime in Kotlin Gradle Plugin (KGP). Required modules are now included directly in KGP artifacts, with the Kotlin language version limited to 2.0 to support compatibility with Gradle Kotlin runtime in versions below 8.2.Deprecation cycle:
2.1.0: report a warning on using
kotlin-compiler-embeddable
2.2.0: raise the warning to an error
tip
Issue: KT-70251
Component: Gradle
Incompatible change type: source
Short summary: Compiler module symbols bundled within the Kotlin Gradle Plugin (KGP), such as
KotlinCompilerVersion
, are hidden from the public API to prevent unintended access in build scripts.Deprecation cycle:
2.1.0: report a warning on accessing these symbols
2.2.0: raise the warning to an error
tip
Issue: KT-68345
Component: Gradle
Incompatible change type: source
Short summary: The
stabilityConfigurationFile
property in the Compose extension is deprecated in favor of a newstabilityConfigurationFiles
property, which allows specifying multiple configuration files.Deprecation cycle:
2.1.0:
stabilityConfigurationFile
property is deprecated
tip
Issue: KT-65565
Component: Gradle
Incompatible change type: source
Short summary: Support for these platform plugin IDs have been removed:
kotlin-platform-common
org.jetbrains.kotlin.platform.common
Deprecation cycle:
1.3: the platform plugin IDs are deprecated
2.1.0: the platform plugin IDs are no longer supported
Thanks for your feedback!