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.
This commit is contained in:
parent
2da4a4fbe3
commit
13701c0957
1 changed files with 18 additions and 10 deletions
|
|
@ -177,6 +177,13 @@ proc sumGeneric(t: PType): int =
|
||||||
tyOpenArray, tyVarargs, tySet, tyRange, tySequence, tyGenericBody:
|
tyOpenArray, tyVarargs, tySet, tyRange, tySequence, tyGenericBody:
|
||||||
t = t.lastSon
|
t = t.lastSon
|
||||||
inc result
|
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:
|
of tyVar:
|
||||||
t = t.sons[0]
|
t = t.sons[0]
|
||||||
inc result
|
inc result
|
||||||
|
|
@ -185,8 +192,8 @@ proc sumGeneric(t: PType): int =
|
||||||
t = t.lastSon
|
t = t.lastSon
|
||||||
if t.kind == tyEmpty: break
|
if t.kind == tyEmpty: break
|
||||||
inc result
|
inc result
|
||||||
of tyGenericInvocation, tyTuple, tyProc:
|
of tyGenericInvocation, tyTuple, tyProc, tyAnd:
|
||||||
result += ord(t.kind == tyGenericInvocation)
|
result += ord(t.kind in {tyGenericInvocation, tyAnd})
|
||||||
for i in 0 .. <t.len:
|
for i in 0 .. <t.len:
|
||||||
if t.sons[i] != nil:
|
if t.sons[i] != nil:
|
||||||
result += t.sons[i].sumGeneric
|
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
|
for i in 1 .. <b.len: y += b.sons[i].sumGeneric
|
||||||
result = x - y
|
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 =
|
proc cmpCandidates*(a, b: TCandidate): int =
|
||||||
result = a.exactMatches - b.exactMatches
|
result = a.exactMatches - b.exactMatches
|
||||||
if result != 0: return
|
if result != 0: return
|
||||||
|
|
@ -248,14 +264,6 @@ proc cmpCandidates*(a, b: TCandidate): int =
|
||||||
if result != 0: return
|
if result != 0: return
|
||||||
result = a.calleeScope - b.calleeScope
|
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 =
|
proc argTypeToString(arg: PNode; prefer: TPreferedDesc): string =
|
||||||
if arg.kind in nkSymChoices:
|
if arg.kind in nkSymChoices:
|
||||||
result = typeToString(arg[0].typ, prefer)
|
result = typeToString(arg[0].typ, prefer)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue