Skip to content

Commit

Permalink
fixes #9381; Fix double evaluation of types in generic objects (#23072)
Browse files Browse the repository at this point in the history
fixes #9381

(cherry picked from commit 1b7b0d6)
  • Loading branch information
Pylgos authored and narimiran committed Apr 19, 2024
1 parent 3d4ec68 commit fca71c4
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 5 deletions.
19 changes: 14 additions & 5 deletions compiler/semtypinst.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down Expand Up @@ -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`
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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)

Expand Down
14 changes: 14 additions & 0 deletions tests/generics/tgenerics_various.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit fca71c4

Please sign in to comment.