mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-31 10:22:15 +00:00
fixes #5383
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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':
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user