diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/importer.nim | 34 | ||||
-rw-r--r-- | compiler/lineinfos.nim | 2 | ||||
-rw-r--r-- | compiler/lookups.nim | 18 | ||||
-rw-r--r-- | compiler/passaux.nim | 2 |
4 files changed, 33 insertions, 23 deletions
diff --git a/compiler/importer.nim b/compiler/importer.nim index 692cdb604..7a5c4de4a 100644 --- a/compiler/importer.nim +++ b/compiler/importer.nim @@ -13,6 +13,7 @@ import intsets, ast, astalgo, msgs, options, idents, lookups, semdata, modulepaths, sigmatch, lineinfos, sets, modulegraphs, wordrecg +from strutils import `%` proc readExceptSet*(c: PContext, n: PNode): IntSet = assert n.kind in {nkImportExceptStmt, nkExportExceptStmt} @@ -224,19 +225,20 @@ proc importForwarded(c: PContext, n: PNode, exceptSet: IntSet; fromMod: PSym; im proc importModuleAs(c: PContext; n: PNode, realModule: PSym, importHidden: bool): PSym = result = realModule - c.unusedImports.add((realModule, n.info)) template createModuleAliasImpl(ident): untyped = - createModuleAlias(realModule, nextSymId c.idgen, ident, realModule.info, c.config.options) + createModuleAlias(realModule, nextSymId c.idgen, ident, n.info, c.config.options) if n.kind != nkImportAs: discard elif n.len != 2 or n[1].kind != nkIdent: localError(c.config, n.info, "module alias must be an identifier") elif n[1].ident.id != realModule.name.id: # some misguided guy will write 'import abc.foo as foo' ... result = createModuleAliasImpl(n[1].ident) + if result == realModule: + # avoids modifying `realModule`, see D20201209T194412 for `import {.all.}` + result = createModuleAliasImpl(realModule.name) if importHidden: - if result == realModule: # avoids modifying `realModule`, see D20201209T194412. - result = createModuleAliasImpl(realModule.name) result.options.incl optImportHidden + c.unusedImports.add((result, n.info)) proc transformImportAs(c: PContext; n: PNode): tuple[node: PNode, importHidden: bool] = var ret: typeof(result) @@ -274,23 +276,22 @@ proc myImportModule(c: PContext, n: var PNode, importStmtResult: PNode): PSym = toFullPath(c.config, c.graph.importStack[i+1]) c.recursiveDep = err + var realModule: PSym discard pushOptionEntry(c) - result = importModuleAs(c, n, c.graph.importModuleCallback(c.graph, c.module, f), transf.importHidden) + realModule = c.graph.importModuleCallback(c.graph, c.module, f) + result = importModuleAs(c, n, realModule, transf.importHidden) popOptionEntry(c) #echo "set back to ", L c.graph.importStack.setLen(L) # we cannot perform this check reliably because of - # test: modules/import_in_config) - when true: - if result.info.fileIndex == c.module.info.fileIndex and - result.info.fileIndex == n.info.fileIndex: - localError(c.config, n.info, "A module cannot import itself") - if sfDeprecated in result.flags: - if result.constraint != nil: - message(c.config, n.info, warnDeprecated, result.constraint.strVal & "; " & result.name.s & " is deprecated") - else: - message(c.config, n.info, warnDeprecated, result.name.s & " is deprecated") + # test: modules/import_in_config) # xxx is that still true? + if realModule == c.module: + localError(c.config, n.info, "module '$1' cannot import itself" % realModule.name.s) + if sfDeprecated in realModule.flags: + var prefix = "" + if realModule.constraint != nil: prefix = realModule.constraint.strVal & "; " + message(c.config, n.info, warnDeprecated, prefix & realModule.name.s & " is deprecated") suggestSym(c.graph, n.info, result, c.graph.usageSym, false) importStmtResult.add newSymNode(result, n.info) #newStrNode(toFullPath(c.config, f), n.info) @@ -303,6 +304,9 @@ proc impMod(c: PContext; it: PNode; importStmtResult: PNode) = addDecl(c, m, it.info) # add symbol to symbol table of module importAllSymbols(c, m) #importForwarded(c, m.ast, emptySet, m) + for s in allSyms(c.graph, m): # fixes bug #17510, for re-exported symbols + if s.owner != m: + c.exportIndirections.incl((m.id, s.id)) proc evalImport*(c: PContext, n: PNode): PNode = result = newNodeI(nkImportStmt, n.info) diff --git a/compiler/lineinfos.nim b/compiler/lineinfos.nim index abe6bce7c..11fa45480 100644 --- a/compiler/lineinfos.nim +++ b/compiler/lineinfos.nim @@ -67,6 +67,7 @@ type warnResultUsed = "ResultUsed", warnCannotOpen = "CannotOpen", warnFileChanged = "FileChanged", + warnDuplicateModuleImport = "DuplicateModuleImport", warnUser = "User", # hints hintSuccess = "Success", hintSuccessX = "SuccessX", @@ -148,6 +149,7 @@ const warnResultUsed: "used 'result' variable", warnCannotOpen: "cannot open: $1", warnFileChanged: "file changed: $1", + warnDuplicateModuleImport: "$1", warnUser: "$1", hintSuccess: "operation successful: $#", # keep in sync with `testament.isSuccess` diff --git a/compiler/lookups.nim b/compiler/lookups.nim index ee79673d0..0e057a79a 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -58,8 +58,8 @@ proc considerQuotedIdent*(c: PContext; n: PNode, origin: PNode = nil): PIdent = template addSym*(scope: PScope, s: PSym) = strTableAdd(scope.symbols, s) -proc addUniqueSym*(scope: PScope, s: PSym): PSym = - result = strTableInclReportConflict(scope.symbols, s) +proc addUniqueSym*(scope: PScope, s: PSym, onConflictKeepOld: bool): PSym = + result = strTableInclReportConflict(scope.symbols, s, onConflictKeepOld) proc openScope*(c: PContext): PScope {.discardable.} = result = PScope(parent: c.currentScope, @@ -288,19 +288,23 @@ proc ensureNoMissingOrUnusedSymbols(c: PContext; scope: PScope) = message(c.config, s.info, hintXDeclaredButNotUsed, s.name.s) proc wrongRedefinition*(c: PContext; info: TLineInfo, s: string; - conflictsWith: TLineInfo) = + conflictsWith: TLineInfo, note = errGenerated) = ## Emit a redefinition error if in non-interactive mode if c.config.cmd != cmdInteractive: - localError(c.config, info, + localError(c.config, info, note, "redefinition of '$1'; previous declaration here: $2" % [s, c.config $ conflictsWith]) # xxx pending bootstrap >= 1.4, replace all those overloads with a single one: # proc addDecl*(c: PContext, sym: PSym, info = sym.info, scope = c.currentScope) {.inline.} = proc addDeclAt*(c: PContext; scope: PScope, sym: PSym, info: TLineInfo) = - let conflict = scope.addUniqueSym(sym) + let conflict = scope.addUniqueSym(sym, onConflictKeepOld = true) if conflict != nil: - wrongRedefinition(c, info, sym.name.s, conflict.info) + var note = errGenerated + if sym.kind == skModule and conflict.kind == skModule and sym.owner == conflict.owner: + # import foo; import foo + note = warnDuplicateModuleImport + wrongRedefinition(c, info, sym.name.s, conflict.info, note) proc addDeclAt*(c: PContext; scope: PScope, sym: PSym) {.inline.} = addDeclAt(c, scope, sym, sym.info) @@ -312,7 +316,7 @@ proc addDecl*(c: PContext, sym: PSym) {.inline.} = addDeclAt(c, c.currentScope, sym) proc addPrelimDecl*(c: PContext, sym: PSym) = - discard c.currentScope.addUniqueSym(sym) + discard c.currentScope.addUniqueSym(sym, onConflictKeepOld = false) from ic / ic import addHidden diff --git a/compiler/passaux.nim b/compiler/passaux.nim index 9abc97be4..87cb3a730 100644 --- a/compiler/passaux.nim +++ b/compiler/passaux.nim @@ -10,7 +10,7 @@ ## implements some little helper passes import - ast, passes, idents, msgs, options, lineinfos + ast, passes, msgs, options, lineinfos from modulegraphs import ModuleGraph, PPassContext |