From abaf5d0bdba3a4908eec65199867831141ed8a55 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Sat, 4 Feb 2017 21:00:07 +0100 Subject: [PATCH] fixes #5285 --- compiler/ast.nim | 3 ++- compiler/seminst.nim | 11 +++++++++-- compiler/semtempl.nim | 11 +++++++++-- tests/template/tgensymregression.nim | 21 +++++++++++++++++++++ tests/template/typedescids.nim | 2 +- 5 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 tests/template/tgensymregression.nim diff --git a/compiler/ast.nim b/compiler/ast.nim index d9c886d7f4..be846e8dfc 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1541,7 +1541,8 @@ 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 sfFromGeneric in s.flags: + result = if s.kind in skProcKinds and {sfGenSym, sfFromGeneric} * s.flags == + {sfFromGeneric}: s.owner.owner else: s.owner diff --git a/compiler/seminst.nim b/compiler/seminst.nim index e1a65da742..9c57be0231 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -97,10 +97,17 @@ proc genericCacheGet(genericSym: PSym, entry: TInstantiation; if inst.compilesId == id and sameInstantiation(entry, inst[]): return inst.sym +when false: + proc `$`(x: PSym): string = + result = x.name.s & " " & " id " & $x.id + proc freshGenSyms(n: PNode, owner, orig: PSym, symMap: var TIdTable) = # we need to create a fresh set of gensym'ed symbols: - if n.kind == nkSym and sfGenSym in n.sym.flags and - (n.sym.owner == orig or n.sym.owner.kind == skPackage): + #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 + # (n.sym.owner == orig or n.sym.owner.kind in {skPackage}): let s = n.sym var x = PSym(idTableGet(symMap, s)) if x == nil: diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index b639288079..5dba125c2f 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -112,6 +112,7 @@ type toBind, toMixin, toInject: IntSet owner: PSym cursorInBody: bool # only for nimsuggest + scopeN: int bracketExpr: PNode template withBracketExpr(ctx, x, body: untyped) = @@ -141,8 +142,13 @@ proc isTemplParam(c: TemplCtx, n: PNode): bool {.inline.} = proc semTemplBody(c: var TemplCtx, n: PNode): PNode -proc openScope(c: var TemplCtx) = openScope(c.c) -proc closeScope(c: var TemplCtx) = closeScope(c.c) +proc openScope(c: var TemplCtx) = + openScope(c.c) + inc c.scopeN + +proc closeScope(c: var TemplCtx) = + dec c.scopeN + closeScope(c.c) proc semTemplBodyScope(c: var TemplCtx, n: PNode): PNode = openScope(c) @@ -166,6 +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) proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) = # locals default to 'gensym': diff --git a/tests/template/tgensymregression.nim b/tests/template/tgensymregression.nim new file mode 100644 index 0000000000..e73ff258dc --- /dev/null +++ b/tests/template/tgensymregression.nim @@ -0,0 +1,21 @@ + +template mathPerComponent(op: untyped): untyped = + proc op*[N,T](v,u: array[N,T]): array[N,T] {.inline.} = + for i in 0 ..< len(result): + result[i] = `*`(v[i], u[i]) + +mathPerComponent(`***`) +# bug #5285 +when true: + if isMainModule: + var v1: array[3, float64] + var v2: array[3, float64] + echo repr(v1 *** v2) + + +proc foo(): void = + var v1: array[4, float64] + var v2: array[4, float64] + echo repr(v1 *** v2) + +foo() diff --git a/tests/template/typedescids.nim b/tests/template/typedescids.nim index ebed49b173..1df2f69fb1 100644 --- a/tests/template/typedescids.nim +++ b/tests/template/typedescids.nim @@ -6,7 +6,7 @@ discard """ var i {.compileTime.} = 2 -template defineId*(t: typedesc): stmt = +template defineId*(t: typedesc) = const id {.genSym.} = i static: inc(i) proc idFor*(T: typedesc[t]): int {.inline, raises: [].} = id