diff --git a/compiler/lookups.nim b/compiler/lookups.nim index ff078c82d2..ee77b3633a 100755 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -164,7 +164,7 @@ proc QualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym = result = nil if result != nil and result.kind == skStub: loadStub(result) -proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = +proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = case n.kind of nkIdent, nkAccQuoted: var ident = considerAcc(n) @@ -174,7 +174,7 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = dec(o.stackPtr) if o.stackPtr < 0: break result = InitIdentIter(o.it, c.tab.stack[o.stackPtr], ident) - of nkSym: + of nkSym: result = n.sym o.mode = oimDone of nkDotExpr: @@ -204,6 +204,13 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = Incl(o.inSymChoice, result.id) else: nil if result != nil and result.kind == skStub: loadStub(result) + +proc lastOverloadScope*(o: TOverloadIter): int = + case o.mode + of oimNoQualifier: result = o.stackPtr + of oimSelfModule: result = ModuleTablePos + of oimOtherModule: result = ImportTablePos + else: result = -1 proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = case o.mode diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 6a36787cba..f0c9f42b05 100755 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -36,14 +36,15 @@ proc resolveOverloads(c: PContext, n, orig: PNode, template best: expr = result #Message(n.info, warnUser, renderTree(n)) var sym = initOverloadIter(o, c, f) + var symScope = o.lastOverloadScope - if sym == nil: return - initCandidate(best, sym, initialBinding) - initCandidate(alt, sym, initialBinding) + if sym == nil: return + initCandidate(best, sym, initialBinding, symScope) + initCandidate(alt, sym, initialBinding, symScope) while sym != nil: if sym.kind in filter: - initCandidate(z, sym, initialBinding) + initCandidate(z, sym, initialBinding, o.lastOverloadScope) z.calleeSym = sym matches(c, n, orig, z) if z.state == csMatch: diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index e56b5e1c86..ca65c670f6 100755 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -27,6 +27,7 @@ type state*: TCandidateState callee*: PType # may not be nil! calleeSym*: PSym # may be nil + calleeScope: int # may be -1 for unknown scope call*: PNode # modified call bindings*: TIdTable # maps types to types baseTypeMatch: bool # needed for conversions from T to openarray[T] @@ -60,9 +61,10 @@ proc put(t: var TIdTable, key, val: PType) {.inline.} = IdentEq(val.sym.name, "TTable"): assert false -proc initCandidate*(c: var TCandidate, callee: PSym, binding: PNode) = +proc initCandidate*(c: var TCandidate, callee: PSym, binding: PNode, calleeScope = -1) = initCandidateAux(c, callee.typ) c.calleeSym = callee + c.calleeScope = calleeScope initIdTable(c.bindings) if binding != nil: var typeParams = callee.ast[genericParamsPos] @@ -94,6 +96,9 @@ proc cmpCandidates*(a, b: TCandidate): int = result = a.intConvMatches - b.intConvMatches if result != 0: return result = a.convMatches - b.convMatches + if result != 0: return + if (a.calleeScope != -1) and (b.calleeScope != -1): + result = a.calleeScope - b.calleeScope proc writeMatches(c: TCandidate) = Writeln(stdout, "exact matches: " & $c.exactMatches)