E05020: a circular type/function hierarchy has been used
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
- Draw out the inheritance relationships to visualize the cycle
- Identify which class should be the true root/base
- Break the cycle by removing one 'extends' clause
- 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
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: