E06060: a generic type does not support private or protected constructors

Category: E06xxx Type hierarchy checks · Reported in phase: SYMBOL_DEFINITION · Classification: GENERIC_CONSTRUCTORS_MUST_BE_PUBLIC · All error codes

What went wrong

A generic type needs public constructors so the type can be parameterised and constructed - and inferred from its arguments - from any context. Protected is never allowed, and neither is a private constructor that takes parameters (type inference uses it). The one exception is the no-argument default constructor: it may be declared 'default private' when the generic has properties of type T with no initial value, so nothing outside can build a partly initialised object.

Worked examples

Compilable examples demonstrating this error and the correct fix:

How to fix it

  1. Remove 'protected' from every constructor of the generic type
  2. Remove 'private' from any constructor that takes parameters
  3. Keep 'default private' only on the no-argument constructor, and only where uninitialised T properties make a public one unsafe

Rationale

Generic types are designed for reuse with ANY valid type parameter. A hidden parameterised constructor would stop 'Container(item)' from inferring 'Container of String', defeating the purpose of the generic.

Common causes

  • Applying encapsulation patterns from non-generic types
  • Wanting to control construction (keep the constructors public and validate with 'require' instead)
  • Copy-pasting from non-generic class

See also

  • E06060: protected or private parameterised constructor in a generic (this error)
  • E06040: missing required constructor
  • E07175: default constructor must be private (uninitialised properties)
  • E06180: accessing inaccessible method (general case)

Examples

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

Fails with E06060: a generic type does not support private or protected constructors

#!ek9
defines module error.e06060.bad

  defines class

    Box of type T
      //Protected is never allowed
      default protected Box()

      //Private is allowed only on the no-argument constructor
      default private Box()
        -> item as T

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

Fixed: Leave a generic type's constructors public (no access modifier)

#!ek9
defines module error.e06060.good

  defines class

    Box of type T
      default Box()

      default Box()
        -> item as T

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

Fixed: The no-argument default constructor may be private, when T properties have no initial value

#!ek9
defines module error.e06060.good.private

  defines class

    Holder of type T
      item as T?

      default private Holder()

      Holder()
        -> item as T
        this.item: item

      contents()
        <- rtn as T: item

      default operator ?

Questions and answers

These Q&A entries show E06060 and its fix: