summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2012-08-20 08:44:17 +0200
committerAraq <rumpf_a@web.de>2012-08-20 08:44:17 +0200
commitda190876de0d500c94d23c64eb372d3bb8e2bb09 (patch)
tree3a55eefb6e85d096263337530a25bf1f2cc0679d /compiler
parent5e15dec1757e6013cbeb5d6baf9d9579cf025361 (diff)
downloadNim-da190876de0d500c94d23c64eb372d3bb8e2bb09.tar.gz
next steps to hygienic templates
Diffstat (limited to 'compiler')
-rwxr-xr-xcompiler/ast.nim18
-rwxr-xr-xcompiler/evals.nim4
-rw-r--r--compiler/idgen.nim6
-rw-r--r--compiler/lambdalifting.nim18
-rwxr-xr-xcompiler/lookups.nim23
-rwxr-xr-xcompiler/pragmas.nim8
-rwxr-xr-xcompiler/sem.nim6
-rwxr-xr-xcompiler/semexprs.nim3
-rwxr-xr-xcompiler/semgnrc.nim2
-rwxr-xr-xcompiler/seminst.nim3
-rwxr-xr-xcompiler/semstmts.nim16
-rwxr-xr-xcompiler/semtempl.nim45
-rwxr-xr-xcompiler/semtypes.nim2
-rwxr-xr-xcompiler/transf.nim6
-rwxr-xr-xcompiler/wordrecg.nim5
15 files changed, 91 insertions, 74 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 90885a71f..36cafe6f3 100755
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -259,7 +259,10 @@ const
   sfImmediate* = sfDeadCodeElim
     # macro or template is immediately expanded
     # without considering any possible overloads
-  
+
+  sfDirty* = sfPure
+    # template is not hygienic (old styled template)
+
   sfAnon* = sfDiscardable
     # symbol name that was generated by the compiler
     # the compiler will avoid printing such names 
@@ -691,7 +694,8 @@ const
 
 
 # creator procs:
-proc NewSym*(symKind: TSymKind, Name: PIdent, owner: PSym): PSym
+proc NewSym*(symKind: TSymKind, Name: PIdent, owner: PSym,
+             info: TLineInfo): PSym
 proc NewType*(kind: TTypeKind, owner: PSym): PType
 proc newNode*(kind: TNodeKind): PNode
 proc newIntNode*(kind: TNodeKind, intVal: BiggestInt): PNode
@@ -922,11 +926,10 @@ proc copyType(t: PType, owner: PSym, keepId: bool): PType =
   result.sym = t.sym          # backend-info should not be copied
   
 proc copySym(s: PSym, keepId: bool = false): PSym = 
-  result = newSym(s.kind, s.name, s.owner)
+  result = newSym(s.kind, s.name, s.owner, s.info)
   result.ast = nil            # BUGFIX; was: s.ast which made problems
-  result.info = s.info
   result.typ = s.typ
-  if keepId: 
+  if keepId:
     result.id = s.id
   else: 
     result.id = getID()
@@ -939,13 +942,14 @@ proc copySym(s: PSym, keepId: bool = false): PSym =
   result.loc = s.loc
   result.annex = s.annex      # BUGFIX
   
-proc NewSym(symKind: TSymKind, Name: PIdent, owner: PSym): PSym = 
+proc NewSym(symKind: TSymKind, Name: PIdent, owner: PSym,
+            info: TLineInfo): PSym = 
   # generates a symbol and initializes the hash field too
   new(result)
   result.Name = Name
   result.Kind = symKind
   result.flags = {}
-  result.info = UnknownLineInfo()
+  result.info = info
   result.options = gOptions
   result.owner = owner
   result.offset = - 1
diff --git a/compiler/evals.nim b/compiler/evals.nim
index e17ab2c6c..58f797e14 100755
--- a/compiler/evals.nim
+++ b/compiler/evals.nim
@@ -254,7 +254,7 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
     for i in countup(0, sonsLen(t) - 1): 
       var p = newNodeIT(nkExprColonExpr, info, t.sons[i])
       var field = if t.n != nil: t.n.sons[i].sym else: newSym(
-        skField, getIdent(":tmp" & $i), t.owner)
+        skField, getIdent(":tmp" & $i), t.owner, info)
       addSon(p, newSymNode(field, info))
       addSon(p, getNullValue(t.sons[i], info))
       addSon(result, p)
