This commit is contained in:
Araq 2018-08-31 00:30:09 +02:00
commit 2f7b979e38
4 changed files with 46 additions and 10 deletions

View file

@ -24,9 +24,15 @@ proc readExceptSet*(c: PContext, n: PNode): IntSet =
result.incl(ident.id) result.incl(ident.id)
proc importPureEnumField*(c: PContext; s: PSym) = 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: if check == nil:
let checkB = strTableGet(c.pureEnumFields, s.name)
if checkB == nil:
strTableAdd(c.pureEnumFields, s) strTableAdd(c.pureEnumFields, s)
else:
# mark as ambigous:
incl(c.ambiguousSymbols, checkB.id)
incl(c.ambiguousSymbols, s.id)
proc rawImportSymbol(c: PContext, s: PSym) = proc rawImportSymbol(c: PContext, s: PSym) =
# This does not handle stubs, because otherwise loading on demand would be # This does not handle stubs, because otherwise loading on demand would be

View file

@ -244,7 +244,7 @@ else:
template fixSpelling(n: PNode; ident: PIdent; op: untyped) = discard template fixSpelling(n: PNode; ident: PIdent; op: untyped) = discard
proc errorUseQualifier*(c: PContext; info: TLineInfo; s: PSym) = 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 ti: TIdentIter
var candidate = initIdentIter(ti, c.importTable.symbols, s.name) var candidate = initIdentIter(ti, c.importTable.symbols, s.name)
var i = 0 var i = 0

View file

@ -937,8 +937,12 @@ Now the following holds::
ord(south) == 2 ord(south) == 2
ord(west) == 3 ord(west) == 3
# Also allowed:
ord(Direction.west) == 3
Thus, north < east < south < west. The comparison operators can be used 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 For better interfacing to other programming languages, the fields of enum
types can be assigned an explicit ordinal value. However, the ordinal values 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 ordinal value and its string value by using a tuple. It is also
possible to only specify one of them. possible to only specify one of them.
An enum can be marked with the ``pure`` pragma so that it's fields are not An enum can be marked with the ``pure`` pragma so that it's fields are
added to the current scope, so they always need to be accessed added to a special module specific hidden scope that is only queried
via ``MyEnum.value``: 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 .. code-block:: nim
type type
MyEnum {.pure.} = enum MyEnum {.pure.} = enum
valueA, valueB, valueC, valueD valueA, valueB, valueC, valueD, amb
echo valueA # error: Unknown identifier OtherEnum {.pure.} = enum
echo MyEnum.valueA # works valueX, valueY, valueZ, amb
echo valueA # MyEnum.valueA
echo amb # Error: Unclear whether it's MyEnum.amb or OtherEnum.amb
echo MyEnum.amb # OK.
String type String type

View file

@ -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