fixes #9381; Fix double evaluation of types in generic objects (#23072)

fixes https://github.com/nim-lang/Nim/issues/9381

(cherry picked from commit 1b7b0d69db)
This commit is contained in:
Pylgos
2023-12-14 17:55:04 +09:00
committed by narimiran
parent 3d4ec68e54
commit fca71c4bb4
2 changed files with 28 additions and 5 deletions

View File

@@ -88,7 +88,7 @@ type
recursionLimit: int
proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType
proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym
proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym, t: PType): PSym
proc replaceTypeVarsN*(cl: var TReplTypeVars, n: PNode; start=0; expectedType: PType = nil): PNode
proc initLayeredTypeMap*(pt: TIdTable): LayeredIdTable =
@@ -129,7 +129,12 @@ proc prepareNode(cl: var TReplTypeVars, n: PNode): PNode =
else: t.n
result = copyNode(n)
result.typ = t
if result.kind == nkSym: result.sym = replaceTypeVarsS(cl, n.sym)
if result.kind == nkSym:
result.sym =
if n.typ != nil and n.typ == n.sym.typ:
replaceTypeVarsS(cl, n.sym, result.typ)
else:
replaceTypeVarsS(cl, n.sym, replaceTypeVarsT(cl, n.sym.typ))
let isCall = result.kind in nkCallKinds
for i in 0..<n.safeLen:
# XXX HACK: ``f(a, b)``, avoid to instantiate `f`
@@ -224,7 +229,11 @@ proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode; start=0; expectedType: PT
discard
of nkOpenSymChoice, nkClosedSymChoice: result = n
of nkSym:
result.sym = replaceTypeVarsS(cl, n.sym)
result.sym =
if n.typ != nil and n.typ == n.sym.typ:
replaceTypeVarsS(cl, n.sym, result.typ)
else:
replaceTypeVarsS(cl, n.sym, replaceTypeVarsT(cl, n.sym.typ))
if result.sym.typ.kind == tyVoid:
# don't add the 'void' field
result = newNodeI(nkRecList, n.info)
@@ -266,7 +275,7 @@ proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode; start=0; expectedType: PT
for i in start..<n.len:
result[i] = replaceTypeVarsN(cl, n[i])
proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym =
proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym, t: PType): PSym =
if s == nil: return nil
# symbol is not our business:
if cl.owner != nil and s.owner != cl.owner:
@@ -307,7 +316,7 @@ proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym =
incl(result.flags, sfFromGeneric)
#idTablePut(cl.symMap, s, result)
result.owner = s.owner
result.typ = replaceTypeVarsT(cl, s.typ)
result.typ = t
if result.kind != skType:
result.ast = replaceTypeVarsN(cl, s.ast)

View File

@@ -231,3 +231,17 @@ doSomething(identity((1, 2)))
proc myProc[T, U](x: T or U) = discard
myProc[int, string](x = 2)
block: # issue #9381
var evalCount {.compileTime.} = 0
macro test(t: typed): untyped =
inc evalCount
t
type GenericObj[T] = object
f: test(T)
var x: GenericObj[int]
static: doAssert evalCount == 1