From 13701c09579447d3c54f6a1e27ab24b89b11b9e9 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Sun, 16 Apr 2017 16:11:45 +0300 Subject: [PATCH] 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. --- compiler/sigmatch.nim | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 90391701c9..a8551fa194 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 ..