diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2019-08-23 16:15:02 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-08-23 16:15:02 +0200 |
commit | b07694cd90ab7c6eb4660971ddb818b461d4eed8 (patch) | |
tree | a158993297748d4c55b6e069a6636eefcacd9865 /compiler/semtempl.nim | |
parent | f28a47ea7b9c579b172653c15dc2cc054adf599a (diff) | |
download | Nim-b07694cd90ab7c6eb4660971ddb818b461d4eed8.tar.gz |
new gensym handling (#11985)
* new .gensym implementation * make astspec test green again * introduce a --useVersion switch to group compatibility switches * fixes #10180 * fixes #11494 * fixes #11483 * object constructor fields and named parameters are also not gensym'ed * disabled broken package
Diffstat (limited to 'compiler/semtempl.nim')
-rw-r--r-- | compiler/semtempl.nim | 62 |
1 files changed, 43 insertions, 19 deletions
diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index ddc0667e4..907d2174e 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -47,7 +47,8 @@ type TSymChoiceRule = enum scClosed, scOpen, scForceOpen -proc symChoice(c: PContext, n: PNode, s: PSym, r: TSymChoiceRule): PNode = +proc symChoice(c: PContext, n: PNode, s: PSym, r: TSymChoiceRule; + isField = false): PNode = var a: PSym o: TOverloadIter @@ -63,9 +64,12 @@ proc symChoice(c: PContext, n: PNode, s: PSym, r: TSymChoiceRule): PNode = # XXX this makes more sense but breaks bootstrapping for now: # (s.kind notin routineKinds or s.magic != mNone): # for instance 'nextTry' is both in tables.nim and astalgo.nim ... - result = newSymNode(s, info) - markUsed(c, info, s) - onUse(info, s) + if not isField or sfGenSym notin s.flags: + result = newSymNode(s, info) + markUsed(c, info, s) + onUse(info, s) + else: + result = n else: # semantic checking requires a type; ``fitNode`` deals with it # appropriately @@ -74,7 +78,7 @@ proc symChoice(c: PContext, n: PNode, s: PSym, r: TSymChoiceRule): PNode = result = newNodeIT(kind, info, newTypeS(tyNone, c)) a = initOverloadIter(o, c, n) while a != nil: - if a.kind != skModule: + if a.kind != skModule and (not isField or sfGenSym notin s.flags): incl(a.flags, sfUsed) addSon(result, newSymNode(a, info)) onUse(info, a) @@ -119,6 +123,7 @@ type owner: PSym cursorInBody: bool # only for nimsuggest scopeN: int + noGenSym: int template withBracketExpr(ctx, x, body: untyped) = body @@ -228,7 +233,7 @@ proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) = else: replaceIdentBySym(c.c, n, ident) -proc semTemplSymbol(c: PContext, n: PNode, s: PSym): PNode = +proc semTemplSymbol(c: PContext, n: PNode, s: PSym; isField: bool): PNode = incl(s.flags, sfUsed) # we do not call onUse here, as the identifier is not really # resolved here. We will fixup the used identifiers later. @@ -237,15 +242,18 @@ proc semTemplSymbol(c: PContext, n: PNode, s: PSym): PNode = # Introduced in this pass! Leave it as an identifier. result = n of OverloadableSyms: - result = symChoice(c, n, s, scOpen) + result = symChoice(c, n, s, scOpen, isField) of skGenericParam: - result = newSymNodeTypeDesc(s, n.info) + if isField: result = n + else: result = newSymNodeTypeDesc(s, n.info) of skParam: result = n of skType: - result = newSymNodeTypeDesc(s, n.info) + if isField: result = n + else: result = newSymNodeTypeDesc(s, n.info) else: - result = newSymNode(s, n.info) + if isField: result = n + else: result = newSymNode(s, n.info) proc semRoutineInTemplName(c: var TemplCtx, n: PNode): PNode = result = n @@ -322,22 +330,23 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = if n.ident.id in c.toInject: return n let s = qualifiedLookUp(c.c, n, {}) if s != nil: - if s.owner == c.owner and s.kind == skParam: + if s.owner == c.owner and s.kind == skParam and + (sfGenSym notin s.flags or c.noGenSym == 0): incl(s.flags, sfUsed) result = newSymNode(s, n.info) onUse(n.info, s) elif contains(c.toBind, s.id): - result = symChoice(c.c, n, s, scClosed) + result = symChoice(c.c, n, s, scClosed, c.noGenSym > 0) elif contains(c.toMixin, s.name.id): - result = symChoice(c.c, n, s, scForceOpen) - elif s.owner == c.owner and sfGenSym in s.flags: + result = symChoice(c.c, n, s, scForceOpen, c.noGenSym > 0) + elif s.owner == c.owner and sfGenSym in s.flags and c.noGenSym == 0: # template tmp[T](x: var seq[T]) = # var yz: T incl(s.flags, sfUsed) result = newSymNode(s, n.info) onUse(n.info, s) else: - result = semTemplSymbol(c.c, n, s) + result = semTemplSymbol(c.c, n, s, c.noGenSym > 0) of nkBind: result = semTemplBody(c, n.sons[0]) of nkBindStmt: @@ -524,12 +533,27 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = onUse(n.info, s) return newSymNode(s, n.info) elif contains(c.toBind, s.id): - return symChoice(c.c, n, s, scClosed) + return symChoice(c.c, n, s, scClosed, c.noGenSym > 0) elif contains(c.toMixin, s.name.id): - return symChoice(c.c, n, s, scForceOpen) + return symChoice(c.c, n, s, scForceOpen, c.noGenSym > 0) else: - return symChoice(c.c, n, s, scOpen) - result = semTemplBodySons(c, n) + return symChoice(c.c, n, s, scOpen, c.noGenSym > 0) + if n.kind == nkDotExpr: + result = n + result.sons[0] = semTemplBody(c, n.sons[0]) + inc c.noGenSym + result.sons[1] = semTemplBody(c, n.sons[1]) + dec c.noGenSym + else: + result = semTemplBodySons(c, n) + of nkExprColonExpr, nkExprEqExpr: + if n.len == 2: + inc c.noGenSym + result.sons[0] = semTemplBody(c, n.sons[0]) + dec c.noGenSym + result.sons[1] = semTemplBody(c, n.sons[1]) + else: + result = semTemplBodySons(c, n) else: result = semTemplBodySons(c, n) |