E10030: use of a constructor directly on an abstract type is not permitted.

Category: E10xxx IR generation · Reported in phase: POST_RESOLUTION_CHECKS · Classification: CONSTRUCTOR_USED_ON_ABSTRACT_TYPE · All error codes

What went wrong

You're trying to create an instance of an ABSTRACT type directly. Abstract types cannot be instantiated - only concrete subtypes can.

IMPORTANT: Parameterizing an abstract generic type does NOT make it concrete.

  • 'Iterator of String' is STILL abstract
  • 'Consumer of String' is STILL abstract

THROUGH A GENERIC: every T() in a generic becomes a constructor call on the type that parameterises it. A generic whose no-arg constructor does 'item: T()', used with an abstract type ('Holder(square)' with 'square as Shape'), is this error - even when that constructor is private and never called.

Worked examples

Compilable examples demonstrating this error and the correct fix:

  • ek9 -q 841 (Why can't I instantiate an abstract generic type like Ite...)
  • ek9 -q 2020 (How do I write a generic type that can be parameterised w...)

Rationale

Abstract types define interfaces without full implementation. Parameterizing preserves abstract nature.

How to fix it

  1. Use a concrete subtype
  2. For function types, provide implementation body
  3. Get iterators from concrete collections
  4. When the abstract type reaches T() through a generic parameterisation, make that generic's no-arg constructor private and do not call T() in it - leave the T property unset and construct through the value constructor ('default private Holder()' plus 'Holder() -> initial as T'). Nothing can then observe the unset property: a construction call reaching the private no-arg is E08264.

Common causes

  • Calling a constructor on an abstract GENERIC type ('Iterator() of String'); on a non-generic abstract class or trait the error is E50080
  • Calling constructor on parameterized abstract generic
  • Forgetting generic parameterization preserves abstractness
  • A generic's T() (often 'item: T()' in its no-arg constructor) when the generic is parameterised with an abstract class or trait

See also

  • E10030: abstract type instantiation (this error)
  • E50080: non-generic abstract types (SignalHandler)
  • E08264: a construction call reaching a private constructor that leaves properties unset

Examples

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

Fails with E10030: use of a constructor directly on an abstract type is not permitted.

#!ek9
defines module error.e10030.bad

  defines class

    Shape as abstract
      area() as abstract
        <- rtn as Float?

      default operator ?

    Square extends Shape
      side as Float?

      default private Square()

      Square()
        -> sideLength as Float
        side: sideLength

      override area()
        <- rtn as Float: side * side

      default operator ?

    <?-
      The no-arg constructor is private and never called, but it calls T().
    -?>
    Holder of type T
      item as T?

      private Holder()
        item: T()

      Holder()
        -> initial as T
        item: initial

      get()
        <- rtn as T: item

      default operator ?

  defines function

    <?-
      Shape is abstract: parameterising Holder with it turns the private constructor's T() into Shape().
    -?>
    holdAbstract()
      square as Shape: Square(3.0)
      held <- Holder(square)
      require held?

Fixed: Leave the T property unset in a private no-arg constructor - no T() is needed

#!ek9
defines module error.e10030.good

  defines class

    Shape as abstract
      area() as abstract
        <- rtn as Float?
      default operator ?

    Square extends Shape
      side as Float?

      default private Square()

      Square()
        -> sideLength as Float
        side: sideLength

      override area()
        <- rtn as Float: side * side

      default operator ?

    Holder of type T
      item as T?

      default private Holder()

      Holder()
        -> initial as T
        item: initial

      get()
        <- rtn as T: item

      default operator ?

  defines function

    holdAbstract()
      <- rtn as Float?
      square as Shape: Square(3.0)
      held <- Holder(square)
      rtn: held.get().area()

Questions and answers

These Q&A entries show E10030 and its fix: