E06150: conflicting methods to be resolved
What went wrong
When a class inherits from multiple sources (class + traits), some inherited methods conflict with each other and the compiler cannot auto-resolve which implementation to use.
A method is in conflict only when two DIFFERENT implementations reach the type. The same method of the same trait reached along several routes - a diamond, 'Duck with trait of Walker, Swimmer' where both are Named - is ONE method and is not a conflict: Duck has Named's methods once, with nothing to override.
ONE implementation plus any number of ABSTRACT declarations of the same method is not a conflict either: the implementation IS the method. If Named's tag() is abstract, Walker implements it and Swimmer leaves it abstract, Duck has Walker's tag(). If Base (with trait of Named) implements it, 'Sub extends Base with trait of Swimmer' has Base's. The type need not override. A concrete type whose abstract method nothing implements is E07130, not this error.
Worked examples
Compilable examples demonstrating this error and the correct fix:
- ek9 -q 680 (How does EK9 resolve the diamond problem with trait metho...)
- ek9 -q 107 (Can a class implement multiple traits in EK9?)
How to fix it
- Override the conflicting method in your class; its body may call super.method() or a delegate's delegate.method() to choose, or combine them
- Rename methods in traits if you control them
Note: 'by' does NOT resolve a conflict. A delegated trait is simply another provider of its full member set (inherited members included), exactly as it would be without 'by'.
Common causes
- Two traits define the same method with different implementations
- Base class method conflicts with trait method
- A diamond where one route overrides the shared method and another does not (Walker overrides Named's describe(), Swimmer keeps Named's)
- A trait delegated with 'by' provides a member the super class, another delegated trait or a trait with a body also provides (an abstract member of a delegated trait counts: the delegate implements it)
- Two unrelated traits that each declare a method of the same signature: they are not the same method, even when only one has a body
See also
Examples
Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.
Fails with E06150: conflicting methods to be resolved
#!ek9 defines module error.e06150.bad defines trait T1 clash() <- rtn <- true T2 clash() <- rtn <- false defines class Base as open clash() <- rtn <- false default operator ? //Two traits both provide a concrete clash() BrokenClass1 with trait T1, T2 default BrokenClass1() someMethod() <- rtn <- true default operator ? //The base class and a trait both provide a concrete clash() BrokenClass2 extends Base with trait T1 default BrokenClass2() someMethod() <- rtn <- true default operator ?
Fixed: Override the method and say which implementation (or what combination) you mean
#!ek9 defines module error.e06150.good defines trait T1 clash() <- rtn <- true T2 clash() <- rtn <- false defines class Base as open clash() <- rtn <- false default operator ? WorkingClass1 with trait T1, T2 default WorkingClass1() override clash() <- rtn as Boolean: T1.clash() and T2.clash() default operator ? WorkingClass2 is Base with trait T1 default WorkingClass2() override clash() <- rtn as Boolean: super.clash() or T1.clash() default operator ?
Questions and answers
These Q&A entries show E06150 and its fix: