summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/configuration.nim2
-rw-r--r--compiler/sigmatch.nim86
-rw-r--r--compiler/suggest.nim36
3 files changed, 63 insertions, 61 deletions
diff --git a/compiler/configuration.nim b/compiler/configuration.nim
index 5164fd6df..44345186d 100644
--- a/compiler/configuration.nim
+++ b/compiler/configuration.nim
@@ -385,7 +385,7 @@ errXhasSideEffects: "'$1' can have side effects",
 errIteratorExpected: "iterator within for loop context expected",
 errLetNeedsInit: "'let' symbol requires an initialization",
 errThreadvarCannotInit: "a thread var cannot be initialized explicitly; this would only run for the main thread",
-errWrongSymbolX: "usage of '$1' is a user-defined error",
+errWrongSymbolX:,
 errIllegalCaptureX: "illegal capture '$1'",
 errXCannotBeClosure: "'$1' cannot have 'closure' calling convention",
 errXMustBeCompileTime: "'$1' can only be used in compile-time context",
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 4263ef581..01413f678 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -99,7 +99,7 @@ type
 const
   isNilConversion = isConvertible # maybe 'isIntConv' fits better?
 
-proc markUsed*(info: TLineInfo, s: PSym; usageSym: var PSym)
+proc markUsed*(conf: ConfigRef; info: TLineInfo, s: PSym; usageSym: var PSym)
 
 template hasFauxMatch*(c: TCandidate): bool = c.fauxMatch != tyNone
 