@@ -1358,7 +1358,7 @@ proc evalMacroCall*(c: PEvalContext, n: PNode, sym: PSym): PNode =
   if evalTemplateCounter > 100: 
     GlobalError(n.info, errTemplateInstantiationTooNested)
 
-  inc genSymBaseId
+  #inc genSymBaseId
   var s = newStackFrame()
   s.call = n
   setlen(s.params, 2)
diff --git a/compiler/idgen.nim b/compiler/idgen.nim
index d2e322796..fbf450c90 100644
--- a/compiler/idgen.nim
+++ b/compiler/idgen.nim
@@ -11,7 +11,7 @@
 
 import idents, strutils, os, options
 
-var gFrontEndId, gBackendId*, genSymBaseId*: int
+var gFrontEndId, gBackendId*: int
 
 const
   debugIds* = false
@@ -34,9 +34,6 @@ proc backendId*(): int {.inline.} =
   result = gBackendId
   inc(gBackendId)
 
-proc genSym*(basename: string): PIdent =
-  result = getIdent(basename & $genSymBaseId)
-
 proc setId*(id: int) {.inline.} = 
   gFrontEndId = max(gFrontEndId, id + 1)
 
@@ -66,4 +63,3 @@ proc loadMaxIds*(project: string) =
         gFrontEndId = max(gFrontEndId, frontEndId)
         gBackEndId = max(gBackEndId, backEndId)
     f.close()
-
diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim
index 057444b2a..0748b99b3 100644
--- a/compiler/lambdalifting.nim
+++ b/compiler/lambdalifting.nim
@@ -162,7 +162,7 @@ proc newEnv(outerProc: PSym, up: PEnv, n: PNode): PEnv =
   result.attachedNode = n
 
 proc addField(tup: PType, s: PSym) =
-  var field = newSym(skField, s.name, s.owner)
+  var field = newSym(skField, s.name, s.owner, s.info)
   let t = skipIntLit(s.typ)
   field.typ = t
   field.position = sonsLen(tup)
@@ -179,7 +179,7 @@ proc addDep(e, d: PEnv, owner: PSym): PSym =
   for x, field in items(e.deps):
     if x == d: return field
   var pos = sonsLen(e.tup)
-  result = newSym(skField, getIdent(upName & $pos), owner)
+  result = newSym(skField, getIdent(upName & $pos), owner, owner.info)
   result.typ = newType(tyRef, owner)
   result.position = pos
   assert d.tup != nil
@@ -220,8 +220,7 @@ proc isInnerProc(s, outerProc: PSym): bool {.inline.} =
   #s.typ.callConv == ccClosure
 
 proc addClosureParam(i: PInnerContext, e: PEnv) =
-  var cp = newSym(skParam, getIdent(paramname), i.fn)
-  cp.info = i.fn.info
+  var cp = newSym(skParam, getIdent(paramname), i.fn, i.fn.info)
   incl(cp.flags, sfFromGeneric)
   cp.typ = newType(tyRef, i.fn)
   rawAddSon(cp.typ, e.tup)
@@ -449,9 +448,8 @@ proc addVar*(father, v: PNode) =
 
 proc getClosureVar(o: POuterContext, e: PEnv): PSym =
   if e.closure == nil:
-    result = newSym(skVar, getIdent(envName), o.fn)
+    result = newSym(skVar, getIdent(envName), o.fn, e.attachedNode.info)
     incl(result.flags, sfShadowed)
-    result.info = e.attachedNode.info
     result.typ = newType(tyRef, o.fn)
     result.typ.rawAddSon(e.tup)
     e.closure = result
@@ -590,8 +588,7 @@ type
     tup: PType
 
 proc newIterResult(iter: PSym): PSym =
-  result = newSym(skResult, getIdent":result", iter)
-  result.info = iter.info
+  result = newSym(skResult, getIdent":result", iter, iter.info)
   result.typ = iter.typ.sons[0]
   incl(result.flags, sfUsed)
 
@@ -650,15 +647,14 @@ proc liftIterator*(iter: PSym, body: PNode): PNode =
   c.tup = newType(tyTuple, iter)
   c.tup.n = newNodeI(nkRecList, iter.info)
 
-  var cp = newSym(skParam, getIdent(paramname), iter)
-  cp.info = iter.info
+  var cp = newSym(skParam, getIdent(paramname), iter, iter.info)
   incl(cp.flags, sfFromGeneric)
   cp.typ = newType(tyRef, iter)
   rawAddSon(cp.typ, c.tup)
   c.closureParam = cp
   addHiddenParam(iter, cp)
 
