summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/renderer.nim2
-rw-r--r--compiler/semexprs.nim4
-rw-r--r--compiler/semfold.nim8
-rw-r--r--compiler/semtypes.nim24
-rw-r--r--compiler/vm.nim11
-rw-r--r--compiler/vmgen.nim12
6 files changed, 36 insertions, 25 deletions
diff --git a/compiler/renderer.nim b/compiler/renderer.nim
index b0d328f9e..3f7b0e657 100644
--- a/compiler/renderer.nim
+++ b/compiler/renderer.nim
@@ -620,7 +620,7 @@ proc gpattern(g: var TSrcGen, n: PNode) =
   if longMode(n) or (lsub(n.sons[0]) + g.lineLen > MaxLineLen):
     incl(c.flags, rfLongMode)
   gcoms(g)                    # a good place for comments
-  gstmts(g, n.sons[0], c)
+  gstmts(g, n, c)
   put(g, tkCurlyRi, "}")
 
 proc gpragmaBlock(g: var TSrcGen, n: PNode) = 
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index ac82e9fed..ce06c2e77 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1249,8 +1249,8 @@ proc semAsgn(c: PContext, n: PNode): PNode =
 proc semReturn(c: PContext, n: PNode): PNode =
   result = n
   checkSonsLen(n, 1)
-  if c.p.owner.kind in {skConverter, skMethod, skProc, skMacro} or
-     c.p.owner.kind == skClosureIterator:
+  if c.p.owner.kind in {skConverter, skMethod, skProc, skMacro,
+                        skClosureIterator}:
     if n.sons[0].kind != nkEmpty:
       # transform ``return expr`` to ``result = expr; return``
       if c.p.resultSym != nil: 
diff --git a/compiler/semfold.nim b/compiler/semfold.nim
index c7ae42548..220abcad7 100644
--- a/compiler/semfold.nim
+++ b/compiler/semfold.nim
@@ -197,18 +197,20 @@ proc getIntervalType*(m: TMagic, n: PNode): PType =
   of mSubI, mSubI64, mSubU:
     binaryOp(`|-|`)
   of mBitandI, mBitandI64:
+    # since uint64 is still not even valid for 'range' (since it's no ordinal
+    # yet), we exclude it from the list (see bug #1638) for now:
     var a = n.sons[1]
     var b = n.sons[2]
     # symmetrical:
-    if b.kind notin {nkIntLit..nkUInt64Lit}: swap(a, b)
-    if b.kind in {nkIntLit..nkUInt64Lit}:
+    if b.kind notin {nkIntLit..nkUInt32Lit}: swap(a, b)
+    if b.kind in {nkIntLit..nkUInt32Lit}:
       let x = b.intVal|+|1
       if (x and -x) == x and x >= 0:
         result = makeRange(a.typ, 0, b.intVal)
   of mModU:
     let a = n.sons[1]
     let b = n.sons[2]
-    if b.kind in {nkIntLit..nkUInt64Lit}:
+    if b.kind in {nkIntLit..nkUInt32Lit}:
       if b.intVal >= 0:
         result = makeRange(a.typ, 0, b.intVal-1)
       else:
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 1d0bba6f0..e33df75ff 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -939,17 +939,19 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
     # turn explicit 'void' return type into 'nil' because the rest of the 
     # compiler only checks for 'nil':
     if skipTypes(r, {tyGenericInst}).kind != tyEmpty:
