Skip to content

Generics + inheritable non-ref objects: type issue #7713

@mratsim

Description

@mratsim

Doing InheritedType is RootType returns true when no generics are involved but false when they are.
Concepts don't have such issue.

Test case:

import macros

## 1. Sanity check

echo "\n 1. Sanity check"

type Foo = object {.inheritable.}
type Bar = object of Foo
type Baz = object of Foo

proc do_smth(x: Foo) =
  echo "got Foo"

proc do_smth(x: Bar) =
  echo "got Bar"

proc do_smth(x: Baz) =
  echo "got Baz"

block:
  var a: Baz
  do_smth(a)    # Got Baz
  echo a is Foo # True

##########################################
echo "\n 2. Generics stack inheritable vs concepts"

type
  TrainableLayer[T] = object {.inheritable.}
    weight: seq[T]
    bias: seq[T]

  Conv2DLayer[T] = object of TrainableLayer[T]
  LinearLayer[T] = object of TrainableLayer[T]

  Trainable[T] = concept layer
    layer.weight is seq[T]
    layer.bias   is seq[T]

type ExampleModel[TT] = object
  cv1: Conv2DLayer[TT]
  classifier: LinearLayer[TT]

block:
  var a: ExampleModel[int]

  for field, val in a.fieldPairs:
    echo "\n   Field: " & field.astToStr
    echo "Trainable: " & $(val is Trainable)
    echo "TrainableLayer: " & $(val is TrainableLayer) # <---- Doesn't work
    echo "Conv2D: " & $(val is Conv2DLayer)
    echo "Linear: " & $(val is LinearLayer)

  #    Field: "cv1"
  # Trainable: true        <---- Concepts works
  # TrainableLayer: false  <---- Doesn't work
  # Conv2D: true
  # Linear: false

  #    Field: "classifier"
  # Trainable: true
  # TrainableLayer: false <---- Doesn't work
  # Conv2D: false
  # Linear: true


##########################################
echo "\n 3. Concrete stack inheritable vs concepts"

type
  TrainableLayer2 = object {.inheritable.}
    weight: int
    bias: int

  Conv2DLayer2 = object of TrainableLayer2
  LinearLayer2 = object of TrainableLayer2

  Trainable2 = concept layer
    layer.weight is int
    layer.bias   is int

type ExampleModel2 = object
  ## Holds the Trainable layers
  cv1: Conv2DLayer2
  classifier: LinearLayer2

block:
  var a: ExampleModel2

  for field, val in a.fieldPairs:
    echo "\n   Field: " & field.astToStr
    echo "Trainable: " & $(val is Trainable2)
    echo "TrainableLayer: " & $(val is TrainableLayer2) # <------ Works
    echo "Conv2D: " & $(val is Conv2DLayer2)
    echo "Linear: " & $(val is LinearLayer2)

  #    Field: "classifier"
  # Trainable: true
  # TrainableLayer: true  <------ Works
  # Conv2D: false
  # Linear: true

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions