summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rwxr-xr-xcompiler/ccgexprs.nim9
-rwxr-xr-xcompiler/evals.nim5
-rwxr-xr-xcompiler/semexprs.nim7
-rwxr-xr-xcompiler/semfold.nim12
4 files changed, 23 insertions, 10 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index e02a38004..7b24e86db 100755
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -489,6 +489,13 @@ proc genEqProc(p: BProc, e: PNode, d: var TLoc) =
   else:
     putIntoDest(p, d, e.typ, ropef("($1 == $2)", [rdLoc(a), rdLoc(b)]))
 
+proc genIsNil(p: BProc, e: PNode, d: var TLoc) =
+  let t = skipTypes(e.sons[1].typ, abstractRange)
+  if t.kind == tyProc and t.callConv == ccClosure:
+    unaryExpr(p, e, d, "$1.ClPrc == 0")
+  else:
+    unaryExpr(p, e, d, "$1 == 0")
+
 proc unaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
   const
     unArithTab: array[mNot..mToBiggestInt, string] = ["!($1)", # Not
@@ -1419,7 +1426,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
   of mEqStr: genStrEquals(p, e, d)
   of mLeStr: binaryExpr(p, e, d, "(#cmpStrings($1, $2) <= 0)")
   of mLtStr: binaryExpr(p, e, d, "(#cmpStrings($1, $2) < 0)")
-  of mIsNil: unaryExpr(p, e, d, "$1 == 0")
+  of mIsNil: genIsNil(p, e, d)
   of mIntToStr: genDollar(p, e, d, "#nimIntToStr($1)")
   of mInt64ToStr: genDollar(p, e, d, "#nimInt64ToStr($1)")
   of mBoolToStr: genDollar(p, e, d, "#nimBoolToStr($1)")
diff --git a/compiler/evals.nim b/compiler/evals.nim
index dd975eb91..1f79466ef 100755
--- a/compiler/evals.nim
+++ b/compiler/evals.nim
@@ -900,16 +900,15 @@ proc evalTypeTrait*(n: PNode, context: PSym): PNode =
   ## XXX: This should be pretty much guaranteed to be true
   # by the type traits procs' signatures, but until the
   # code is more mature it doesn't hurt to be extra safe
-  internalAssert n.sons.len >= 2 and
+  internalAssert n.sons.len >= 2 and n.sons[1].kind == nkSym and
                  n.sons[1].sym.typ.kind == tyTypeDesc
   
   let typ = n.sons[1].sym.typ.skipTypes({tyTypeDesc})
-  case n.sons[0].sym.name.s
+  case n.sons[0].sym.name.s.normalize
   of "name":
     result = newStrNode(nkStrLit, typ.typeToString(preferExported))
     result.typ = newType(tyString, context)
     result.info = n.info
-
   else:
     internalAssert false
 
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 803dcdcfe..a0e7c329c 100755
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -262,11 +262,12 @@ proc semOf(c: PContext, n: PNode): PNode =
 
 proc semIs(c: PContext, n: PNode): PNode = 
   if sonsLen(n) == 3:
-    var a = semTypeNode(c, n[1], nil)
-    var b = semTypeNode(c, n[2], nil)
     n.typ = getSysType(tyBool)
+    let a = semTypeNode(c, n[1], nil)
     n.sons[1] = newNodeIT(nkType, n[1].info, a)
-    n.sons[2] = newNodeIT(nkType, n[2].info, b)
+    if n[2].kind notin {nkStrLit..nkTripleStrLit}:
+      let b = semTypeNode(c, n[2], nil)
+      n.sons[2] = newNodeIT(nkType, n[2].info, b)
     result = n
   else:
     GlobalError(n.info, errXExpectsTwoArguments, "is")
diff --git a/compiler/semfold.nim b/compiler/semfold.nim
index 30061f6eb..748a0a154 100755
--- a/compiler/semfold.nim
+++ b/compiler/semfold.nim
@@ -604,9 +604,15 @@ proc getConstExpr(m: PSym, n: PNode): PNode =
           result = magicCall(m, n)
       of mIs:
         # BUGFIX: don't evaluate this too early: ``T is void``
-        if not containsGenericType(n[1].typ) and 
-           not containsGenericType(n[2].typ):
-          result = newIntNodeT(ord(sameType(n[1].typ, n[2].typ)), n)
+        if not containsGenericType(n[1].typ):
+          if n[2].kind in {nkStrLit..nkTripleStrLit}:
+            case n[2].strVal.normalize
+            of "closure":
+              let t = skipTypes(n[1].typ, abstractRange)
+              result = newIntNodeT(ord(t.kind == tyProc and
+                                       t.callConv == ccClosure), n)
+          elif not containsGenericType(n[2].typ):
+            result = newIntNodeT(ord(sameType(n[1].typ, n[2].typ)), n)
       of mAstToStr:
         result = newStrNodeT(renderTree(n[1], {renderNoComments}), n)
       of mConStrStr: