summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2018-08-31 00:30:09 +0200
committerAraq <rumpf_a@web.de>2018-08-31 00:30:19 +0200
commit2f7b979e384ff6cc750e123939401a72c3f59093 (patch)
treefc78fafe5efbb2fb5e63038ce1ecb6934b7f56f6
parentfab449872776badf7c81f08b29ddaf2f598a5c3d (diff)
downloadNim-2f7b979e384ff6cc750e123939401a72c3f59093.tar.gz
fixes #8066
-rw-r--r--compiler/importer.nim10
-rw-r--r--compiler/lookups.nim2
-rw-r--r--doc/manual.rst25
-rw-r--r--tests/enum/tpure_enums_conflict.nim19
4 files changed, 46 insertions, 10 deletions
diff --git a/compiler/importer.nim b/compiler/importer.nim
index 6a225a761..739759794 100644
--- a/compiler/importer.nim
+++ b/compiler/importer.nim
@@ -24,9 +24,15 @@ proc readExceptSet*(c: PContext, n: PNode): IntSet =
     result.incl(ident.id)
 
 proc importPureEnumField*(c: PContext; s: PSym) =
-  var check = strTableGet(c.importTable.symbols, s.name)
+  let check = strTableGet(c.importTable.symbols, s.name)
   if check == nil:
-    strTableAdd(c.pureEnumFields, s)
+    let checkB = strTableGet(c.pureEnumFields, s.name)
+    if checkB == nil:
+      strTableAdd(c.pureEnumFields, s)
+    else:
+      # mark as ambigous:
+      incl(c.ambiguousSymbols, checkB.id)
+      incl(c.ambiguousSymbols, s.id)
 
 proc rawImportSymbol(c: PContext, s: PSym) =
   # This does not handle stubs, because otherwise loading on demand would be
diff --git a/compiler/lookups.nim b/compiler/lookups.nim
index 7f0882754..ec9c130e3 100644
--- a/compiler/lookups.nim
+++ b/compiler/lookups.nim
@@ -244,7 +244,7 @@ else:
   template fixSpelling(n: PNode; ident: PIdent; op: untyped) = discard
 
 proc errorUseQualifier*(c: PContext; info: TLineInfo; s: PSym) =
-  var err = "Error: ambiguous identifier: '" & s.name.s & "'"
+  var err = "ambiguous identifier: '" & s.name.s & "'"
   var ti: TIdentIter
   var candidate = initIdentIter(ti, c.importTable.symbols, s.name)
   var i = 0
diff --git a/doc/manual.rst b/doc/manual.rst
index ca32c9c61..29671d3dd 100644
--- a/doc/manual.rst
+++ b/doc/manual.rst
@@ -937,8 +937,12 @@ Now the following holds::
   ord(south) == 2
   ord(west) == 3
 
+  # Also allowed:
+  ord(Direction.west) == 3
+
 Thus, north < east < south < west. The comparison operators can be used
-with enumeration types.
+with enumeration types. Instead of ``north`` etc, the enum value can also
+be qualified with the enum type that it resides in, ``Direction.north``.
 
 For better interfacing to other programming languages, the fields of enum
 types can be assigned an explicit ordinal value. However, the ordinal values
@@ -974,18 +978,25 @@ As can be seen from the example, it is possible to both specify a field's
 ordinal value and its string value by using a tuple. It is also
 possible to only specify one of them.
 
-An enum can be marked with the ``pure`` pragma so that it's fields are not
-added to the current scope, so they always need to be accessed
-via ``MyEnum.value``:
+An enum can be marked with the ``pure`` pragma so that it's fields are
+added to a special module specific hidden scope that is only queried
+as the last attempt. Only non-ambiguous symbols are added to this scope.
+But one can always access these via type qualification written
+as ``MyEnum.value``:
 
 .. code-block:: nim
 
   type
     MyEnum {.pure.} = enum
-      valueA, valueB, valueC, valueD
+      valueA, valueB, valueC, valueD, amb
+
+    OtherEnum {.pure.} = enum
+      valueX, valueY, valueZ, amb
+
 
-  echo valueA # error: Unknown identifier
-  echo MyEnum.valueA # works
+  echo valueA # MyEnum.valueA
+  echo amb    # Error: Unclear whether it's MyEnum.amb or OtherEnum.amb
+  echo MyEnum.amb # OK.
 
 
 String type
diff --git a/tests/enum/tpure_enums_conflict.nim b/tests/enum/tpure_enums_conflict.nim
new file mode 100644
index 000000000..3c7528a72
--- /dev/null
+++ b/tests/enum/tpure_enums_conflict.nim
@@ -0,0 +1,19 @@
+discard """
+  errormsg: "ambiguous identifier: 'amb'"
+  line: 19
+"""
+
+# bug #8066
+
+when true:
+  type
+    MyEnum {.pure.} = enum
+      valueA, valueB, valueC, valueD, amb
+
+    OtherEnum {.pure.} = enum
+      valueX, valueY, valueZ, amb
+
+
+  echo valueA # MyEnum.valueA
+  echo MyEnum.amb # OK.
+  echo amb    # Error: Unclear whether it's MyEnum.amb or OtherEnum.amb