sigmatch: speed it up
This commit is contained in:
parent
6408646b02
commit
9d77f61038
2 changed files with 19 additions and 20 deletions
|
|
@ -59,7 +59,8 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode,
|
||||||
filter: TSymKinds,
|
filter: TSymKinds,
|
||||||
best, alt: var TCandidate,
|
best, alt: var TCandidate,
|
||||||
errors: var CandidateErrors,
|
errors: var CandidateErrors,
|
||||||
diagnosticsFlag: bool) =
|
diagnosticsFlag: bool,
|
||||||
|
errorsEnabled: bool) =
|
||||||
var o: TOverloadIter
|
var o: TOverloadIter
|
||||||
var sym = initOverloadIter(o, c, headSymbol)
|
var sym = initOverloadIter(o, c, headSymbol)
|
||||||
var scope = o.lastOverloadScope
|
var scope = o.lastOverloadScope
|
||||||
|
|
@ -103,13 +104,12 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode,
|
||||||
var cmp = cmpCandidates(best, z)
|
var cmp = cmpCandidates(best, z)
|
||||||
if cmp < 0: best = z # x is better than the best so far
|
if cmp < 0: best = z # x is better than the best so far
|
||||||
elif cmp == 0: alt = z # x is as good as the best so far
|
elif cmp == 0: alt = z # x is as good as the best so far
|
||||||
elif errors.enabled or z.diagnosticsEnabled:
|
elif errorsEnabled or z.diagnosticsEnabled:
|
||||||
errors.s.safeAdd(CandidateError(
|
errors.safeAdd(CandidateError(
|
||||||
sym: sym,
|
sym: sym,
|
||||||
unmatchedVarParam: int z.mutabilityProblem,
|
unmatchedVarParam: int z.mutabilityProblem,
|
||||||
firstMismatch: z.firstMismatch,
|
firstMismatch: z.firstMismatch,
|
||||||
diagnostics: z.diagnostics))
|
diagnostics: z.diagnostics))
|
||||||
errors.enabled = true
|
|
||||||
else:
|
else:
|
||||||
# Symbol table has been modified. Restart and pre-calculate all syms
|
# Symbol table has been modified. Restart and pre-calculate all syms
|
||||||
# before any further candidate init and compare. SLOW, but rare case.
|
# before any further candidate init and compare. SLOW, but rare case.
|
||||||
|
|
@ -151,7 +151,7 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors):
|
||||||
# we do a pre-analysis. If all types produce the same string, we will add
|
# we do a pre-analysis. If all types produce the same string, we will add
|
||||||
# module information.
|
# module information.
|
||||||
let proto = describeArgs(c, n, 1, preferName)
|
let proto = describeArgs(c, n, 1, preferName)
|
||||||
for err in errors.s:
|
for err in errors:
|
||||||
var errProto = ""
|
var errProto = ""
|
||||||
let n = err.sym.typ.n
|
let n = err.sym.typ.n
|
||||||
for i in countup(1, n.len - 1):
|
for i in countup(1, n.len - 1):
|
||||||
|
|
@ -165,7 +165,7 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors):
|
||||||
break
|
break
|
||||||
|
|
||||||
var candidates = ""
|
var candidates = ""
|
||||||
for err in errors.s:
|
for err in errors:
|
||||||
if err.sym.kind in routineKinds and err.sym.ast != nil:
|
if err.sym.kind in routineKinds and err.sym.ast != nil:
|
||||||
add(candidates, renderTree(err.sym.ast,
|
add(candidates, renderTree(err.sym.ast,
|
||||||
{renderNoBody, renderNoComments, renderNoPragmas}))
|
{renderNoBody, renderNoComments, renderNoPragmas}))
|
||||||
|
|
@ -209,7 +209,7 @@ proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) =
|
||||||
if errorOutputs == {}:
|
if errorOutputs == {}:
|
||||||
# fail fast:
|
# fail fast:
|
||||||
globalError(n.info, errTypeMismatch, "")
|
globalError(n.info, errTypeMismatch, "")
|
||||||
if errors.s.len == 0:
|
if errors.len == 0:
|
||||||
localError(n.info, errExprXCannotBeCalled, n[0].renderTree)
|
localError(n.info, errExprXCannotBeCalled, n[0].renderTree)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -222,26 +222,26 @@ proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) =
|
||||||
localError(n.info, errGenerated, result & "\nexpression: " & $n)
|
localError(n.info, errGenerated, result & "\nexpression: " & $n)
|
||||||
|
|
||||||
proc bracketNotFoundError(c: PContext; n: PNode) =
|
proc bracketNotFoundError(c: PContext; n: PNode) =
|
||||||
var errors = CandidateErrors(enabled: true, s: @[])
|
var errors: CandidateErrors = @[]
|
||||||
var o: TOverloadIter
|
var o: TOverloadIter
|
||||||
let headSymbol = n[0]
|
let headSymbol = n[0]
|
||||||
var symx = initOverloadIter(o, c, headSymbol)
|
var symx = initOverloadIter(o, c, headSymbol)
|
||||||
while symx != nil:
|
while symx != nil:
|
||||||
if symx.kind in routineKinds:
|
if symx.kind in routineKinds:
|
||||||
errors.s.add(CandidateError(sym: symx,
|
errors.add(CandidateError(sym: symx,
|
||||||
unmatchedVarParam: 0, firstMismatch: 0,
|
unmatchedVarParam: 0, firstMismatch: 0,
|
||||||
diagnostics: nil,
|
diagnostics: nil,
|
||||||
enabled: false))
|
enabled: false))
|
||||||
errors.enabled = true
|
|
||||||
symx = nextOverloadIter(o, c, headSymbol)
|
symx = nextOverloadIter(o, c, headSymbol)
|
||||||
if errors.s.len == 0:
|
if errors.len == 0:
|
||||||
localError(n.info, "could not resolve: " & $n)
|
localError(n.info, "could not resolve: " & $n)
|
||||||
else:
|
else:
|
||||||
notFoundError(c, n, errors)
|
notFoundError(c, n, errors)
|
||||||
|
|
||||||
proc resolveOverloads(c: PContext, n, orig: PNode,
|
proc resolveOverloads(c: PContext, n, orig: PNode,
|
||||||
filter: TSymKinds, flags: TExprFlags,
|
filter: TSymKinds, flags: TExprFlags,
|
||||||
errors: var CandidateErrors): TCandidate =
|
errors: var CandidateErrors,
|
||||||
|
errorsEnabled: bool): TCandidate =
|
||||||
var initialBinding: PNode
|
var initialBinding: PNode
|
||||||
var alt: TCandidate
|
var alt: TCandidate
|
||||||
var f = n.sons[0]
|
var f = n.sons[0]
|
||||||
|
|
@ -254,7 +254,8 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
|
||||||
|
|
||||||
template pickBest(headSymbol) =
|
template pickBest(headSymbol) =
|
||||||
pickBestCandidate(c, headSymbol, n, orig, initialBinding,
|
pickBestCandidate(c, headSymbol, n, orig, initialBinding,
|
||||||
filter, result, alt, errors, efExplain in flags)
|
filter, result, alt, errors, efExplain in flags,
|
||||||
|
errorsEnabled)
|
||||||
pickBest(f)
|
pickBest(f)
|
||||||
|
|
||||||
let overloadsState = result.state
|
let overloadsState = result.state
|
||||||
|
|
@ -428,11 +429,11 @@ proc tryDeref(n: PNode): PNode =
|
||||||
|
|
||||||
proc semOverloadedCall(c: PContext, n, nOrig: PNode,
|
proc semOverloadedCall(c: PContext, n, nOrig: PNode,
|
||||||
filter: TSymKinds, flags: TExprFlags): PNode =
|
filter: TSymKinds, flags: TExprFlags): PNode =
|
||||||
var errors = CandidateErrors(enabled: efExplain in flags, s: nil)
|
var errors: CandidateErrors = if efExplain in flags: @[] else: nil
|
||||||
var r = resolveOverloads(c, n, nOrig, filter, flags, errors)
|
var r = resolveOverloads(c, n, nOrig, filter, flags, errors, efExplain in flags)
|
||||||
if r.state == csMatch:
|
if r.state == csMatch:
|
||||||
# this may be triggered, when the explain pragma is used
|
# this may be triggered, when the explain pragma is used
|
||||||
if errors.s.len > 0:
|
if errors.len > 0:
|
||||||
let (_, candidates) = presentFailedCandidates(c, n, errors)
|
let (_, candidates) = presentFailedCandidates(c, n, errors)
|
||||||
message(n.info, hintUserRaw,
|
message(n.info, hintUserRaw,
|
||||||
"Non-matching candidates for " & renderTree(n) & "\n" &
|
"Non-matching candidates for " & renderTree(n) & "\n" &
|
||||||
|
|
@ -447,7 +448,7 @@ proc semOverloadedCall(c: PContext, n, nOrig: PNode,
|
||||||
# into sigmatch with hidden conversion produced there
|
# into sigmatch with hidden conversion produced there
|
||||||
#
|
#
|
||||||
n.sons[1] = n.sons[1].tryDeref
|
n.sons[1] = n.sons[1].tryDeref
|
||||||
var r = resolveOverloads(c, n, nOrig, filter, flags, errors)
|
var r = resolveOverloads(c, n, nOrig, filter, flags, errors, efExplain in flags)
|
||||||
if r.state == csMatch: result = semResolvedCall(c, n, r)
|
if r.state == csMatch: result = semResolvedCall(c, n, r)
|
||||||
else:
|
else:
|
||||||
# get rid of the deref again for a better error message:
|
# get rid of the deref again for a better error message:
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,7 @@ type
|
||||||
diagnostics*: seq[string]
|
diagnostics*: seq[string]
|
||||||
enabled*: bool
|
enabled*: bool
|
||||||
|
|
||||||
CandidateErrors* = object
|
CandidateErrors* = seq[CandidateError]
|
||||||
enabled*: bool
|
|
||||||
s*: seq[CandidateError]
|
|
||||||
|
|
||||||
TCandidate* = object
|
TCandidate* = object
|
||||||
c*: PContext
|
c*: PContext
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue