Releases

Kotlin 1.6.0 Released

Kotlin 1.6.0 is now officially released with Stable exhaustive whens, Kover, and a new memory manager for Kotlin/Native. Other language and standard library features released in 1.5.30 became Stable as well. Thanks for the feedback you’ve shared with us. If you still haven’t tried these new features out, now is the time!

In this blog post, you can find an overview of the following updates:

  • Language features with sealed when statements, suspending functions and suspend conversions, instantiation of annotation classes, improved regular type inference and builder type inference.
  • Kotlin/JVM with optimized delegated properties and repeatable annotations.
  • Kotlin/Native with a preview of a new memory model, Xcode 13 support, a cross-compilation of Windows targets, LLVM and linker updates, performance updates, and unified compiler plugin ABI.
  • Option to disable downloading of Node.js and Yarn for Kotlin/JS.
  • Kover announcement.
  • Standard library with new functions for standard input, Stable typeOf(), Stable Duration API, and other stabilized stdlib functions.

Subscribe to our blog and don’t miss out on any Kotlin updates

How to update

If you use IntelliJ IDEA or Android Studio, you have the option to automatically update to the new Kotlin release as soon as it becomes available.

Learn more about installing Kotlin 1.6.0.

Update to Kotlin 1.6.0

Language features

We stabilized features from Kotlin 1.5.30 based on your feedback.

Sealed (exhaustive) when statements

Sealed when is a long-awaited feature that makes the Kotlin compiler warn you if your when statements are not exhaustive. This makes your code safer without having to introduce your own functions. 

Kotlin has always been exhaustive in checking when expressions for sealed classes, enums, and Boolean types. It is useful when you model your domain with those algebraic data types. For example, you might have different contact preferences for users of your app modeled as a sealed class hierarchy:

Now, if you write an expression that returns a different result based on different contact preference, the compiler will flag an error if you forget to handle all of the types you have in your app:

This is a great help, both in writing code and for future maintenance. If you add a different type of contact preference later, you know that the compiler will make sure you have not forgotten to handle the different types of contact preferences all around your code.

However, before Kotlin 1.6, the following code that uses when statements successfully compiles, even though it totally forgets to handle sending an announcement to your users via instant message:

Only a weak IDE inspection was reported, without any messages from the compiler. Starting from Kotlin 1.6, it produces the following compiler warning:

Non-exhaustive 'when' statements on sealed class/interface will be prohibited in 1.7. Add an 'is InstantMessage' branch or 'else' branch instead.

In Kotlin 1.7 it will become an error, leaving no chance to accidentally forget it. Please see KT-47709 for a more detailed explanation of the change and its effects. 

Suspending functions as supertypes

Kotlin 1.6 stabilizes support for implementing suspend functional types as super interfaces. It was one of the missing pieces in the Kotlin coroutines design. 

When you design Kotlin APIs, it is idiomatic to accept functional types when you need to customize the behavior of various library functions. For example, kotlinx.coroutines API has a member function in its Job interface that looks similar to this:

You can conveniently use this function with lambdas like invokeOnCompletion { doSomething() }. If you have a class that you wanted to handle the completion with, you can streamline and optimize your code by implementing the functional type () -> Unit directly in your class without creating an additional lambda:

Starting from Kotlin 1.6 this optimization is possible with suspending functions. If your APIs accept suspending functional types, like this:

… then you are not limited to passing lambdas and suspending function references to this code anymore. You can implement the corresponding suspending functional types in a class, too:

Suspend conversions

Kotlin 1.6 stabilizes conversions from regular to suspending functional types. You can now pass any expression of a suitable regular functional type where suspending is expected as a parameter. The compiler will perform a conversion automatically.

This fixes a small but annoying inconsistency in the interaction between regular and suspending functions in Kotlin. In you have a higher-order function that accepts a suspending function, like a collect call on a Kotlin Flow, then instead of using a lambda to call it, like this:

… you might find it convenient to pass a reference to the processItem function to the collect call to the same effect:

You would then extract a reference to your processing function into a variable in order to customize the behavior in your code. However, that didn’t work in Kotlin versions prior to 1.6. This is because you have a regular function that is being passed as a parameter of a suspending type:

