summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/importer.nim6
-rw-r--r--compiler/lookups.nim17
-rw-r--r--compiler/msgs.nim3
-rw-r--r--compiler/semdata.nim1
-rw-r--r--compiler/semexprs.nim2
-rw-r--r--compiler/semgnrc.nim4
-rw-r--r--compiler/semmagic.nim2
7 files changed, 22 insertions, 13 deletions
diff --git a/compiler/importer.nim b/compiler/importer.nim
index b7e574c62..feebf97c4 100644
--- a/compiler/importer.nim
+++ b/compiler/importer.nim
@@ -100,7 +100,7 @@ proc importSymbol(c: PContext, n: PNode, fromMod: PSym) =
   let ident = lookups.considerQuotedIdent(n)
   let s = strTableGet(fromMod.tab, ident)
   if s == nil:
-    localError(n.info, errUndeclaredIdentifier, ident.s)
+    errorUndeclaredIdentifier(c, n.info, ident.s)
   else:
     if s.kind == skStub: loadStub(s)
     if s.kind notin ExportableSymKinds:
@@ -172,13 +172,13 @@ proc myImportModule(c: PContext, n: PNode): PSym =
         if i > recursion: err.add "\n"
         err.add toFullPath(c.graph.importStack[i]) & " imports " &
                 toFullPath(c.graph.importStack[i+1])
-      localError(n.info, "recursive module dependency detected:\n" & err)
+      c.recursiveDep = err
     result = importModuleAs(n, gImportModule(c.graph, c.module, f, c.cache))
     #echo "set back to ", L
     c.graph.importStack.setLen(L)
     # we cannot perform this check reliably because of
     # test: modules/import_in_config)
-    when false:
+    when true:
       if result.info.fileIndex == c.module.info.fileIndex and
           result.info.fileIndex == n.info.fileIndex:
         localError(n.info, errGenerated, "A module cannot import itself")
diff --git a/compiler/lookups.nim b/compiler/lookups.nim
index df19a6afb..fe159011c 100644
--- a/compiler/lookups.nim
+++ b/compiler/lookups.nim
@@ -242,6 +242,15 @@ proc errorUseQualifier*(c: PContext; info: TLineInfo; s: PSym) =
     inc i
   localError(info, errGenerated, err)
 
+proc errorUndeclaredIdentifier*(c: PContext; info: TLineInfo; name: string) =
+  var err = "undeclared identifier: '" & name & "'"
+  if c.recursiveDep.len > 0:
+    err.add "\nThis might be caused by a recursive module dependency: "
+    err.add c.recursiveDep
+    # prevent excessive errors for 'nim check'
+    c.recursiveDep = nil
+  localError(info, errGenerated, err)
+
 proc lookUp*(c: PContext, n: PNode): PSym =
   # Looks up a symbol. Generates an error in case of nil.
   case n.kind
@@ -249,7 +258,7 @@ proc lookUp*(c: PContext, n: PNode): PSym =
     result = searchInScopes(c, n.ident).skipAlias(n)
     if result == nil:
       fixSpelling(n, n.ident, searchInScopes)
-      localError(n.info, errUndeclaredIdentifier, n.ident.s)
+      errorUndeclaredIdentifier(c, n.info, n.ident.s)
       result = errorSym(c, n)
   of nkSym:
     result = n.sym
@@ -258,7 +267,7 @@ proc lookUp*(c: PContext, n: PNode): PSym =
     result = searchInScopes(c, ident).skipAlias(n)
     if result == nil:
       fixSpelling(n, ident, searchInScopes)
-      localError(n.info, errUndeclaredIdentifier, ident.s)
+      errorUndeclaredIdentifier(c, n.info, ident.s)
       result = errorSym(c, n)
   else:
     internalError(n.info, "lookUp")
@@ -282,7 +291,7 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags: set[TLookupFlag]): PSym =
       result = searchInScopes(c, ident, allExceptModule).skipAlias(n)
     if result == nil and checkUndeclared in flags:
       fixSpelling(n, ident, searchInScopes)
-      localError(n.info, errUndeclaredIdentifier, ident.s)
+      errorUndeclaredIdentifier(c, n.info, ident.s)
       result = errorSym(c, n)
     elif checkAmbiguity in flags and result != nil and
         contains(c.ambiguousSymbols, result.id):
@@ -307,7 +316,7 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags: set[TLookupFlag]): PSym =
           result = strTableGet(m.tab, ident).skipAlias(n)
         if result == nil and checkUndeclared in flags:
           fixSpelling(n.sons[1], ident, searchInScopes)
