Skip to content

Commit 0cc4e14

Browse files
committed
update: add expected actual classes change to k2 guide
1 parent e4896c0 commit 0cc4e14

File tree

1 file changed

+82
-11
lines changed

1 file changed

+82
-11
lines changed

docs/topics/k2-compiler-migration-guide.md

Lines changed: 82 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,7 @@ This section highlights the following modifications:
574574
* [Forbidden use of inaccessible generic types](#forbidden-use-of-inaccessible-generic-types)
575575
* [Consistent resolution order of Kotlin properties and Java fields with the same name](#consistent-resolution-order-of-kotlin-properties-and-java-fields-with-the-same-name)
576576
* [Improved null safety for Java primitive arrays](#improved-null-safety-for-java-primitive-arrays)
577+
* [Stricter rules for abstract members in expected classes](#stricter-rules-for-abstract-members-in-expected-classes)
577578

578579
### Immediate initialization of open properties with backing fields
579580

@@ -995,6 +996,75 @@ and errors if you use them:
995996

996997
For more information, see the [corresponding issue in YouTrack](https://youtrack.jetbrains.com/issue/KT-54521).
997998

999+
### Stricter rules for abstract members in expected classes
1000+
1001+
> Expected and actual classes are in [Beta](components-stability.md#stability-levels-explained).
1002+
> They are almost stable, but you may need to perform migration steps in the future.
1003+
> We'll do our best to minimize any further changes for you to make.
1004+
>
1005+
{type="warning"}
1006+
1007+
**What's changed?**
1008+
1009+
Due to the separation of common and platform sources during compilation with the K2 compiler, we've implemented stricter
1010+
rules for abstract members in expected classes.
1011+
1012+
With the previous compiler, it was possible for an expected non-abstract class to inherit an abstract function without
1013+
[overriding the function](inheritance.md#overriding-rules). Since the compiler could access both common and platform code
1014+
at the same time, the compiler could see whether the abstract function had a corresponding override and definition in the
1015+
actual class.
1016+
1017+
Now that common and platform sources are compiled separately, the inherited function must be explicitly overridden in the
1018+
expected class so that the compiler knows the function is not abstract. Otherwise, the compiler reports an
1019+
`ABSTRACT_MEMBER_NOT_IMPLEMENTED` error.
1020+
1021+
For example, let's say you have a common source set where you declare an abstract class called `FileSystem` that has an
1022+
abstract function `listFiles()`. You define the `listFiles()` function in the platform source set as part of an actual
1023+
declaration.
1024+
1025+
In your common code, if you have an expected non-abstract class called `PlatformFileSystem` that inherits from the
1026+
`FileSystem` class, the `PlatformFileSystem` class inherits the abstract function `listFiles()`. However, you can't have
1027+
an abstract function in a non-abstract class in Kotlin. To make the `listFiles()` function non-abstract, you must declare
1028+
it as an override without the `abstract` keyword:
1029+
1030+
<table header-style="top">
1031+
<tr>
1032+
<td>Common code</td>
1033+
<td>Platform code</td>
1034+
</tr>
1035+
<tr>
1036+
<td>
1037+
1038+
```kotlin
1039+
abstract class FileSystem {
1040+
abstract fun listFiles()
1041+
}
1042+
expect open class PlatformFileSystem() : FileSystem {
1043+
// In Kotlin 2.0.0, an explicit override is needed
1044+
expect override fun listFiles()
1045+
// Before Kotlin 2.0.0, an override wasn't needed
1046+
}
1047+
```
1048+
1049+
</td>
1050+
<td>
1051+
1052+
```kotlin
1053+
actual open class PlatformFileSystem : FileSystem {
1054+
actual override fun listFiles() {}
1055+
}
1056+
```
1057+
1058+
</td>
1059+
</tr>
1060+
</table>
1061+
1062+
**What's the best practice now?**
1063+
1064+
If you inherit abstract functions in an expected non-abstract class, add a non-abstract override.
1065+
1066+
For more information, see the corresponding issue in [YouTrack](https://youtrack.jetbrains.com/issue/KT-59739/K2-MPP-reports-ABSTRACTMEMBERNOTIMPLEMENTED-for-inheritor-in-common-code-when-the-implementation-is-located-in-the-actual).
1067+
9981068
### Per subject area
9991069

10001070
These subject areas list changes that are unlikely to affect your code but provide links to the relevant YouTrack issues
@@ -1150,17 +1220,18 @@ for further reading. Changes listed with an asterisk (*) next to the Issue ID ar
11501220

11511221
#### Miscellaneous {initial-collapse-state="collapsed"}
11521222

1153-
| Issue ID | Title |
1154-
|-----------------------------------------------------------|------------------------------------------------------------------------------------------------------------|
1155-
| [KT-49015](https://youtrack.jetbrains.com/issue/KT-49015) | Qualified this: change behavior in case of potential label conflicts |
1156-
| [KT-56545](https://youtrack.jetbrains.com/issue/KT-56545) | Fix incorrect functions mangling in JVM backend in case of accidental clashing overload in a Java subclass |
1157-
| [KT-62019](https://youtrack.jetbrains.com/issue/KT-62019) | [LC issue] Prohibit suspend-marked anonymous function declarations in statement positions |
1158-
| [KT-55111](https://youtrack.jetbrains.com/issue/KT-55111) | OptIn: forbid constructor calls with default arguments under marker |
1159-
| [KT-61182](https://youtrack.jetbrains.com/issue/KT-61182) | Unit conversion is accidentally allowed to be used for expressions on variables + invoke resolution |
1160-
| [KT-55199](https://youtrack.jetbrains.com/issue/KT-55199) | Forbid promoting callable references with adaptations to KFunction |
1161-
| [KT-65776](https://youtrack.jetbrains.com/issue/KT-65776) | [LC] K2 breaks \`false && ...\` and \`false \|\| ...\` |
1162-
| [KT-65682](https://youtrack.jetbrains.com/issue/KT-65682) | [LC] Deprecate \`header\`/\`impl\` keywords |
1163-
| [KT-45375](https://youtrack.jetbrains.com/issue/KT-45375) | Generate all Kotlin lambdas via invokedynamic + LambdaMetafactory by default |
1223+
| Issue ID | Title |
1224+
|------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
1225+
| [KT-59739](https://youtrack.jetbrains.com/issue/KT-59739)* | K2/MPP reports [ABSTRACT_MEMBER_NOT_IMPLEMENTED] for inheritor in common code when the implementation is located in the actual counterpart |
1226+
| [KT-49015](https://youtrack.jetbrains.com/issue/KT-49015) | Qualified this: change behavior in case of potential label conflicts |
1227+
| [KT-56545](https://youtrack.jetbrains.com/issue/KT-56545) | Fix incorrect functions mangling in JVM backend in case of accidental clashing overload in a Java subclass |
1228+
| [KT-62019](https://youtrack.jetbrains.com/issue/KT-62019) | [LC issue] Prohibit suspend-marked anonymous function declarations in statement positions |
1229+
| [KT-55111](https://youtrack.jetbrains.com/issue/KT-55111) | OptIn: forbid constructor calls with default arguments under marker |
1230+
| [KT-61182](https://youtrack.jetbrains.com/issue/KT-61182) | Unit conversion is accidentally allowed to be used for expressions on variables + invoke resolution |
1231+
| [KT-55199](https://youtrack.jetbrains.com/issue/KT-55199) | Forbid promoting callable references with adaptations to KFunction |
1232+
| [KT-65776](https://youtrack.jetbrains.com/issue/KT-65776) | [LC] K2 breaks \`false && ...\` and \`false \|\| ...\` |
1233+
| [KT-65682](https://youtrack.jetbrains.com/issue/KT-65682) | [LC] Deprecate \`header\`/\`impl\` keywords |
1234+
| [KT-45375](https://youtrack.jetbrains.com/issue/KT-45375) | Generate all Kotlin lambdas via invokedynamic + LambdaMetafactory by default |
11641235

11651236
## Compatibility with Kotlin releases
11661237

0 commit comments

Comments
 (0)