diff options
author | Zahary Karadjov <zahary@gmail.com> | 2017-04-16 16:11:45 +0300 |
---|---|---|
committer | Zahary Karadjov <zahary@gmail.com> | 2017-04-16 16:11:45 +0300 |
commit | 13701c09579447d3c54f6a1e27ab24b89b11b9e9 (patch) | |
tree | 2c220fa47fb06706aecd06e34be44796dc13a486 | |
parent | 2da4a4fbe3d7ac24b05ee308d5b602a4775ed501 (diff) | |
download | Nim-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.nim | 28 |
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) |