@@ -152,13 +152,13 @@ proc initCandidate*(ctx: PContext, c: var TCandidate, callee: PSym,
     for i in 1..min(sonsLen(typeParams), sonsLen(binding)-1):
       var formalTypeParam = typeParams.sons[i-1].typ
       var bound = binding[i].typ
-      internalAssert bound != nil
-      if formalTypeParam.kind == tyTypeDesc:
-        if bound.kind != tyTypeDesc:
-          bound = makeTypeDesc(ctx, bound)
-      else:
-        bound = bound.skipTypes({tyTypeDesc})
-      put(c, formalTypeParam, bound)
+      if bound != nil:
+        if formalTypeParam.kind == tyTypeDesc:
+          if bound.kind != tyTypeDesc:
+            bound = makeTypeDesc(ctx, bound)
+        else:
+          bound = bound.skipTypes({tyTypeDesc})
+        put(c, formalTypeParam, bound)
 
 proc newCandidate*(ctx: PContext, callee: PSym,
                    binding: PNode, calleeScope = -1): TCandidate =
@@ -362,8 +362,8 @@ proc concreteType(c: TCandidate, t: PType): PType =
         # proc sort[T](cmp: proc(a, b: T): int = cmp)
       if result.kind != tyGenericParam: break
   of tyGenericInvocation:
-    internalError("cannot resolve type: " & typeToString(t))
     result = t
+    doAssert(false, "cannot resolve type: " & typeToString(t))
   else:
     result = t                # Note: empty is valid here
 
@@ -519,8 +519,8 @@ proc recordRel(c: var TCandidate, f, a: PType): TTypeRelation =
     if f.n != nil and a.n != nil:
       for i in countup(0, sonsLen(f.n) - 1):
         # check field names:
-        if f.n.sons[i].kind != nkSym: internalError(f.n.info, "recordRel")
-        elif a.n.sons[i].kind != nkSym: internalError(a.n.info, "recordRel")
+        if f.n.sons[i].kind != nkSym: return isNone
+        elif a.n.sons[i].kind != nkSym: return isNone
         else:
           var x = f.n.sons[i].sym
           var y = a.n.sons[i].sym
@@ -661,7 +661,7 @@ proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType =
     matchedConceptContext.prev = prevMatchedConcept
     matchedConceptContext.depth = prevMatchedConcept.depth + 1
     if prevMatchedConcept.depth > 4:
-      localError(body.info, $body & " too nested for type matching")
+      localError(m.c.graph.config, body.info, $body & " too nested for type matching")
       return nil
 
   openScope(c)
@@ -760,19 +760,20 @@ proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType =
 
   result.n = checkedBody
 
-proc shouldSkipDistinct(rules: PNode, callIdent: PIdent): bool =
+proc shouldSkipDistinct(m: TCandidate; rules: PNode, callIdent: PIdent): bool =
+  # XXX This is bad as 'considerQuotedIdent' can produce an error!
   if rules.kind == nkWith:
     for r in rules:
-      if r.considerQuotedIdent == callIdent: return true
+      if considerQuotedIdent(m.c.graph.config, r) == callIdent: return true
     return false
   else:
     for r in rules:
-      if r.considerQuotedIdent == callIdent: return false
+      if considerQuotedIdent(m.c.graph.config, r) == callIdent: return false
     return true
 
-proc maybeSkipDistinct(t: PType, callee: PSym): PType =
+proc maybeSkipDistinct(m: TCandidate; t: PType, callee: PSym): PType =
   if t != nil and t.kind == tyDistinct and t.n != nil and
-     shouldSkipDistinct(t.n, callee.name):
+     shouldSkipDistinct(m, t.n, callee.name):
     result = t.base
   else:
     result = t
@@ -868,11 +869,11 @@ proc inferStaticParam*(c: var TCandidate, lhs: PNode, rhs: BiggestInt): bool =
 
   return false
 
-proc failureToInferStaticParam(n: PNode) =
+proc failureToInferStaticParam(conf: ConfigRef; n: PNode) =
   let staticParam = n.findUnresolvedStatic
   let name = if staticParam != nil: staticParam.sym.name.s
              else: "unknown"
-  localError(n.info, errCannotInferStaticParam, name)
+  localError(conf, n.info, "cannot infer the value of the static param '" & name & "'")
 
 proc inferStaticsInRange(c: var TCandidate,
                          inferred, concrete: PType): TTypeRelation =
@@ -886,7 +887,7 @@ proc inferStaticsInRange(c: var TCandidate,
     if inferStaticParam(c, exp, rhs):
       return isGeneric
     else:
-      failureToInferStaticParam exp
+      failureToInferStaticParam(c.c.graph.config, exp)
 
   if lowerBound.kind == nkIntLit:
     if upperBound.kind == nkIntLit:
@@ -999,7 +1000,8 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
         of tyStatic:
           candidate = computedType
         else:
-          localError(f.n.info, errTypeExpected)
+          # XXX What is this non-sense? Error reporting in signature matching?
+          discard "localError(f.n.info, errTypeExpected)"
       else:
         discard
 
@@ -1013,7 +1015,7 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
   template doBind: bool = trDontBind notin flags
 
   # var and static arguments match regular modifier-free types
-  var a = aOrig.skipTypes({tyStatic, tyVar, tyLent}).maybeSkipDistinct(c.calleeSym)
+  var a = maybeSkipDistinct(c, aOrig.skipTypes({tyStatic, tyVar, tyLent}), c.calleeSym)
   # XXX: Theoretically, maybeSkipDistinct could be called before we even
   # start the param matching process. This could be done in `prepareOperand`
   # for example, but unfortunately `prepareOperand` is not called in certain
@@ -1442,7 +1444,7 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
           (sonsLen(x) - 1 == sonsLen(f)):
       for i in countup(1, sonsLen(f) - 1):
         if x.sons[i].kind == tyGenericParam:
-          internalError("wrong instantiated type!")
+          internalError(c.c.graph.config, "wrong instantiated type!")
         elif typeRel(c, f.sons[i], x.sons[i]) <= isSubtype:
           # Workaround for regression #4589
           if f.sons[i].kind != tyTypeDesc: return
@@ -1474,7 +1476,7 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
           if x == nil:
             discard "maybe fine (for eg. a==tyNil)"
           elif x.kind in {tyGenericInvocation, tyGenericParam}:
-            internalError("wrong instantiated type!")
+            internalError(c.c.graph.config, "wrong instantiated type!")
           else:
             put(c, f.sons[i], x)
 
@@ -1597,7 +1599,7 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
           if f.sonsLen == 0:
             result = isGeneric
           else:
-            internalAssert a.sons != nil and a.sons.len > 0
+            internalAssert c.c.graph.config, a.sons != nil and a.sons.len > 0
             c.typedescMatched = true
             var aa = a
             while aa.kind in {tyTypeDesc, tyGenericParam} and aa.len > 0:
@@ -1739,13 +1741,13 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
         if not exprStructuralEquivalent(aOrig.n, reevaluated.typ.n):
           result = isNone
     else:
-      localError(f.n.info, errTypeExpected)
+      localError(c.c.graph.config, f.n.info, "type expected")
       result = isNone
 
   of tyNone:
     if a.kind == tyNone: result = isEqual
   else:
-    internalError " unknown type kind " & $f.kind
+    internalError c.c.graph.config, " unknown type kind " & $f.kind
 
 proc cmpTypes*(c: PContext, f, a: PType): TTypeRelation =
   var m: TCandidate
@@ -1758,7 +1760,7 @@ proc getInstantiatedType(c: PContext, arg: PNode, m: TCandidate,
   if result == nil:
     result = generateTypeInstance(c, m.bindings, arg, f)
   if result == nil:
-    internalError(arg.info, "getInstantiatedType")
+    internalError(c.graph.config, arg.info, "getInstantiatedType")
     result = errorType(c)
 
 proc implicitConv(kind: TNodeKind, f: PType, arg: PNode, m: TCandidate,
@@ -1771,7 +1773,7 @@ proc implicitConv(kind: TNodeKind, f: PType, arg: PNode, m: TCandidate,
       result.typ = errorType(c)
   else:
     result.typ = f
-  if result.typ == nil: internalError(arg.info, "implicitConv")
+  if result.typ == nil: internalError(c.graph.config, arg.info, "implicitConv")
   addSon(result, ast.emptyNode)
   addSon(result, arg)
 
@@ -1792,7 +1794,7 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType,
       dest = generateTypeInstance(c, m.bindings, arg, dest)
     let fdest = typeRel(m, f, dest)
     if fdest in {isEqual, isGeneric}:
-      markUsed(arg.info, c.converters[i], c.graph.usageSym)
+      markUsed(c.config, arg.info, c.converters[i], c.graph.usageSym)
       var s = newSymNode(c.converters[i])
       s.typ = c.converters[i].typ
       s.info = arg.info
@@ -2066,7 +2068,7 @@ proc paramTypesMatch*(m: var TCandidate, f, a: PType,
       result = nil
     elif y.state == csMatch and cmpCandidates(x, y) == 0:
       if x.state != csMatch:
-        internalError(arg.info, "x.state is not csMatch")
+        internalError(m.c.graph.config, arg.info, "x.state is not csMatch")
       # ambiguous: more than one symbol fits!
       # See tsymchoice_for_expr as an example. 'f.kind == tyExpr' should match
       # anyway:
@@ -2074,12 +2076,11 @@ proc paramTypesMatch*(m: var TCandidate, f, a: PType,
       else: result = nil
     else:
       # only one valid interpretation found:
-      markUsed(arg.info, arg.sons[best].sym, m.c.graph.usageSym)
+      markUsed(m.c.config, arg.info, arg.sons[best].sym, m.c.graph.usageSym)
       styleCheckUse(arg.info, arg.sons[best].sym)
       result = paramTypesMatchAux(m, f, arg.sons[best].typ, arg.sons[best],
                                   argOrig)
 
-
 proc setSon(father: PNode, at: int, son: PNode) =
   let oldLen = father.len
   if oldLen <= at:
@@ -2115,10 +2116,10 @@ proc prepareOperand(c: PContext; a: PNode): PNode =
     result = a
     considerGenSyms(c, result)
 
-proc prepareNamedParam(a: PNode) =
+proc prepareNamedParam(a: PNode; conf: ConfigRef) =
   if a.sons[0].kind != nkIdent:
     var info = a.sons[0].info
-    a.sons[0] = newIdentNode(considerQuotedIdent(a.sons[0]), info)
+    a.sons[0] = newIdentNode(considerQuotedIdent(conf, a.sons[0]), info)
 
 proc arrayConstr(c: PContext, n: PNode): PType =
   result = newTypeS(tyArray, c)
@@ -2182,9 +2183,9 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
     elif n.sons[a].kind == nkExprEqExpr:
       # named param
       # check if m.callee has such a param:
-      prepareNamedParam(n.sons[a])
+      prepareNamedParam(n.sons[a], c.config)
       if n.sons[a].sons[0].kind != nkIdent:
-        localError(n.sons[a].info, errNamedParamHasToBeIdent)
+        localError(c.config, n.sons[a].info, "named parameter has to be an identifier")
         m.state = csNoMatch
         return
       formal = getSymFromList(m.callee.n, n.sons[a].sons[0].ident, 1)
@@ -2227,8 +2228,9 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
           # we have no formal here to snoop at:
           n.sons[a] = prepareOperand(c, n.sons[a])
           if skipTypes(n.sons[a].typ, abstractVar-{tyTypeDesc}).kind==tyString:
-            addSon(m.call, implicitConv(nkHiddenStdConv, getSysType(tyCString),
-                                        copyTree(n.sons[a]), m, c))
+            addSon(m.call, implicitConv(nkHiddenStdConv,
+                  getSysType(c.graph, n.sons[a].info, tyCString),
+                  copyTree(n.sons[a]), m, c))
           else:
             addSon(m.call, copyTree(n.sons[a]))
         elif formal != nil and formal.typ.kind == tyVarargs:
@@ -2251,7 +2253,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
           return
       else:
         if m.callee.n.sons[f].kind != nkSym:
-          internalError(n.sons[a].info, "matches")
+          internalError(c.config, n.sons[a].info, "matches")
           return
         formal = m.callee.n.sons[f].sym
         if containsOrIncl(marker, formal.position) and container.isNil:
@@ -2359,7 +2361,7 @@ proc instTypeBoundOp*(c: PContext; dc: PSym; t: PType; info: TLineInfo;
   var m: TCandidate
   initCandidate(c, m, dc.typ)
   if col >= dc.typ.len:
-    localError(info, errGenerated, "cannot instantiate '" & dc.name.s & "'")
+    localError(c.config, info, "cannot instantiate '" & dc.name.s & "'")
     return nil
   var f = dc.typ.sons[col]
 
@@ -2368,7 +2370,7 @@ proc instTypeBoundOp*(c: PContext; dc: PSym; t: PType; info: TLineInfo;
   else:
     if f.kind == tyVar: f = f.lastSon
   if typeRel(m, f, t) == isNone:
-    localError(info, errGenerated, "cannot instantiate '" & dc.name.s & "'")
+    localError(c.config, info, "cannot instantiate '" & dc.name.s & "'")
   else:
     result = c.semGenerateInstance(c, dc, m.bindings, info)
     if op == attachedDeepCopy:
diff --git a/compiler/suggest.nim b/compiler/suggest.nim
index 555ec9867..82b6038a4 100644
--- a/compiler/suggest.nim
+++ b/compiler/suggest.nim
@@ -32,7 +32,7 @@
 
 # included from sigmatch.nim
 
-import algorithm, prefixmatches
+import algorithm, prefixmatches, configuration
 from wordrecg import wDeprecated
 
 when defined(nimsuggest):
@@ -192,8 +192,8 @@ proc suggestResult(s: Suggest) =
   else:
     suggestWriteln($s)
 
-proc produceOutput(a: var Suggestions) =
-  if gIdeCmd in {ideSug, ideCon}:
+proc produceOutput(a: var Suggestions; conf: ConfigRef) =
+  if conf.ideCmd in {ideSug, ideCon}:
     a.sort cmpSuggestions
   when defined(debug):
     # debug code
@@ -480,30 +480,30 @@ proc suggestSym*(info: TLineInfo; s: PSym; usageSym: var PSym; isDecl=true) {.in
         isDecl:
       suggestResult(symToSuggest(s, isLocal=false, ideOutline, info, 100, PrefixMatch.None, false, 0))
 
-proc warnAboutDeprecated(info: TLineInfo; s: PSym) =
+proc warnAboutDeprecated(conf: ConfigRef; info: TLineInfo; s: PSym) =
   if s.kind in routineKinds:
     let n = s.ast[pragmasPos]
     if n.kind != nkEmpty:
       for it in n:
         if whichPragma(it) == wDeprecated and it.safeLen == 2 and
             it[1].kind in {nkStrLit..nkTripleStrLit}:
-          message(info, warnDeprecated, it[1].strVal & "; " & s.name.s)
+          message(conf, info, warnDeprecated, it[1].strVal & "; " & s.name.s)
           return
-  message(info, warnDeprecated, s.name.s)
+  message(conf, info, warnDeprecated, s.name.s)
 
-proc markUsed(info: TLineInfo; s: PSym; usageSym: var PSym) =
+proc markUsed(conf: ConfigRef; info: TLineInfo; s: PSym; usageSym: var PSym) =
   incl(s.flags, sfUsed)
   if s.kind == skEnumField and s.owner != nil:
     incl(s.owner.flags, sfUsed)
   if {sfDeprecated, sfError} * s.flags != {}:
-    if sfDeprecated in s.flags: warnAboutDeprecated(info, s)
-    if sfError in s.flags: localError(info, errWrongSymbolX, s.name.s)
+    if sfDeprecated in s.flags: warnAboutDeprecated(conf, info, s)
+    if sfError in s.flags: localError(conf, info,  "usage of '$1' is a user-defined error" % s.name.s)
   when defined(nimsuggest):
     suggestSym(info, s, usageSym, false)
 
-proc useSym*(sym: PSym; usageSym: var PSym): PNode =
+proc useSym*(conf: ConfigRef; sym: PSym; usageSym: var PSym): PNode =
   result = newSymNode(sym)
-  markUsed(result.info, sym, usageSym)
+  markUsed(conf, result.info, sym, usageSym)
 
 proc safeSemExpr*(c: PContext, n: PNode): PNode =
   # use only for idetools support!
@@ -534,9 +534,9 @@ proc suggestExprNoCheck*(c: PContext, n: PNode) =
   if c.compilesContextId > 0: return
   inc(c.compilesContextId)
   var outputs: Suggestions = @[]
-  if gIdeCmd == ideSug:
+  if c.config.ideCmd == ideSug:
     sugExpr(c, n, outputs)
-  elif gIdeCmd == ideCon:
+  elif c.config.ideCmd == ideCon:
     if n.kind in nkCallKinds:
       var a = copyNode(n)
       var x = safeSemExpr(c, n.sons[0])
@@ -550,8 +550,8 @@ proc suggestExprNoCheck*(c: PContext, n: PNode) =
       suggestCall(c, a, n, outputs)
 
   dec(c.compilesContextId)
-  if outputs.len > 0 and gIdeCmd in {ideSug, ideCon, ideDef}:
-    produceOutput(outputs)
+  if outputs.len > 0 and c.config.ideCmd in {ideSug, ideCon, ideDef}:
+    produceOutput(outputs, c.config)
     suggestQuit()
 
 proc suggestExpr*(c: PContext, n: PNode) =
@@ -570,11 +570,11 @@ proc suggestStmt*(c: PContext, n: PNode) =
 proc suggestEnum*(c: PContext; n: PNode; t: PType) =
   var outputs: Suggestions = @[]
   suggestSymList(c, t.n, nil, n.info, outputs)
-  produceOutput(outputs)
+  produceOutput(outputs, c.config)
   if outputs.len > 0: suggestQuit()
 
 proc suggestSentinel*(c: PContext) =
-  if gIdeCmd != ideSug or c.module.position != gTrackPos.fileIndex.int32: return
+  if c.config.ideCmd != ideSug or c.module.position != gTrackPos.fileIndex.int32: return
   if c.compilesContextId > 0: return
   inc(c.compilesContextId)
   var outputs: Suggestions = @[]
@@ -590,4 +590,4 @@ proc suggestSentinel*(c: PContext) =
         outputs.add(symToSuggest(it, isLocal = isLocal, ideSug, newLineInfo(gTrackPos.fileIndex, -1, -1), 0, PrefixMatch.None, false, scopeN))
 
   dec(c.compilesContextId)
-  produceOutput(outputs)
+  produceOutput(outputs, c.config)