E05020: a circular type/function hierarchy has been used

Category: E05xxx Explicit type symbol definition · Reported in phase: TYPE_HIERARCHY_CHECKS · Classification: CIRCULAR_HIERARCHY_DETECTED · All error codes

What went wrong

The type hierarchy contains a cycle - a type directly or indirectly extends/implements itself. This is logically impossible: you cannot inherit from something that inherits from you.

Worked examples

Compilable examples demonstrating this error and the correct fix:

  • ek9 -q 772 (Why does EK9 reject circular type hierarchies?)

How to fix it

  1. Draw out the inheritance relationships to visualize the cycle
  2. Identify which class should be the true root/base
  3. Break the cycle by removing one 'extends' clause
  4. Consider if composition would work better than inheritance

Common causes

  • Refactoring that accidentally swapped inheritance direction
  • Copy-paste errors when creating similar classes
  • Merging code from different branches with conflicting hierarchies
  • Circular dependency in design (A needs B's features, B needs A's)

EVERY member of the cycle is reported, each in the file that declares it, and each message names the whole cycle, e.g. (Alpha -> Beta -> Alpha). Breaking any ONE link fixes all of them. A type that merely extends a member of the cycle is not reported.

See also

  • E05020: circular inheritance (this error)
  • E05030: extending non-open class (different - class is closed)

Examples

Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.

Fails with E05020: a circular type/function hierarchy has been used

#!ek9
defines module error.e05020.bad

  defines class

    C1 is C3 as open
      field1 <- "Steve"

      default C1()

    C2 is C1 as open
      field2 <- "Stephen"

      default C2()

    C3 is C2 as open
      field3 <- "Stephene"

      default C3()

    CA is CB as open
      field3 <- "Stephene"

      default CA()

    CB is CA as open
      field4 <- "Steven"

      default CB()

Fixed: A hierarchy is a tree: pick the one type at the root and extend downwards

#!ek9
defines module error.e05020.good

  defines class

    C1 as open
      field1 <- "Steve"
      default C1()
      default operator ?

    C2 is C1 as open
      field2 <- "Stephen"
      default C2()
      default operator ?

    C3 is C2
      field3 <- "Stephene"
      default C3()
      default operator ?

Questions and answers

These Q&A entries show E05020 and its fix: