diff options
author | Araq <rumpf_a@web.de> | 2018-08-31 00:30:09 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2018-08-31 00:30:19 +0200 |
commit | 2f7b979e384ff6cc750e123939401a72c3f59093 (patch) | |
tree | fc78fafe5efbb2fb5e63038ce1ecb6934b7f56f6 | |
parent | fab449872776badf7c81f08b29ddaf2f598a5c3d (diff) | |
download | Nim-2f7b979e384ff6cc750e123939401a72c3f59093.tar.gz |
fixes #8066
-rw-r--r-- | compiler/importer.nim | 10 | ||||
-rw-r--r-- | compiler/lookups.nim | 2 | ||||
-rw-r--r-- | doc/manual.rst | 25 | ||||
-rw-r--r-- | tests/enum/tpure_enums_conflict.nim | 19 |
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 |