diff options
-rw-r--r-- | compiler/importer.nim | 6 | ||||
-rw-r--r-- | compiler/lookups.nim | 21 | ||||
-rw-r--r-- | compiler/semdata.nim | 1 | ||||
-rw-r--r-- | tests/import/t21496.nim | 2 |
4 files changed, 21 insertions, 9 deletions
diff --git a/compiler/importer.nim b/compiler/importer.nim index 84f4bb545..0324b2fbc 100644 --- a/compiler/importer.nim +++ b/compiler/importer.nim @@ -228,6 +228,11 @@ proc importForwarded(c: PContext, n: PNode, exceptSet: IntSet; fromMod: PSym; im for i in 0..n.safeLen-1: importForwarded(c, n[i], exceptSet, fromMod, importSet) +proc addUnique[T](x: var seq[T], y: sink T) {.noSideEffect.} = + for i in 0..high(x): + if x[i] == y: return + x.add y + proc importModuleAs(c: PContext; n: PNode, realModule: PSym, importHidden: bool): PSym = result = realModule template createModuleAliasImpl(ident): untyped = @@ -245,6 +250,7 @@ proc importModuleAs(c: PContext; n: PNode, realModule: PSym, importHidden: bool) result.options.incl optImportHidden c.unusedImports.add((result, n.info)) c.importModuleMap[result.id] = realModule.id + c.importModuleLookup.mgetOrPut(realModule.name.id, @[]).addUnique realModule.id proc transformImportAs(c: PContext; n: PNode): tuple[node: PNode, importHidden: bool] = var ret: typeof(result) diff --git a/compiler/lookups.nim b/compiler/lookups.nim index 8b98ea3f1..3b4599f2c 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -8,7 +8,7 @@ # # This module implements lookup helpers. -import std/[algorithm, strutils] +import std/[algorithm, strutils, tables] when defined(nimPreviewSlimSystem): import std/assertions @@ -343,14 +343,15 @@ proc addDeclAt*(c: PContext; scope: PScope, sym: PSym, info: TLineInfo) = if sym.name.s == "_": return let conflict = scope.addUniqueSym(sym) if conflict != nil: - if sym.kind == skModule and conflict.kind == skModule and - sym.position == conflict.position: + if sym.kind == skModule and conflict.kind == skModule: # e.g.: import foo; import foo # xxx we could refine this by issuing a different hint for the case - # where a duplicate import happens inside an include. - localError(c.config, info, hintDuplicateModuleImport, - "duplicate import of '$1'; previous import here: $2" % - [sym.name.s, c.config $ conflict.info]) + # where a duplicate import happens inside an include. + if c.importModuleMap[sym.id] == c.importModuleMap[conflict.id]: + #only hints if the conflict is the actual module not just a shared name + localError(c.config, info, hintDuplicateModuleImport, + "duplicate import of '$1'; previous import here: $2" % + [sym.name.s, c.config $ conflict.info]) else: wrongRedefinition(c, info, sym.name.s, conflict.info, errGenerated) @@ -631,7 +632,11 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags: set[TLookupFlag]): PSym = if m == c.module: result = strTableGet(c.topLevelScope.symbols, ident).skipAlias(n, c.config) else: - result = someSym(c.graph, m, ident).skipAlias(n, c.config) + if c.importModuleLookup.getOrDefault(m.name.id).len > 1: + var amb: bool + result = errorUseQualifier(c, n.info, m, amb) + else: + result = someSym(c.graph, m, ident).skipAlias(n, c.config) if result == nil and checkUndeclared in flags: result = errorUndeclaredIdentifierHint(c, n[1], ident) elif n[1].kind == nkSym: diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 5b94cc770..90d496c8c 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -166,6 +166,7 @@ type lastTLineInfo*: TLineInfo sideEffects*: Table[int, seq[(TLineInfo, PSym)]] # symbol.id index inUncheckedAssignSection*: int + importModuleLookup*: Table[int, seq[int]] # (module.ident.id, [module.id]) template config*(c: PContext): ConfigRef = c.graph.config diff --git a/tests/import/t21496.nim b/tests/import/t21496.nim index 568f2ac51..b49d830b0 100644 --- a/tests/import/t21496.nim +++ b/tests/import/t21496.nim @@ -1,5 +1,5 @@ discard """ - errormsg: "redefinition of 'm21496'; previous declaration here: t21496.nim(5, 12)" + errormsg: "ambiguous identifier: 'm21496'" """ import fizz/m21496, buzz/m21496 |