summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorcooldome <ariabushenko@bk.ru>2018-06-12 00:20:08 +0100
committercooldome <ariabushenko@bk.ru>2018-06-12 00:20:08 +0100
commit1b7cf3df5192ab1d7612ba0b349117a8960156e3 (patch)
treec6191c0aa79d942e34e3d5ebbf801c7253ac4fc3
parente03b3bdde75f5e82f9c5512fcd00033704de4a34 (diff)
downloadNim-1b7cf3df5192ab1d7612ba0b349117a8960156e3.tar.gz
New approach
-rw-r--r--compiler/hlo.nim50
-rw-r--r--compiler/patterns.nim2
-rw-r--r--compiler/sigmatch.nim7
3 files changed, 27 insertions, 32 deletions
diff --git a/compiler/hlo.nim b/compiler/hlo.nim
index 511712b54..8251e3179 100644
--- a/compiler/hlo.nim
+++ b/compiler/hlo.nim
@@ -36,35 +36,27 @@ 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 ;-)
-  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
+  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/compiler/patterns.nim b/compiler/patterns.nim
index 5409a4811..8c1017a95 100644
--- a/compiler/patterns.nim
+++ b/compiler/patterns.nim
@@ -77,7 +77,7 @@ proc checkTypes(c: PPatternContext, p: PSym, n: PNode): bool =
   if isNil(n.typ):
     result = p.typ.kind in {tyVoid, tyStmt}
   else:
-    result = sigmatch.argtypeMatches(c.c, p.typ, n.typ)
+    result = sigmatch.argtypeMatches(c.c, p.typ, n.typ, from_hlo = true)
 
 proc isPatternParam(c: PPatternContext, p: PNode): bool {.inline.} =
   result = p.kind == nkSym and p.sym.kind == skParam and p.sym.owner == c.owner
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index fcfdda8bb..dd0270443 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -2359,14 +2359,17 @@ proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) =
     for t in m.inferredTypes:
       if t.sonsLen > 1: t.sons.setLen 1
 
-proc argtypeMatches*(c: PContext, f, a: PType): bool =
+proc argtypeMatches*(c: PContext, f, a: PType, from_hlo = false): bool =
   var m: TCandidate
   initCandidate(c, m, f)
   let res = paramTypesMatch(m, f, a, ast.emptyNode, nil)
   #instantiateGenericConverters(c, res, m)
   # XXX this is used by patterns.nim too; I think it's better to not
   # instantiate generic converters for that
-  result = res != nil
+  if not from_hlo:
+    res != nil
+  else:
+    res != nil and m.convMatches == 0 and m.intConvMatches in [0, 256]
 
 proc instTypeBoundOp*(c: PContext; dc: PSym; t: PType; info: TLineInfo;
                       op: TTypeAttachedOp; col: int): PSym {.procvar.} =