E06080: the constraining type with a generic/template cannot be a function

Category: E06xxx Type hierarchy checks · Reported in phase: EXPLICIT_TYPE_SYMBOL_DEFINITION · Classification: CONSTRAINED_FUNCTIONS_NOT_SUPPORTED · All error codes

What went wrong

When constraining a generic type parameter, you must use a class, record, or trait - NOT a function type. Generic constraints exist to enable method access on T, and functions have no methods.

Worked examples

Compilable examples demonstrating this error and the correct fix:

  • ek9 -q 647 (Why cannot I use a function type as a generic constraint?)

Rationale

Generic constraints enable calling methods on the parameterized type T. By constraining T to a class/trait, you can call methods defined on that constraining type. Functions only support () invocation - they have no methods to access, so constraining to a function is pointless.

How to fix it

  1. Define a class, record, or trait with the methods you need
  2. Constrain your generic to that type: 'of type T constrain by MyBaseClass'
  3. If you need function behavior, pass functions as parameters instead

Pass function as parameter

Where you wanted "any T that can be called", take the function as a parameter instead: a parameter typed 'Function of (String, Integer)' (or your own function type) can be called inside the method. The [EXAMPLE] section below shows a type parameter constrained by a function, then by a trait and by a component.

Common causes

  • Wanting to constrain T to "anything callable" (use Function parameter instead)
  • Confusing function types with class types
  • Not realizing constraints are for method access

See also

  • E06080: function type used as constraint (this error)
  • E06130: constraining type missing required constructors

Examples

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

Fails with E06080: the constraining type with a generic/template cannot be a function

#!ek9
defines module error.e06080.bad

  defines class

    //A type parameter can be constrained by a type, never by a function
    Checked of type T constrain by checkFunction
      default Checked()

      Checked()
        -> item as T
        require item?

      check()
        -> item as T
        <- rtn as Boolean: item?

    AlsoChecked of type T constrain by abstractCheck
      default AlsoChecked()

      AlsoChecked()
        -> item as T
        require item?

      check()
        -> item as T
        <- rtn as Boolean: item?

  defines function

    checkFunction()
      -> amount as Integer
      <- rtn as Boolean: amount?

    abstractCheck() as abstract
      -> amount as Integer
      <- rtn as Boolean?

Fixed: Constrain the type parameter by a trait, class or component instead

#!ek9
defines module error.e06080.good

  defines trait

    Checkable
      check()
        -> text as String
        <- rtn as Boolean: text?

  defines class

    ByTrait of type T constrain by Checkable
      default ByTrait()

      ByTrait()
        -> item as T
        require item?

      check()
        -> item as T
        <- rtn as Boolean: item?

    ByComponent of type T constrain by Checker
      default ByComponent()

      ByComponent()
        -> item as T
        require item?

      check()
        -> item as T
        <- rtn as Boolean: item?

  defines component

    Checker as open
      check()
        -> text as String
        <- rtn as Boolean: text?

Questions and answers

These Q&A entries show E06080 and its fix: