make getType nodes of generic insts have full inst type (#22655)

fixes #22639 for the third time

Nodes generated by `getType` for `tyGenericInst` types, instead of
having the original `tyGenericInst` type, will have the type of the last
child (due to the `mapTypeToAst` calls which set the type to the given
argument). This will cause subsequent `getType` calls to lose
information and think it's OK to use the sym of the instantiated type
rather than fully expand the generic instantiation.

To prevent this, update the type of the node from the `mapTypeToAst`
calls to the full generic instantiation type.
This commit is contained in:
metagn
2023-09-07 06:30:37 +03:00
committed by GitHub
parent b9f039e0c3
commit ed9e3cba07
2 changed files with 39 additions and 0 deletions

View File

@@ -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)

View File

@@ -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]