-          localError(n.sons[1].info, errUndeclaredIdentifier, ident.s)
+          errorUndeclaredIdentifier(c, n.sons[1].info, ident.s)
           result = errorSym(c, n.sons[1])
       elif n.sons[1].kind == nkSym:
         result = n.sons[1].sym
diff --git a/compiler/msgs.nim b/compiler/msgs.nim
index 0f39eb4d3..94b0bee00 100644
--- a/compiler/msgs.nim
+++ b/compiler/msgs.nim
@@ -35,7 +35,7 @@ type
     errNoneSpeedOrSizeExpectedButXFound, errGuiConsoleOrLibExpectedButXFound,
     errUnknownOS, errUnknownCPU, errGenOutExpectedButXFound,
     errArgsNeedRunOption, errInvalidMultipleAsgn, errColonOrEqualsExpected,
-    errExprExpected, errUndeclaredIdentifier, errUndeclaredField,
+    errExprExpected, errUndeclaredField,
     errUndeclaredRoutine, errUseQualifier,
     errTypeExpected,
     errSystemNeeds, errExecutionOfProgramFailed, errNotOverloadable,
@@ -197,7 +197,6 @@ const
     errInvalidMultipleAsgn: "multiple assignment is not allowed",
     errColonOrEqualsExpected: "\':\' or \'=\' expected, but found \'$1\'",
     errExprExpected: "expression expected, but found \'$1\'",
-    errUndeclaredIdentifier: "undeclared identifier: \'$1\'",
     errUndeclaredField: "undeclared field: \'$1\'",
     errUndeclaredRoutine: "attempting to call undeclared routine: \'$1\'",
     errUseQualifier: "ambiguous identifier: \'$1\' -- use a qualifier",
diff --git a/compiler/semdata.nim b/compiler/semdata.nim
index 5b84b7cdf..2fec8c757 100644
--- a/compiler/semdata.nim
+++ b/compiler/semdata.nim
@@ -110,6 +110,7 @@ type
     cache*: IdentCache
     graph*: ModuleGraph
     signatures*: TStrTable
+    recursiveDep*: string
 
 proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair =
   result.genericSym = s
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index d3431de70..8aaf4f9d8 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1551,7 +1551,7 @@ proc expectMacroOrTemplateCall(c: PContext, n: PNode): PSym =
   if isCallExpr(n):
     var expandedSym = qualifiedLookUp(c, n[0], {checkUndeclared})
     if expandedSym == nil:
-      localError(n.info, errUndeclaredIdentifier, n[0].renderTree)
+      errorUndeclaredIdentifier(c, n.info, n[0].renderTree)
       return errorSym(c, n[0])
 
     if expandedSym.kind notin {skMacro, skTemplate}:
diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim
index b8451865e..ab0ce7c4c 100644
--- a/compiler/semgnrc.nim
+++ b/compiler/semgnrc.nim
@@ -107,7 +107,7 @@ proc lookup(c: PContext, n: PNode, flags: TSemGenericFlags,
   var s = searchInScopes(c, ident).skipAlias(n)
   if s == nil:
     if ident.id notin ctx.toMixin and withinMixin notin flags:
-      localError(n.info, errUndeclaredIdentifier, ident.s)
+      errorUndeclaredIdentifier(c, n.info, ident.s)
   else:
     if withinBind in flags:
       result = symChoice(c, n, s, scClosed)
@@ -195,7 +195,7 @@ proc semGenericStmt(c: PContext, n: PNode,
     if s == nil and withinMixin notin flags and
         fn.kind in {nkIdent, nkAccQuoted} and
         considerQuotedIdent(fn).id notin ctx.toMixin:
-      localError(n.info, errUndeclaredIdentifier, fn.renderTree)
+      errorUndeclaredIdentifier(c, n.info, fn.renderTree)
 
     var first = 0
     var mixinContext = false
diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim
index cd90782d1..e72172c81 100644
--- a/compiler/semmagic.nim
+++ b/compiler/semmagic.nim
@@ -143,7 +143,7 @@ proc semBindSym(c: PContext, n: PNode): PNode =
     var sc = symChoice(c, id, s, TSymChoiceRule(isMixin.intVal))
     result.add(sc)
   else:
-    localError(n.sons[1].info, errUndeclaredIdentifier, sl.strVal)
+    errorUndeclaredIdentifier(c, n.sons[1].info, sl.strVal)
 
 proc semShallowCopy(c: PContext, n: PNode, flags: TExprFlags): PNode