summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorcooldome <ariabushenko@bk.ru>2018-06-06 23:41:19 +0100
committercooldome <ariabushenko@bk.ru>2018-06-06 23:41:19 +0100
commite03b3bdde75f5e82f9c5512fcd00033704de4a34 (patch)
treeca562440f4c978a3c060524fe1fe7c01f5069a02
parentbf394ed1a1d27d8d38d4bc386946e3442736cd75 (diff)
downloadNim-e03b3bdde75f5e82f9c5512fcd00033704de4a34.tar.gz
fixes 7980
-rw-r--r--compiler/hlo.nim50
-rw-r--r--tests/template/tpattern_with_converter.nim27
2 files changed, 56 insertions, 21 deletions
diff --git a/compiler/hlo.nim b/compiler/hlo.nim
index 8251e3179..511712b54 100644
--- a/compiler/hlo.nim
+++ b/compiler/hlo.nim
@@ -36,27 +36,35 @@ proc applyPatterns(c: PContext, n: PNode): PNode =
   # we apply the last pattern first, so that pattern overriding is possible;
   # however the resulting AST would better not trigger the old rule then
   # anymore ;-)
-  for i in countdown(c.patterns.len-1, 0):
-    let pattern = c.patterns[i]
-    if not isNil(pattern):
-      let x = applyRule(c, pattern, result)
-      if not isNil(x):
-        assert x.kind in {nkStmtList, nkCall}
-        # better be safe than sorry, so check evalTemplateCounter too:
-        inc(evalTemplateCounter)
-        if evalTemplateCounter > evalTemplateLimit:
-          globalError(c.config, n.info, "template instantiation too nested")
-        # deactivate this pattern:
-        c.patterns[i] = nil
-        if x.kind == nkStmtList:
-          assert x.len == 3
-          x.sons[1] = evalPattern(c, x.sons[1], result)
-          result = flattenStmts(x)
-        else:
-          result = evalPattern(c, x, result)
-        dec(evalTemplateCounter)
-        # activate this pattern again:
-        c.patterns[i] = pattern
+  if c.patterns.len > 0:
+
+    # temporary disable converters
+    var ctx_converters: TSymSeq
+    shallowCopy(ctx_converters, c.converters)
+    c.converters = @[]
+    defer: shallowCopy(c.converters, ctx_converters)
+
+    for i in countdown(c.patterns.len-1, 0):
+      let pattern = c.patterns[i]
+      if not isNil(pattern):
+        let x = applyRule(c, pattern, result)
+        if not isNil(x):
+          assert x.kind in {nkStmtList, nkCall}
+          # better be safe than sorry, so check evalTemplateCounter too:
+          inc(evalTemplateCounter)
+          if evalTemplateCounter > evalTemplateLimit:
+            globalError(c.config, n.info, "template instantiation too nested")
+          # deactivate this pattern:
+          c.patterns[i] = nil
+          if x.kind == nkStmtList:
+            assert x.len == 3
+            x.sons[1] = evalPattern(c, x.sons[1], result)
+            result = flattenStmts(x)
+          else:
+            result = evalPattern(c, x, result)
+          dec(evalTemplateCounter)
+          # activate this pattern again:
+          c.patterns[i] = pattern
 
 proc hlo(c: PContext, n: PNode): PNode =
   inc(c.hloLoopDetector)
diff --git a/tests/template/tpattern_with_converter.nim b/tests/template/tpattern_with_converter.nim
new file mode 100644
index 000000000..e0632552b
--- /dev/null
+++ b/tests/template/tpattern_with_converter.nim
@@ -0,0 +1,27 @@
+discard """
+  output: 10.0
+"""
+
+type
+  MyFloat = object
+    val: float
+
+converter to_myfloat*(x: float): MyFloat {.inline.} =
+  MyFloat(val: x)
+
+proc `+`(x1, x2: MyFloat): MyFloat =
+  MyFloat(val: x1.val + x2.val)
+
+proc `*`(x1, x2: MyFloat): MyFloat =
+    MyFloat(val: x1.val * x2.val)
+
+template optMul{`*`(a, 2.0)}(a: MyFloat): MyFloat =
+  a + a
+
+func floatMyFloat(x: MyFloat): MyFloat =
+  result = x * 2.0
+
+func floatDouble(x: float): float =
+  result = x * 2.0
+
+echo floatDouble(5)
\ No newline at end of file