summary refs log tree commit diff stats
path: root/compiler/modulegraphs.nim
diff options
context:
space:
mode:
authormetagn <metagngn@gmail.com>2024-08-20 22:32:35 +0300
committerGitHub <noreply@github.com>2024-08-20 21:32:35 +0200
commite38cbd3c846a8e95bed0d709e4d61cc1ad5279b2 (patch)
treeb556b87bbf9fcec4ee94b96d3ca08dc0f709564b /compiler/modulegraphs.nim
parentab189620857a9fe36480044732c407dfcfdec73a (diff)
downloadNim-e38cbd3c846a8e95bed0d709e4d61cc1ad5279b2.tar.gz
consider ambiguity for qualified symbols (#23989)
fixes #23893

When type symbols are ambiguous, calls to them aren't allowed to be type
conversions and only routine symbols are considered instead. But the
compiler doesn't acknowledge that qualified symbols can be ambiguous,
`qualifiedLookUp` directly tries to access the identifier from the
module string table. Now it checks the relevant symbol iterators for any
symbol after the first received symbol, in which case the symbol is
considered ambiguous. `nkDotExpr` is also included in the whitelist of
node kinds for ambiguous type symbols (not entirely sure why this
exists, it's missing `nkAccQuoted` as well).
Diffstat (limited to 'compiler/modulegraphs.nim')
-rw-r--r--compiler/modulegraphs.nim19
1 files changed, 19 insertions, 0 deletions
diff --git a/compiler/modulegraphs.nim b/compiler/modulegraphs.nim
index 749cb0cc4..77762d23a 100644
--- a/compiler/modulegraphs.nim
+++ b/compiler/modulegraphs.nim
@@ -274,6 +274,25 @@ proc someSym*(g: ModuleGraph; m: PSym; name: PIdent): PSym =
   else:
     result = strTableGet(g.ifaces[m.position].interfSelect(importHidden), name)
 
+proc someSymAmb*(g: ModuleGraph; m: PSym; name: PIdent; amb: var bool): PSym =
+  let importHidden = optImportHidden in m.options
+  if isCachedModule(g, m):
+    result = nil
+    for s in interfaceSymbols(g.config, g.cache, g.packed, FileIndex(m.position), name, importHidden):
+      if result == nil:
+        # set result to the first symbol
+        result = s
+      else:
+        # another symbol found
+        amb = true
+        break
+  else:
+    var ti: TIdentIter = default(TIdentIter)
+    result = initIdentIter(ti, g.ifaces[m.position].interfSelect(importHidden), name)
+    if result != nil and nextIdentIter(ti, g.ifaces[m.position].interfSelect(importHidden)) != nil:
+      # another symbol exists with same name
+      amb = true
+
 proc systemModuleSym*(g: ModuleGraph; name: PIdent): PSym =
   result = someSym(g, g.systemModule, name)