diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2016-02-29 00:25:51 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2016-02-29 00:25:51 +0100 |
commit | 554a3e9335fddac4656a9313ab283ae0e4d14a9e (patch) | |
tree | c8d815090521ce0b6284dcfbfdf5ee40e587c569 /compiler | |
parent | 7d7de36a91d07567de96150432dc5a44f818b48a (diff) | |
download | Nim-554a3e9335fddac4656a9313ab283ae0e4d14a9e.tar.gz |
better 'self' handling for overload resolution
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/semcall.nim | 51 |
1 files changed, 23 insertions, 28 deletions
diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 2fb226404..916d897c9 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -39,8 +39,7 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode, initialBinding: PNode, filter: TSymKinds, best, alt: var TCandidate, - errors: var CandidateErrors; - fromUsingStmt: bool) = + errors: var CandidateErrors) = var o: TOverloadIter # thanks to the lazy semchecking for operands, we need to iterate over the # symbol table *before* any call to 'initCandidate' which might invoke @@ -52,11 +51,7 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode, var syms: seq[tuple[a: PSym, b: int]] = @[] while symx != nil: if symx.kind in filter: - if fromUsingStmt and (symx.typ.n.len <= 1 or - sfIsSelf notin symx.typ.n[1].sym.flags): - discard "only consider procs that have a 'self' too" - else: - syms.add((symx, o.lastOverloadScope)) + syms.add((symx, o.lastOverloadScope)) symx = nextOverloadIter(o, c, headSymbol) if syms.len == 0: return @@ -156,30 +151,30 @@ proc resolveOverloads(c: PContext, n, orig: PNode, else: initialBinding = nil - template pickBest(headSymbol, fromUsingStmt) = + template pickBest(headSymbol) = pickBestCandidate(c, headSymbol, n, orig, initialBinding, - filter, result, alt, errors, fromUsingStmt) - - #gatherUsedSyms(c, usedSyms) - if c.p != nil and c.p.selfSym != nil: - # we need to enforce semchecking of selfSym again because it - # might need auto-deref: - var hiddenArg = newSymNode(c.p.selfSym) - hiddenArg.typ = nil - n.sons.insert(hiddenArg, 1) - orig.sons.insert(hiddenArg, 1) - - pickBest(f, true) + filter, result, alt, errors) - if result.state != csMatch: - n.sons.delete(1) - orig.sons.delete(1) - else: return - pickBest(f, false) + pickBest(f) let overloadsState = result.state if overloadsState != csMatch: + if c.p != nil and c.p.selfSym != nil: + # we need to enforce semchecking of selfSym again because it + # might need auto-deref: + var hiddenArg = newSymNode(c.p.selfSym) + hiddenArg.typ = nil + n.sons.insert(hiddenArg, 1) + orig.sons.insert(hiddenArg, 1) + + pickBest(f) + + if result.state != csMatch: + n.sons.delete(1) + orig.sons.delete(1) + else: return + if nfDotField in n.flags: internalAssert f.kind == nkIdent and n.sonsLen >= 2 let calleeName = newStrNode(nkStrLit, f.ident.s).withInfo(n.info) @@ -193,7 +188,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode, let op = newIdentNode(getIdent(x), n.info) n.sons[0] = op orig.sons[0] = op - pickBest(op, false) + pickBest(op) if nfExplicitCall in n.flags: tryOp ".()" @@ -208,7 +203,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode, let callOp = newIdentNode(getIdent".=", n.info) n.sons[0..1] = [callOp, n[1], calleeName] orig.sons[0..1] = [callOp, orig[1], calleeName] - pickBest(callOp, false) + pickBest(callOp) if overloadsState == csEmpty and result.state == csEmpty: if nfDotField in n.flags and nfExplicitCall notin n.flags: @@ -227,7 +222,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode, n.sons[0] = f errors = @[] - pickBest(f, false) + pickBest(f) #notFoundError(c, n, errors) return |