What is the full set of type hierarchy checks EK9 performs?

← Type Hierarchy Constraints · Ref: Q611

EK9 performs comprehensive type hierarchy validation during compilation, catching structural errors that would cause runtime failures in less strict languages.

CIRCULAR HIERARCHIES (E05020)

Detects cycles in inheritance chains at any depth. A class that directly or indirectly extends itself is rejected. Applies to classes, traits, records, and components.

CLOSED TYPE EXTENSION (E05030)

EK9 types are closed by default. Extending a type that is not 'as open' or 'as abstract' produces E05030.

THIS() AND SUPER() CALLS (E05060, E05070)

Constructor delegation - calling 'this()' or 'super()' - belongs in constructors: in a method it is E05060, and calling 'this()' inside a function, which has no constructors at all, is E05070. (Naming 'this' in a function is legal: it is the function itself.)

OVERRIDE VALIDATION (E05100-E05120)

E05100: 'override' on a member of something nothing can extend (such as a program or service). E05110: 'override' on a method that has no parent version with the same signature. E05120: a method with the same name AND signature as a parent method, but without 'override'. A same-named method with DIFFERENT parameters is a legal overload.

PURITY HIERARCHY (E05150-E05160)

E05150: overriding a pure method without marking the override as pure. E05160: marking an override as pure when the parent version is NOT pure.

SEALED TYPE ENFORCEMENT (E05240-E05270)

E05240: a type not named in the 'allow only' list extends the sealed type. E05250: abstract type in 'allow only' list. E05260: dispatcher missing handler for permitted type. E05270: sealed class not declared 'as open'.

See Q602 for circular hierarchies. See Q605 for 'this' context. See Q606 for method shadowing. See Q607 for sealed class requirements. See Q570 for override mechanics.
See Q679 for sealed allow-only. See Q680 for diamond trait resolution.
See Q763 for inheritance depth boundary example.

Example

defines module qa.typehierarchy.summary

  defines trait

    //Trait hierarchy: clean and valid
    Loggable
      logEntry() as abstract
        <- rtn as String?

  defines class

    //Open class: can be extended
    BaseEntity as open
      entityId()
        <- rtn as String: "entity"
      default operator ?

    //Extends open class: valid
    UserEntity extends BaseEntity with trait of Loggable
      override entityId()
        <- rtn as String: "user"
      override logEntry()
        <- rtn as String: "User entity"
      default operator ?

    //Sealed class: open + allow only
    Status allow only Active, Inactive as open
      label()
        <- rtn as String: "status"

    Active extends Status
      override label()
        <- rtn as String: "active"

    Inactive extends Status
      override label()
        <- rtn as String: "inactive"

  defines function

    testHierarchySummary()
      user <- UserEntity()
      require user.entityId() == "user"
      require user.logEntry() == "User entity"

      active <- Active()
      inactive <- Inactive()
      require active.label() == "active"
      require inactive.label() == "inactive"

Common mistakes

E05270 — A sealed class with allow only must be declared as open. Without as open, the class is closed by default and no subclasses can extend it. See ek9 -h E05270 for details.

Incorrect:

Status allow only Active, Inactive

Correct:

Status allow only Active, Inactive as open

E05120 — UserEntity.entityId has the same signature as BaseEntity.entityId, so it replaces it and must say so with 'override'. Without it, the compiler reports E05120. See ek9 -h E05120 for details.

Incorrect:

entityId()

Correct:

override entityId()

E50060 — String has no toUpperCase() method in EK9. Use upperCase() instead. See ek9 -h E50060 for details.

Incorrect:

require user.entityId().toUpperCase() == "user"

Correct:

require user.entityId() == "user"
Other ways to ask this
  • What hierarchy errors can EK9 detect?
  • How does EK9 validate type hierarchies?
  • What are all the E05xxx hierarchy error codes?

Coming from another language?

Java: some checks at compile time (circular, override), others at runtime. Python: MRO failures at class creation time. C++: compile-time hierarchy checks but no sealed types. Kotlin: comprehensive compile-time checks similar to EK9. Rust: no inheritance, trait coherence rules instead. EK9: all hierarchy checks at compile time, no runtime surprises.

Keywords: check, circular, type, hierarchy, inherit, E05110, E05030, E05120, compile, E05060, E05020, summary, E05270, validation, E05240