Skip to content

regression: can't get head Foo of Foo[T] #9855

Closed
@timotheecour

Description

@timotheecour

/cc @Araq

while reviving #8554 I noticed my unittests are now failing, there's a regression since 0.19.0

Nim Compiler Version 0.19.0
nim c -r test.nim # works
Nim Compiler Version 0.19.9 [MacOSX: amd64]
Compiled at 2018-12-03
Copyright (c) 2006-2018 by Andreas Rumpf

git hash: f86b827d9e10f0178f1bb89d1c7df8c6b7b7eba0
active boot switches: -d:release

nim c -r test.nim # fails
Error: unhandled exception: /Users/timothee/git_clone/nim/Nim/tests/stdlib/tsugar2.nim(36, 12) `extractGeneric(Foo2, -1) is Foo`  [AssertionError]
=> fails here: `doAssert extractGeneric(Foo2, -1) is Foo`
import macros

macro extractGeneric*(T: typedesc, index:static[int]): untyped =
  ## extract generic type numbered ``index`` used to construct ``T``. Note:
  ## ``-1`` returns ``Foo`` in ``Foo[T]``
  runnableExamples:
    type Foo[T1, T2]=object
    doAssert extractGeneric(Foo[float, string], 0) is float
    doAssert extractGeneric(Foo[float, string], 1) is string
    doAssert extractGeneric(Foo[float, string], -1) is Foo

  var impl = getTypeImpl(T)
  expectKind(impl, nnkBracketExpr)
  impl = impl[1]
  while true:
    case impl.kind
      of nnkSym:
        impl = impl.getImpl
        continue
      of nnkTypeDef:
        impl = impl[2]
        continue
      of nnkBracketExpr:
        if index == -1:
          impl=impl[0] #return `Foo` in `Foo[T]`
        else:
          impl=impl[1+index]  #return `T` in `Foo[T]` (when index = 0)
        break
      else:
        error "internal error: impl.kind: " & $impl.kind
  impl

block extractGeneric:
  type Foo[T1, T2]=object
  type Foo2=Foo[float, string]
  doAssert extractGeneric(Foo2, -1) is Foo
  doAssert extractGeneric(Foo2, 0) is float
  doAssert extractGeneric(Foo2, 1) is string
  doAssert extractGeneric(Foo[float, string], 1) is string
  # doAssert extractGeneric(Foo[float, string], -1) is Foo
  # workaround for seq[int].T not working,
  # see https://github.com/nim-lang/Nim/issues/8433
  doAssert extractGeneric(seq[int], 0) is int
  doAssert extractGeneric(seq[seq[string]], 0) is seq[string]
  # doAssert not compiles(extractGeneric(seq[int], 1))
  doAssert extractGeneric(seq[int], -1) is seq

  type Foo3[T] = T
  doAssert extractGeneric(Foo3[int], 0) is int

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