summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2017-04-16 16:11:45 +0300
committerZahary Karadjov <zahary@gmail.com>2017-04-16 16:11:45 +0300
commit13701c09579447d3c54f6a1e27ab24b89b11b9e9 (patch)
tree2c220fa47fb06706aecd06e34be44796dc13a486
parent2da4a4fbe3d7ac24b05ee308d5b602a4775ed501 (diff)
downloadNim-13701c09579447d3c54f6a1e27ab24b89b11b9e9.tar.gz
Restore the compilation of linalg by tweaking the complex disambiguation rules
This commit is a potentially breaking change, but the problem was that
linalg was relying on a previous bug in the compiler, which was fixed
in the concepts branch.

With the old disambiguation rules, generic procs like:

proc \`==\`[T](lhs, rhs: T)

and

proc \`==\`(lhs, rhs: Matrix32|Matrix64)

.. were considered equal, even though it's obvious that the second one
should be preferred. We never noticed this, because there was a bug in
sigmatch incorrectly counting one of the params of the second proc as
a non-generic match, thus giving it an edge.

This commit gives some preference to tyOr and tyAnd during the complex
disambiguation, which may affect overload resolution in other cases.

I see this only as a temporary solution. With my upcoming work on
concept refinement, I plan to provide an experimental implementation
of alaternative C++-like rules for determining which proc is more specific.
We can then discuss our strategy for dealing with such a breaking change.
-rw-r--r--compiler/sigmatch.nim28
1 files changed, 18 insertions, 10 deletions
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 90391701c..a8551fa19 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -177,6 +177,13 @@ proc sumGeneric(t: PType): int =
         tyOpenArray, tyVarargs, tySet, tyRange, tySequence, tyGenericBody:
       t = t.lastSon
       inc result
+    of tyOr:
+      var maxBranch = 0
+      for branch in t.sons:
+        let branchSum = branch.sumGeneric
+        if branchSum > maxBranch: maxBranch = branchSum
+      inc result, maxBranch + 1
+      break
     of tyVar:
       t = t.sons[0]
       inc result
@@ -185,8 +192,8 @@ proc sumGeneric(t: PType): int =
       t = t.lastSon
       if t.kind == tyEmpty: break
       inc result
-    of tyGenericInvocation, tyTuple, tyProc:
-      result += ord(t.kind == tyGenericInvocation)
+    of tyGenericInvocation, tyTuple, tyProc, tyAnd:
+      result += ord(t.kind in {tyGenericInvocation, tyAnd})
       for i in 0 .. <t.len:
         if t.sons[i] != nil:
           result += t.sons[i].sumGeneric
@@ -228,6 +235,15 @@ proc complexDisambiguation(a, b: PType): int =
     for i in 1 .. <b.len: y += b.sons[i].sumGeneric
     result = x - y
 
+proc writeMatches*(c: TCandidate) =
+  echo "Candidate '", c.calleeSym.name.s, "' at ", c.calleeSym.info
+  echo "  exact matches: ", c.exactMatches
+  echo "  generic matches: ", c.genericMatches
+  echo "  subtype matches: ", c.subtypeMatches
+  echo "  intconv matches: ", c.intConvMatches
+  echo "  conv matches: ", c.convMatches
+  echo "  inheritance: ", c.inheritancePenalty
+
 proc cmpCandidates*(a, b: TCandidate): int =
   result = a.exactMatches - b.exactMatches
   if result != 0: return
@@ -248,14 +264,6 @@ proc cmpCandidates*(a, b: TCandidate): int =
   if result != 0: return
   result = a.calleeScope - b.calleeScope
 
-proc writeMatches*(c: TCandidate) =
-  writeLine(stdout, "exact matches: " & $c.exactMatches)
-  writeLine(stdout, "generic matches: " & $c.genericMatches)
-  writeLine(stdout, "subtype matches: " & $c.subtypeMatches)
-  writeLine(stdout, "intconv matches: " & $c.intConvMatches)
-  writeLine(stdout, "conv matches: " & $c.convMatches)
-  writeLine(stdout, "inheritance: " & $c.inheritancePenalty)
-
 proc argTypeToString(arg: PNode; prefer: TPreferedDesc): string =
   if arg.kind in nkSymChoices:
     result = typeToString(arg[0].typ, prefer)