Sealed classes inside another class in Kotlin can't be compiled: cannot access '<init>' it is private

Randy Sugianto &#39;Yuku&#39; picture Randy Sugianto 'Yuku' · Jun 27, 2018 · Viewed 8.5k times · Source

If I used the example from the docs,

class SomeActivity : AppCompatActivity() {
    sealed class Expr
    data class Const(val number: Double) : Expr()
    data class Sum(val e1: Expr, val e2: Expr) : Expr()
    object NotANumber : Expr()
}

it does not compile, with the error:

Cannot access '<init>', it is private in 'Expr'.

However, moving it outside the enclosing class makes it compile:

sealed class Expr
data class Const(val number: Double) : Expr()
data class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()

class SomeActivity : AppCompatActivity() {
}

Why is this so? Is this an intended behavior? The docs does not seem to mention this.

Answer

Alexey Romanov picture Alexey Romanov · Jul 14, 2018

Yes, it turns out to be intended behavior. According to the proposal allowing non-nested subclasses:

Proposal: allow top-level subclasses for a top-level sealed class in the same file.

For a non top-level sealed class all subclasses should be declared inside it. So, for such classes nothing changes.

The scenario you want is listed as an open question. There is a ticket for it at https://youtrack.jetbrains.com/issue/KT-13495. Nobody seems to be working on it at the moment. In the discussion of the proposal, the developer says:

Well, there is some not-trivial implementations details(about generation synthetic constructors) which was solved for top-level classes but how do it in general is not clear.