-  c.state = newSym(skField, getIdent(":state"), iter)
+  c.state = newSym(skField, getIdent(":state"), iter, iter.info)
   c.state.typ = getStateType(iter)
   addField(c.tup, c.state)
 
diff --git a/compiler/lookups.nim b/compiler/lookups.nim
index 556f6eb4a..9ab5d2c48 100755
--- a/compiler/lookups.nim
+++ b/compiler/lookups.nim
@@ -22,18 +22,14 @@ proc considerAcc*(n: PNode): PIdent =
     of 0: GlobalError(n.info, errIdentifierExpected, renderTree(n))
     of 1: result = considerAcc(n.sons[0])
     else:
-      if n.len == 2 and n[0].kind == nkIdent and n[0].ident.id == ord(wStar):
-        # XXX find a better way instead of `*x` for 'genSym'
-        result = genSym(n[1].ident.s)
-      else:
-        var id = ""
-        for i in 0.. <n.len:
-          let x = n.sons[i]
-          case x.kind
-          of nkIdent: id.add(x.ident.s)
-          of nkSym: id.add(x.sym.name.s)
-          else: GlobalError(n.info, errIdentifierExpected, renderTree(n))
-        result = getIdent(id)
+      var id = ""
+      for i in 0.. <n.len:
+        let x = n.sons[i]
+        case x.kind
+        of nkIdent: id.add(x.ident.s)
+        of nkSym: id.add(x.sym.name.s)
+        else: GlobalError(n.info, errIdentifierExpected, renderTree(n))
+      result = getIdent(id)
   else:
     GlobalError(n.info, errIdentifierExpected, renderTree(n))
  
@@ -46,8 +42,7 @@ proc errorSym*(c: PContext, n: PNode): PSym =
       considerAcc(m)
     else:
       getIdent("err:" & renderTree(m))
-  result = newSym(skError, ident, getCurrOwner())
-  result.info = n.info
+  result = newSym(skError, ident, getCurrOwner(), n.info)
   result.typ = errorType(c)
   incl(result.flags, sfDiscardable)
   # pretend it's imported from some unknown module to prevent cascading errors:
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index 08cdb46c5..cbdf63a1c 100755
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -27,7 +27,7 @@ const
     wGenSym, wInject}
   converterPragmas* = procPragmas
   methodPragmas* = procPragmas
-  templatePragmas* = {wImmediate, wDeprecated, wError, wGenSym, wInject}
+  templatePragmas* = {wImmediate, wDeprecated, wError, wGenSym, wInject, wDirty}
   macroPragmas* = {FirstCallConv..LastCallConv, wImmediate, wImportc, wExportc,
     wNodecl, wMagic, wNosideEffect, wCompilerProc, wDeprecated, wExtern,
     wImportcpp, wImportobjc, wError, wDiscardable, wGenSym, wInject}
@@ -454,8 +454,7 @@ proc processPragma(c: PContext, n: PNode, i: int) =
   elif it.sons[0].kind != nkIdent: invalidPragma(n)
   elif it.sons[1].kind != nkIdent: invalidPragma(n)
   
-  var userPragma = NewSym(skTemplate, it.sons[1].ident, nil)
-  userPragma.info = it.info
+  var userPragma = NewSym(skTemplate, it.sons[1].ident, nil, it.info)
   var body = newNodeI(nkPragma, n.info)
   for j in i+1 .. sonsLen(n)-1: addSon(body, n.sons[j])
   userPragma.ast = body
@@ -488,6 +487,9 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
           of wImmediate:
             if sym.kind in {skTemplate, skMacro}: incl(sym.flags, sfImmediate)
             else: invalidPragma(it)
+          of wDirty:
+            if sym.kind == skTemplate: incl(sym.flags, sfDirty)
+            else: invalidPragma(it)
           of wImportCpp:
             processImportCpp(sym, getOptionalStr(c, it, sym.name.s))
           of wImportObjC:
diff --git a/compiler/sem.nim b/compiler/sem.nim
index cfdd936ad..0f9cb1d16 100755
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -55,8 +55,7 @@ proc isTopLevel(c: PContext): bool {.inline.} =
   result = c.tab.tos <= 2
 
 proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym = 
