mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
better 'self' handling for overload resolution
This commit is contained in:
@@ -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)
|
||||
filter, result, alt, errors)
|
||||
|
||||
#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)
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user