In Kotlin 1.6, the above code compiles and works, too.

Improved type inference for recursive generic types

From 1.6.0, the Kotlin compiler can infer a type argument based only on the upper bounds of the corresponding type parameter if it is a recursive generic by default. This makes it possible to create various patterns with recursive generic types that are often used in Java to make builder APIs.

Builder inference improvements

Kotlin 1.5.30 introduced the -Xunrestricted-builder-inference compiler option, which made type information about a builder call available to get inside builder lambdas. Namely, it introduced the ability of making calls that return an instance of a not yet inferred type, such as get() inside a buildList() lambda.

Starting with 1.6.0, you don’t need to specify -Xunrestricted-builder-inference to make previously prohibited calls. With the -Xenable-builder-inference compiler option, you can now also write your own generic builders without applying the @BuilderInference annotation and automatically enable builder inference if regular type inference cannot resolve type information.

Supporting previous API versions for a longer period

Starting with Kotlin 1.6.0, you can now develop using three previous API versions instead of two (along with the current stable one). Currently, this includes API versions 1.3, 1.4, 1.5, and 1.6.

Kotlin/JVM

Repeatable annotations with runtime retention. Kotlin, like Java 8, has repeatable annotations. With Kotlin 1.6, the feature is compatible with Java, and @kotlin.annotation.Repeatable now accepts any retention and makes the annotation repeatable both in Kotlin and Java. Java repeatable annotations are now also supported from the Kotlin side.

Kotlin/Native

Now you can try the Experimental version of the new Kotlin/Native memory manager. With this feature we are moving closer to providing a consistent developer experience in multiplatform projects. This means that the new memory manager lifts the existing restrictions on object sharing between threads and provides fully leak-free concurrent programming primitives that are safe and don’t require any special management or annotations from the developers.

You can freely update your Xcode and continue working on your Kotlin projects, as Kotlin/Native now supports Xcode 13

Compilation of Windows targets on any host. You can compile Windows targets mingwX64 and mingwX86 on any host that supports Kotlin/Native.

We’ve reworked the LLVM dependency that Kotlin/Native uses under the hood. This brings some benefits along with an updated LLVM version to 11.1.0 and decreased dependency size.

Unified compiler plugin ABI with JVM and JS IR backends. Now, the Kotlin Multiplatform Gradle plugin is able to use the embeddable compiler jar – the one used for JVM and JS IR backends – for Kotlin/Native. You can now use the same compiler plugin artifacts for Native and other supported platforms.

Kotlin/JS

For building on a server without internet connectivity, you can now disable downloading Node.js and Yarn for Kotlin/JS projects and use the instances already installed on the host.

Kover

Since the first release, precise measurement of code coverage has been a challenge. Some great tools like JaCoCo work with Kotlin code, but they are not fully integrated with our Gradle toolchain and multiplatform projects. In this Kotlin release, we have started to fix this issue. Meet Kover, our new Gradle plugin that measures code coverage for Kotlin code built with the Kotlin/JVM compiler. Now it is in the early development stage and is experimental – we would appreciate your feedback on it in GitHub.

Watch the Kover video for more details.

Standard library

Kotlin 1.6.0 completes three stdlib roadmap items by getting rid of !! after readLine(), stabilizing typeOf(), and providing a Stable Duration API. It also promotes the following stdlib functions to Stable:

  • Collection builders
  • Bit rotation operations on integers
  • Regex function for splitting a string into a sequence

We’ve also added the ability to call compareTo in infix notation and invested in providing a consistent experience with replace() functions on JVM and JS.

New functions for standard input

In Kotlin 1.6.0, we got rid of the need to use the not-null assertion operator !! after reading a line from the standard input in order to improve the experience for newcomers and simplify teaching Kotlin.

We provide new functions for reading from the console with the following experience:

  • readln() throws an exception when EOF has been reached. Use this function instead of checking the result of readLine() for null with the !! operator.
  • The new readlnOrNull() is a null-returning alternative. It behaves in the same way as the former readLine() but has a more representative name.

These functions are now available for JVM and Native. The naming convention for these functions is now consistent with the println() counterpart, which is especially important for newcomers.