-  result = newSym(kind, considerAcc(n), getCurrOwner())
-  result.info = n.info
+  result = newSym(kind, considerAcc(n), getCurrOwner(), n.info)
 
 proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym =
   # like newSymS, but considers gensym'ed symbols
@@ -65,8 +64,7 @@ proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym =
     InternalAssert sfGenSym in result.flags
     InternalAssert result.kind == kind
   else:
-    result = newSym(kind, considerAcc(n), getCurrOwner())
-    result.info = n.info
+    result = newSym(kind, considerAcc(n), getCurrOwner(), n.info)
 
 proc semIdentVis(c: PContext, kind: TSymKind, n: PNode,
                  allowed: TSymFlags): PSym
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index e4e449c9e..e20a518e5 100755
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1470,7 +1470,8 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
   of nkTypeOfExpr:
     var typ = semTypeNode(c, n, nil).skipTypes({tyTypeDesc})
     typ = makeTypedesc(c, typ)
-    var sym = newSym(skType, getIdent"TypeOfExpr", typ.owner).linkTo(typ)
+    var sym = newSym(skType, getIdent"TypeOfExpr", 
+                     typ.owner, n.info).linkTo(typ)
     sym.flags.incl(sfAnon)
     result = newSymNode(sym, n.info)
   of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit: 
diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim
index de73d6d86..3a11f87ce 100755
--- a/compiler/semgnrc.nim
+++ b/compiler/semgnrc.nim
@@ -255,7 +255,7 @@ proc semGenericStmt(c: PContext, n: PNode,
                                               flags, toBind)
     if n.sons[paramsPos].kind != nkEmpty: 
       if n.sons[paramsPos].sons[0].kind != nkEmpty: 
-        addPrelimDecl(c, newSym(skUnknown, getIdent("result"), nil))
+        addPrelimDecl(c, newSym(skUnknown, getIdent("result"), nil, n.info))
       n.sons[paramsPos] = semGenericStmt(c, n.sons[paramsPos], flags, toBind)
     n.sons[pragmasPos] = semGenericStmt(c, n.sons[pragmasPos], flags, toBind)
     var body: PNode
diff --git a/compiler/seminst.nim b/compiler/seminst.nim
index 0e2d38196..8e4cb086d 100755
--- a/compiler/seminst.nim
+++ b/compiler/seminst.nim
@@ -21,8 +21,7 @@ proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable,
       InternalError(a.info, "instantiateGenericParamList; no symbol")
     var q = a.sym
     if q.typ.kind notin {tyTypeDesc, tyGenericParam, tyTypeClass, tyExpr}: continue
-    var s = newSym(skType, q.name, getCurrOwner())
-    s.info = q.info
+    var s = newSym(skType, q.name, getCurrOwner(), q.info)
     s.flags = s.flags + {sfUsed, sfFromGeneric}
     var t = PType(IdTableGet(pt, q.typ))
     if t == nil:
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index d531118c5..b8bf9e970 100755
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -380,7 +380,7 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
   var trueSymbol = StrTableGet(magicsys.systemModule.Tab, getIdent"true")
   if trueSymbol == nil: 
     LocalError(n.info, errSystemNeeds, "true")
-    trueSymbol = newSym(skUnknown, getIdent"true", getCurrOwner())
+    trueSymbol = newSym(skUnknown, getIdent"true", getCurrOwner(), n.info)
     trueSymbol.typ = getSysType(tyBool)
 
   result.add(newSymNode(trueSymbol, n.info))
@@ -620,10 +620,8 @@ proc typeSectionFinalPass(c: PContext, n: PNode) =
        aa.sons[0].kind == nkObjectTy:
       # give anonymous object a dummy symbol:
       assert s.typ.sons[0].sym == nil
-      var anonObj = newSym(skType, getIdent(s.name.s & ":ObjectType"), 
-                                 getCurrOwner())
-      anonObj.info = s.info
-      s.typ.sons[0].sym = anonObj
+      s.typ.sons[0].sym = newSym(skType, getIdent(s.name.s & ":ObjectType"), 
+                                 getCurrOwner(), s.info)
 
 proc SemTypeSection(c: PContext, n: PNode): PNode =
   typeSectionLeftSidePass(c, n)
@@ -650,8 +648,7 @@ proc semBorrow(c: PContext, n: PNode, s: PSym) =
   
 proc addResult(c: PContext, t: PType, info: TLineInfo, owner: TSymKind) = 
   if t != nil: 
