summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/lookups.nim11
-rw-r--r--compiler/modulegraphs.nim19
-rw-r--r--compiler/semexprs.nim9
-rw-r--r--tests/lookups/mqualifiedamb1.nim1
-rw-r--r--tests/lookups/mqualifiedamb2.nim4
-rw-r--r--tests/lookups/tqualifiedamb.nim4
6 files changed, 41 insertions, 7 deletions
diff --git a/compiler/lookups.nim b/compiler/lookups.nim
index 759153830..c6940a4dc 100644
--- a/compiler/lookups.nim
+++ b/compiler/lookups.nim
@@ -679,13 +679,18 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags: set[TLookupFlag]): PSym =
         ident = considerQuotedIdent(c, n[1])
       if ident != nil:
         if m == c.module:
-          result = strTableGet(c.topLevelScope.symbols, ident)
+          var ti: TIdentIter = default(TIdentIter)
+          result = initIdentIter(ti, c.topLevelScope.symbols, ident)
+          if result != nil and nextIdentIter(ti, c.topLevelScope.symbols) != nil:
+            # another symbol exists with same name
+            c.isAmbiguous = true
         else:
+          var amb: bool = false
           if c.importModuleLookup.getOrDefault(m.name.id).len > 1:
-            var amb: bool = false
             result = errorUseQualifier(c, n.info, m, amb)
           else:
-            result = someSym(c.graph, m, ident)
+            result = someSymAmb(c.graph, m, ident, amb)
+            if amb: c.isAmbiguous = true
         if result == nil and checkUndeclared in flags:
           result = errorUndeclaredIdentifierHint(c, ident, n[1].info)
       elif n[1].kind == nkSym:
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)
 
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index bc66ba3d5..9293f8497 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -3321,12 +3321,13 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}, expectedType: PType
       of skType:
         # XXX think about this more (``set`` procs)
         let ambig = c.isAmbiguous
-        if not (n[0].kind in {nkClosedSymChoice, nkOpenSymChoice, nkIdent} and ambig) and n.len == 2:
+        if not (n[0].kind in nkSymChoices + {nkIdent, nkDotExpr} and ambig) and n.len == 2:
           result = semConv(c, n, flags, expectedType)
-        elif ambig and n.len == 1:
-          errorUseQualifier(c, n.info, s)
         elif n.len == 1:
-          result = semObjConstr(c, n, flags, expectedType)
+          if ambig:
+            errorUseQualifier(c, n.info, s)
+          else:
+            result = semObjConstr(c, n, flags, expectedType)
         elif s.magic == mNone: result = semDirectOp(c, n, flags, expectedType)
         else: result = semMagic(c, n, s, flags, expectedType)
       of skProc, skFunc, skMethod, skConverter, skIterator:
diff --git a/tests/lookups/mqualifiedamb1.nim b/tests/lookups/mqualifiedamb1.nim
new file mode 100644
index 000000000..47046142e
--- /dev/null
+++ b/tests/lookups/mqualifiedamb1.nim
@@ -0,0 +1 @@
+type K* = object
diff --git a/tests/lookups/mqualifiedamb2.nim b/tests/lookups/mqualifiedamb2.nim
new file mode 100644
index 000000000..3ea5bd04f
--- /dev/null
+++ b/tests/lookups/mqualifiedamb2.nim
@@ -0,0 +1,4 @@
+import ./mqualifiedamb1
+export mqualifiedamb1
+template K*(kind: static int): auto = typedesc[mqualifiedamb1.K]
+template B*(kind: static int): auto = typedesc[mqualifiedamb1.K]
diff --git a/tests/lookups/tqualifiedamb.nim b/tests/lookups/tqualifiedamb.nim
new file mode 100644
index 000000000..a5e1955f3
--- /dev/null
+++ b/tests/lookups/tqualifiedamb.nim
@@ -0,0 +1,4 @@
+import ./mqualifiedamb2
+discard default(K(0))       # works
+discard default(mqualifiedamb2.B(0))     # works
+discard default(mqualifiedamb2.K(0))     # doesn't work