diff options
Diffstat (limited to 'tests/enum/toverloadable_enums.nim')
-rw-r--r-- | tests/enum/toverloadable_enums.nim | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/tests/enum/toverloadable_enums.nim b/tests/enum/toverloadable_enums.nim new file mode 100644 index 000000000..9bb551467 --- /dev/null +++ b/tests/enum/toverloadable_enums.nim @@ -0,0 +1,120 @@ +discard """ + output: '''B +0 +E2-B''' +joinable: false +""" + +{.experimental: "overloadableEnums".} + +type + E1 = enum + value1, + value2 + E2 = enum + value1, + value2 = 4 + +const + Lookuptable = [ + E1.value1: "1", + value2: "2" + ] + +when false: + const + Lookuptable: array[E1, string] = [ + value1: "1", + value2: "2" + ] + + +proc p(e: E1): int = + # test that the 'case' statement is smart enough: + case e + of value1: echo "A" + of value2: echo "B" + + +let v = p value2 # ERROR: ambiguous! +# (value2|value2) nkClosedSymChoice -> nkSym + +proc x(p: int) = discard +proc x(p: string) = discard + +proc takeCallback(param: proc(p: int)) = discard + +takeCallback x + +echo ord v + +block: # https://github.com/nim-lang/RFCs/issues/8 + type + Enum1 = enum + A, B, C + Enum2 = enum + A, Z + + proc f(e: Enum1): int = ord(e) + proc g(e: Enum2): int = ord(e) + + proc h(e: Enum1): int = ord(e) + proc h(e: Enum2): int = ord(e) + + let fA = f(A) # Type of A is well defined + let gA = g(A) # Same as above + + let hA1 = h(Enum1.A) # A requires disambiguation + let hA2 = h(Enum2.A) # Similarly + let hA3 = h(B) + let hA4 = h(B) + let x = ord(Enum1.A) # Also + doAssert fA == 0 + doAssert gA == 0 + doAssert hA1 == 0 + doAssert hA2 == 0 + doAssert x == 0 + doAssert hA3 == 1 + doAssert hA4 == 1 + +# bug #18769 +proc g3[T](x: T, e: E2): int = + case e + of value1: echo "E2-A" # Error: type mismatch: got 'E1' for 'value1' but expected 'E2 = enum' + of value2: echo "E2-B" + +let v5 = g3(99, E2.value2) + +block: # only allow enums to overload enums + # mirrors behavior without overloadableEnums + proc foo() = discard + block: + type Foo = enum foo + doAssert foo is Foo + foo() + +import macros +block: # test with macros/templates + type + Enum1 = enum + value01, value02 + Enum2 = enum + value01, value10 + + macro isOneM(a: untyped): bool = + result = newCall(bindSym"==", a, ident"value01") + + macro isOneMS(a: untyped): bool = + result = newCall(bindSym"==", a, bindSym"value01") + + template isOneT(a: untyped): bool = + a == value01 + + let e1 = Enum1.value01 + let e2 = Enum2.value01 + doAssert isOneM(e1) + doAssert isOneM(e2) + doAssert isOneMS(e1) + doAssert isOneMS(e2) + doAssert isOneT(e1) + doAssert isOneT(e2) |