E06150: conflicting methods to be resolved

Category: E06xxx Type hierarchy checks · Reported in phase: FULL_RESOLUTION · Classification: METHODS_CONFLICT · All error codes

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

  1. Override the conflicting method in your class; its body may call super.method() or a delegate's delegate.method() to choose, or combine them
  2. 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

  • E06150: trait method conflict (this error)
  • E06140: method overload ambiguity (different - about cost matching)
  • E07130: a concrete type with an abstract method nothing implements

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: