E04010: is not a candidate to be constrained

Category: E04xxx Reference checks · Reported in phase: TYPE_HIERARCHY_CHECKS · Classification: TYPE_CANNOT_BE_CONSTRAINED · All error codes

What went wrong

You're trying to apply a type constraint to a type that cannot be constrained. Only certain built-in types support the constraining mechanism.

Worked examples

Compilable examples demonstrating this error and the correct fix:

  • ek9 -q 956 (Why can't I constrain a Boolean type in EK9?)

Constrainable types

  • String (length, pattern constraints)
  • Integer, Float (range constraints)
  • Date, Time, DateTime (range constraints)
  • Duration, Milliseconds (range constraints)
  • Dimension, Money (range constraints)

[NON-CONSTRAINABLE]

  • Classes, Records, Traits
  • Generic parameterized types
  • Function types

How to fix it

  • Use a constrainable base type (String, Integer, etc.)
  • For custom validation, implement validation in a class instead

Common causes

  • Trying to constrain a custom class or record
  • Confusing type aliasing with constraining

Examples

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

Fails with E04010: is not a candidate to be constrained

#!ek9
defines module error.e04010.bad

  defines type
    Index as Integer

    Name as String

    //We will allow aliasing or typing of other constructs
    ValidOther as R1

    //But not functions and selected other classes.

    Other1 as FunctionA

    Other2 as Boolean

    Other3 as JSON

    Other4 as Bits

    //A constrained type is a one-level concept: a base type limited to a range of values. Once
    //constrained it is its own distinct type and CANNOT itself be used as a base — neither further
    //constrained nor aliased. To make a more specific type, constrain the base type directly.
    PositiveInt as Integer constrain as
      > 0

    Other5 as PositiveInt constrain as
      < 100

    Other6 as PositiveInt

  defines record
    R1
      count <- 0
      default R1()
      //A copy constructor, so R1 can be an alias or constrained base (E06131 without one).
      R1()
        -> other as R1
        count: Integer(other.count)
      default operator

  defines function
    FunctionA()
      <- rtn <- true

Fixed: Constrain a value type, a record or a class - and constrain the base type directly

#!ek9
defines module error.e04010.good

  defines type

    Index as Integer

    Name as String

    ValidOther as R1

    PositiveInt as Integer constrain as
      > 0

    //Not 'PositiveInt constrain as < 100': constrain Integer itself, once
    Percentage as Integer constrain as
      > 0 and < 100

  defines record

    R1
      count <- 0
      default R1()
      R1()
        -> other as R1
        count: Integer(other.count)
      default operator

Questions and answers

These Q&A entries show E04010 and its fix: