summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/ast.nim1
-rw-r--r--compiler/condsyms.nim1
-rw-r--r--compiler/lineinfos.nim2
-rw-r--r--compiler/pragmas.nim5
-rw-r--r--compiler/semexprs.nim4
-rw-r--r--compiler/semtempl.nim3
-rw-r--r--compiler/wordrecg.nim1
7 files changed, 15 insertions, 2 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 910c95451..c720a76fb 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -334,6 +334,7 @@ const
   sfEscapes* = sfProcvar              # param escapes
   sfBase* = sfDiscriminant
   sfCustomPragma* = sfRegister        # symbol is custom pragma template
+  sfTemplateRedefinition* = sfExportc # symbol is a redefinition of an earlier template
 
 const
   # getting ready for the future expr/stmt merge
diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim
index 5a7e78d5f..4d4358b16 100644
--- a/compiler/condsyms.nim
+++ b/compiler/condsyms.nim
@@ -140,3 +140,4 @@ proc initDefines*(symbols: StringTableRef) =
   defineSymbol("nimHasEffectsOf")
 
   defineSymbol("nimHasEnforceNoRaises")
+  defineSymbol("nimHasTemplateRedefinitionPragma")
diff --git a/compiler/lineinfos.nim b/compiler/lineinfos.nim
index 07cc988a9..ec1643960 100644
--- a/compiler/lineinfos.nim
+++ b/compiler/lineinfos.nim
@@ -81,6 +81,7 @@ type
     warnCstringConv = "CStringConv",
     warnEffect = "Effect",
     warnCastSizes = "CastSizes"
+    warnTemplateRedefinition = "TemplateRedefinition",
     warnUser = "User",
     # hints
     hintSuccess = "Success", hintSuccessX = "SuccessX",
@@ -175,6 +176,7 @@ const
     warnCstringConv: "$1",
     warnEffect: "$1",
     warnCastSizes: "$1",
+    warnTemplateRedefinition: "template '$1' is implicitly redefined, consider adding an explicit .redefine pragma",
     warnUser: "$1",
     hintSuccess: "operation successful: $#",
     # keep in sync with `testament.isSuccess`
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index d5c728418..b662e09c5 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -38,7 +38,7 @@ const
   converterPragmas* = procPragmas
   methodPragmas* = procPragmas+{wBase}-{wImportCpp}
   templatePragmas* = {wDeprecated, wError, wGensym, wInject, wDirty,
-    wDelegator, wExportNims, wUsed, wPragma}
+    wDelegator, wExportNims, wUsed, wPragma, wRedefine}
   macroPragmas* = declPragmas + {FirstCallConv..LastCallConv,
     wMagic, wNoSideEffect, wCompilerProc, wNonReloadable, wCore,
     wDiscardable, wGensym, wInject, wDelegator}
@@ -870,6 +870,9 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
       of wDirty:
         if sym.kind == skTemplate: incl(sym.flags, sfDirty)
         else: invalidPragma(c, it)
+      of wRedefine:
+        if sym.kind == skTemplate: incl(sym.flags, sfTemplateRedefinition)
+        else: invalidPragma(c, it)
       of wImportCpp:
         processImportCpp(c, sym, getOptionalStr(c, it, "$1"), it.info)
       of wCppNonPod:
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 119daa8b3..b47aff429 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -2112,10 +2112,12 @@ proc semQuoteAst(c: PContext, n: PNode): PNode =
   ids[0] = newAnonSym(c, skParam, n.info).newSymNode
   processQuotations(c, quotedBlock, op, quotes, ids)
 
+  let dummyTemplateSym = newAnonSym(c, skTemplate, n.info)
+  incl(dummyTemplateSym.flags, sfTemplateRedefinition)
   var dummyTemplate = newProcNode(
     nkTemplateDef, quotedBlock.info, body = quotedBlock,
     params = c.graph.emptyNode,
-    name = newAnonSym(c, skTemplate, n.info).newSymNode,
+    name = dummyTemplateSym.newSymNode,
               pattern = c.graph.emptyNode, genericParams = c.graph.emptyNode,
               pragmas = c.graph.emptyNode, exceptions = c.graph.emptyNode)
 
diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim
index 1f76aff75..c72e9db05 100644
--- a/compiler/semtempl.nim
+++ b/compiler/semtempl.nim
@@ -691,6 +691,9 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
   if proto == nil:
     addInterfaceOverloadableSymAt(c, c.currentScope, s)
   elif not comesFromShadowscope:
+    if {sfTemplateRedefinition, sfGenSym} * s.flags == {}:
+      #wrongRedefinition(c, n.info, proto.name.s, proto.info)
+      message(c.config, n.info, warnTemplateRedefinition, s.name.s)
     symTabReplace(c.currentScope.symbols, proto, s)
   if n[patternPos].kind != nkEmpty:
     c.patterns.add(s)
diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim
index 71b2e6384..d33982b0f 100644
--- a/compiler/wordrecg.nim
+++ b/compiler/wordrecg.nim
@@ -87,6 +87,7 @@ type
     wGlobal = "global", wCodegenDecl = "codegenDecl", wUnchecked = "unchecked",
     wGuard = "guard", wLocks = "locks", wPartial = "partial", wExplain = "explain",
     wLiftLocals = "liftlocals", wEnforceNoRaises = "enforceNoRaises",
+    wRedefine = "redefine",
 
     wAuto = "auto", wBool = "bool", wCatch = "catch", wChar = "char",
     wClass = "class", wCompl = "compl", wConstCast = "const_cast", wDefault = "default",