diff options
-rw-r--r-- | compiler/sigmatch.nim | 38 | ||||
-rw-r--r-- | tests/overload/tsystemcmp.nim | 4 |
2 files changed, 26 insertions, 16 deletions
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 141416a54..1fce99e50 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1200,6 +1200,17 @@ proc isEmptyContainer*(t: PType): bool = of tyGenericInst: result = isEmptyContainer(t.lastSon) else: result = false +proc incMatches(m: var TCandidate; r: TTypeRelation; convMatch = 1) = + case r + of isConvertible, isIntConv: inc(m.convMatches, convMatch) + of isSubtype, isSubrange: inc(m.subtypeMatches) + of isGeneric, isInferred: inc(m.genericMatches) + of isFromIntLit: inc(m.intConvMatches, 256) + of isInferredConvertible: + inc(m.convMatches) + of isEqual: inc(m.exactMatches) + of isNone: discard + proc paramTypesMatchAux(m: var TCandidate, f, argType: PType, argSemantized, argOrig: PNode): PNode = var @@ -1240,18 +1251,9 @@ proc paramTypesMatchAux(m: var TCandidate, f, argType: PType, if r != isNone and m.calleeSym != nil and m.calleeSym.kind in {skMacro, skTemplate}: - # XXX: duplicating this is ugly, maybe we should move this + # XXX: duplicating this is ugly, but we cannot (!) move this # directly into typeRel using return-like templates - case r - of isConvertible, isIntConv: inc(m.convMatches) - of isSubtype, isSubrange: inc(m.subtypeMatches) - of isGeneric, isInferred: inc(m.genericMatches) - of isFromIntLit: inc(m.intConvMatches, 256) - of isInferredConvertible: - inc(m.convMatches) - of isEqual: inc(m.exactMatches) - of isNone: discard - + incMatches(m, r) if f.kind == tyStmt: return arg elif f.kind == tyTypeDesc: @@ -1366,20 +1368,23 @@ proc paramTypesMatch*(m: var TCandidate, f, a: PType, z.calleeSym = arg.sons[i].sym #if arg.sons[i].sym.name.s == "cmp": # ggDebug = true - # echo "CALLLEEEEEEEE ", typeToString(z.callee) - var r = typeRel(z, f, arg.sons[i].typ) + # echo "CALLLEEEEEEEE A ", typeToString(z.callee) + # XXX this is still all wrong: (T, T) should be 2 generic matches + # and (int, int) 2 exact matches, etc. Essentially you cannot call + # typeRel here and expect things to work! + let r = typeRel(z, f, arg.sons[i].typ) + incMatches(z, r, 2) #if arg.sons[i].sym.name.s == "cmp": # and arg.info.line == 606: # echo "M ", r, " ", arg.info, " ", typeToString(arg.sons[i].sym.typ) - # debug arg.sons[i].sym # writeMatches(z) if r != isNone: + z.state = csMatch case x.state of csEmpty, csNoMatch: x = z best = i - x.state = csMatch of csMatch: - var cmp = cmpCandidates(x, z) + let cmp = cmpCandidates(x, z) if cmp < 0: best = i x = z @@ -1402,6 +1407,7 @@ proc paramTypesMatch*(m: var TCandidate, f, a: PType, result = paramTypesMatchAux(m, f, arg.sons[best].typ, arg.sons[best], argOrig) + proc setSon(father: PNode, at: int, son: PNode) = if sonsLen(father) <= at: setLen(father.sons, at + 1) father.sons[at] = son diff --git a/tests/overload/tsystemcmp.nim b/tests/overload/tsystemcmp.nim index 9bfca35d7..68cbf9fa7 100644 --- a/tests/overload/tsystemcmp.nim +++ b/tests/overload/tsystemcmp.nim @@ -16,3 +16,7 @@ proc cmp(a, b: MyType): int = cmp(a.x, b.x) var modulesB = @[MyType(x: "ho"), MyType(x: "ha")] sort(modulesB, cmp) + +# bug #2397 + +proc f(x: (proc(a,b: string): int) = system.cmp) = discard |