summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ast.nim4
-rw-r--r--compiler/condsyms.nim1
-rw-r--r--compiler/parser.nim63
-rw-r--r--compiler/sem.nim3
-rw-r--r--compiler/semexprs.nim39
-rw-r--r--compiler/semtypes.nim38
-rw-r--r--compiler/sigmatch.nim14
-rw-r--r--lib/system.nim22
-rw-r--r--tests/lexer/tmissingnl.nim2
-rw-r--r--tests/parser/ttypemodifiers.nim152
10 files changed, 228 insertions, 110 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 40c1b064d..d266e20b0 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -571,8 +571,8 @@ type
   TMagic* = enum # symbols that require compiler magic:
     mNone,
     mDefined, mDefinedInScope, mCompiles, mArrGet, mArrPut, mAsgn,
-    mLow, mHigh, mSizeOf, mTypeTrait, mIs, mOf, mAddr, mTypeOf, mRoof, mPlugin,
-    mEcho, mShallowCopy, mSlurp, mStaticExec,
+    mLow, mHigh, mSizeOf, mTypeTrait, mIs, mOf, mAddr, mType, mTypeOf,
+    mRoof, mPlugin, mEcho, mShallowCopy, mSlurp, mStaticExec, mStatic,
     mParseExprToAst, mParseStmtToAst, mExpandToAst, mQuoteAst,
     mUnaryLt, mInc, mDec, mOrd,
     mNew, mNewFinalize, mNewSeq, mNewSeqOfCap,
diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim
index 56587a4fa..8b2d36722 100644
--- a/compiler/condsyms.nim
+++ b/compiler/condsyms.nim
@@ -44,6 +44,7 @@ proc initDefines*(symbols: StringTableRef) =
   defineSymbol("nimcomputedgoto")
   defineSymbol("nimunion")
   defineSymbol("nimnewshared")
+  defineSymbol("nimNewTypedesc")
   defineSymbol("nimrequiresnimframe")
   defineSymbol("nimparsebiggestfloatmagic")
   defineSymbol("nimalias")
diff --git a/compiler/parser.nim b/compiler/parser.nim
index c0465b05e..33ee8c9e6 100644
--- a/compiler/parser.nim
+++ b/compiler/parser.nim
@@ -50,6 +50,9 @@ type
   SymbolMode = enum
     smNormal, smAllowNil, smAfterDot
 
+  TPrimaryMode = enum
+    pmNormal, pmTypeDesc, pmTypeDef, pmSkipSuffix
+
 proc parseAll*(p: var TParser): PNode
 proc closeParser*(p: var TParser)
 proc parseTopLevelStmt*(p: var TParser): PNode
@@ -81,6 +84,9 @@ proc parsePragma(p: var TParser): PNode
 proc postExprBlocks(p: var TParser, x: PNode): PNode
 proc parseExprStmt(p: var TParser): PNode
 proc parseBlock(p: var TParser): PNode
+proc primary(p: var TParser, mode: TPrimaryMode): PNode
+proc simpleExprAux(p: var TParser, limit: int, mode: TPrimaryMode): PNode
+
 # implementation
 
 proc getTok(p: var TParser) =
@@ -332,6 +338,8 @@ proc colcom(p: var TParser, n: PNode) =
   eat(p, tkColon)
   skipComment(p, n)
 
+const tkBuiltInMagics = {tkType, tkStatic, tkAddr}
+
 proc parseSymbol(p: var TParser, mode = smNormal): PNode =
   #| symbol = '`' (KEYW|IDENT|literal|(operator|'('|')'|'['|']'|'{'|'}'|'=')+)+ '`'
   #|        | IDENT | KEYW
@@ -340,7 +348,7 @@ proc parseSymbol(p: var TParser, mode = smNormal): PNode =
     result = newIdentNodeP(p.tok.ident, p)
     getTok(p)
   of tokKeywordLow..tokKeywordHigh:
