From 44cad8f488d20d6ba38dc81426047e062b0a2b47 Mon Sep 17 00:00:00 2001 From: Andrey Polyakov Date: Wed, 15 May 2024 19:15:35 +0400 Subject: [PATCH] feat: update the Kotlin release information and evolution principles (#4173) * update: update kotlin-evolution.md * update: update releases.md * update: update wording * update: review fixes, anchor fixes * fix: fix one more anchor --- docs/topics/components-stability-pre-1.4.md | 6 +- docs/topics/kotlin-evolution.md | 143 ++++++++++++++------ docs/topics/releases.md | 112 ++++++++++----- docs/topics/whatsnew14.md | 2 +- docs/topics/whatsnew15.md | 2 +- docs/topics/whatsnew16.md | 2 +- docs/topics/whatsnew17.md | 2 +- docs/topics/whatsnew18.md | 2 +- docs/topics/whatsnew19.md | 2 +- 9 files changed, 186 insertions(+), 87 deletions(-) diff --git a/docs/topics/components-stability-pre-1.4.md b/docs/topics/components-stability-pre-1.4.md index 6c080013e8e..79b6ba3db23 100644 --- a/docs/topics/components-stability-pre-1.4.md +++ b/docs/topics/components-stability-pre-1.4.md @@ -1,12 +1,12 @@ [//]: # (title: Stability of Kotlin components \(pre 1.4\)) -There can be different modes of stability depending of how quickly a component is evolving: +There can be different modes of stability depending on how quickly a component is evolving: -* **Moving fast (MF)**: no compatibility should be expected between even [incremental releases](kotlin-evolution.md#feature-releases-and-incremental-releases), any functionality can be added, removed or changed without warning. +* **Moving fast (MF)**: no compatibility should be expected between even [incremental releases](kotlin-evolution.md#language-and-tooling-releases), any functionality can be added, removed or changed without warning. * **Additions in Incremental Releases (AIR)**: things can be added in an incremental release, removals and changes of behavior should be avoided and announced in a previous incremental release if necessary. -* **Stable Incremental Releases (SIR)**: incremental releases are fully compatible, only optimizations and bug fixes happen. Any changes can be made in a [feature release](kotlin-evolution.md#feature-releases-and-incremental-releases). +* **Stable Incremental Releases (SIR)**: incremental releases are fully compatible, only optimizations and bug fixes happen. Any changes can be made in a [language release](kotlin-evolution.md#language-and-tooling-releases). * **Fully Stable (FS)**: incremental releases are fully compatible, only optimizations and bug fixes happen. Feature releases are backwards compatible. diff --git a/docs/topics/kotlin-evolution.md b/docs/topics/kotlin-evolution.md index bba4c937426..0f0c0c1d50a 100644 --- a/docs/topics/kotlin-evolution.md +++ b/docs/topics/kotlin-evolution.md @@ -8,7 +8,7 @@ > > _and with some effort we can reshape it later._ > ->_Kotlin Design Team_ +> _Kotlin Design Team_ Kotlin is designed to be a pragmatic tool for programmers. When it comes to language evolution, its pragmatic nature is captured by the following principles: @@ -32,29 +32,37 @@ want most of the code in the world to be already updated and thus have no issues incompatible changes we'll be making in the future. Apart from using our best judgement, we believe that trying things out in real life is the best way to validate a design. Before casting things in stone we want them battle-tested. This is why we use every opportunity to make early versions of our designs available in production versions of the language, but in one -of the _pre-stable_ statuses: [Experimental, Alpha, or Beta](components-stability.md). Such features are not stable, +of the _pre-stable_ statuses: [Experimental, Alpha, or Beta](components-stability.md). Such features are not stable, they can be changed at any time, and the users that opt into using them do so explicitly to indicate that they are ready to deal with the future migration issues. These users provide invaluable feedback that we gather to iterate on the design and make it rock-solid. ## Incompatible changes -If, upon updating from one version to another, some code that used to work doesn't work any more, it is an _incompatible change_ in the language (sometimes referred to as "breaking change"). There can be debates as to what "doesn't work any more" means precisely in some cases, but it definitely includes the following: +If, upon updating from one version to another, some code that used to work doesn't work anymore, +it is an _incompatible change_ in the language (sometimes referred to as "breaking change"). +There can be debates as to what "doesn't work anymore" means precisely in some cases, but it definitely includes the following: -* Code that compiled and ran fine is now rejected with an error (at compile or link time). This includes removing language constructs and adding new restrictions. -* Code that executed normally is now throwing an exception. +* Code that compiled and ran fine is now rejected with an error (at compile or link time). + This includes removing language constructs and adding new restrictions. +* Code that executed normally is now throwing an exception. -The less obvious cases that belong to the "grey area" include handling corner cases differently, throwing an exception of a different type than before, changing behavior observable only through reflection, changes in undocumented/undefined behavior, renaming binary artifacts, etc. Sometimes such changes are very important and affect migration experience dramatically, sometimes they are insignificant. +The less obvious cases that belong to the "gray area" include handling corner cases differently, throwing an exception of a different type than before, +changing behavior observable only through reflection, changing in undocumented or undefined behavior, renaming binary artifacts, and others. +Sometimes such changes are crucial and affect migration experience dramatically, sometimes they are insignificant. -Some examples of what definitely isn't an incompatible change include +Some examples of what definitely isn't an incompatible change include: * Adding new warnings. * Enabling new language constructs or relaxing limitations for existing ones. * Changing private/internal APIs and other implementation details. -The principles of Keeping the Language Modern and Comfortable Updates suggest that incompatible changes are sometimes necessary, but they should be introduced carefully. Our goal is to make the users aware of upcoming changes well in advance to let them migrate their code comfortably. +The principles of Keeping the Language Modern and Comfortable Updates suggest that incompatible changes are sometimes necessary, +but they should be introduced carefully. Our goal is to make the users aware of upcoming changes well in advance to let them migrate their code comfortably. -Ideally, every incompatible change should be announced through a compile-time warning reported in the problematic code (usually referred to as a _deprecation warning_) and accompanied with automated migration aids. So, the ideal migration workflow goes as follows: +Ideally, every incompatible change should be announced through a compile-time warning reported in the problematic code +(usually referred to as a _deprecation warning_) and accompanied by automated migration aids. +So, the ideal migration workflow goes as follows: * Update to version A (where the change is announced) * See warnings about the upcoming change @@ -62,90 +70,139 @@ Ideally, every incompatible change should be announced through a compile-time wa * Update to version B (where the change happens) * See no issues at all -In practice some changes can't be accurately detected at compile time, so no warnings can be reported, but at least the users will be notified through Release notes of version A that a change is coming in version B. +In practice, some changes can't be accurately detected at compile time, so no warnings can be reported, +but at least the users will be notified through Release notes of version A that a change is coming in version B. ### Dealing with compiler bugs -Compilers are complicated software and despite the best effort of their developers they have bugs. The bugs that cause the compiler itself to fail or report spurious errors or generate obviously failing code, though annoying and often embarrassing, are easy to fix, because the fixes do not constitute incompatible changes. Other bugs may cause the compiler to generate incorrect code that does not fail: e.g. by missing some errors in the source or simply generating wrong instructions. Fixes of such bugs are technically incompatible changes (some code used to compile fine, but now it won't any more), but we are inclined to fixing them as soon as possible to prevent the bad code patterns from spreading across user code. In our opinion, this serves the principle of Comfortable Updates, because fewer users have a chance of encountering the issue. Of course, this applies only to bugs that are found soon after appearing in a released version. +Compilers are complicated software, and despite the best effort of their developers, they have bugs. +The bugs that cause the compiler itself to fail or report spurious errors or generate obviously failing code, +though annoying and often embarrassing, are easy to fix, because the fixes do not constitute incompatible changes. +Other bugs may cause the compiler to generate incorrect code that does not fail: +for example, by missing some errors in the source or simply generating wrong instructions. +Fixes of such bugs are technically incompatible changes (some code used to compile fine, but now it won't anymore), +but we are inclined to fix them as soon as possible to prevent the bad code patterns from spreading across user code. +In our opinion, this serves the principle of Comfortable Updates, +because fewer users have a chance of encountering the issue. +Of course, this applies only to bugs that are found soon after appearing in a released version. ## Decision making -[JetBrains](https://jetbrains.com), the original creator of Kotlin, is driving its progress with the help of the community and in accord with the [Kotlin Foundation](https://kotlinfoundation.org/). +[JetBrains](https://jetbrains.com), the original creator of Kotlin, +is driving its progress with the help of the community and in accord with the [Kotlin Foundation](https://kotlinfoundation.org/). -All changes to the Kotlin Programming Language are overseen by the [Lead Language Designer](https://kotlinfoundation.org/structure/) (currently Michail Zarečenskij). The Lead Designer has the final say in all matters related to language evolution. Additionally, incompatible changes to fully stable components have to be approved to by the [Language Committee](https://kotlinfoundation.org/structure/) designated -under the [Kotlin Foundation](https://kotlinfoundation.org/structure/) (currently comprised of Jeffrey van Gogh, Werner Dietl, and Michail Zarečenskij). +All changes to the Kotlin Programming Language are overseen by the [Lead Language Designer](https://kotlinfoundation.org/structure/) (currently Michail Zarečenskij). +The Lead Designer has the final say in all matters related to language evolution. +Additionally, incompatible changes to fully stable components have to be approved to by the [Language Committee](https://kotlinfoundation.org/structure/) designated +under the [Kotlin Foundation](https://kotlinfoundation.org/structure/) (currently comprising Jeffrey van Gogh, Werner Dietl, and Michail Zarečenskij). -The Language Committee makes final decisions on what incompatible changes will be made and what exact measures should be taken to make user updates comfortable. In doing so, it relies on a set of guidelines available [here](https://kotlinfoundation.org/language-committee-guidelines/). +The Language Committee makes final decisions on what incompatible changes will be made and what exact measures should be taken to make user updates comfortable. +In doing so, it relies on a set of [Language committee guidelines](https://kotlinfoundation.org/language-committee-guidelines/). -## Feature releases and incremental releases +## Language and tooling releases -Stable releases with versions 1.2, 1.3, etc. are usually considered to be _feature releases_ bringing major changes in the language. Normally, we publish _incremental releases_, numbered 1.2.20, 1.2.30, etc, in between feature releases. +Stable releases with versions, such as 2.0.0, are usually considered to be _language releases_ bringing major changes in the language. +Normally, we publish _tooling releases_, numbered x.x.**20** in between language releases. -Incremental releases bring updates in the tooling (often including features), performance improvements and bug fixes. We try to keep such versions compatible with each other, so changes to the compiler are mostly optimizations and warning additions/removals. Pre-stable features may, of course, be added, removed or changed at any time. +Tooling releases bring updates in the tooling (often including features), performance improvements, and bug fixes. +We try to keep such versions compatible with each other, +so changes to the compiler are mostly optimizations and warning additions/removals. +Pre-stable features may be added, removed, or changed at any time. -Feature releases often add new features and may remove or change previously deprecated ones. Feature graduation from pre-stable to stable also happens in feature releases. +Language releases often add new features and may remove or change previously deprecated ones. +Feature graduation from pre-stable to stable also happens in language releases. ### EAP builds -Before releasing stable versions, we usually publish a number of preview builds dubbed EAP (for "Early Access Preview") that let us iterate faster and gather feedback from the community. EAPs of feature releases usually produce binaries that will be later rejected by the stable compiler to make sure that possible bugs in the binary format survive no longer than the preview period. Final Release Candidates normally do not bear this limitation. +Before releasing stable versions of language and tooling releases, +we publish a number of preview builds dubbed EAP (for "Early Access Preview") that let us iterate faster and gather feedback from the community. +EAPs of language releases usually produce binaries that will be later rejected by the stable compiler +to make sure that possible bugs in the binary format survive no longer than the preview period. +Final Release Candidates normally do not bear this limitation. ### Pre-stable features -According to the Feedback Loop principle described above, we iterate on our designs in the open and release versions of the language where some features have one of the _pre-stable_ statuses and _are supposed to change_. Such features can be added, changed or removed at any point and without warning. We do our best to ensure that pre-stable features can't be used accidentally by an unsuspecting user. Such features usually require some sort of an explicit opt-in either in the code or in the project configuration. +According to the Feedback Loop principle described above, we iterate on our designs in the open and +release versions of the language where some features have one of the _pre-stable_ statuses and _are supposed to change_. +Such features can be added, changed or removed at any point and without warning. +We do our best to ensure that pre-stable features can't be used accidentally by an unsuspecting user. +Such features usually require some sort of explicit opt-in either in the code or in the project configuration. Pre-stable features usually graduate to the stable status after some iterations. ### Status of different components -To check the stability status of different components of Kotlin (Kotlin/JVM, JS, Native, various libraries, etc), please consult [this link](components-stability.md). +Learn more about the [stability status of different components in Kotlin (such as Kotlin/JVM, JS, and Native compilers, various libraries)](components-stability.md) ## Libraries A language is nothing without its ecosystem, so we pay extra attention to enabling smooth library evolution. -Ideally, a new version of a library can be used as a "drop-in replacement" for an older version. This means that upgrading a binary dependency should not break anything, even if the application is not recompiled (this is possible under dynamic linking). +Ideally, a new version of a library can be used as a "drop-in replacement" for an older version. +This means that upgrading a binary dependency should not break anything, +even if the application is not recompiled (this is possible under dynamic linking). -On the one hand, to achieve this, the compiler has to provide certain ABI stability guarantees under the constraints of separate compilation. This is why every change in the language is examined from the point of view of binary compatibility. +On the one hand, to achieve this, the compiler has to provide certain ABI stability guarantees under the constraints of separate compilation. +This is why every change in the language is examined from a binary compatibility standpoint. -On the other hand, a lot depends on the library authors being careful about which changes are safe to make. Thus it's very important that library authors understand how source changes affect compatibility and follow certain best practices to keep both APIs and ABIs of their libraries stable. Here are some assumptions that we make when considering language changes from the library evolution standpoint: +On the other hand, a lot depends on the library authors being careful about which changes are safe to make. +Thus, it's crucial that library authors understand how source changes affect compatibility +and follow certain best practices to keep both APIs and ABIs of their libraries stable. +Here are some assumptions that we make when considering language changes from the library evolution standpoint: -* Library code should always specify return types of public/protected functions and properties explicitly thus never relying on type inference for public API. Subtle changes in type inference may cause return types to change inadvertently, leading to binary compatibility issues. -* Overloaded functions and properties provided by the same library should do essentially the same thing. Changes in type inference may result in more precise static types to be known at call sites causing changes in overload resolution. +* Library code should always specify return types of public/protected functions and properties explicitly, + thus never relying on type inference for public API. Subtle changes in type inference may cause return types to change inadvertently, + leading to binary compatibility issues. +* Overloaded functions and properties provided by the same library should do essentially the same thing. + Changes in type inference may result in more precise static types to be known at call sites, + causing changes in overload resolution. -Library authors can use the @Deprecated and [@RequiresOptIn](opt-in-requirements.md) annotations to control the evolution of their API surface. Note that @Deprecated(level=HIDDEN) can be used to preserve binary compatibility even for declarations removed from the API. +Library authors can use the `@Deprecated` and [`@RequiresOptIn`](opt-in-requirements.md) annotations +to control the evolution of their API surface. Note that `@Deprecated(level=HIDDEN)` +can be used to preserve binary compatibility even for declarations removed from the API. -Also, by convention, packages named "internal" are not considered public API. All API residing in packages named "experimental" is considered pre-stable and can change at any moment. +Also, by convention, packages named "internal" are not considered public API. +All API residing in packages named "experimental" is considered pre-stable and can change at any moment. -We evolve the Kotlin Standard Library (kotlin-stdlib) for stable platforms according to the principles stated above. Changes to the contracts for its API undergo the same procedures as changes in the language itself. +We evolve the Kotlin Standard Library (`kotlin-stdlib`) for stable platforms according to the principles stated above. +Changes to the contracts for its API undergo the same procedures as changes in the language itself. -## Compiler keys +## Compiler options -Command line keys accepted by the compiler are also a kind of public API, and they are subject to the same considerations. Supported flags (those that don't have the "-X" or "-XX" prefix) can be added only in feature releases and should be properly deprecated before removing them. The "-X" and "-XX" flags are experimental and can be added and removed at any time. +Command line options accepted by the compiler are also a kind of public API, and they are subject to the same considerations. +Supported options (those that don't have the "-X" or "-XX" prefix) can be added only in language releases and should be properly deprecated before removing them. +The "-X" and "-XX" options are experimental and can be added and removed at any time. ## Compatibility tools -As legacy features get removed and bugs fixed, the source language changes, and old code that has not been properly migrated may not compile any more. The normal deprecation cycle allows a comfortable period of time for migration, and even when it's over and the change ships in a stable version, there's still a way to compile unmigrated code. +As legacy features get removed and bugs fixed, the source language changes, and old code that has not been properly migrated may not compile anymore. +The normal deprecation cycle allows a comfortable period of time for migration, +and even when it's over and the change ships in a stable version, there's still a way to compile non-migrated code. -### Compatibility flags +### Compatibility options -We provide the `-language-version X.Y` and `-api-version X.Y` flags that make a new version emulate the behavior of an old +We provide the `-language-version X.Y` and `-api-version X.Y` options that make a new version emulate the behavior of an old one for compatibility purposes. To give you more time for migration, we [support](compatibility-modes.md) the development for three previous language and API versions in addition to the latest stable one. -Actively maintained code bases can benefit from getting bug fixes ASAP, without waiting for a full deprecation cycle to complete. Currently, such project can enable the `-progressive` flag and get such fixes enabled even in incremental releases. +Actively maintained code bases can benefit from getting bug fixes ASAP, without waiting for a full deprecation cycle to complete. +Currently, such projects can enable the `-progressive` option and get such fixes enabled even in tooling releases. -All flags are available on the command line as well as [Gradle](gradle-compiler-options.md) and [Maven](maven.md#specify-compiler-options). +All options are available in the command line as well as in [Gradle](gradle-compiler-options.md) and in [Maven](maven.md#specify-compiler-options). ### Evolving the binary format -Unlike sources that can be fixed by hand in the worst case, binaries are a lot harder to migrate, and this makes backwards compatibility very important in the case of binaries. Incompatible changes to binaries can make updates very uncomfortable and thus should be introduced with even more care than those in the source language syntax. +Unlike sources that can be fixed by hand in the worst case, binaries are a lot harder to migrate, +and this makes backwards compatibility crucial in the case of binaries. +Incompatible changes to binaries can make updates very uncomfortable and thus should be introduced with even more care than those in the source language syntax. -For fully stable versions of the compiler the default binary compatibility protocol is the following: +For fully stable versions of the compiler, the default binary compatibility protocol is the following: -* All binaries are backwards compatible, i.e. a newer compiler can read older binaries (e.g. 1.3 understands 1.0 through 1.2), -* Older compilers reject binaries that rely on new features (e.g. a 1.0 compiler rejects binaries that use coroutines). -* Preferably (but we can't guarantee it), the binary format is mostly forwards compatible with the next feature release, but not later ones (in the cases when new features are not used, e.g. 1.3 can understand most binaries from 1.4, but not 1.5). +* All binaries are backwards compatible; that means a newer compiler can read older binaries (for example, 1.3 understands 1.0 through 1.2). +* Older compilers reject binaries that rely on new features (for example, the 1.0 compiler rejects binaries that use coroutines). +* Preferably (but we can't guarantee it), the binary format is mostly forwards compatible with the next language release, but not later ones + (in the cases when new features are not used, for example, 1.3 can understand most binaries from 1.4, but not 1.5). This protocol is designed for comfortable updates as no project can be blocked from updating its dependencies even if it's using a slightly outdated compiler. -Please note that not all target platforms have reached this level of stability (but Kotlin/JVM has). +Please note that not all target platforms have reached this level of stability (but Kotlin/JVM has). \ No newline at end of file diff --git a/docs/topics/releases.md b/docs/topics/releases.md index 742e4965670..89105b17edc 100644 --- a/docs/topics/releases.md +++ b/docs/topics/releases.md @@ -1,57 +1,92 @@ [//]: # (title: Kotlin releases) -We ship different types of releases: +Since Kotlin 2.0.0, we ship the following types of releases: -* _Feature releases_ (1._x_) that bring major changes in the language. -* _Incremental releases_ (1._x_._y_) that are shipped between feature releases and include updates in the tooling, - performance improvements, and bug fixes. -* _Bug fix releases_ (1._x_._yz_) that include bug fixes for incremental releases. +* _Language releases_ (2._x_._0_) that bring major changes in the language and include tooling updates. Released once in 6 months. +* _Tooling releases_ (2._x_._20_) that are shipped between language releases and include updates in the tooling, + performance improvements, and bug fixes. + Released in 3 months after corresponding _language release_. +* _Bug fix releases_ (2._x_._yz_) that include bug fixes for _tooling releases_. There is no exact release schedule for these releases. -For example, for the feature release 1.3 we had several incremental releases including 1.3.10, 1.3.20, and 1.3.70. -For 1.3.70, we had 2 bug fix releases – 1.3.71 and 1.3.72. + -For each incremental and feature release, we also ship several preview (_EAP_) versions for you to try +For each language and tooling release, we also ship several preview (_EAP_) versions for you to try new features before they are released. See [Early Access Preview](eap.md) for details. -Learn more about [types of Kotlin releases and their compatibility](kotlin-evolution.md#feature-releases-and-incremental-releases). - ## Update to a new release -> Starting from IntelliJ IDEA 2023.3 and Android Studio Iguana (2023.2.1) Canary 15, the Kotlin plugin is automatically -> updated. All you need to do is update the Kotlin version in your projects. -> -{type="note"} +To upgrade your project to a new release, you need to update your build script file. +For example, to update to Kotlin %kotlinVersion%, change the version of the Kotlin Gradle plugin in your +`build.gradle(.kts)` file: + + + -IntelliJ IDEA and Android Studio suggest updating to a new release once it is out. When you accept the suggestion, -it automatically updates the Kotlin plugin to the new version. You can check the Kotlin version in **Tools** | **Kotlin** -| **Configure Kotlin Plugin Updates**. +```kotlin +plugins { + // Replace `<...>` with the plugin name appropriate for your target environment + kotlin("<...>") version "%kotlinVersion%" + // For example, if your target environment is JVM: + // kotlin("jvm") version "%kotlinVersion%" + // If you target is Kotlin Multiplatform + // kotlin("multiplatform") version "%kotlinVersion%" +} +``` + + + + +```groovy +plugins { + // Replace `<...>` with the plugin name appropriate for your target environment + id 'org.jetbrains.kotlin.<...>' version '%kotlinVersion%' + // For example, if your target environment is JVM: + // id 'org.jetbrains.kotlin.jvm' version '%kotlinVersion%' + // If you target is Kotlin Multiplatform + // id 'org.jetbrains.kotlin.multiplatform' version '%kotlinVersion%' +} +``` + + + If you have projects created with earlier Kotlin versions, change the Kotlin version in your projects and update kotlinx libraries if necessary. -If you are migrating to the new feature release, Kotlin plugin's migration tools will help you with the migration. +If you are migrating to the new language release, Kotlin plugin's migration tools will help you with the migration. ## IDE support -The IDE support for the latest version of the language is available for the following versions of IntelliJ IDEA and Android Studio: -* IntelliJ IDEA: - * Latest stable - * Previous stable - * [Early access](https://www.jetbrains.com/resources/eap/) versions -* Android Studio: - * [Latest released](https://developer.android.com/studio) version - * [Early access](https://developer.android.com/studio/preview) versions +Even with the release of the K2 compiler, IntelliJ IDEA and Android Studio still use the K1 compiler by default +for code analysis, code completion, highlighting, and other IDE-related features. -> Learn more about the latest Kotlin-related updates in IntelliJ IDEA in the **Kotlin** section of the -> [What's new in IntelliJ IDEA page](https://www.jetbrains.com/idea/whatsnew/). -> -{type="tip"} +Starting from 2024.1, IntelliJ IDEA can use the new K2 compiler to analyze your code with its K2 Kotlin mode. +To enable it, go to **Settings** | **Languages & Frameworks** | **Kotlin** and select the **Enable the K2-based Kotlin plugin** option. + +> The K2 Kotlin mode is in Alpha. The performance and stability of code highlighting and code completion have been significantly improved, +> but not all IDE features are supported yet. +> +{type="warning"} + +After enabling K2 mode, you may notice differences in IDE analysis due to changes in compiler behavior. +Learn how the K2 compiler differs from K1 in the [migration guide](k2-compiler-migration-guide.md). + +## Kotlin release compatibility + +Learn more about [types of Kotlin releases and their compatibility](kotlin-evolution.md#language-and-tooling-releases) ## Release details -The following table lists details of the latest Kotlin releases. +The following table lists details of the latest Kotlin releases: -You can also use [preview versions of Kotlin](eap.md#build-details). +> You can also use [preview versions of Kotlin](eap.md#build-details). +> +{type="tip"} @@ -118,7 +153,10 @@ You can also use [preview versions of Kotlin](eap.md#build-details).

Release on GitHub

-

A feature release with Kotlin K2 compiler updates, new enum class values function, new operator for open-ended ranges, preview of Gradle configuration cache in Kotlin Multiplatform, changes to Android target support in Kotlin Multiplatform, preview of custom memory allocator in Kotlin/Native.

+

A feature release with Kotlin K2 compiler updates, new enum class values function, + new operator for open-ended ranges, preview of Gradle configuration cache in Kotlin Multiplatform, + changes to Android target support in Kotlin Multiplatform, preview of custom memory allocator in Kotlin/Native. +

Learn more in:

  • What's new in Kotlin 1.9.0
  • @@ -153,7 +191,9 @@ You can also use [preview versions of Kotlin](eap.md#build-details).

    Release on GitHub

    -

    A feature release with Kotlin K2 compiler updates, AutoCloseable interface and Base64 encoding in stdlib, new JVM incremental compilation enabled by default, new Kotlin/Wasm compiler backend.

    +

    A feature release with Kotlin K2 compiler updates, AutoCloseable interface and Base64 encoding in stdlib, + new JVM incremental compilation enabled by default, new Kotlin/Wasm compiler backend. +

    Learn more in:

  • What's new in Kotlin 1.8.20
  • @@ -203,7 +243,9 @@ You can also use [preview versions of Kotlin](eap.md#build-details).

    Release on GitHub

    -

    An incremental release with new language features, the support for several compiler plugins in the Kotlin K2 compiler, the new Kotlin/Native memory manager enabled by default, and the support for Gradle 7.1.

    +

    An incremental release with new language features, the support for several compiler plugins in the Kotlin K2 compiler, + the new Kotlin/Native memory manager enabled by default, and the support for Gradle 7.1. +

    Learn more in:

  • What's new in Kotlin 1.7.20
  • diff --git a/docs/topics/whatsnew14.md b/docs/topics/whatsnew14.md index bf29f0d3236..31c277aeadb 100644 --- a/docs/topics/whatsnew14.md +++ b/docs/topics/whatsnew14.md @@ -1517,7 +1517,7 @@ to help you decide which suggestions to accept and which to ignore. ![Migration inspections](migration-inspection-wn.png) -Kotlin 1.4.0 is a [feature release](kotlin-evolution.md#feature-releases-and-incremental-releases) and therefore can +Kotlin 1.4.0 is a [feature release](kotlin-evolution.md#language-and-tooling-releases) and therefore can bring incompatible changes to the language. Find the detailed list of such changes in the **[Compatibility Guide for Kotlin 1.4](compatibility-guide-14.md)**.