E07825: a trait cannot supply a dispatcher handler - move the handler into the class

Category: E07xxx Full resolution · Reported in phase: FULL_RESOLUTION · Classification: DISPATCHER_HANDLER_IN_TRAIT · All error codes

What went wrong

A trait method has the name and the number of parameters of a dispatcher on this class, so it would be one of that dispatcher's handlers. A trait cannot supply a dispatcher handler: a dispatcher and every one of its handlers live in one class hierarchy, just as the dispatcher entry point itself cannot be declared in a trait (E07810).

It does not matter where the trait is listed - on the class that declares the dispatcher, on a sub-type that inherits it, or as a trait of a listed trait. The error is reported on the listed trait that brings the method in (or on the class, when it comes only through a super class), and names the trait method and the dispatcher.

How to fix it

  1. Move the handler into the class: declare the method, with the same parameter types, in the class that declares the dispatcher or in the sub-type that needs it
  2. If the trait's method is wanted for its own sake, give it a name that is not the dispatcher's, and call it from the handler in the class

The [EXAMPLE] section below shows a class taking a handler from a trait, and the same class with the handler declared in it.

Common causes

  • Collecting shared handlers in a trait so that several classes can reuse them
  • A sub-type listing a trait whose method happens to share a dispatcher's name

Note

A trait method that only DECLARES the entry point (abstract, with the dispatcher's own parameter types) is not a handler, and a trait method the class overrides with its own method is the class's handler, not the trait's. Neither is this error.

See also

  • E07825: a dispatcher handler supplied by a trait (this error)
  • E07810: dispatcher outside a class
  • E07820: multiple dispatcher entry points
  • E06320: wrong number of parameters on a dispatcher or a handler

Examples

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

Fails with E07825: a trait cannot supply a dispatcher handler - move the handler into the class

#!ek9
defines module error.e07825.bad

  defines trait

    RoundDescriptions
      describe()
        -> circle as Circle
        <- rtn as String: "a round " + circle.kind()

  defines class

    Shape as open
      kind()
        <- rtn as String: "shape"

    Circle extends Shape
      override kind()
        <- rtn as String: "circle"

  defines class

    //The trait's describe() has the dispatcher's name and arity, so it would be a handler
    Describer with trait of RoundDescriptions
      describe() as dispatcher
        -> shape as Shape
        <- rtn as String: "some " + shape.kind()

Fixed: Declare the handler in the class

#!ek9
defines module error.e07825.good

  defines class

    Shape as open
      kind()
        <- rtn as String: "shape"

    Circle extends Shape
      override kind()
        <- rtn as String: "circle"

    Describer
      describe()
        -> circle as Circle
        <- rtn as String: "a round " + circle.kind()

      describe() as dispatcher
        -> shape as Shape
        <- rtn as String: "some " + shape.kind()

      //The handler lives beside its dispatcher

  defines program

    Describe()
      stdout <- Stdout()
      describer <- Describer()
      shapes as List of Shape: [Shape(), Circle()]
      for shape in shapes
        stdout.println(describer.describe(shape))