-    if p.tok.tokType == tkAddr or p.tok.tokType == tkType or mode == smAfterDot:
+    if p.tok.tokType in tkBuiltInMagics or mode == smAfterDot:
       # for backwards compatibility these 2 are always valid:
       result = newIdentNodeP(p.tok.ident, p)
       getTok(p)
@@ -525,9 +533,6 @@ proc parseGStrLit(p: var TParser, a: PNode): PNode =
   else:
     result = a
 
-type
-  TPrimaryMode = enum pmNormal, pmTypeDesc, pmTypeDef, pmSkipSuffix
-
 proc complexOrSimpleStmt(p: var TParser): PNode
 proc simpleExpr(p: var TParser, mode = pmNormal): PNode
 
@@ -625,7 +630,7 @@ proc identOrLiteral(p: var TParser, mode: TPrimaryMode): PNode =
   #| tupleConstr = '(' optInd (exprColonEqExpr comma?)* optPar ')'
   #| arrayConstr = '[' optInd (exprColonEqExpr comma?)* optPar ']'
   case p.tok.tokType
-  of tkSymbol, tkType, tkAddr:
+  of tkSymbol, tkBuiltInMagics:
     result = newIdentNodeP(p.tok.ident, p)
     getTok(p)
     result = parseGStrLit(p, result)
@@ -741,7 +746,12 @@ proc commandParam(p: var TParser, isFirstParam: var bool): PNode =
     addSon(result, parseExpr(p))
   isFirstParam = false
 
-proc primarySuffix(p: var TParser, r: PNode, baseIndent: int): PNode =
+const
+  tkTypeClasses = {tkRef, tkPtr, tkVar, tkStatic, tkType,
+                   tkEnum, tkTuple, tkObject, tkProc}
+
+proc primarySuffix(p: var TParser, r: PNode,
+                   baseIndent: int, mode: TPrimaryMode): PNode =
   #| primarySuffix = '(' (exprColonEqExpr comma?)* ')' doBlocks?
   #|       | doBlocks
   #|       | '.' optInd symbol generalizedLit?
@@ -758,7 +768,14 @@ proc primarySuffix(p: var TParser, r: PNode, baseIndent: int): PNode =
     case p.tok.tokType
     of tkParLe:
       # progress guaranteed
-      somePar()
+      if p.tok.strongSpaceA > 0:
+        # inside type sections, expressions such as `ref (int, bar)`
+        # are parsed as a nkCommand with a single tuple argument (nkPar)
+        if mode == pmTypeDef:
+          result = newNodeP(nkCommand, p)
+          result.addSon r
+          result.addSon primary(p, pmNormal)
+        break
       result = namedParams(p, result, nkCall, tkParRi)
       if result.len > 1 and result.sons[1].kind == nkExprColonExpr:
         result.kind = nkObjConstr
@@ -774,9 +791,15 @@ proc primarySuffix(p: var TParser, r: PNode, baseIndent: int): PNode =
       # progress guaranteed
       somePar()
       result = namedParams(p, result, nkCurlyExpr, tkCurlyRi)
-    of tkSymbol, tkAccent, tkIntLit..tkCharLit, tkNil, tkCast, tkAddr, tkType,
-       tkOpr, tkDotDot:
-      if p.inPragma == 0 and (isUnary(p) or p.tok.tokType notin {tkOpr, tkDotDot}):
+    of tkSymbol, tkAccent, tkIntLit..tkCharLit, tkNil, tkCast,
+       tkOpr, tkDotDot, tkTypeClasses - {tkRef, tkPtr}:
+        # XXX: In type sections we allow the free application of the
+        # command syntax, with the exception of expressions such as
+        # `foo ref` or `foo ptr`. Unfortunately, these two are also
+        # used as infix operators for the memory regions feature and
+        # the current parsing rules don't play well here.
+      if mode == pmTypeDef or
+        (p.inPragma == 0 and (isUnary(p) or p.tok.tokType notin {tkOpr, tkDotDot})):
         # actually parsing {.push hints:off.} as {.push(hints:off).} is a sweet
         # solution, but pragmas.nim can't handle that
         let a = result