-    var s = newSym(skResult, getIdent"result", getCurrOwner())
-    s.info = info
+    var s = newSym(skResult, getIdent"result", getCurrOwner(), info)
     s.typ = t
     incl(s.flags, sfUsed)
     addParamOrResult(c, s, owner)
@@ -697,8 +694,7 @@ proc semLambda(c: PContext, n: PNode): PNode =
   if result != nil: return result
   result = n
   checkSonsLen(n, bodyPos + 1)
-  var s = newSym(skProc, getIdent":anonymous", getCurrOwner())
-  s.info = n.info
+  var s = newSym(skProc, getIdent":anonymous", getCurrOwner(), n.info)
   s.ast = n
   n.sons[namePos] = newSymNode(s)
   pushOwner(s)
@@ -830,7 +826,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
       popProcCon(c)
     else: 
       if s.typ.sons[0] != nil and kind != skIterator:
-        addDecl(c, newSym(skUnknown, getIdent"result", nil))
+        addDecl(c, newSym(skUnknown, getIdent"result", nil, n.info))
       var toBind = initIntSet()
       n.sons[bodyPos] = semGenericStmtScope(c, n.sons[bodyPos], {}, toBind)
       fixupInstantiatedSymbols(c, s)
diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim
index 4849f6d6c..62b4f06dd 100755
--- a/compiler/semtempl.nim
+++ b/compiler/semtempl.nim
@@ -104,9 +104,9 @@ proc getIdentNode(c: var TemplCtx, n: PNode): PNode =
     illFormedAst(n)
     result = n
 
-proc isTemplParam(n: PNode): bool {.inline.} =
+proc isTemplParam(c: TemplCtx, n: PNode): bool {.inline.} =
   result = n.kind == nkSym and n.sym.kind == skParam and
-           n.sym.owner.kind == skTemplate
+           n.sym.owner == c.owner
 
 proc semTemplBody(c: var TemplCtx, n: PNode): PNode
 
@@ -119,15 +119,15 @@ proc semTemplBodyScope(c: var TemplCtx, n: PNode): PNode =
   closeScope(c)
 
 proc newGenSym(kind: TSymKind, n: PNode, c: var TemplCtx): PSym =
-  result = newSym(kind, considerAcc(n), c.owner)
+  result = newSym(kind, considerAcc(n), c.owner, n.info)
   incl(result.flags, sfGenSym)
   incl(result.flags, sfShadowed)
 
 proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) =
   # locals default to 'gensym':
   if n.kind != nkPragmaExpr or symBinding(n.sons[1]) != spInject:
-    let ident = getIdentNode(c, n)    
-    if not isTemplParam(ident):
+    let ident = getIdentNode(c, n)
+    if not isTemplParam(c, ident):
       let local = newGenSym(k, ident, c)
       addPrelimDecl(c.c, local)
       replaceIdentBySym(n, newSymNode(local, n.info))
@@ -142,7 +142,7 @@ proc semRoutineInTemplBody(c: var TemplCtx, n: PNode, k: TSymKind): PNode =
   # routines default to 'inject':
   if n.kind notin nkLambdaKinds and symBinding(n.sons[pragmasPos]) == spGenSym:
     let ident = getIdentNode(c, n.sons[namePos])
-    if not isTemplParam(ident):
+    if not isTemplParam(c, ident):
       let s = newGenSym(k, ident, c)
       addPrelimDecl(c.c, s)
       n.sons[namePos] = newSymNode(s, n.sons[namePos].info)
@@ -164,6 +164,7 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
     let s = QualifiedLookUp(c.c, n, {})
     if s != nil:
       if s.owner == c.owner and s.kind == skParam:
+        incl(s.flags, sfUsed)
         result = newSymNode(s, n.info)
       elif Contains(c.toBind, s.id):
         result = symChoice(c.c, n, s)
@@ -286,6 +287,33 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
     result = n
     for i in countup(0, sonsLen(n) - 1):
       result.sons[i] = semTemplBody(c, n.sons[i])
