better 'self' handling for overload resolution
This commit is contained in:
parent
7d7de36a91
commit
554a3e9335
1 changed files with 23 additions and 28 deletions
|
|
@ -39,8 +39,7 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode,
|
||||||
initialBinding: PNode,
|
initialBinding: PNode,
|
||||||
filter: TSymKinds,
|
filter: TSymKinds,
|
||||||
best, alt: var TCandidate,
|
best, alt: var TCandidate,
|
||||||
errors: var CandidateErrors;
|
errors: var CandidateErrors) =
|
||||||
fromUsingStmt: bool) =
|
|
||||||
var o: TOverloadIter
|
var o: TOverloadIter
|
||||||
# thanks to the lazy semchecking for operands, we need to iterate over the
|
# thanks to the lazy semchecking for operands, we need to iterate over the
|
||||||
# symbol table *before* any call to 'initCandidate' which might invoke
|
# 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]] = @[]
|
var syms: seq[tuple[a: PSym, b: int]] = @[]
|
||||||
while symx != nil:
|
while symx != nil:
|
||||||
if symx.kind in filter:
|
if symx.kind in filter:
|
||||||
if fromUsingStmt and (symx.typ.n.len <= 1 or
|
syms.add((symx, o.lastOverloadScope))
|
||||||
sfIsSelf notin symx.typ.n[1].sym.flags):
|
|
||||||
discard "only consider procs that have a 'self' too"
|
|
||||||
else:
|
|
||||||
syms.add((symx, o.lastOverloadScope))
|
|
||||||
symx = nextOverloadIter(o, c, headSymbol)
|
symx = nextOverloadIter(o, c, headSymbol)
|
||||||
if syms.len == 0: return
|
if syms.len == 0: return
|
||||||
|
|
||||||
|
|
@ -156,30 +151,30 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
|
||||||
else:
|
else:
|
||||||
initialBinding = nil
|
initialBinding = nil
|
||||||
|
|
||||||
template pickBest(headSymbol, fromUsingStmt) =
|
template pickBest(headSymbol) =
|
||||||
pickBestCandidate(c, headSymbol, n, orig, initialBinding,
|
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)
|
pickBest(f)
|
||||||
|
|
||||||
if result.state != csMatch:
|
|
||||||
n.sons.delete(1)
|
|
||||||
orig.sons.delete(1)
|
|
||||||
else: return
|
|
||||||
|
|
||||||
pickBest(f, false)
|
|
||||||
|
|
||||||
let overloadsState = result.state
|
let overloadsState = result.state
|
||||||
if overloadsState != csMatch:
|
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:
|
if nfDotField in n.flags:
|
||||||
internalAssert f.kind == nkIdent and n.sonsLen >= 2
|
internalAssert f.kind == nkIdent and n.sonsLen >= 2
|
||||||
let calleeName = newStrNode(nkStrLit, f.ident.s).withInfo(n.info)
|
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)
|
let op = newIdentNode(getIdent(x), n.info)
|
||||||
n.sons[0] = op
|
n.sons[0] = op
|
||||||
orig.sons[0] = op
|
orig.sons[0] = op
|
||||||
pickBest(op, false)
|
pickBest(op)
|
||||||
|
|
||||||
if nfExplicitCall in n.flags:
|
if nfExplicitCall in n.flags:
|
||||||
tryOp ".()"
|
tryOp ".()"
|
||||||
|
|
@ -208,7 +203,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
|
||||||
let callOp = newIdentNode(getIdent".=", n.info)
|
let callOp = newIdentNode(getIdent".=", n.info)
|
||||||
n.sons[0..1] = [callOp, n[1], calleeName]
|
n.sons[0..1] = [callOp, n[1], calleeName]
|
||||||
orig.sons[0..1] = [callOp, orig[1], calleeName]
|
orig.sons[0..1] = [callOp, orig[1], calleeName]
|
||||||
pickBest(callOp, false)
|
pickBest(callOp)
|
||||||
|
|
||||||
if overloadsState == csEmpty and result.state == csEmpty:
|
if overloadsState == csEmpty and result.state == csEmpty:
|
||||||
if nfDotField in n.flags and nfExplicitCall notin n.flags:
|
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
|
n.sons[0] = f
|
||||||
|
|
||||||
errors = @[]
|
errors = @[]
|
||||||
pickBest(f, false)
|
pickBest(f)
|
||||||
#notFoundError(c, n, errors)
|
#notFoundError(c, n, errors)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue