fixes #5383
This commit is contained in:
parent
8de6c39f87
commit
71026cec6e
11 changed files with 60 additions and 17 deletions
|
|
@ -1541,8 +1541,7 @@ proc skipGenericOwner*(s: PSym): PSym =
|
||||||
## Generic instantiations are owned by their originating generic
|
## Generic instantiations are owned by their originating generic
|
||||||
## symbol. This proc skips such owners and goes straight to the owner
|
## symbol. This proc skips such owners and goes straight to the owner
|
||||||
## of the generic itself (the module or the enclosing proc).
|
## of the generic itself (the module or the enclosing proc).
|
||||||
result = if s.kind in skProcKinds and {sfGenSym, sfFromGeneric} * s.flags ==
|
result = if s.kind in skProcKinds and sfFromGeneric in s.flags:
|
||||||
{sfFromGeneric}:
|
|
||||||
s.owner.owner
|
s.owner.owner
|
||||||
else:
|
else:
|
||||||
s.owner
|
s.owner
|
||||||
|
|
|
||||||
|
|
@ -168,6 +168,16 @@ proc commonType*(x, y: PType): PType =
|
||||||
proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym =
|
proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym =
|
||||||
result = newSym(kind, considerQuotedIdent(n), getCurrOwner(), n.info)
|
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 newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym =
|
||||||
proc `$`(kind: TSymKind): string = substr(system.`$`(kind), 2).toLowerAscii
|
proc `$`(kind: TSymKind): string = substr(system.`$`(kind), 2).toLowerAscii
|
||||||
|
|
||||||
|
|
@ -178,6 +188,11 @@ proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym =
|
||||||
if result.kind != kind:
|
if result.kind != kind:
|
||||||
localError(n.info, "cannot use symbol of kind '" &
|
localError(n.info, "cannot use symbol of kind '" &
|
||||||
$result.kind & "' as a '" & $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
|
# when there is a nested proc inside a template, semtmpl
|
||||||
# will assign a wrong owner during the first pass over the
|
# will assign a wrong owner during the first pass over the
|
||||||
# template; we must fix it here: see #909
|
# template; we must fix it here: see #909
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ type
|
||||||
next*: PProcCon # used for stacking procedure contexts
|
next*: PProcCon # used for stacking procedure contexts
|
||||||
wasForwarded*: bool # whether the current proc has a separate header
|
wasForwarded*: bool # whether the current proc has a separate header
|
||||||
bracketExpr*: PNode # current bracket expression (for ^ support)
|
bracketExpr*: PNode # current bracket expression (for ^ support)
|
||||||
|
mapping*: TIdTable
|
||||||
|
|
||||||
TInstantiationPair* = object
|
TInstantiationPair* = object
|
||||||
genericSym*: PSym
|
genericSym*: PSym
|
||||||
|
|
@ -147,6 +148,15 @@ proc lastOptionEntry*(c: PContext): POptionEntry =
|
||||||
|
|
||||||
proc popProcCon*(c: PContext) {.inline.} = c.p = c.p.next
|
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 =
|
proc newOptionEntry*(): POptionEntry =
|
||||||
new(result)
|
new(result)
|
||||||
result.options = gOptions
|
result.options = gOptions
|
||||||
|
|
|
||||||
|
|
@ -922,7 +922,8 @@ proc readTypeParameter(c: PContext, typ: PType,
|
||||||
return newSymNode(copySym(tParam.sym).linkTo(foundTyp), info)
|
return newSymNode(copySym(tParam.sym).linkTo(foundTyp), info)
|
||||||
#echo "came here: returned nil"
|
#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
|
case s.kind
|
||||||
of skConst:
|
of skConst:
|
||||||
markUsed(n.info, s)
|
markUsed(n.info, s)
|
||||||
|
|
|
||||||
|
|
@ -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.kind == nkSym and sfGenSym in n.sym.flags:
|
||||||
# if n.sym.owner != orig:
|
# if n.sym.owner != orig:
|
||||||
# echo "symbol ", n.sym.name.s, " orig ", orig, " owner ", n.sym.owner
|
# 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}):
|
# (n.sym.owner == orig or n.sym.owner.kind in {skPackage}):
|
||||||
let s = n.sym
|
let s = n.sym
|
||||||
var x = PSym(idTableGet(symMap, s))
|
var x = PSym(idTableGet(symMap, s))
|
||||||
if x == nil:
|
if x != nil:
|
||||||
|
n.sym = x
|
||||||
|
when false:
|
||||||
x = copySym(s, false)
|
x = copySym(s, false)
|
||||||
x.owner = owner
|
x.owner = owner
|
||||||
idTablePut(symMap, s, x)
|
idTablePut(symMap, s, x)
|
||||||
n.sym = x
|
|
||||||
else:
|
else:
|
||||||
for i in 0 .. <safeLen(n): freshGenSyms(n.sons[i], owner, orig, symMap)
|
for i in 0 .. <safeLen(n): freshGenSyms(n.sons[i], owner, orig, symMap)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1345,6 +1345,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||||
proc determineType(c: PContext, s: PSym) =
|
proc determineType(c: PContext, s: PSym) =
|
||||||
if s.typ != nil: return
|
if s.typ != nil: return
|
||||||
#if s.magic != mNone: return
|
#if s.magic != mNone: return
|
||||||
|
#if s.ast.isNil: return
|
||||||
discard semProcAux(c, s.ast, s.kind, {}, stepDetermineType)
|
discard semProcAux(c, s.ast, s.kind, {}, stepDetermineType)
|
||||||
|
|
||||||
proc semIterator(c: PContext, n: PNode): PNode =
|
proc semIterator(c: PContext, n: PNode): PNode =
|
||||||
|
|
|
||||||
|
|
@ -172,7 +172,7 @@ proc newGenSym(kind: TSymKind, n: PNode, c: var TemplCtx): PSym =
|
||||||
result = newSym(kind, considerQuotedIdent(n), c.owner, n.info)
|
result = newSym(kind, considerQuotedIdent(n), c.owner, n.info)
|
||||||
incl(result.flags, sfGenSym)
|
incl(result.flags, sfGenSym)
|
||||||
incl(result.flags, sfShadowed)
|
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) =
|
proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) =
|
||||||
# locals default to 'gensym':
|
# locals default to 'gensym':
|
||||||
|
|
|
||||||
|
|
@ -297,7 +297,7 @@ proc semOrdinal(c: PContext, n: PNode, prev: PType): PType =
|
||||||
|
|
||||||
proc semTypeIdent(c: PContext, n: PNode): PSym =
|
proc semTypeIdent(c: PContext, n: PNode): PSym =
|
||||||
if n.kind == nkSym:
|
if n.kind == nkSym:
|
||||||
result = n.sym
|
result = getGenSym(c, n.sym)
|
||||||
else:
|
else:
|
||||||
when defined(nimfix):
|
when defined(nimfix):
|
||||||
result = pickSym(c, n, skType)
|
result = pickSym(c, n, skType)
|
||||||
|
|
@ -1319,8 +1319,9 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
prev.id = s.typ.id
|
prev.id = s.typ.id
|
||||||
result = prev
|
result = prev
|
||||||
of nkSym:
|
of nkSym:
|
||||||
if n.sym.kind == skType and n.sym.typ != nil:
|
let s = getGenSym(c, n.sym)
|
||||||
var t = n.sym.typ
|
if s.kind == skType and s.typ != nil:
|
||||||
|
var t = s.typ
|
||||||
let alias = maybeAliasType(c, t, prev)
|
let alias = maybeAliasType(c, t, prev)
|
||||||
if alias != nil:
|
if alias != nil:
|
||||||
result = alias
|
result = alias
|
||||||
|
|
@ -1332,7 +1333,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
markUsed(n.info, n.sym)
|
markUsed(n.info, n.sym)
|
||||||
styleCheckUse(n.info, n.sym)
|
styleCheckUse(n.info, n.sym)
|
||||||
else:
|
else:
|
||||||
if n.sym.kind != skError: localError(n.info, errTypeExpected)
|
if s.kind != skError: localError(n.info, errTypeExpected)
|
||||||
result = newOrPrevType(tyError, prev, c)
|
result = newOrPrevType(tyError, prev, c)
|
||||||
of nkObjectTy: result = semObjectNode(c, n, prev)
|
of nkObjectTy: result = semObjectNode(c, n, prev)
|
||||||
of nkTupleTy: result = semTuple(c, n, prev)
|
of nkTupleTy: result = semTuple(c, n, prev)
|
||||||
|
|
|
||||||
|
|
@ -869,7 +869,10 @@ proc transform(c: PTransf, n: PNode): PTransNode =
|
||||||
else:
|
else:
|
||||||
result = transformSons(c, n)
|
result = transformSons(c, n)
|
||||||
of nkIdentDefs, nkConstDef:
|
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:
|
# XXX comment handling really sucks:
|
||||||
if importantComments():
|
if importantComments():
|
||||||
PNode(result).comment = n.comment
|
PNode(result).comment = n.comment
|
||||||
|
|
|
||||||
|
|
@ -19,3 +19,16 @@ proc foo(): void =
|
||||||
echo repr(v1 *** v2)
|
echo repr(v1 *** v2)
|
||||||
|
|
||||||
foo()
|
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()
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import macros
|
||||||
|
|
||||||
# Test that parameters are properly gensym'ed finally:
|
# Test that parameters are properly gensym'ed finally:
|
||||||
|
|
||||||
template genNodeKind(kind, name: expr): stmt =
|
template genNodeKind(kind, name: untyped) =
|
||||||
proc name*(children: varargs[PNimrodNode]): PNimrodNode {.compiletime.}=
|
proc name*(children: varargs[NimNode]): NimNode {.compiletime.}=
|
||||||
result = newNimNode(kind)
|
result = newNimNode(kind)
|
||||||
for c in children:
|
for c in children:
|
||||||
result.add(c)
|
result.add(c)
|
||||||
|
|
@ -22,7 +22,7 @@ type Something = object
|
||||||
|
|
||||||
proc testA(x: Something) = discard
|
proc testA(x: Something) = discard
|
||||||
|
|
||||||
template def(name: expr) {.immediate.} =
|
template def(name: untyped) =
|
||||||
proc testB[T](reallyUniqueName: T) =
|
proc testB[T](reallyUniqueName: T) =
|
||||||
`test name`(reallyUniqueName)
|
`test name`(reallyUniqueName)
|
||||||
def A
|
def A
|
||||||
|
|
@ -35,8 +35,7 @@ testB(x)
|
||||||
# Test that templates in generics still work (regression to fix the
|
# Test that templates in generics still work (regression to fix the
|
||||||
# regression...)
|
# regression...)
|
||||||
|
|
||||||
template forStatic(index: expr, slice: Slice[int], predicate: stmt):
|
template forStatic(index, slice, predicate: untyped) =
|
||||||
stmt {.immediate.} =
|
|
||||||
const a = slice.a
|
const a = slice.a
|
||||||
const b = slice.b
|
const b = slice.b
|
||||||
when a <= b:
|
when a <= b:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue