Skip to content

Commit

Permalink
fixes #5383
Browse files Browse the repository at this point in the history
  • Loading branch information
Araq committed Feb 16, 2017
1 parent 8de6c39 commit 71026ce
Show file tree
Hide file tree
Showing 11 changed files with 60 additions and 17 deletions.
3 changes: 1 addition & 2 deletions compiler/ast.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1541,8 +1541,7 @@ proc skipGenericOwner*(s: PSym): PSym =
## Generic instantiations are owned by their originating generic
## symbol. This proc skips such owners and goes straight to the owner
## of the generic itself (the module or the enclosing proc).
result = if s.kind in skProcKinds and {sfGenSym, sfFromGeneric} * s.flags ==
{sfFromGeneric}:
result = if s.kind in skProcKinds and sfFromGeneric in s.flags:
s.owner.owner
else:
s.owner
Expand Down
15 changes: 15 additions & 0 deletions compiler/sem.nim
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,16 @@ proc commonType*(x, y: PType): PType =
proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym =
result = newSym(kind, considerQuotedIdent(n), getCurrOwner(), n.info)

proc getGenSym(c: PContext; s: PSym): PSym =
var it = c.p
while it != nil:
result = get(it, s)
if result != nil:
#echo "got from table ", result.name.s, " ", result.info
return result
it = it.next
result = s

proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym =
proc `$`(kind: TSymKind): string = substr(system.`$`(kind), 2).toLowerAscii

Expand All @@ -178,6 +188,11 @@ proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym =
if result.kind != kind:
localError(n.info, "cannot use symbol of kind '" &
$result.kind & "' as a '" & $kind & "'")
if sfGenSym in result.flags and result.kind notin {skTemplate, skMacro, skParam}:
# declarative context, so produce a fresh gensym:
result = copySym(result)
result.ast = n.sym.ast
put(c.p, n.sym, result)
# when there is a nested proc inside a template, semtmpl
# will assign a wrong owner during the first pass over the
# template; we must fix it here: see #909
Expand Down
10 changes: 10 additions & 0 deletions compiler/semdata.nim
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type
next*: PProcCon # used for stacking procedure contexts
wasForwarded*: bool # whether the current proc has a separate header
bracketExpr*: PNode # current bracket expression (for ^ support)
mapping*: TIdTable

TInstantiationPair* = object
genericSym*: PSym
Expand Down Expand Up @@ -147,6 +148,15 @@ proc lastOptionEntry*(c: PContext): POptionEntry =

proc popProcCon*(c: PContext) {.inline.} = c.p = c.p.next

proc put*(p: PProcCon; key, val: PSym) =
if p.mapping.data == nil: initIdTable(p.mapping)
#echo "put into table ", key.info
p.mapping.idTablePut(key, val)

proc get*(p: PProcCon; key: PSym): PSym =
if p.mapping.data == nil: return nil
result = PSym(p.mapping.idTableGet(key))

proc newOptionEntry*(): POptionEntry =
new(result)
result.options = gOptions
Expand Down
3 changes: 2 additions & 1 deletion compiler/semexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -922,7 +922,8 @@ proc readTypeParameter(c: PContext, typ: PType,
return newSymNode(copySym(tParam.sym).linkTo(foundTyp), info)
#echo "came here: returned nil"

proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
let s = getGenSym(c, sym)
case s.kind
of skConst:
markUsed(n.info, s)
Expand Down
7 changes: 4 additions & 3 deletions compiler/seminst.nim
Original file line number Diff line number Diff line change
Expand Up @@ -106,15 +106,16 @@ proc freshGenSyms(n: PNode, owner, orig: PSym, symMap: var TIdTable) =
#if n.kind == nkSym and sfGenSym in n.sym.flags:
# if n.sym.owner != orig:
# echo "symbol ", n.sym.name.s, " orig ", orig, " owner ", n.sym.owner
if n.kind == nkSym and {sfGenSym, sfFromGeneric} * n.sym.flags == {sfGenSym}: # and
if n.kind == nkSym and sfGenSym in n.sym.flags: # and
# (n.sym.owner == orig or n.sym.owner.kind in {skPackage}):
let s = n.sym
var x = PSym(idTableGet(symMap, s))
if x == nil:
if x != nil:
n.sym = x
when false:
x = copySym(s, false)
x.owner = owner
idTablePut(symMap, s, x)
n.sym = x
else:
for i in 0 .. <safeLen(n): freshGenSyms(n.sons[i], owner, orig, symMap)

Expand Down
1 change: 1 addition & 0 deletions compiler/semstmts.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1345,6 +1345,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
proc determineType(c: PContext, s: PSym) =
if s.typ != nil: return
#if s.magic != mNone: return
#if s.ast.isNil: return
discard semProcAux(c, s.ast, s.kind, {}, stepDetermineType)

proc semIterator(c: PContext, n: PNode): PNode =
Expand Down
2 changes: 1 addition & 1 deletion compiler/semtempl.nim
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ proc newGenSym(kind: TSymKind, n: PNode, c: var TemplCtx): PSym =
result = newSym(kind, considerQuotedIdent(n), c.owner, n.info)
incl(result.flags, sfGenSym)
incl(result.flags, sfShadowed)
if c.scopeN == 0: incl(result.flags, sfFromGeneric)
#if c.scopeN == 0: incl(result.flags, sfFromGeneric)

proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) =
# locals default to 'gensym':
Expand Down
9 changes: 5 additions & 4 deletions compiler/semtypes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ proc semOrdinal(c: PContext, n: PNode, prev: PType): PType =

