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 updated changelogs or compiler warnings, this document provides a complete reference for migration from Kotlin 1.9 to Kotlin 2.0.
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
Deprecate use of a synthetic setter on a projected receiver
Correct mangling when calling functions with inline class parameters that are overloaded in a Java subclass
Correct type approximation algorithm for contravariant captured types
Prohibit accessing property value before property initialization
Report error when there's ambiguity in imported classes with the same name
Generate Kotlin lambdas via invokedynamic and LambdaMetafactory by default
Forbid if condition with one branch when an expression is required
Prohibit violation of self upper bounds by passing a star-projection of a generic type
Approximate anonymous types in private inline functions return type
Change overload resolution behavior to prioritize local extension function calls over invoke conventions of local functional type properties
Report error when an inherited member conflict occurs due to a change in a supertype from binary dependency
Ignore @UnsafeVariance annotations on parameters in invariant types
Change type for out-of-call references to a companion object's member
Prohibit exposure of anonymous types from private inline functions
Report error for an unsound smart cast after a while-loop break
Report error when a variable of an intersection type is assigned a value that is not a subtype of that intersection type
Require opt-in when an interface constructed with a SAM constructor contains a method that requires an opt-in
Prohibit upper bound violation in typealias constructors
Make the real type of a destructuring variable consistent with the explicit type when specified
Require opt-in when calling a constructor that has parameter types with default values that require an opt-in
Report ambiguity between a property and an enum entry with the same name at the same scope level
Change qualifier resolution behavior to prefer companion property over enum entry
Resolve invoke call receiver type and the invoke function type as if written in desugared form
Prohibit exposing private class members through non-private inline functions
Correct nullability of definitely non-null types in projected generic types
Change inferred type of prefix increment to match getter's return type instead of inc() operator's return type
Enforce bound checks when inheriting inner classes from generic inner classes declared in superclasses
Forbid assigning callable references with SAM types when the expected type is a function type with a function type parameter
Consider companion object scope for annotation resolution on companion objects
Change evaluation semantics for combination of safe calls and convention operators
Require properties with backing field and a custom setter to be immediately initialized
Prohibit Unit conversion on arbitrary expressions in invoke operator convention call
Forbid nullable assignment to non-null Java field when the field is accessed with a safe call
Require star-projected type when overriding a Java method containing a raw-type parameter
Change (V)::foo reference resolution when V has a companion
Forbid implicit non-public API access in effectively public inline functions
Prohibit use-site get annotations on property getters
Prevent implicit inference of type parameters into upper bounds in builder inference lambda functions
Keep nullability when approximating local types in public signatures
Remove special handling for false && ... and false || ... for the purposes of smart-casting
Forbid inline open functions in enums
Tools
Visibility changes in Gradle
Deprecate kotlinOptions DSL
Deprecate compilerOptions in KotlinCompilation DSL