diff options
-rw-r--r-- | compiler/vmdeps.nim | 4 | ||||
-rw-r--r-- | tests/generics/timpl_ast.nim | 35 |
2 files changed, 39 insertions, 0 deletions
diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim index 863896419..a47d034c7 100644 --- a/compiler/vmdeps.nim +++ b/compiler/vmdeps.nim @@ -133,6 +133,8 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo; if inst: if allowRecursion: result = mapTypeToAstR(t.lastSon, info) + # keep original type info for getType calls on the output node: + result.typ = t else: result = newNodeX(nkBracketExpr) #result.add mapTypeToAst(t.lastSon, info) @@ -141,6 +143,8 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo; result.add mapTypeToAst(t[i], info) else: result = mapTypeToAstX(cache, t.lastSon, info, idgen, inst, allowRecursion) + # keep original type info for getType calls on the output node: + result.typ = t of tyGenericBody: if inst: result = mapTypeToAstR(t.lastSon, info) diff --git a/tests/generics/timpl_ast.nim b/tests/generics/timpl_ast.nim index 016128e30..97fe128cd 100644 --- a/tests/generics/timpl_ast.nim +++ b/tests/generics/timpl_ast.nim @@ -43,3 +43,38 @@ block: # issues #9899, ##14708 macro parse(s: static string) = result = parseStmt(s) parse("type " & implRepr(Option)) + +block: # issue #22639 + type + Spectrum[N: static int] = object + data: array[N, float] + AngleInterpolator = object + data: seq[Spectrum[60]] + proc initInterpolator(num: int): AngleInterpolator = + result = AngleInterpolator() + for i in 0 ..< num: + result.data.add Spectrum[60]() + macro genCompatibleTuple(t: typed): untyped = + let typ = t.getType[1].getTypeImpl[2] + result = nnkTupleTy.newTree() + for i, ch in typ: # is `nnkObjectTy` + result.add nnkIdentDefs.newTree(ident(ch[0].strVal), # ch is `nnkIdentDefs` + ch[1], + newEmptyNode()) + proc fullSize[T: object | tuple](x: T): int = + var tmp: genCompatibleTuple(T) + result = 0 + for field, val in fieldPairs(x): + result += sizeof(val) + doAssert result == sizeof(tmp) + + let reflectivity = initInterpolator(1) + for el in reflectivity.data: + doAssert fullSize(el) == sizeof(el) + doAssert fullSize(reflectivity.data[0]) == sizeof(reflectivity.data[0]) + doAssert genCompatibleTuple(Spectrum[60]) is tuple[data: array[60, float]] + doAssert genCompatibleTuple(Spectrum[120]) is tuple[data: array[120, float]] + type Foo[T] = object + data: T + doAssert genCompatibleTuple(Foo[int]) is tuple[data: int] + doAssert genCompatibleTuple(Foo[float]) is tuple[data: float] |