@@ -800,9 +823,6 @@ proc primarySuffix(p: var TParser, r: PNode, baseIndent: int): PNode =
     else:
       break
 
-proc primary(p: var TParser, mode: TPrimaryMode): PNode
-proc simpleExprAux(p: var TParser, limit: int, mode: TPrimaryMode): PNode
-
 proc parseOperators(p: var TParser, headNode: PNode,
                     limit: int, mode: TPrimaryMode): PNode =
   result = headNode
@@ -1107,9 +1127,9 @@ proc parseProcExpr(p: var TParser; isExpr: bool; kind: TNodeKind): PNode =
 proc isExprStart(p: TParser): bool =
   case p.tok.tokType
   of tkSymbol, tkAccent, tkOpr, tkNot, tkNil, tkCast, tkIf,
-     tkProc, tkFunc, tkIterator, tkBind, tkAddr,
+     tkProc, tkFunc, tkIterator, tkBind, tkBuiltInMagics,
      tkParLe, tkBracketLe, tkCurlyLe, tkIntLit..tkCharLit, tkVar, tkRef, tkPtr,
-     tkTuple, tkObject, tkType, tkWhen, tkCase, tkOut:
+     tkTuple, tkObject, tkWhen, tkCase, tkOut:
     result = true
   else: result = false
 
@@ -1170,7 +1190,6 @@ proc primary(p: var TParser, mode: TPrimaryMode): PNode =
   #|          | 'proc' | 'iterator' | 'distinct' | 'object' | 'enum'
   #| primary = typeKeyw typeDescK
   #|         /  prefixOperator* identOrLiteral primarySuffix*
-  #|         / 'static' primary
   #|         / 'bind' primary
   if isOperator(p.tok):
     let isSigil = isSigilLike(p.tok)
@@ -1183,7 +1202,7 @@ proc primary(p: var TParser, mode: TPrimaryMode): PNode =
       #XXX prefix operators
       let baseInd = p.lex.currLineIndent
       addSon(result, primary(p, pmSkipSuffix))
-      result = primarySuffix(p, result, baseInd)
+      result = primarySuffix(p, result, baseInd, mode)
     else:
       addSon(result, primary(p, pmNormal))
     return
@@ -1213,14 +1232,6 @@ proc primary(p: var TParser, mode: TPrimaryMode): PNode =
       result = parseTypeClass(p)
     else:
       parMessage(p, "the 'concept' keyword is only valid in 'type' sections")
-  of tkStatic:
-    let info = parLineInfo(p)
-    getTokNoInd(p)
-    let next = primary(p, pmNormal)
-    if next.kind == nkBracket and next.sonsLen == 1:
-      result = newNode(nkStaticTy, info, @[next.sons[0]])
-    else:
-      result = newNode(nkStaticExpr, info, @[next])
   of tkBind:
     result = newNodeP(nkBind, p)
     getTok(p)
@@ -1235,7 +1246,7 @@ proc primary(p: var TParser, mode: TPrimaryMode): PNode =
     let baseInd = p.lex.currLineIndent
     result = identOrLiteral(p, mode)
     if mode != pmSkipSuffix:
-      result = primarySuffix(p, result, baseInd)
+      result = primarySuffix(p, result, baseInd, mode)
 
 proc parseTypeDesc(p: var TParser): PNode =
   #| typeDesc = simpleExpr
diff --git a/compiler/sem.nim b/compiler/sem.nim
index 3b16e0938..3c3ffa194 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -48,6 +48,9 @@ proc semQuoteAst(c: PContext, n: PNode): PNode
 proc finishMethod(c: PContext, s: PSym)
 proc evalAtCompileTime(c: PContext, n: PNode): PNode
 proc indexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode
