diff options
-rw-r--r-- | changelog.md | 3 | ||||
-rw-r--r-- | compiler/ast.nim | 21 | ||||
-rw-r--r-- | compiler/ccgexprs.nim | 6 | ||||
-rw-r--r-- | compiler/ccgliterals.nim | 2 | ||||
-rw-r--r-- | compiler/guards.nim | 2 | ||||
-rw-r--r-- | compiler/injectdestructors.nim | 6 | ||||
-rw-r--r-- | compiler/jsgen.nim | 6 | ||||
-rw-r--r-- | compiler/parampatterns.nim | 2 | ||||
-rw-r--r-- | compiler/patterns.nim | 2 | ||||
-rw-r--r-- | compiler/pragmas.nim | 6 | ||||
-rw-r--r-- | compiler/semcall.nim | 4 | ||||
-rw-r--r-- | compiler/semexprs.nim | 4 | ||||
-rw-r--r-- | compiler/semfold.nim | 8 | ||||
-rw-r--r-- | compiler/sempass2.nim | 9 | ||||
-rw-r--r-- | compiler/semstmts.nim | 45 | ||||
-rw-r--r-- | compiler/sighashes.nim | 2 | ||||
-rw-r--r-- | compiler/suggest.nim | 10 | ||||
-rw-r--r-- | compiler/transf.nim | 10 | ||||
-rw-r--r-- | compiler/vmgen.nim | 2 | ||||
-rw-r--r-- | lib/core/macros.nim | 2 | ||||
-rw-r--r-- | tests/deprecated/tconst.nim | 8 | ||||
-rw-r--r-- | tests/macros/t19766_20114.nim | 16 | ||||
-rw-r--r-- | tests/macros/tgetimpl.nim | 2 | ||||
-rw-r--r-- | tests/pragmas/tcustom_pragma.nim | 40 | ||||
-rw-r--r-- | tests/trmacros/tnorewrite.nim | 20 | ||||
-rw-r--r-- | tests/trmacros/trmacros_various.nim | 3 |
26 files changed, 176 insertions, 65 deletions
diff --git a/changelog.md b/changelog.md index 6d4ccd4b0..7d52b289c 100644 --- a/changelog.md +++ b/changelog.md @@ -51,6 +51,9 @@ - Static linking against OpenSSL versions below 1.1, previously done by setting `-d:openssl10`, is no longer supported. + +- `macros.getImpl` for `const` symbols now returns the full definition node + (as `nnkConstDef`) rather than the AST of the constant value. - ORC is now the default memory management strategy. Use `--mm:refc` for a transition period. diff --git a/compiler/ast.nim b/compiler/ast.nim index f81dc443d..399d7e561 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1233,6 +1233,25 @@ proc getDeclPragma*(n: PNode): PNode = if result != nil: assert result.kind == nkPragma, $(result.kind, n.kind) +proc extractPragma*(s: PSym): PNode = + ## gets the pragma node of routine/type/var/let/const symbol `s` + if s.kind in routineKinds: + result = s.ast[pragmasPos] + elif s.kind in {skType, skVar, skLet, skConst}: + if s.ast != nil and s.ast.len > 0: + if s.ast[0].kind == nkPragmaExpr and s.ast[0].len > 1: + # s.ast = nkTypedef / nkPragmaExpr / [nkSym, nkPragma] + result = s.ast[0][1] + assert result == nil or result.kind == nkPragma + +proc skipPragmaExpr*(n: PNode): PNode = + ## if pragma expr, give the node the pragmas are applied to, + ## otherwise give node itself + if n.kind == nkPragmaExpr: + result = n[0] + else: + result = n + when defined(useNodeIds): const nodeIdToDebug* = -1 # 2322968 var gNodeId: int @@ -1321,7 +1340,7 @@ proc newSym*(symKind: TSymKind, name: PIdent, id: ItemId, owner: PSym, proc astdef*(s: PSym): PNode = # get only the definition (initializer) portion of the ast - if s.ast != nil and s.ast.kind == nkIdentDefs: + if s.ast != nil and s.ast.kind in {nkIdentDefs, nkConstDef}: s.ast[2] else: s.ast diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 9b085b8ed..63de3ba14 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -2856,7 +2856,7 @@ proc genConstSetup(p: BProc; sym: PSym): bool = useHeader(m, sym) if sym.loc.k == locNone: fillBackendName(p.module, sym) - fillLoc(sym.loc, locData, sym.ast, OnStatic) + fillLoc(sym.loc, locData, sym.astdef, OnStatic) if m.hcrOn: incl(sym.loc.flags, lfIndirect) result = lfNoDecl notin sym.loc.flags @@ -2882,7 +2882,7 @@ proc genConstDefinition(q: BModule; p: BProc; sym: PSym) = var data = newRopeAppender() data.addf("N_LIB_PRIVATE NIM_CONST $1 $2 = ", [getTypeDesc(q, sym.typ), actualConstName]) - genBracedInit(q.initProc, sym.ast, isConst = true, sym.typ, data) + genBracedInit(q.initProc, sym.astdef, isConst = true, sym.typ, data) data.addf(";$n", []) q.s[cfsData].add data if q.hcrOn: @@ -2942,7 +2942,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = of skConst: if isSimpleConst(sym.typ): var lit = newRopeAppender() - genLiteral(p, sym.ast, sym.typ, lit) + genLiteral(p, sym.astdef, sym.typ, lit) putIntoDest(p, d, n, lit, OnStatic) elif useAliveDataFromDce in p.module.flags: genConstHeader(p.module, p.module, p, sym) diff --git a/compiler/ccgliterals.nim b/compiler/ccgliterals.nim index 7130c8462..cbef6771f 100644 --- a/compiler/ccgliterals.nim +++ b/compiler/ccgliterals.nim @@ -21,7 +21,7 @@ template detectVersion(field, corename) = if core == nil or core.kind != skConst: m.g.field = 1 else: - m.g.field = toInt(ast.getInt(core.ast)) + m.g.field = toInt(ast.getInt(core.astdef)) result = m.g.field proc detectStrVersion(m: BModule): int = diff --git a/compiler/guards.nim b/compiler/guards.nim index a50593aca..f14c1d915 100644 --- a/compiler/guards.nim +++ b/compiler/guards.nim @@ -200,7 +200,7 @@ proc highBound*(conf: ConfigRef; x: PNode; o: Operators): PNode = nkIntLit.newIntNode(lastOrd(conf, typ)) elif typ.kind == tySequence and x.kind == nkSym and x.sym.kind == skConst: - nkIntLit.newIntNode(x.sym.ast.len-1) + nkIntLit.newIntNode(x.sym.astdef.len-1) else: o.opAdd.buildCall(o.opLen.buildCall(x), minusOne()) result.info = x.info diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index 40ff7ab55..63cfbbd9f 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -866,9 +866,9 @@ proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode): PNode = if it.kind == nkVarTuple and hasDestructor(c, ri.typ): let x = lowerTupleUnpacking(c.graph, it, c.idgen, c.owner) result.add p(x, c, s, consumed) - elif it.kind == nkIdentDefs and hasDestructor(c, it[0].typ): + elif it.kind == nkIdentDefs and hasDestructor(c, skipPragmaExpr(it[0]).typ): for j in 0..<it.len-2: - let v = it[j] + let v = skipPragmaExpr(it[j]) if v.kind == nkSym: if sfCompileTime in v.sym.flags: continue pVarTopLevel(v, c, s, result) @@ -1125,7 +1125,7 @@ proc injectDefaultCalls(n: PNode, c: var Con) = if it.kind == nkIdentDefs and it[^1].kind == nkEmpty: computeUninit(c) for j in 0..<it.len-2: - let v = it[j] + let v = skipPragmaExpr(it[j]) doAssert v.kind == nkSym if c.uninit.contains(v.sym.id): it[^1] = genDefaultCall(v.sym.typ, c, v.info) diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index dc58efb82..301662f10 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -1484,7 +1484,7 @@ proc genSym(p: PProc, n: PNode, r: var TCompRes) = if s.loc.r == "": internalError(p.config, n.info, "symbol has no generated name: " & s.name.s) if sfCompileTime in s.flags: - genVarInit(p, s, if s.ast != nil: s.ast else: newNodeI(nkEmpty, s.info)) + genVarInit(p, s, if s.astdef != nil: s.astdef else: newNodeI(nkEmpty, s.info)) if s.kind == skParam: genCopyForParamIfNeeded(p, n) let k = mapType(p, s.typ) @@ -1945,8 +1945,8 @@ proc genVarStmt(p: PProc, n: PNode) = proc genConstant(p: PProc, c: PSym) = if lfNoDecl notin c.loc.flags and not p.g.generatedSyms.containsOrIncl(c.id): let oldBody = move p.body - #genLineDir(p, c.ast) - genVarInit(p, c, c.ast) + #genLineDir(p, c.astdef) + genVarInit(p, c, c.astdef) p.g.constants.add(p.body) p.body = oldBody diff --git a/compiler/parampatterns.nim b/compiler/parampatterns.nim index cceb236ae..38b7faa07 100644 --- a/compiler/parampatterns.nim +++ b/compiler/parampatterns.nim @@ -224,7 +224,7 @@ proc isAssignable*(owner: PSym, n: PNode): TAssignableResult = const kinds = {skVar, skResult, skTemp, skParam, skLet, skForVar} if n.sym.kind == skParam: result = if n.sym.typ.kind in {tyVar, tySink}: arLValue else: arAddressableConst - elif n.sym.kind == skConst and dontInlineConstant(n, n.sym.ast): + elif n.sym.kind == skConst and dontInlineConstant(n, n.sym.astdef): result = arAddressableConst elif n.sym.kind in kinds: if n.sym.kind in {skParam, skLet, skForVar}: diff --git a/compiler/patterns.nim b/compiler/patterns.nim index 87e9c825c..d4577981f 100644 --- a/compiler/patterns.nim +++ b/compiler/patterns.nim @@ -146,7 +146,7 @@ proc matches(c: PPatternContext, p, n: PNode): bool = elif n.kind == nkSym and n.sym.kind == skConst: # try both: if p.kind == nkSym: result = p.sym == n.sym - elif matches(c, p, n.sym.ast): result = true + elif matches(c, p, n.sym.astdef): result = true elif p.kind == nkPattern: # pattern operators: | * let opr = p[0].ident.s diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index fdf4dd91f..a312478ae 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -313,7 +313,7 @@ proc expectDynlibNode(c: PContext, n: PNode): PNode = # {.dynlib: myGetProcAddr(...).} result = c.semExpr(c, n[1]) if result.kind == nkSym and result.sym.kind == skConst: - result = result.sym.ast # look it up + result = result.sym.astdef # look it up if result.typ == nil or result.typ.kind notin {tyPointer, tyString, tyProc}: localError(c.config, n.info, errStringLiteralExpected) result = newEmptyStrNode(c, n) @@ -998,7 +998,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, of wExplain: sym.flags.incl sfExplain of wDeprecated: - if sym != nil and sym.kind in routineKinds + {skType, skVar, skLet}: + if sym != nil and sym.kind in routineKinds + {skType, skVar, skLet, skConst}: if it.kind in nkPragmaCallKinds: discard getStrLitNode(c, it) incl(sym.flags, sfDeprecated) elif sym != nil and sym.kind != skModule: @@ -1247,7 +1247,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, elif comesFromPush and whichKeyword(ident) != wInvalid: discard "ignore the .push pragma; it doesn't apply" else: - if sym == nil or (sym.kind in {skVar, skLet, skParam, skIterator, + if sym == nil or (sym.kind in {skVar, skLet, skConst, skParam, skIterator, skField, skProc, skFunc, skConverter, skMethod, skType}): n[i] = semCustomPragma(c, it) elif sym != nil: diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 21e519a59..3dff744a3 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -544,8 +544,8 @@ proc semResolvedCall(c: PContext, x: TCandidate, for s in instantiateGenericParamList(c, gp, x.bindings): case s.kind of skConst: - if not s.ast.isNil: - x.call.add s.ast + if not s.astdef.isNil: + x.call.add s.astdef else: x.call.add c.graph.emptyNode of skType: diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 32bb4c331..a0753010a 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -108,7 +108,7 @@ proc semSymGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = result = symChoice(c, n, s, scClosed) proc inlineConst(c: PContext, n: PNode, s: PSym): PNode {.inline.} = - result = copyTree(s.ast) + result = copyTree(s.astdef) if result.isNil: localError(c.config, n.info, "constant of type '" & typeToString(s.typ) & "' has no value") result = newSymNode(s) @@ -1230,7 +1230,7 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode = # It is clear that ``[]`` means two totally different things. Thus, we # copy `x`'s AST into each context, so that the type fixup phase can # deal with two different ``[]``. - if s.ast.safeLen == 0: result = inlineConst(c, n, s) + if s.astdef.safeLen == 0: result = inlineConst(c, n, s) else: result = newSymNode(s, n.info) of tyStatic: if typ.n != nil: diff --git a/compiler/semfold.nim b/compiler/semfold.nim index f627bffc7..94e5fda31 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -517,12 +517,12 @@ proc getConstExpr(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode "{.intdefine.} const was set to an invalid integer: '" & g.config.symbols[s.name.s] & "'") else: - result = copyTree(s.ast) + result = copyTree(s.astdef) of mStrDefine: if isDefined(g.config, s.name.s): result = newStrNodeT(g.config.symbols[s.name.s], n, g) else: - result = copyTree(s.ast) + result = copyTree(s.astdef) of mBoolDefine: if isDefined(g.config, s.name.s): try: @@ -532,9 +532,9 @@ proc getConstExpr(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode "{.booldefine.} const was set to an invalid bool: '" & g.config.symbols[s.name.s] & "'") else: - result = copyTree(s.ast) + result = copyTree(s.astdef) else: - result = copyTree(s.ast) + result = copyTree(s.astdef) of skProc, skFunc, skMethod: result = n of skParam: diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 940291f53..5d701c496 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -1101,12 +1101,13 @@ proc track(tracked: PEffects, n: PNode) = for i in 0..<child.len-2: createTypeBoundOps(tracked, child[i].typ, child.info) else: - createTypeBoundOps(tracked, child[0].typ, child.info) + createTypeBoundOps(tracked, skipPragmaExpr(child[0]).typ, child.info) if child.kind == nkIdentDefs and last.kind != nkEmpty: for i in 0..<child.len-2: - initVar(tracked, child[i], volatileCheck=false) - addAsgnFact(tracked.guards, child[i], last) - notNilCheck(tracked, last, child[i].typ) + let a = skipPragmaExpr(child[i]) + initVar(tracked, a, volatileCheck=false) + addAsgnFact(tracked.guards, a, last) + notNilCheck(tracked, last, a.typ) elif child.kind == nkVarTuple and last.kind != nkEmpty: for i in 0..<child.len-1: if child[i].kind == nkEmpty or diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index fd8f2180b..faf8e3baa 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -694,28 +694,25 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = if def.kind != nkEmpty: if sfThread in v.flags: localError(c.config, def.info, errThreadvarCannotInit) setVarType(c, v, typ) + # this is needed for the evaluation pass, guard checking + # and custom pragmas: b = newNodeI(nkIdentDefs, a.info) if importantComments(c.config): # keep documentation information: b.comment = a.comment - b.add newSymNode(v) - # keep type desc for doc generator - b.add a[^2] - b.add copyTree(def) - addToVarSection(c, result, n, b) - # this is needed for the evaluation pass, guard checking - # and custom pragmas: - var ast = newNodeI(nkIdentDefs, a.info) + # postfix not generated here (to generate, get rid of it in transf) if a[j].kind == nkPragmaExpr: var p = newNodeI(nkPragmaExpr, a.info) p.add newSymNode(v) - p.add a[j][1].copyTree - ast.add p + p.add a[j][1] + b.add p else: - ast.add newSymNode(v) - ast.add a[^2].copyTree - ast.add def - v.ast = ast + b.add newSymNode(v) + # keep type desc for doc generator + b.add a[^2] + b.add copyTree(def) + addToVarSection(c, result, n, b) + v.ast = b else: if def.kind in {nkPar, nkTupleConstr}: v.ast = def[j] # bug #7663, for 'nim check' this can be a non-tuple: @@ -811,12 +808,21 @@ proc semConst(c: PContext, n: PNode): PNode = if a.kind != nkVarTuple: setVarType(c, v, typ) - v.ast = def # no need to copy + when false: + v.ast = def # no need to copy b = newNodeI(nkConstDef, a.info) if importantComments(c.config): b.comment = a.comment - b.add newSymNode(v) + # postfix not generated here (to generate, get rid of it in transf) + if a[j].kind == nkPragmaExpr: + var p = newNodeI(nkPragmaExpr, a.info) + p.add newSymNode(v) + p.add a[j][1].copyTree + b.add p + else: + b.add newSymNode(v) b.add a[1] b.add copyTree(def) + v.ast = b else: setVarType(c, v, typ[j]) v.ast = if def[j].kind != nkExprColonExpr: def[j] @@ -2330,6 +2336,11 @@ proc setLine(n: PNode, info: TLineInfo) = for i in 0..<n.safeLen: setLine(n[i], info) n.info = info +proc recursiveSetFlag(n: PNode, flag: TNodeFlag) = + if n != nil: + for i in 0..<n.safeLen: recursiveSetFlag(n[i], flag) + incl(n.flags, flag) + proc semPragmaBlock(c: PContext, n: PNode; expectedType: PType = nil): PNode = checkSonsLen(n, 2, c.config) let pragmaList = n[0] @@ -2354,7 +2365,7 @@ proc semPragmaBlock(c: PContext, n: PNode; expectedType: PType = nil): PNode = for i in 0..<pragmaList.len: case whichPragma(pragmaList[i]) of wLine: setLine(result, pragmaList[i].info) - of wNoRewrite: incl(result.flags, nfNoRewrite) + of wNoRewrite: recursiveSetFlag(result, nfNoRewrite) else: discard proc semStaticStmt(c: PContext, n: PNode): PNode = diff --git a/compiler/sighashes.nim b/compiler/sighashes.nim index f58c9c3ef..3dfd71315 100644 --- a/compiler/sighashes.nim +++ b/compiler/sighashes.nim @@ -333,7 +333,7 @@ proc hashVarSymBody(graph: ModuleGraph, c: var MD5Context, s: PSym) = c &= hashNonProc(s) # this one works for let and const but not for var. True variables can change value # later on. it is user resposibility to hash his global state if required - if s.ast != nil and s.ast.kind == nkIdentDefs: + if s.ast != nil and s.ast.kind in {nkIdentDefs, nkConstDef}: hashBodyTree(graph, c, s.ast[^1]) else: hashBodyTree(graph, c, s.ast) diff --git a/compiler/suggest.nim b/compiler/suggest.nim index 5e8d896bf..9d4089707 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -535,16 +535,6 @@ proc suggestSym*(g: ModuleGraph; info: TLineInfo; s: PSym; usageSym: var PSym; i if parentFileIndex == conf.m.trackPos.fileIndex: suggestResult(conf, symToSuggest(g, s, isLocal=false, ideOutline, info, 100, PrefixMatch.None, false, 0)) -proc extractPragma(s: PSym): PNode = - if s.kind in routineKinds: - result = s.ast[pragmasPos] - elif s.kind in {skType, skVar, skLet}: - if s.ast != nil and s.ast.len > 0: - if s.ast[0].kind == nkPragmaExpr and s.ast[0].len > 1: - # s.ast = nkTypedef / nkPragmaExpr / [nkSym, nkPragma] - result = s.ast[0][1] - doAssert result == nil or result.kind == nkPragma - proc warnAboutDeprecated(conf: ConfigRef; info: TLineInfo; s: PSym) = var pragmaNode: PNode pragmaNode = if s.kind == skEnumField: extractPragma(s.owner) else: extractPragma(s) diff --git a/compiler/transf.nim b/compiler/transf.nim index 47d7fb3a5..7ab67873b 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -184,10 +184,12 @@ proc transformVarSection(c: PTransf, v: PNode): PNode = if it.kind == nkCommentStmt: result[i] = it elif it.kind == nkIdentDefs: - if it[0].kind == nkSym: + var vn = it[0] + if vn.kind == nkPragmaExpr: vn = vn[0] + if vn.kind == nkSym: internalAssert(c.graph.config, it.len == 3) - let x = freshVar(c, it[0].sym) - idNodeTablePut(c.transCon.mapping, it[0].sym, x) + let x = freshVar(c, vn.sym) + idNodeTablePut(c.transCon.mapping, vn.sym, x) var defs = newTransNode(nkIdentDefs, it.info, 3) if importantComments(c.graph.config): # keep documentation information: @@ -1036,7 +1038,7 @@ proc transform(c: PTransf, n: PNode): PNode = result = transformAsgn(c, n) of nkIdentDefs, nkConstDef: result = newTransNode(n) - result[0] = transform(c, n[0]) + result[0] = transform(c, skipPragmaExpr(n[0])) # Skip the second son since it only contains an unsemanticized copy of the # variable type used by docgen let last = n.len-1 diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index f15cb2752..a0bf6af56 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -2000,7 +2000,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) = elif importcCond(c, s): c.importcSym(n.info, s) genLit(c, n, dest) of skConst: - let constVal = if s.ast != nil: s.ast else: s.typ.n + let constVal = if s.astdef != nil: s.astdef else: s.typ.n gen(c, constVal, dest) of skEnumField: # we never reach this case - as of the time of this comment, diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 24901180e..cc2d5041e 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -1567,7 +1567,7 @@ proc customPragmaNode(n: NimNode): NimNode = let impl = n.getImpl() if impl.kind in RoutineNodes: return impl.pragma - elif impl.kind == nnkIdentDefs and impl[0].kind == nnkPragmaExpr: + elif impl.kind in {nnkIdentDefs, nnkConstDef} and impl[0].kind == nnkPragmaExpr: return impl[0][1] else: let timpl = typ.getImpl() diff --git a/tests/deprecated/tconst.nim b/tests/deprecated/tconst.nim new file mode 100644 index 000000000..51eb6cb0e --- /dev/null +++ b/tests/deprecated/tconst.nim @@ -0,0 +1,8 @@ +discard """ + nimout: ''' +tconst.nim(8, 9) Warning: abcd; foo is deprecated [Deprecated] +''' +""" + +const foo* {.deprecated: "abcd".} = 42 +discard foo diff --git a/tests/macros/t19766_20114.nim b/tests/macros/t19766_20114.nim new file mode 100644 index 000000000..ac336f150 --- /dev/null +++ b/tests/macros/t19766_20114.nim @@ -0,0 +1,16 @@ +discard """ + action: compile + nimout: ''' +const + foo {.strdefine.} = "abc" +let hey {.tddd.} = 5 +''' +""" + +import macros + +template tddd {.pragma.} + +expandMacros: + const foo {.strdefine.} = "abc" + let hey {.tddd.} = 5 diff --git a/tests/macros/tgetimpl.nim b/tests/macros/tgetimpl.nim index de132f253..66722a234 100644 --- a/tests/macros/tgetimpl.nim +++ b/tests/macros/tgetimpl.nim @@ -1,5 +1,5 @@ discard """ - nimout: '''"muhaha" + nimout: '''foo = "muhaha" proc poo(x, y: int) = let y = x echo ["poo"]''' diff --git a/tests/pragmas/tcustom_pragma.nim b/tests/pragmas/tcustom_pragma.nim index b624f32ba..5a68b7677 100644 --- a/tests/pragmas/tcustom_pragma.nim +++ b/tests/pragmas/tcustom_pragma.nim @@ -439,3 +439,43 @@ when false: # left-to-right priority/override order for getCustomPragmaVal assert bb.getCustomPragmaVal(hehe) == (key: "hi", val: "hu", haha: "he") + +{.experimental: "dynamicBindSym".} + +# const +block: + template myAttr() {.pragma.} + template myAttr2(x: int) {.pragma.} + template myAttr3(x: string) {.pragma.} + + type + MyObj2 = ref object + + const a {.myAttr,myAttr2(2),myAttr3:"test".}: int = 0 + const b {.myAttr,myAttr2(2),myAttr3:"test".} = 0 + + macro forceHasCustomPragma(x: untyped, y: typed): untyped = + var x = bindSym(x.repr) + for c in x: + if c.symKind == nskConst: + x = c + break + result = getAst(hasCustomPragma(x, y)) + + macro forceGetCustomPragmaVal(x: untyped, y: typed): untyped = + var x = bindSym(x.repr) + for c in x: + if c.symKind == nskConst: + x = c + break + result = getAst(getCustomPragmaVal(x, y)) + + template check(s: untyped) = + doAssert forceHasCustomPragma(s, myAttr) + doAssert forceHasCustomPragma(s, myAttr2) + doAssert forceGetCustomPragmaVal(s, myAttr2) == 2 + doAssert forceHasCustomPragma(s, myAttr3) + doAssert forceGetCustomPragmaVal(s, myAttr3) == "test" + + check(a) + check(b) diff --git a/tests/trmacros/tnorewrite.nim b/tests/trmacros/tnorewrite.nim new file mode 100644 index 000000000..e6769246f --- /dev/null +++ b/tests/trmacros/tnorewrite.nim @@ -0,0 +1,20 @@ +block: + proc get(x: int): int = x + + template t{get(a)}(a: int): int = + {.noRewrite.}: + get(a) + 1 + + doAssert get(0) == 1 + +block: + var x: int + + template asgn{a = b}(a: int{lvalue}, b: int) = + let newVal = b + 1 + # ^ this is needed but should it be? + {.noRewrite.}: + a = newVal + + x = 10 + doAssert x == 11, $x diff --git a/tests/trmacros/trmacros_various.nim b/tests/trmacros/trmacros_various.nim index 74b248739..8fe51e548 100644 --- a/tests/trmacros/trmacros_various.nim +++ b/tests/trmacros/trmacros_various.nim @@ -33,7 +33,8 @@ block tcse: block hoist: template optPeg{peg(pattern)}(pattern: string{lit}): Peg = - var gl {.global, gensym.} = peg(pattern) + {.noRewrite.}: + var gl {.global, gensym.} = peg(pattern) gl doAssert match("(a b c)", peg"'(' @ ')'") doAssert match("W_HI_Le", peg"\y 'while'") |