Closed
Description
/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