proc semTypeIdent(c: PContext, n: PNode): PSym =
if n.kind == nkSym:
result = n.sym
result = getGenSym(c, n.sym)
else:
when defined(nimfix):
result = pickSym(c, n, skType)
Expand Down Expand Up @@ -1319,8 +1319,9 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
prev.id = s.typ.id
result = prev
of nkSym:
if n.sym.kind == skType and n.sym.typ != nil:
var t = n.sym.typ
let s = getGenSym(c, n.sym)
if s.kind == skType and s.typ != nil:
var t = s.typ
let alias = maybeAliasType(c, t, prev)
if alias != nil:
result = alias
Expand All @@ -1332,7 +1333,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
markUsed(n.info, n.sym)
styleCheckUse(n.info, n.sym)
else:
if n.sym.kind != skError: localError(n.info, errTypeExpected)
if s.kind != skError: localError(n.info, errTypeExpected)
result = newOrPrevType(tyError, prev, c)
of nkObjectTy: result = semObjectNode(c, n, prev)
of nkTupleTy: result = semTuple(c, n, prev)
Expand Down
5 changes: 4 additions & 1 deletion compiler/transf.nim
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,10 @@ proc transform(c: PTransf, n: PNode): PTransNode =
else:
result = transformSons(c, n)
of nkIdentDefs, nkConstDef:
result = transformSons(c, n)
result = n.PTransNode
#transformSons(c, n)
let L = n.len-1
result[L] = transform(c, n.sons[L])
# XXX comment handling really sucks:
if importantComments():
PNode(result).comment = n.comment
Expand Down
13 changes: 13 additions & 0 deletions tests/template/tgensymregression.nim
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,16 @@ proc foo(): void =
echo repr(v1 *** v2)

foo()

# bug #5383
import sequtils

proc zipWithIndex[A](ts: seq[A]): seq[(int, A)] =
toSeq(pairs(ts))

proc main =
discard zipWithIndex(@["foo", "bar"])
discard zipWithIndex(@[1, 2])
discard zipWithIndex(@[true, false])

main()
9 changes: 4 additions & 5 deletions tests/template/tparams_gensymed.nim
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import macros

# Test that parameters are properly gensym'ed finally:

template genNodeKind(kind, name: expr): stmt =
proc name*(children: varargs[PNimrodNode]): PNimrodNode {.compiletime.}=
template genNodeKind(kind, name: untyped) =
proc name*(children: varargs[NimNode]): NimNode {.compiletime.}=
result = newNimNode(kind)
for c in children:
result.add(c)
Expand All @@ -22,7 +22,7 @@ type Something = object

proc testA(x: Something) = discard

template def(name: expr) {.immediate.} =
template def(name: untyped) =
proc testB[T](reallyUniqueName: T) =
`test name`(reallyUniqueName)
def A
Expand All @@ -35,8 +35,7 @@ testB(x)
# Test that templates in generics still work (regression to fix the
# regression...)

template forStatic(index: expr, slice: Slice[int], predicate: stmt):
stmt {.immediate.} =
template forStatic(index, slice, predicate: untyped) =
const a = slice.a
const b = slice.b
when a <= b:
Expand Down

0 comments on commit 71026ce

Please sign in to comment.