Compatibility Guide for Kotlin 1.4

    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.3 to Kotlin 1.4.

    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.

    Prohibit access to protected members inside public inline members

    Issue:

    Component: Core language

    Incompatible change type: source

    Short summary: Kotlin 1.4 will prohibit access to protected members from public inline members.

    Deprecation cycle:

    • < 1.4: introduce warning at call-site for problematic cases
    • 1.4: raise this warning to an error, -XXLanguage:-ProhibitProtectedCallFromInline can be used to temporarily revert to pre-1.4 behavior

    Contracts on calls with implicit receivers

    Issue:

    Component: Core Language

    Incompatible change type: behavioral

    Short summary: smart casts from contracts will be available on calls with implicit receivers in 1.4

    Deprecation cycle:

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed, -XXLanguage:-ContractsOnCallsWithImplicitReceiver can be used to temporarily revert to pre-1.4 behavior

    Inconsistent behavior of floating-point number comparisons

    Issues:

    Component: Core language

    Incompatible change type: behavioral

    Short summary: since Kotlin 1.4, Kotlin compiler will use IEEE 754 standard to compare floating-point numbers

    Deprecation cycle:

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed, -XXLanguage:-ProperIeee754Comparisons can be used to temporarily revert to pre-1.4 behavior

    No smart cast on the last expression in a generic lambda

    Issue:

    Component: Core Language

    Incompatible change type: behavioral

    Short summary: smart casts for last expressions in lambdas will be correctly applied since 1.4

    Deprecation cycle:

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed, -XXLanguage:-NewInference can be used to temporarily revert to pre-1.4 behavior. Note that this flag will also disable several new language features.

    Do not depend on the order of lambda arguments to coerce result to Unit

    Issue:

    Component: Core language

    Incompatible change type: source

    Short summary: since Kotlin 1.4, lambda arguments will be resolved independently without implicit coercion to Unit

    Deprecation cycle:

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed, -XXLanguage:-NewInference can be used to temporarily revert to pre-1.4 behavior. Note that this flag will also disable several new language features.

    Wrong common supertype between raw and integer literal type leads to unsound code

    Issue:

    Components: Core language

    Incompatible change type: source

    Short summary: since Kotlin 1.4, common supertype between raw Comparable type and integer literal type will be more specific

    Deprecation cycle:

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed, -XXLanguage:-NewInference can be used to temporarily revert to pre-1.4 behavior. Note that this flag will also disable several new language features.

    Type safety problem because several equal type variables are instantiated with a different types

    Issue:

    Component: Core language

    Incompatible change type: source

    Short summary: since Kotlin 1.4, Kotlin compiler will prohibit instantiating equal type variables with different types

    Deprecation cycle:

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed, -XXLanguage:-NewInference can be used to temporarily revert to pre-1.4 behavior. Note that this flag will also disable several new language features.

    Type safety problem because of incorrect subtyping for intersection types

    Issues:

    Component: Core language

    Incompatible change type: source

    Short summary: in Kotlin 1.4, subtyping for intersection types will be refined to work more correctly

    Deprecation cycle:

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed, -XXLanguage:-NewInference can be used to temporarily revert to pre-1.4 behavior. Note that this flag will also disable several new language features.

    No type mismatch with an empty when expression inside lambda

    Issue:

    Component: Core language

    Incompatible change type: source

    Short summary: since Kotlin 1.4, there will be a type mismatch for empty when expression if it’s used as the last expression in a lambda

    Deprecation cycle:

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed, -XXLanguage:-NewInference can be used to temporarily revert to pre-1.4 behavior. Note that this flag will also disable several new language features.

    Return type Any inferred for lambda with early return with integer literal in one of possible return values

    Issue:

    Component: Core language

    Incompatible change type: source

    Short summary: since Kotlin 1.4, integer type returning from a lambda will be more specific for cases when there is early return

    Deprecation cycle:

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed, -XXLanguage:-NewInference can be used to temporarily revert to pre-1.4 behavior. Note that this flag will also disable several new language features.

    Proper capturing of star projections with recursive types

    Issue:

    Component: Core language

    Incompatible change type: source

    Short summary: since Kotlin 1.4, more candidates will become applicable because capturing for recursive types will work more correctly

    Deprecation cycle:

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed, -XXLanguage:-NewInference can be used to temporarily revert to pre-1.4 behavior. Note that this flag will also disable several new language features.

    Common supertype calculation with non-proper type and flexible one leads to incorrect results

    Issue:

    Component: Core language

    Incompatible change type: behavioral

    Short summary: since Kotlin 1.4, common supertype between flexible types will be more specific protecting from runtime errors

    Deprecation cycle:

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed, -XXLanguage:-NewInference can be used to temporarily revert to pre-1.4 behavior. Note that this flag will also disable several new language features.

    Type safety problem because of lack of captured conversion against nullable type argument

    Issue:

    Component: Core language

    Incompatible change type: source

    Short summary: since Kotlin 1.4, subtyping between captured and nullable types will be more correct protecting from runtime errors

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed, can be used to temporarily revert to pre-1.4 behavior. Note that this flag will also disable several new language features.

    Type variable leaks from builder inference because of using this expression

    Issue:

    Component: Core language

    Incompatible change type: source

    Short summary: since Kotlin 1.4, using this inside builder functions like sequence {} is prohibited if there are no other proper constraints

    Deprecation cycle:

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed, -XXLanguage:-NewInference can be used to temporarily revert to pre-1.4 behavior. Note that this flag will also disable several new language features.

    Wrong overload resolution for contravariant types with nullable type arguments

    Issue:

    Component: Core language

    Incompatible change type: source

    Short summary: since Kotlin 1.4, if two overloads of a function that takes contravariant type arguments differ only by the nullability of the type (such as In<T> and In<T?>), the nullable type is considered more specific.

    Deprecation cycle:

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed, -XXLanguage:-NewInference can be used to temporarily revert to pre-1.4 behavior. Note that this flag will also disable several new language features.

    Builder inference with non-nested recursive constraints

    Issue:

    Component: Core language

    Incompatible change type: source

    Short summary: since Kotlin 1.4, builder functions such as sequence {} with type that depends on a recursive constraint inside the passed lambda cause a compiler error.

    Deprecation cycle:

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed, -XXLanguage:-NewInference can be used to temporarily revert to pre-1.4 behavior. Note that this flag will also disable several new language features.

    Eager type variable fixation leads to a contradictory constraint system

    Issue:

    Component: Core language

    Incompatible change type: source

    Short summary: since Kotlin 1.4, the type inference in certain cases works less eagerly allowing to find the constraint system that is not contradictory.

    Deprecation cycle:

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed, -XXLanguage:-NewInference can be used to temporarily revert to pre-1.4 behavior. Note that this flag will also disable several new language features.

    Prohibit tailrec modifier on open functions

    Issue:

    Component: Core language

    Incompatible change type: source

    Short summary: since Kotlin 1.4, functions can’t have open and tailrec modifiers at the same time.

    Deprecation cycle:

    • < 1.4: report a warning on functions that have open and tailrec modifiers together (error in the progressive mode).
    • >= 1.4: raise this warning to an error.

    The INSTANCE field of a companion object more visible than the companion object class itself

    Issue:

    Component: Kotlin/JVM

    Incompatible change type: source

    Short summary: since Kotlin 1.4, if a companion object is private, then its field INSTANCE will be also private

    Deprecation cycle:

    • >= 1.4: companion object INSTANCE field has proper visibility

    Outer finally block inserted before return is not excluded from thecatch interval of the inner try block without finally

    Issue:

    Component: Kotlin/JVM

    Incompatible change type: behavioral

    Short summary: since Kotlin 1.4, the catch interval will be computed properly for nested try/catch blocks

    Deprecation cycle:

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed, -XXLanguage:-ProperFinally can be used to temporarily revert to pre-1.4 behavior

    Use the boxed version of an inline class in return type position for covariant and generic-specialized overrides

    Issues:

    Component: Kotlin/JVM

    Incompatible change type: behavioral

    Short summary: since Kotlin 1.4, functions using covariant and generic-specialized overrides will return boxed values of inline classes

    Deprecation cycle:

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed

    Do not declare checked exceptions in JVM bytecode when using delegation to Kotlin interfaces

    Issue:

    Component: Kotlin/JVM

    Incompatible change type: source

    Short summary: Kotlin 1.4 will not generate checked exceptions during interface delegation to Kotlin interfaces

    Deprecation cycle:

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed, -XXLanguage:-DoNotGenerateThrowsForDelegatedKotlinMembers can be used to temporarily revert to pre-1.4 behavior

    Changed behavior of signature-polymorphic calls to methods with a single vararg parameter to avoid wrapping the argument into another array

    Issue:

    Component: Kotlin/JVM

    Incompatible change type: source

    Short summary: Kotlin 1.4 will not wrap the argument into another array on a signature-polymorphic call

    Deprecation cycle:

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed

    Incorrect generic signature in annotations when KClass is used as a generic parameter

    Issue:

    Component: Kotlin/JVM

    Incompatible change type: source

    Short summary: Kotlin 1.4 will fix incorrect type mapping in annotations when KClass is used as a generic parameter

    Deprecation cycle:

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed

    Forbid spread operator in signature-polymorphic calls

    Issue:

    Component: Kotlin/JVM

    Incompatible change type: source

    Short summary: Kotlin 1.4 will prohibit the use of spread operator (*) on signature-polymorphic calls

    Deprecation cycle:

    • < 1.4: report a warning on the use of a spread operator in signature-polymorphic calls
    • >= 1.5: raise this warning to an error, -XXLanguage:-ProhibitSpreadOnSignaturePolymorphicCall can be used to temporarily revert to pre-1.4 behavior

    Change initialization order of default values for tail-recursive optimized functions

    Issue:

    Component: Kotlin/JVM

    Incompatible change type: behavioral

    Short summary: Since Kotlin 1.4, the initialization order for tail-recursive functions will be the same as for regular functions

    Deprecation cycle:

    • < 1.4: report a warning at declaration-site for problematic functions
    • >= 1.4: behavior changed, -XXLanguage:-ProperComputationOrderOfTailrecDefaultParameters can be used to temporarily revert to pre-1.4 behavior

    Generated overloads for @JvmOverloads on open methods should be final

    Issue:

    Components: Kotlin/JVM

    Incompatible change type: source

    Short summary: overloads for functions with @JvmOverloads will be generated as final

    Deprecation cycle:

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed, -XXLanguage:-GenerateJvmOverloadsAsFinal can be used to temporarily revert to pre-1.4 behavior

    Lambdas returning kotlin.Result now return boxed value instead of unboxed

    Issue:

    Component: Kotlin/JVM

    Incompatible change type: behavioral

    Short summary: since Kotlin 1.4, lambdas returning values of kotlin.Result type will return boxed value instead of unboxed

    Deprecation cycle:

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed

    Unify exceptions from null checks

    Issue:

    Component: Kotlin/JVM

    Incompatible change type: behavior

    Short summary: Starting from Kotlin 1.4, all runtime null checks will throw a java.lang.NullPointerException

    Deprecation cycle:

    • < 1.4: runtime null checks throw different exceptions, such as KotlinNullPointerException, IllegalStateException, IllegalArgumentException, and TypeCastException
    • >= 1.4: all runtime null checks throw a java.lang.NullPointerException. -Xno-unified-null-checks can be used to temporarily revert to pre-1.4 behavior

    Comparing floating-point values in array/list operations contains, indexOf, lastIndexOf: IEEE 754 or total order

    Issue:

    Component: kotlin-stdlib (JVM)

    Incompatible change type: behavioral

    Short summary: the List implementation returned from Double/FloatArray.asList() will implement contains, , and lastIndexOf, so that they use total order equality

    Deprecation cycle:

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed

    Gradually change the return type of collection min and max functions to non-nullable

    Issue:

    Component: kotlin-stdlib (JVM)

    Incompatible change type: source

    Short summary: return type of collection min and max functions will be changed to non-nullable in 1.6

    Deprecation cycle:

    • 1.4: introduce ...OrNull functions as synonyms and deprecate the affected API (see details in the issue)
    • 1.5.x: raise the deprecation level of the affected API to error
    • >=1.6: reintroduce the affected API but with non-nullable return type

    Deprecate appendln in favor of appendLine

    Issue:

    Component: kotlin-stdlib (JVM)

    Incompatible change type: source

    Short summary: StringBuilder.appendln() will be deprecated in favor of StringBuilder.appendLine()

    Deprecation cycle:

    • 1.4: introduce appendLine function as a replacement for appendln and deprecate appendln
    • >=1.5: raise the deprecation level to error

    Deprecate conversions of floating-point types to Short and Byte

    Issue:

    Component: kotlin-stdlib (JVM)

    Incompatible change type: source

    Short summary: since Kotlin 1.4, conversions of floating-point types to Short and Byte will be deprecated

    Deprecation cycle:

    • 1.4: deprecate Double.toShort()/toByte() and Float.toShort()/toByte() and propose replacement
    • >=1.5: raise the deprecation level to error

    Fail fast in Regex.findAll on an invalid startIndex

    Issue:

    Component: kotlin-stdlib

    Incompatible change type: behavioral

    Short summary: since Kotlin 1.4, findAll will be improved to check that startIndex is in the range of the valid position indices of the input char sequence at the moment of entering findAll, and throw IndexOutOfBoundsException if it’s not

    Deprecation cycle:

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed

    Remove deprecated kotlin.coroutines.experimental

    Issue:

    Component: kotlin-stdlib

    Incompatible change type: source

    Short summary: since Kotlin 1.4, the deprecated kotlin.coroutines.experimental API is removed from stdlib

    Deprecation cycle:

    • < 1.4: kotlin.coroutines.experimental is deprecated with the ERROR level
    • >= 1.4: kotlin.coroutines.experimental is removed from stdlib. On the JVM, a separate compatibility artifact is provided (see details in the issue).

    Remove deprecated mod operator

    Issue:

    Component: kotlin-stdlib

    Incompatible change type: source

    Short summary: since Kotlin 1.4, mod operator on numeric types is removed from stdlib

    Deprecation cycle:

    • < 1.4: mod is deprecated with the ERROR level
    • >= 1.4: mod is removed from stdlib

    Hide Throwable.addSuppressed member and prefer extension instead

    Issue:

    Component: kotlin-stdlib

    Incompatible change type: behavioral

    Short summary: Throwable.addSuppressed() extension function is now preferred over the Throwable.addSuppressed() member function

    Deprecation cycle:

    • < 1.4: old behavior (see details in the issue)
    • >= 1.4: behavior changed

    capitalize should convert digraphs to title case

    Issue:

    Component: kotlin-stdlib

    Incompatible change type: behavioral

    Short summary: String.capitalize() function now capitalizes digraphs from the Serbo-Croatian Gaj’s Latin alphabet in the title case (Dž instead of DŽ)

    Deprecation cycle:

    • < 1.4: digraphs are capitalized in the upper case (DŽ)
    • >= 1.4: digraphs are capitalized in the title case (Dž)

    Compiler arguments with delimiter characters must be passed in double quotes on Windows

    Issue: KT-30211

    Component: CLI

    Incompatible change type: behavioral

    Short summary: on Windows, kotlinc.bat arguments that contain delimiter characters (whitespace, =, ;, ,) now require double quotes (")

    Deprecation cycle:

    • < 1.4: all compiler arguments are passed without quotes
    • >= 1.4: compiler arguments that contain delimiter characters (whitespace, =, ;, ,) require double quotes (")