+proc semStaticExpr(c: PContext, n: PNode): PNode
+proc semStaticType(c: PContext, childNode: PNode, prev: PType): PType
+proc semTypeOf(c: PContext; n: PNode): PNode
 
 proc isArrayConstr(n: PNode): bool {.inline.} =
   result = n.kind == nkBracket and
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 9d7c493a7..4b45ccf87 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -191,7 +191,25 @@ proc semConv(c: PContext, n: PNode): PNode =
     return n
 
   result = newNodeI(nkConv, n.info)
-  var targetType = semTypeNode(c, n.sons[0], nil).skipTypes({tyTypeDesc})
+
+  var targetType = semTypeNode(c, n.sons[0], nil)
+  if targetType.kind == tyTypeDesc:
+    internalAssert targetType.len > 0
+    if targetType.base.kind == tyNone:
+      return semTypeOf(c, n[1])
+    else:
+      targetType = targetType.base
+  elif targetType.kind == tyStatic:
+    var evaluated = semStaticExpr(c, n[1])
+    if evaluated.kind == nkType or evaluated.typ.kind == tyTypeDesc:
+      result = n
+      result.typ = c.makeTypeDesc semStaticType(c, evaluated, nil)
+      return
+    elif targetType.base.kind == tyNone:
+      return evaluated
+    else:
+      targetType = targetType.base
+
   maybeLiftType(targetType, c, n[0].info)
 
   if targetType.kind in {tySink, tyLent}:
@@ -632,7 +650,7 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode =
     #  echo "SUCCESS evaluated at compile time: ", call.renderTree
 
 proc semStaticExpr(c: PContext, n: PNode): PNode =
-  let a = semExpr(c, n.sons[0])
+  let a = semExpr(c, n)
   if a.findUnresolvedStatic != nil: return a
   result = evalStaticExpr(c.module, c.graph, a, c.p.owner)
   if result.isNil:
@@ -1034,7 +1052,7 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
   of skType:
     markUsed(c.config, n.info, s, c.graph.usageSym)
     styleCheckUse(n.info, s)
-    if s.typ.kind == tyStatic and s.typ.n != nil:
+    if s.typ.kind == tyStatic and s.typ.base.kind != tyNone and s.typ.n != nil:
       return s.typ.n
     result = newSymNode(s, n.info)
     result.typ = makeTypeDesc(c, s.typ)
@@ -1261,8 +1279,18 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
   # make sure we don't evaluate generic macros/templates
   n.sons[0] = semExprWithType(c, n.sons[0],
                               {efNoEvaluateGeneric})