-      if r.sym == nil or sfAnon notin r.sym.flags:
-        let lifted = liftParamType(c, kind, genericParams, r, "result",
-                                   n.sons[0].info)
-        if lifted != nil: r = lifted
-        r.flags.incl tfRetType
-      r = skipIntLit(r)
-      if kind == skIterator:
-        # see tchainediterators
-        # in cases like iterator foo(it: iterator): type(it)
-        # we don't need to change the return type to iter[T]
-        if not r.isInlineIterator: r = newTypeWithSons(c, tyIter, @[r])
+      # 'auto' as a return type does not imply a generic:
+      if r.kind != tyExpr:
+        if r.sym == nil or sfAnon notin r.sym.flags:
+          let lifted = liftParamType(c, kind, genericParams, r, "result",
+                                     n.sons[0].info)
+          if lifted != nil: r = lifted
+          r.flags.incl tfRetType
+        r = skipIntLit(r)
+        if kind == skIterator:
+          # see tchainediterators
+          # in cases like iterator foo(it: iterator): type(it)
+          # we don't need to change the return type to iter[T]
+          if not r.isInlineIterator: r = newTypeWithSons(c, tyIter, @[r])
       result.sons[0] = r
       res.typ = r
 
diff --git a/compiler/vm.nim b/compiler/vm.nim
index 2da242771..ad0d3b0a1 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -454,8 +454,11 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
     of opcLdStrIdx:
       decodeBC(rkInt)
       let idx = regs[rc].intVal.int
-      if idx <=% regs[rb].node.strVal.len:
-        regs[ra].intVal = regs[rb].node.strVal[idx].ord
+      let s = regs[rb].node.strVal
+      if s.isNil:
+        stackTrace(c, tos, pc, errNilAccess)
+      elif idx <=% s.len:
+        regs[ra].intVal = s[idx].ord
       else:
         stackTrace(c, tos, pc, errIndexOutOfBounds)
     of opcWrArr:
@@ -1058,7 +1061,9 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
       regs[ra].intVal = regs[ra].intVal and ((1'i64 shl rb)-1)
     of opcIsNil:
       decodeB(rkInt)
-      regs[ra].intVal = ord(regs[rb].node.kind == nkNilLit)
+      let node = regs[rb].node
+      regs[ra].intVal = ord(node.kind == nkNilLit or
+        (node.kind in {nkStrLit..nkTripleStrLit} and node.strVal.isNil))
     of opcNBindSym:
       decodeBx(rkNode)
       regs[ra].node = copyTree(c.constants.sons[rbx])
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index fe909b887..7397a562c 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -370,8 +370,8 @@ proc sameConstant*(a, b: PNode): bool =
     of nkCharLit..nkInt64Lit: result = a.intVal == b.intVal
     of nkFloatLit..nkFloat64Lit: result = a.floatVal == b.floatVal
     of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal
-    of nkType: result = a.typ == b.typ
-    of nkEmpty, nkNilLit: result = true
+    of nkType, nkNilLit: result = a.typ == b.typ
+    of nkEmpty: result = true
     else:
       if sonsLen(a) == sonsLen(b):
         for i in countup(0, sonsLen(a) - 1):
@@ -1350,7 +1350,9 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
     result = newNodeIT(nkUIntLit, info, t)
   of tyFloat..tyFloat128: 
     result = newNodeIT(nkFloatLit, info, t)
-  of tyVar, tyPointer, tyPtr, tyCString, tySequence, tyString, tyExpr,
+  of tyCString, tyString:
+    result = newNodeIT(nkStrLit, info, t)
+  of tyVar, tyPointer, tyPtr, tySequence, tyExpr,
      tyStmt, tyTypeDesc, tyStatic, tyRef:
     result = newNodeIT(nkNilLit, info, t)
   of tyProc:
@@ -1570,7 +1572,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
       genLit(c, n, dest)
   of nkUIntLit..pred(nkNilLit): genLit(c, n, dest)
   of nkNilLit:
-    if not n.typ.isEmptyType: genLit(c, n, dest)
+    if not n.typ.isEmptyType: genLit(c, getNullValue(n.typ, n.info), dest)
     else: unused(n, dest)
   of nkAsgn, nkFastAsgn: 
     unused(n, dest)
@@ -1647,7 +1649,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
     if allowCast in c.features:
       genConv(c, n, n.sons[1], dest, opcCast)
     else:
-      localError(n.info, errGenerated, "VM is not allowed to 'cast'")
+      globalError(n.info, errGenerated, "VM is not allowed to 'cast'")
   else:
     internalError n.info, "cannot generate VM code for " & n.renderTree