Stable Duration API

Thanks to your feedback, we have stabilized the Duration API and closed the corresponding roadmap item.

In addition to a more readable output of Duration.toString() and new functions for parsing Duration from String that were available for preview in 1.5.30, the Duration API has received the following changes:

  • The days component of the toComponents function now has the Long type instead of Int to avoid cutting off values.
  • The DurationUnit enum is now not a type alias. There are no cases of using it as a type alias for java.util.concurrent.TimeUnit on JVM.
  • In response to community feedback, we’re bringing back extension properties like Int.seconds. To limit their applicability, they are available only in the Companion of the Duration class.

Stable typeOf()

Kotlin 1.6.0 brings Stable typeOf() and closes the corresponding roadmap item. Since 1.3.40, typeOf() has been available on the JVM platform as an experimental API, and now you can use it on any Kotlin platform and get a KType representation of any Kotlin type that the compiler can infer. 

Stable collection builders

Kotlin 1.6.0 promotes collection builder functions – buildMap(), buildList(), and buildSet()– to Stable. Collections returned by the builders are now serializable in their read-only state.

Stable bit rotation operations for integers

In Kotlin 1.6.0, the rotateLeft() and rotateRight() functions, which rotate the binary representation of the number left or right by the specified number of bits, became Stable.

Stable Regex function for splitting a string into a sequence

Kotlin 1.6.0 also stabilizes splitToSequence() – a function for regular expressions that splits a string into a sequence.

compareTo in infix notation

We’ve added the ability to call the Comparable.compareTo function in infix notation to compare two objects for order: 

Consistent replace() and replaceFirst() on JVM and JS

Before Kotlin 1.6.0, the replace() and replaceFirst() Regex functions behaved differently on JVM and JS when the replacement string contained a group reference. The behavior on Kotlin/JS is now consistent with that on JVM.

​​Compatibility

As with all feature releases, some deprecation cycles of previously announced changes are coming to an end with Kotlin 1.6.0. All of these cases were carefully reviewed by the language committee and are listed in the Compatibility Guide for Kotlin 1.6. You can also explore these changes on YouTrack.

How to install Kotlin 1.6.0

If you’re using IntelliJ IDEA or Android Studio, your IDE will suggest updating Kotlin to 1.6.0 automatically. Alternatively, you can update manually by following these instructions.

You can download the latest versions of these IDEs to get extensive support for Kotlin:

  • IntelliJ IDEA – for developing Kotlin applications for various platforms.
  • Android Studio –  for developing Android and cross-platform mobile applications.

Make sure that you have also updated the kotlinx libraries to the compatible versions and specified Kotlin 1.6.0 in the build scripts of your existing projects.

If you need the command-line compiler, download it from the Github release page.

If you run into any problems:

Stay up to date with the latest Kotlin features! Subscribe to receive Kotlin updates by filling out the form to the right of this post.

What else to read and watch

Top issue reporters from YouTrack 

Ryan Nett (48 issues), Zac Sweers (22 issues), Tianyu Geng (18 issues), zhelenskiy (18 issues), Thodoris Sotiropoulos (15 issues), AndroidDeveloperLB (14 issues), Morgan, Bartholomew (14 issues), Mikhail Naftal (14 issues), Louis CAD (12 issues), Philip Wedemann (12 issues), Victor Turansky (11 issues), Igor Wojda (11 issues), Martin Bonnin (11 issues), Iaroslav Postovalov (11 issues), Cedric (10 issues), (9 issues), Ben Woodworth (8 issues), Tianyi Guan (8 issues), Chris Povirk (8 issues), Alon Albert (8 issues).

External contributors

We’d like to thank all of our contributors whose pull requests were included in this release: Pyos, Tianyu Geng, Jinseong Jeon, Steven Schäfer, Mark Punzalan, Hung Nguyen, Mads Ager, Ting-Yuan Huang, Matthew Gharrity, Ivan Gavrilovic, Xin Wang, ov7a, Jiaxiang Chen, Yigit Boyar, Bingran, bracadabra, Steffi Stumpos, Andrey Kuleshov.