implements #21620: allowing to import multiple modules with shared names (#21628)

This commit is contained in:
Juan M Gómez
2023-04-21 14:40:13 +01:00
committed by GitHub
parent 4fa86422c0
commit c136ebf1ed
4 changed files with 21 additions and 9 deletions

View File

@@ -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)

View File

@@ -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:

View File

@@ -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

View File

@@ -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