+
+proc semTemplBodyDirty(c: var TemplCtx, n: PNode): PNode = 
+  result = n
+  case n.kind
+  of nkIdent:
+    let s = QualifiedLookUp(c.c, n, {})
+    if s != nil:
+      if s.owner == c.owner and s.kind == skParam:
+        result = newSymNode(s, n.info)
+      elif Contains(c.toBind, s.id):
+        result = symChoice(c.c, n, s)
+  of nkBind:
+    result = semTemplBodyDirty(c, n.sons[0])
+  of nkBindStmt:
+    result = semBindStmt(c.c, n, c.toBind)
+  of nkEmpty, nkSym..nkNilLit:
+    nil
+  else:
+    # dotExpr is ambiguous: note that we explicitely allow 'x.TemplateParam',
+    # so we use the generic code for nkDotExpr too
+    if n.kind == nkDotExpr or n.kind == nkAccQuoted:
+      let s = QualifiedLookUp(c.c, n, {})
+      if s != nil and Contains(c.toBind, s.id):
+        return symChoice(c.c, n, s)
+    result = n
+    for i in countup(0, sonsLen(n) - 1):
+      result.sons[i] = semTemplBodyDirty(c, n.sons[i])
   
 proc transformToExpr(n: PNode): PNode = 
   var realStmt: int
@@ -340,7 +368,10 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
   ctx.toBind = initIntSet()
   ctx.c = c
   ctx.owner = s
-  n.sons[bodyPos] = semTemplBody(ctx, n.sons[bodyPos])
+  if sfDirty in s.flags:
+    n.sons[bodyPos] = semTemplBodyDirty(ctx, n.sons[bodyPos])
+  else:
+    n.sons[bodyPos] = semTemplBody(ctx, n.sons[bodyPos])
   if s.typ.sons[0].kind notin {tyStmt, tyTypeDesc}:
     n.sons[bodyPos] = transformToExpr(n.sons[bodyPos]) 
     # only parameters are resolved, no type checking is performed
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index a54c3a297..d05adab3b 100755
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -622,7 +622,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
             result = genericParams.sons[i].typ
             break addImplicitGeneric
 
-        var s = newSym(skType, paramTypId, getCurrOwner())
+        var s = newSym(skType, paramTypId, getCurrOwner(), info)
         if isAnon: s.flags.incl(sfAnon)
         s.linkTo(typeClass)
         s.position = genericParams.len
diff --git a/compiler/transf.nim b/compiler/transf.nim
index 5cc0a5c74..57ada2b1a 100755
--- a/compiler/transf.nim
+++ b/compiler/transf.nim
@@ -96,8 +96,7 @@ proc getCurrOwner(c: PTransf): PSym =
   else: result = c.module
   
 proc newTemp(c: PTransf, typ: PType, info: TLineInfo): PSym = 
-  result = newSym(skTemp, getIdent(genPrefix), getCurrOwner(c))
-  result.info = info
+  result = newSym(skTemp, getIdent(genPrefix), getCurrOwner(c), info)
   result.typ = skipTypes(typ, {tyGenericInst})
   incl(result.flags, sfFromGeneric)
 
@@ -205,9 +204,8 @@ proc hasContinue(n: PNode): bool =
       if hasContinue(n.sons[i]): return true
 
 proc newLabel(c: PTransf, n: PNode): PSym =
-  result = newSym(skLabel, nil, getCurrOwner(c))
+  result = newSym(skLabel, nil, getCurrOwner(c), n.info)
   result.name = getIdent(genPrefix & $result.id)
-  result.info = n.info
 
 proc transformBlock(c: PTransf, n: PNode): PTransNode =
   var labl: PSym
diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim
index 43bdf4fa4..a68db8eb2 100755
--- a/compiler/wordrecg.nim
+++ b/compiler/wordrecg.nim
@@ -60,7 +60,8 @@ type
     wFieldChecks, 
     wWatchPoint, wSubsChar, 
     wAcyclic, wShallow, wUnroll, wLinearScanEnd,
-    wWrite, wGensym, wInject, wInheritable, wThreadVar, wEmit, wNoStackFrame,
+    wWrite, wGensym, wInject, wDirty, wInheritable, wThreadVar, wEmit, 
+    wNoStackFrame,
     wImplicitStatic, wGlobal, wHoist
 
     wAuto, wBool, wCatch, wChar, wClass,
@@ -138,7 +139,7 @@ const
     "passc", "passl", "borrow", "discardable", "fieldchecks",
     "watchpoint",
     "subschar", "acyclic", "shallow", "unroll", "linearscanend",
-    "write", "gensym", "inject", "inheritable", "threadvar", "emit",
+    "write", "gensym", "inject", "dirty", "inheritable", "threadvar", "emit",
     "nostackframe", "implicitstatic", "global", "hoist",
     
     "auto", "bool", "catch", "char", "class",