summary refs log tree commit diff stats
diff options
context:
space:
mode:
authormetagn <metagngn@gmail.com>2024-01-11 14:39:51 +0300
committerGitHub <noreply@github.com>2024-01-11 12:39:51 +0100
commit6650b417779d61a895da23d24ab32ee1388216c2 (patch)
treec56e847d7058d051a27ab528e53a0c34ff1dc351
parent29ac3c9986de5731a32beaf015e81a18dd6bd498 (diff)
downloadNim-6650b417779d61a895da23d24ab32ee1388216c2.tar.gz
document the new ambiguous identifier resolution (#23166)
refs #23123

Not sure if detailed enough.
-rw-r--r--doc/manual.md30
-rw-r--r--tests/lookups/mambsym3.nim4
-rw-r--r--tests/lookups/mambsym4.nim4
-rw-r--r--tests/lookups/tambsymmanual.nim25
4 files changed, 59 insertions, 4 deletions
diff --git a/doc/manual.md b/doc/manual.md
index 268d04f67..9ffd9b2cd 100644
--- a/doc/manual.md
+++ b/doc/manual.md
@@ -6976,25 +6976,47 @@ All identifiers of a module are valid from the point of declaration until
 the end of the module. Identifiers from indirectly dependent modules are *not*
 available. The `system`:idx: module is automatically imported in every module.
 
-If a module imports an identifier by two different modules, each occurrence of
-the identifier has to be qualified unless it is an overloaded procedure or
-iterator in which case the overloading resolution takes place:
+If a module imports the same identifier from two different modules, the
+identifier is considered ambiguous, which can be resolved in the following ways:
+
+* Qualifying the identifier as `module.identifier` resolves ambiguity
+  between modules. (See below for the case that the module name itself
+  is ambiguous.)
+* Calling the identifier as a routine makes overload resolution take place,
+  which resolves ambiguity in the case that one overload matches stronger
+  than the others.
+* Using the identifier in a context where the compiler can infer the type
+  of the identifier resolves ambiguity in the case that one definition
+  matches the type stronger than the others.
 
   ```nim
   # Module A
   var x*: string
+  proc foo*(a: string) =
+    echo "A: ", a
   ```
 
   ```nim
   # Module B
   var x*: int
+  proc foo*(b: int) =
+    echo "B: ", b
   ```
 
   ```nim
   # Module C
   import A, B
+
+  foo("abc") # A: abc
+  foo(123) # B: 123
+  let inferred: proc (x: string) = foo
+  foo("def") # A: def
+
   write(stdout, x) # error: x is ambiguous
   write(stdout, A.x) # no error: qualifier used
+  
+  proc bar(a: int): int = a + 1
+  assert bar(x) == x + 1 # no error: only A.x of type int matches
 
   var x = 4
   write(stdout, x) # not ambiguous: uses the module C's x
@@ -7018,7 +7040,7 @@ proc fb* = echo "buzz"
 import A/C
 import B/C
 
-C.fb() # Error: ambiguous identifier: 'fb'
+C.fb() # Error: ambiguous identifier: 'C'
 ```
 
 
diff --git a/tests/lookups/mambsym3.nim b/tests/lookups/mambsym3.nim
new file mode 100644
index 000000000..946a5ff29
--- /dev/null
+++ b/tests/lookups/mambsym3.nim
@@ -0,0 +1,4 @@
+# Module A
+var x*: string
+proc foo*(a: string) =
+  echo "A: ", a
diff --git a/tests/lookups/mambsym4.nim b/tests/lookups/mambsym4.nim
new file mode 100644
index 000000000..ed66cc16d
--- /dev/null
+++ b/tests/lookups/mambsym4.nim
@@ -0,0 +1,4 @@
+# Module B
+var x*: int
+proc foo*(b: int) =
+  echo "B: ", b
diff --git a/tests/lookups/tambsymmanual.nim b/tests/lookups/tambsymmanual.nim
new file mode 100644
index 000000000..3ad91b8cc
--- /dev/null
+++ b/tests/lookups/tambsymmanual.nim
@@ -0,0 +1,25 @@
+discard """
+  output: '''
+A: abc
+B: 123
+A: def
+4
+'''
+"""
+# Module C
+import mambsym3, mambsym4
+
+foo("abc") # A: abc
+foo(123) # B: 123
+let inferred: proc (x: string) = foo
+foo("def") # A: def
+
+doAssert not compiles(write(stdout, x)) # error: x is ambiguous
+write(stdout, mambsym3.x) # no error: qualifier used
+
+proc bar(a: int): int = a + 1
+doAssert bar(x) == x + 1 # no error: only A.x of type int matches
+
+var x = 4
+write(stdout, x) # not ambiguous: uses the module C's x
+echo() # for test output