-  let arr = skipTypes(n.sons[0].typ, {tyGenericInst,
+  var arr = skipTypes(n.sons[0].typ, {tyGenericInst,
                                       tyVar, tyLent, tyPtr, tyRef, tyAlias, tySink})
+  if arr.kind == tyStatic:
+    if arr.base.kind == tyNone:
+      result = n
+      result.typ = semStaticType(c, n[1], nil)
+      return
+    elif arr.n != nil:
+      return semSubscript(c, arr.n, flags)
+    else:
+      arr = arr.base
+
   case arr.kind
   of tyArray, tyOpenArray, tyVarargs, tySequence, tyString,
      tyCString:
@@ -2426,8 +2454,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
     # handling of sym choices is context dependent
     # the node is left intact for now
     discard
-  of nkStaticExpr:
-    result = semStaticExpr(c, n)
+  of nkStaticExpr: result = semStaticExpr(c, n[0])
   of nkAsgn: result = semAsgn(c, n)
   of nkBlockStmt, nkBlockExpr: result = semBlock(c, n)
   of nkStmtList, nkStmtListExpr: result = semStmtList(c, n, flags)
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 3e62652a7..597522f6f 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -37,6 +37,12 @@ const
   errNoGenericParamsAllowedForX = "no generic parameters allowed for $1"
   errInOutFlagNotExtern = "the '$1' modifier can be used only with imported types"
 
+const
+  mStaticTy = {mStatic}
+  mTypeTy = {mType, mTypeOf}
+  # XXX: This should be needed only temporarily until the C
+  # sources are rebuilt
+
 proc newOrPrevType(kind: TTypeKind, prev: PType, c: PContext): PType =
   if prev == nil:
     result = newTypeS(kind, c)
@@ -363,6 +369,7 @@ proc semTypeIdent(c: PContext, n: PNode): PSym =
     if result != nil:
       markUsed(c.config, n.info, result, c.graph.usageSym)
       styleCheckUse(n.info, result)
+
       if result.kind == skParam and result.typ.kind == tyTypeDesc:
         # This is a typedesc param. is it already bound?
         # it's not bound when it's used multiple times in the
@@ -388,8 +395,7 @@ proc semTypeIdent(c: PContext, n: PNode): PSym =
         else:
           localError(c.config, n.info, errTypeExpected)
           return errorSym(c, n)
-
-      if result.kind != skType:
+      if result.kind != skType and result.magic notin (mStaticTy + mTypeTy):
         # this implements the wanted ``var v: V, x: V`` feature ...
         var ov: TOverloadIter
         var amb = initOverloadIter(ov, c, n)
@@ -856,9 +862,9 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
     result = addImplicitGenericImpl(c, newTypeS(tyGenericParam, c), nil)
 
   of tyStatic:
-    # proc(a: expr{string}, b: expr{nkLambda})
-    # overload on compile time values and AST trees
-    if paramType.n != nil: return # this is a concrete type
+    if paramType.base.kind != tyNone and paramType.n != nil:
+      # this is a concrete type
+      return
     if tfUnresolved in paramType.flags: return # already lifted
     let base = paramType.base.maybeLift
     if base.isMetaType and procKind == skMacro:
@@ -879,7 +885,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
   of tyDistinct:
     if paramType.sonsLen == 1:
       # disable the bindOnce behavior for the type class
-      result = liftingWalk(paramType.sons[0], true)
+      result = liftingWalk(paramType.base, true)
 
   of tySequence, tySet, tyArray, tyOpenArray,
      tyVar, tyLent, tyPtr, tyRef, tyProc:
@@ -1349,6 +1355,12 @@ proc symFromExpectedTypeNode(c: PContext, n: PNode): PSym =
     localError(c.config, n.info, errTypeExpected)
     result = errorSym(c, n)
 
+proc semStaticType(c: PContext, childNode: PNode, prev: PType): PType =
+  result = newOrPrevType(tyStatic, prev, c)
+  var base = semTypeNode(c, childNode, nil).skipTypes({tyTypeDesc, tyAlias})
+  result.rawAddSon(base)
+  result.flags.incl tfHasStatic
+
 proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
   result = nil
   inc c.inTypeContext
@@ -1456,7 +1468,8 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
     of mSeq: result = semContainer(c, n, tySequence, "seq", prev)
     of mOpt: result = semContainer(c, n, tyOpt, "opt", prev)
     of mVarargs: result = semVarargs(c, n, prev)
-    of mTypeDesc: result = makeTypeDesc(c, semTypeNode(c, n[1], nil))
+    of mTypeDesc, mTypeTy: result = makeTypeDesc(c, semTypeNode(c, n[1], nil))
+    of mStaticTy: result = semStaticType(c, n[1], prev)
     of mExpr:
       result = semTypeNode(c, n.sons[0], nil)
       if result != nil:
@@ -1545,11 +1558,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
   of nkPtrTy: result = semAnyRef(c, n, tyPtr, prev)
   of nkVarTy: result = semVarType(c, n, prev)
   of nkDistinctTy: result = semDistinct(c, n, prev)
-  of nkStaticTy:
-    result = newOrPrevType(tyStatic, prev, c)
-    var base = semTypeNode(c, n.sons[0], nil).skipTypes({tyTypeDesc})
-    result.rawAddSon(base)
-    result.flags.incl tfHasStatic
+  of nkStaticTy: result = semStaticType(c, n[0], prev)
   of nkIteratorTy:
     if n.sonsLen == 0:
       result = newTypeS(tyBuiltInTypeClass, c)
@@ -1645,9 +1654,12 @@ proc processMagicType(c: PContext, m: PSym) =
   of mStmt:
     setMagicType(c.config, m, tyStmt, 0)
     if m.name.s == "stmt": m.typ.flags.incl tfOldSchoolExprStmt
-  of mTypeDesc:
+  of mTypeDesc, mType:
     setMagicType(c.config, m, tyTypeDesc, 0)
     rawAddSon(m.typ, newTypeS(tyNone, c))
+  of mStatic:
+    setMagicType(m, tyStatic, 0)
+    rawAddSon(m.typ, newTypeS(tyNone, c))
   of mVoidType:
     setMagicType(c.config, m, tyVoid, 0)
   of mArray:
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 9a3c75261..5a556732b 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -1666,13 +1666,17 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
     let prev = PType(idTableGet(c.bindings, f))
     if prev == nil:
       if aOrig.kind == tyStatic:
-        result = typeRel(c, f.lastSon, a)
-        if result != isNone and f.n != nil:
-          if not exprStructuralEquivalent(f.n, aOrig.n):
-            result = isNone
+        if f.base.kind != tyNone:
+          result = typeRel(c, f.base, a)
+          if result != isNone and f.n != nil:
+            if not exprStructuralEquivalent(f.n, aOrig.n):
+              result = isNone
+        else:
+          result = isGeneric
         if result != isNone: put(c, f, aOrig)
       elif aOrig.n != nil and aOrig.n.typ != nil:
-        result = typeRel(c, f.lastSon, aOrig.n.typ)
+        result = if f.base.kind != tyNone: typeRel(c, f.lastSon, aOrig.n.typ)
+                 else: isGeneric
         if result != isNone:
           var boundType = newTypeWithSons(c.c, tyStatic, @[aOrig.n.typ])
           boundType.n = aOrig.n
diff --git a/lib/system.nim b/lib/system.nim
index fb02fde23..15f952feb 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -179,10 +179,24 @@ proc unsafeAddr*[T](x: T): ptr T {.magic: "Addr", noSideEffect.} =
   ## Cannot be overloaded.
   discard
 
-proc `type`*(x: untyped): typeDesc {.magic: "TypeOf", noSideEffect, compileTime.} =
-  ## Builtin 'type' operator for accessing the type of an expression.
-  ## Cannot be overloaded.
-  discard
+when defined(nimNewTypedesc):
+  type
+    `static`* {.magic: "Static".}[T]
+      ## meta type representing all values that can be evaluated at compile-time.
+      ##
+      ## The type coercion ``static(x)`` can be used to force the compile-time
+      ## evaluation of the given expression ``x``.
+
+    `type`* {.magic: "Type".}[T]
+      ## meta type representing the type of all type values.
+      ##
+      ## The coercion ``type(x)`` can be used to obtain the type of the given
+      ## expression ``x``.
+else:
+  proc `type`*(x: untyped): typeDesc {.magic: "TypeOf", noSideEffect, compileTime.} =
+    ## Builtin 'type' operator for accessing the type of an expression.
+    ## Cannot be overloaded.
+    discard
 
 proc `not` *(x: bool): bool {.magic: "Not", noSideEffect.}
   ## Boolean not; returns true iff ``x == false``.
diff --git a/tests/lexer/tmissingnl.nim b/tests/lexer/tmissingnl.nim
index 33b7debf1..095d9570e 100644
--- a/tests/lexer/tmissingnl.nim
+++ b/tests/lexer/tmissingnl.nim
@@ -4,7 +4,7 @@ discard """
   errormsg: "invalid indentation"
 """
 
-import strutils var s: seq[int] = @[0, 1, 2, 3, 4, 5, 6]
+import strutils let s: seq[int] = @[0, 1, 2, 3, 4, 5, 6]
 
 #s[1..3] = @[]
 
diff --git a/tests/parser/ttypemodifiers.nim b/tests/parser/ttypemodifiers.nim
index db7ab903f..2c322b44b 100644
--- a/tests/parser/ttypemodifiers.nim
+++ b/tests/parser/ttypemodifiers.nim
@@ -54,24 +54,32 @@ StmtList
           Ident "a"
           Ident "b"
     TypeDef
+      Ident "BareStatic"
+      Empty
+      Ident "static"
+    TypeDef
       Ident "GenericStatic"
       Empty
-      StaticTy
+      BracketExpr
+        Ident "static"
         Ident "int"
     TypeDef
       Ident "PrefixStatic"
       Empty
-      StaticExpr
+      Command
+        Ident "static"
         Ident "int"
     TypeDef
       Ident "StaticTupleCl"
       Empty
-      StaticExpr
+      Command
+        Ident "static"
         TupleClassTy
     TypeDef
       Ident "StaticTuple"
       Empty
-      StaticExpr
+      Command
+        Ident "static"
         Par
           Ident "int"
           Ident "string"
@@ -92,6 +100,12 @@ StmtList
         Ident "type"
         TupleClassTy
     TypeDef
+      Ident "TypeTupleCl"
+      Empty
+      Command
+        Ident "type"
+        TupleClassTy
+    TypeDef
       Ident "TypeInstance"
       Empty
       Command
@@ -110,6 +124,13 @@ StmtList
         Ident "type"
         Ident "a"
     TypeDef
+      Ident "TypeOfVarAlt"
+      Empty
+      Command
+        Ident "type"
+        Par
+          Ident "a"
+    TypeDef
       Ident "TypeOfTuple1"
       Empty
       Call
@@ -123,6 +144,29 @@ StmtList
         Ident "a"
         Ident "b"
     TypeDef
+      Ident "TypeOfTuple1A"
+      Empty
+      Command
+        Ident "type"
+        TupleConstr
+          Ident "a"
+    TypeDef
+      Ident "TypeOfTuple2A"
+      Empty
+      Command
+        Ident "type"
+        Par
+          Ident "a"
+          Ident "b"
+    TypeDef
+      Ident "TypeTuple"
+      Empty
+      Command
+        Ident "type"
+        Par
+          Ident "int"
+          Ident "string"
+    TypeDef
       Ident "GenericTypedesc"
       Empty
       BracketExpr
@@ -173,32 +217,52 @@ StmtList
           Ident "type"
         Empty
       IdentDefs
+        Ident "typeTupleCl"
+        Command
+          Ident "type"
+          TupleClassTy
+        Empty
+      IdentDefs
+        Ident "bareStatic"
+        Ident "static"
+        Empty
+      IdentDefs
         Ident "genStatic"
-        StaticTy
+        BracketExpr
+          Ident "static"
           Ident "int"
         Empty
       IdentDefs
         Ident "staticInt"
-        StaticExpr
+        Command
+          Ident "static"
           Ident "int"
         Empty
       IdentDefs
         Ident "staticVal1"
-        StaticExpr
+        Command
+          Ident "static"
           IntLit 10
         Empty
       IdentDefs
         Ident "staticVal2"
-        StaticExpr
-          Par
-            StrLit "str"
+        Call
+          Ident "static"
+          StrLit "str"
         Empty
       IdentDefs
         Ident "staticVal3"
-        StaticExpr
+        Command
+          Ident "static"
           StrLit "str"
         Empty
       IdentDefs
+        Ident "staticVal4"
+        CallStrLit
+          Ident "static"
+          RStrLit "str"
+        Empty
+      IdentDefs
         Ident "staticDotVal"
         DotExpr
           IntLit 10
@@ -285,50 +349,32 @@ StmtList
     StmtList
       Asgn
         Ident "staticTen"
-        StaticExpr
+        Command
+          Ident "static"
           IntLit 10
       Asgn
         Ident "staticA"
-        StaticExpr
-          Par
-            Ident "a"
-      Asgn
-        Ident "staticAspace"
-        StaticExpr
-          Par
-            Ident "a"
-      Asgn
-        Ident "staticAtuple"
-        StaticExpr
-          TupleConstr
-            Ident "a"
-      Asgn
-        Ident "staticTuple"
-        StaticExpr
-          Par
-            Ident "a"
-            Ident "b"
-      Asgn
-        Ident "staticTypeTuple"
-        StaticExpr
-          Par
-            Ident "int"
-            Ident "string"
+        Call
+          Ident "static"
+          Ident "a"
       Asgn
         Ident "staticCall"
-        StaticExpr
+        Command
+          Ident "static"
           Call
             Ident "foo"
             IntLit 1
       Asgn
         Ident "staticStrCall"
-        StaticExpr
+        Command
+          Ident "static"
           CallStrLit
             Ident "foo"
             RStrLit "x"
       Asgn
         Ident "staticChainCall"
-        StaticExpr
+        Command
+          Ident "static"
           Command
             Ident "foo"
             Ident "bar"
@@ -399,7 +445,7 @@ dumpTree:
     RefTupleCl    = ref tuple
     RefTupleType  = ref (int, string)
     RefTupleVars  = ref (a, b)
-    # BareStatic  = static                # Error: invalid indentation
+    BareStatic    = static                # Used to be Error: invalid indentation
     GenericStatic = static[int]
     PrefixStatic  = static int
     StaticTupleCl = static tuple
@@ -407,16 +453,16 @@ dumpTree:
     BareType      = type
     GenericType   = type[float]
     TypeTupleGen  = type[tuple]
-    # TypeTupleCl = type tuple            # Error: invalid indentation
+    TypeTupleCl   = type tuple            # Used to be Error: invalid indentation
     TypeInstance  = type Foo[ref]
     bareTypeDesc  = typedesc
     TypeOfVar     = type(a)
-    # TypeOfVarAlt= type (a)              # Error: invalid indentation
+    TypeOfVarAlt  = type (a)              # Used to be Error: invalid indentation
     TypeOfTuple1  = type(a,)
     TypeOfTuple2  = type(a,b)
-    # TypeOfTuple1A = type (a,)           # Error: invalid indentation
-    # TypeOfTuple2A = type (a,b)          # Error: invalid indentation
-    # TypeTuple     = type (int, string)  # Error: invalid indentation
+    TypeOfTuple1A = type (a,)             # Used to be Error: invalid indentation
+    TypeOfTuple2A = type (a,b)            # Used to be Error: invalid indentation
+    TypeTuple     = type (int, string)    # Used to be Error: invalid indentation
     GenericTypedesc = typedesc[int]
     T = type
 
@@ -427,14 +473,14 @@ dumpTree:
     typeIntAlt      : type(int),
     typeOfVar       : type(a),
     typeDotType     : foo.type,
-    # typeTupleCl   : type tuple,         # Error: ')' expected
-    # bareStatic    : static,             # Error: expression expected, but found ','
+    typeTupleCl     : type tuple,         # Used to be Error: ')' expected
+    bareStatic      : static,             # Used to be Error: expression expected, but found ','
     genStatic       : static[int],
     staticInt       : static int,
     staticVal1      : static 10,
     staticVal2      : static("str"),
     staticVal3      : static "str",
-    # staticVal4    : static"str",        # Error: expression expected, but found 'str'
+    staticVal4      : static"str",        # Used to be Error: expression expected, but found 'str'
     staticDotVal    : 10.static,
     bareRef         : ref,
     refTuple1       : ref (int),
@@ -451,10 +497,10 @@ dumpTree:
   ): type =
     staticTen       = static 10
     staticA         = static(a)
-    staticAspace    = static (a)
-    staticAtuple    = static (a,)
-    staticTuple     = static (a,b)
-    staticTypeTuple = static (int,string)
+    # staticAspace    = static (a)          # With newTypedesc: Error: invalid indentation
+    # staticAtuple    = static (a,)         # With newTypedesc: Error: invalid indentation
+    # staticTuple     = static (a,b)        # With newTypedesc: Error: invalid indentation
+    # staticTypeTuple = static (int,string) # With newTypedesc: Error: invalid indentation
     staticCall      = static foo(1)
     staticStrCall   = static foo"x"
     staticChainCall = static foo bar