summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2018-04-28 18:48:18 +0200
committerAndreas Rumpf <rumpf_a@web.de>2018-04-28 18:48:18 +0200
commit9d77f61038ddabeb4b59847d709e6d722e743082 (patch)
tree6ddd46c5f47fac7a1ea531e6117367e08ef2ae66
parent6408646b02a8a7bc7a7182277499978cd16fcd70 (diff)
downloadNim-9d77f61038ddabeb4b59847d709e6d722e743082.tar.gz
sigmatch: speed it up
-rw-r--r--compiler/semcall.nim35
-rw-r--r--compiler/sigmatch.nim4
2 files changed, 19 insertions, 20 deletions
diff --git a/compiler/semcall.nim b/compiler/semcall.nim
index 3a12ca980..aa53fda3b 100644
--- a/compiler/semcall.nim
+++ b/compiler/semcall.nim
@@ -59,7 +59,8 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode,
                        filter: TSymKinds,
                        best, alt: var TCandidate,
                        errors: var CandidateErrors,
-                       diagnosticsFlag: bool) =
+                       diagnosticsFlag: bool,
+                       errorsEnabled: bool) =
   var o: TOverloadIter
   var sym = initOverloadIter(o, c, headSymbol)
   var scope = o.lastOverloadScope
@@ -103,13 +104,12 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode,
           var cmp = cmpCandidates(best, z)
           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 errors.enabled or z.diagnosticsEnabled:
-        errors.s.safeAdd(CandidateError(
+      elif errorsEnabled or z.diagnosticsEnabled:
+        errors.safeAdd(CandidateError(
           sym: sym,
           unmatchedVarParam: int z.mutabilityProblem,
           firstMismatch: z.firstMismatch,
           diagnostics: z.diagnostics))
-        errors.enabled = true
     else:
       # Symbol table has been modified. Restart and pre-calculate all syms
       # 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
   # module information.
   let proto = describeArgs(c, n, 1, preferName)
-  for err in errors.s:
+  for err in errors:
     var errProto = ""
     let n = err.sym.typ.n
     for i in countup(1, n.len - 1):
@@ -165,7 +165,7 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors):
       break
 
   var candidates = ""
-  for err in errors.s:
+  for err in errors:
     if err.sym.kind in routineKinds and err.sym.ast != nil:
       add(candidates, renderTree(err.sym.ast,
             {renderNoBody, renderNoComments, renderNoPragmas}))
@@ -209,7 +209,7 @@ proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) =
   if errorOutputs == {}:
     # fail fast:
     globalError(n.info, errTypeMismatch, "")
-  if errors.s.len == 0:
+  if errors.len == 0:
     localError(n.info, errExprXCannotBeCalled, n[0].renderTree)
     return
 
@@ -222,26 +222,26 @@ proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) =
   localError(n.info, errGenerated, result & "\nexpression: " & $n)
 
 proc bracketNotFoundError(c: PContext; n: PNode) =
-  var errors = CandidateErrors(enabled: true, s: @[])
+  var errors: CandidateErrors = @[]
   var o: TOverloadIter
   let headSymbol = n[0]
   var symx = initOverloadIter(o, c, headSymbol)
   while symx != nil:
     if symx.kind in routineKinds:
-      errors.s.add(CandidateError(sym: symx,
+      errors.add(CandidateError(sym: symx,
                                 unmatchedVarParam: 0, firstMismatch: 0,
                                 diagnostics: nil,
                                 enabled: false))
-      errors.enabled = true
     symx = nextOverloadIter(o, c, headSymbol)
-  if errors.s.len == 0:
+  if errors.len == 0:
     localError(n.info, "could not resolve: " & $n)
   else:
     notFoundError(c, n, errors)
 
 proc resolveOverloads(c: PContext, n, orig: PNode,
                       filter: TSymKinds, flags: TExprFlags,
-                      errors: var CandidateErrors): TCandidate =
+                      errors: var CandidateErrors,
+                      errorsEnabled: bool): TCandidate =
   var initialBinding: PNode
   var alt: TCandidate
   var f = n.sons[0]
@@ -254,7 +254,8 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
 
   template pickBest(headSymbol) =
     pickBestCandidate(c, headSymbol, n, orig, initialBinding,
-                      filter, result, alt, errors, efExplain in flags)
+                      filter, result, alt, errors, efExplain in flags,
+                      errorsEnabled)
   pickBest(f)
 
   let overloadsState = result.state
@@ -428,11 +429,11 @@ proc tryDeref(n: PNode): PNode =
 
 proc semOverloadedCall(c: PContext, n, nOrig: PNode,
                        filter: TSymKinds, flags: TExprFlags): PNode =
-  var errors = CandidateErrors(enabled: efExplain in flags, s: nil)
-  var r = resolveOverloads(c, n, nOrig, filter, flags, errors)
+  var errors: CandidateErrors = if efExplain in flags: @[] else: nil
+  var r = resolveOverloads(c, n, nOrig, filter, flags, errors, efExplain in flags)
   if r.state == csMatch:
     # 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)
       message(n.info, hintUserRaw,
               "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
     #
     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)
     else:
       # get rid of the deref again for a better error message:
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 2b105f48a..4263ef581 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -28,9 +28,7 @@ type
     diagnostics*: seq[string]
     enabled*: bool
 
-  CandidateErrors* = object
-    enabled*: bool
-    s*: seq[CandidateError]
+  CandidateErrors* = seq[CandidateError]
 
   TCandidate* = object
     c*: PContext