summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2016-04-04 02:45:43 +0200
committerAndreas Rumpf <rumpf_a@web.de>2016-04-04 02:45:43 +0200
commit0acdaea3342e13317ac9956add08e606208b2986 (patch)
tree6440d2c6868f2543d8245a6dffbb724b79c6ba22
parent86e79f5cec118587c7e52f614c245176cf480597 (diff)
downloadNim-0acdaea3342e13317ac9956add08e606208b2986.tar.gz
fixes #3561, fixes #2409
-rw-r--r--compiler/vmgen.nim10
-rw-r--r--tests/vm/tanonproc.nim52
2 files changed, 59 insertions, 3 deletions
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index 7e506f8a0..038a07a16 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -708,6 +708,10 @@ proc genAddSubInt(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) =
   c.genNarrow(n, dest)
 
 proc genConv(c: PCtx; n, arg: PNode; dest: var TDest; opc=opcConv) =
+  if n.typ.kind == arg.typ.kind and arg.typ.kind == tyProc:
+    # don't do anything for lambda lifting conversions:
+    gen(c, arg, dest)
+    return
   let tmp = c.genx(arg)
   if dest < 0: dest = c.getTemp(n.typ)
   c.gABC(n, opc, dest, tmp)
@@ -1740,9 +1744,9 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
   of declarativeDefs:
     unused(n, dest)
   of nkLambdaKinds:
-    let s = n.sons[namePos].sym
-    discard genProc(c, s)
-    genLit(c, n.sons[namePos], dest)
+    #let s = n.sons[namePos].sym
+    #discard genProc(c, s)
+    genLit(c, newSymNode(n.sons[namePos].sym), dest)
   of nkChckRangeF, nkChckRange64, nkChckRange:
     let
       tmp0 = c.genx(n.sons[0])
diff --git a/tests/vm/tanonproc.nim b/tests/vm/tanonproc.nim
new file mode 100644
index 000000000..474b768ca
--- /dev/null
+++ b/tests/vm/tanonproc.nim
@@ -0,0 +1,52 @@
+discard """
+  output: '''`Test`'''
+"""
+
+# bug #3561
+
+import macros, future, strutils
+
+type
+  Option[T] = ref object
+    case valid: bool
+    of true:
+      data: T
+    else:
+      discard
+
+proc some[T](v: T): Option[T] = Option[T](valid: true, data: v)
+proc none[T](v: T): Option[T] = Option[T](valid: false)
+proc none(T: typedesc): Option[T] = Option[T](valid: false)
+
+proc map[T,U](o: Option[T], f: T -> U): Option[U] =
+  case o.valid
+  of true:
+    f(o.data).some
+  else:
+    U.none
+
+proc notEmpty(o: Option[string]): Option[string] =
+  case o.valid
+  of true:
+    if o.data.strip == "": string.none else: o.data.strip.some
+  else:
+    o
+
+proc getOrElse[T](o: Option[T], def: T): T =
+  case o.valid
+  of true:
+    o.data
+  else:
+    def
+
+proc quoteStr(s: string): Option[string] =
+  s.some.notEmpty.map(v => "`" & v & "`")
+
+macro str(s: string): stmt =
+  let x = s.strVal
+  let y = quoteStr(x)
+  let sn = newStrLitNode(y.getOrElse("NONE"))
+  result = quote do:
+    echo `sn`
+
+str"Test"