Compatibility Guide for Kotlin 1.3

Keeping the Language Modern and Comfortable Updates are among the fundamental principles in Kotlin Language Design. The former says that constructions 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.2 to Kotlin 1.3

Nullability assertions on access to Java types annotated with @NotNull

Short summary: nullability assertions for Java-types annotated with not-null annotations will be generated more aggressively, causing code which passes null here to fail faster.

Deprecation cycle:

<1.3: the compiler could miss such assertions when type inference was involved, allowing potential null propagation during compilation against binaries (see Issue for details).

>=1.3: the compiler generates missed assertions. This can case code which was (erroneously) passing nulls here fail faster.-XXLanguage:-StrictJavaNullabilityAssertions can be used to temporarily return to the pre-1.3 behavior. Support for this flag will be removed in the next major release.

Unsound smartcasts on enum members

Short summary: a smartcast on a member of one enum entry will be correctly applied to only this enum entry

Deprecation cycle:

<1.3: a smartcast on a member of one enum entry could lead to an unsound smartcast on the same member of other enum entries.

>=1.3: smartcast will be properly applied only to the member of one enum entry. -XXLanguage:-SoundSmartcastForEnumEntries will temporarily return old behavior. Support for this flag will be removed in the next major release.

Array capturing before the for-loop where it is iterated

Short summary: if an expression in for-loop range is a local variable updated in a loop body, this change affects loop execution. This is inconsistent with iterating over other containers, such as ranges, character sequences, and collections.

Deprecation cycle:

<1.2: described code patterns are compiled fine, but updates to local variable affect loop execution

1.2.X: deprecation warning reported if a range expression in a for-loop is an array-typed local variable which is assigned in a loop body

1.3: change behavior in such cases to be consistent with other containers

Array.copyOfRange throws an exception when indices are out of bounds instead of enlarging the returned array

Short summary: since Kotlin 1.3, ensure that the toIndex argument of Array.copyOfRange, which represents the exclusive end of the range being copied, is not greater than the array size and throw IllegalArgumentException if it is.

Deprecation cycle:

<1.3: in case toIndex in the invocation of Array.copyOfRange is greater than the array size, the missing elements in range fill be filled with nulls, violating soundness of the Kotlin type system.

>=1.3: check that toIndex is in the array bounds, and throw exception if it isn't

Progressions of ints and longs with a step of Int.MIN_VALUE and Long.MIN_VALUE are outlawed and won’t be allowed to be instantiated

Short summary: since Kotlin 1.3, prohibit step value for integer progressions being the minimum negative value of its integer type (Long or Int), so that calling IntProgression.fromClosedRange(0, 1, step = Int.MIN_VALUE) will throw IllegalArgumentException

Deprecation cycle:

<1.3: it was possible to create an IntProgression with Int.MIN_VALUE step, which yields two values [0, -2147483648], which is non-obvious behavior

>=1.3: throw IllegalArgumentException if the step is the minimum negative value of its integer type

Annotations in stdlib

Short summary: Kotlin 1.3 removes annotations from the package org.jetbrains.annotations from stdlib and moves them to the separate artifacts shipped with the compiler: annotations-13.0.jar and mutability-annotations-compat.jar