summary refs log tree commit diff stats
path: root/tests/enum
diff options
context:
space:
mode:
Diffstat (limited to 'tests/enum')
-rw-r--r--tests/enum/m16462_1.nim3
-rw-r--r--tests/enum/m16462_2.nim3
-rw-r--r--tests/enum/mcrossmodule.nim6
-rw-r--r--tests/enum/t16462.nim5
-rw-r--r--tests/enum/t21863.nim28
-rw-r--r--tests/enum/tambiguousoverloads.nim26
-rw-r--r--tests/enum/tcrossmodule.nim15
-rw-r--r--tests/enum/tenum.nim267
-rw-r--r--tests/enum/tenum_duplicate.nim10
-rw-r--r--tests/enum/tenum_invalid.nim8
-rw-r--r--tests/enum/tenum_no_rtti.nim12
-rw-r--r--tests/enum/tenum_self.nim11
-rw-r--r--tests/enum/tenumfieldpragma.nim22
-rw-r--r--tests/enum/tenumfieldpragmanoannot.nim10
-rw-r--r--tests/enum/tenumitems.nim7
-rw-r--r--tests/enum/tenumitems2.nim14
-rw-r--r--tests/enum/tenummix.nim11
-rw-r--r--tests/enum/toverloadable_enums.nim120
-rw-r--r--tests/enum/toverloadedname.nim7
-rw-r--r--tests/enum/tpure_enums_conflict.nim27
-rw-r--r--tests/enum/tpure_enums_conflict_legacy.nim25
-rw-r--r--tests/enum/tredefinition.nim9
-rw-r--r--tests/enum/ttypenameconflict.nim13
23 files changed, 659 insertions, 0 deletions
diff --git a/tests/enum/m16462_1.nim b/tests/enum/m16462_1.nim
new file mode 100644
index 000000000..631c63256
--- /dev/null
+++ b/tests/enum/m16462_1.nim
@@ -0,0 +1,3 @@
+type
+  Scancode* {.pure.} = enum
+    SCANCODE_LEFT = 80
\ No newline at end of file
diff --git a/tests/enum/m16462_2.nim b/tests/enum/m16462_2.nim
new file mode 100644
index 000000000..631c63256
--- /dev/null
+++ b/tests/enum/m16462_2.nim
@@ -0,0 +1,3 @@
+type
+  Scancode* {.pure.} = enum
+    SCANCODE_LEFT = 80
\ No newline at end of file
diff --git a/tests/enum/mcrossmodule.nim b/tests/enum/mcrossmodule.nim
new file mode 100644
index 000000000..e534a202c
--- /dev/null
+++ b/tests/enum/mcrossmodule.nim
@@ -0,0 +1,6 @@
+
+type
+  OtherEnum* = enum
+    Success, Failed, More
+
+proc some*(x: OtherEnum): bool = x == Success
diff --git a/tests/enum/t16462.nim b/tests/enum/t16462.nim
new file mode 100644
index 000000000..9f38286bb
--- /dev/null
+++ b/tests/enum/t16462.nim
@@ -0,0 +1,5 @@
+import m16462_1 except Scancode
+import m16462_2
+
+# bug #16462
+let a = SCANCODE_LEFT
\ No newline at end of file
diff --git a/tests/enum/t21863.nim b/tests/enum/t21863.nim
new file mode 100644
index 000000000..d0d8b1fcd
--- /dev/null
+++ b/tests/enum/t21863.nim
@@ -0,0 +1,28 @@
+discard """
+cmd: "nim check --hints:off $file"
+action: reject
+nimout: '''
+t21863.nim(28, 16) Error: undeclared field: 'A' 
+  found 'A' [enumField declared in t21863.nim(24, 18)]
+  found 'A' [enumField declared in t21863.nim(25, 18)]
+t21863.nim(28, 16) Error: undeclared field: '.'
+t21863.nim(28, 16) Error: undeclared field: '.'
+t21863.nim(28, 16) Error: expression '' has no type (or is ambiguous)
+'''
+"""
+
+
+
+
+
+
+
+
+
+block:
+  type
+    EnumA = enum A, B
+    EnumB = enum A
+    EnumC = enum C
+
+  discard EnumC.A
diff --git a/tests/enum/tambiguousoverloads.nim b/tests/enum/tambiguousoverloads.nim
new file mode 100644
index 000000000..12c78c848
--- /dev/null
+++ b/tests/enum/tambiguousoverloads.nim
@@ -0,0 +1,26 @@
+discard """
+cmd: "nim check --hints:off $file"
+"""
+
+block: # bug #21887
+  type
+    EnumA = enum A = 300, B
+    EnumB = enum A = 10
+    EnumC = enum C
+
+  doAssert typeof(EnumC(A)) is EnumC #[tt.Error
+                        ^ ambiguous identifier: 'A' -- use one of the following:
+  EnumA.A: EnumA
+  EnumB.A: EnumB]#
+
+block: # issue #22598
+  type
+    A = enum
+      red
+    B = enum
+      red
+
+  let a = red #[tt.Error
+          ^ ambiguous identifier: 'red' -- use one of the following:
+  A.red: A
+  B.red: B]#
diff --git a/tests/enum/tcrossmodule.nim b/tests/enum/tcrossmodule.nim
new file mode 100644
index 000000000..c21072198
--- /dev/null
+++ b/tests/enum/tcrossmodule.nim
@@ -0,0 +1,15 @@
+import mcrossmodule
+
+type
+  MyEnum = enum
+    Success
+
+template t =
+  doAssert some(Success)
+
+t()
+
+block: # legacy support for behavior before overloadableEnums
+  # warning: ambiguous enum field 'Success' assumed to be of type MyEnum
+  let x = {Success}
+  doAssert x is set[MyEnum]
diff --git a/tests/enum/tenum.nim b/tests/enum/tenum.nim
new file mode 100644
index 000000000..a03019c5d
--- /dev/null
+++ b/tests/enum/tenum.nim
@@ -0,0 +1,267 @@
+discard """
+  output: '''
+B
+B
+ABCDC
+foo
+first0second32third64
+my value A1my value Bconc2valueCabc4abc
+my value A0my value Bconc1valueCabc3abc
+'''
+"""
+
+
+import macros
+
+block tenum1:
+  type E = enum a, b, c, x, y, z
+  var en: E
+  en = a
+
+  # Bug #4066
+  macro genEnum(): untyped = newNimNode(nnkEnumTy).add(newEmptyNode(), newIdentNode("geItem1"))
+  type GeneratedEnum = genEnum()
+  doAssert(type(geItem1) is GeneratedEnum)
+
+
+
+block tenum2:
+  type
+    TEnumHole = enum
+      eA = 0,
+      eB = 4,
+      eC = 5
+
+  var
+    e: TEnumHole = eB
+
+  case e
+  of eA: echo "A"
+  of eB: echo "B"
+  of eC: echo "C"
+
+
+
+block tenum3:
+  type
+    TEnumHole {.size: sizeof(int).} = enum
+      eA = 0,
+      eB = 4,
+      eC = 5
+
+  var
+    e: TEnumHole = eB
+
+  case e
+  of eA: echo "A"
+  of eB: echo "B"
+  of eC: echo "C"
+
+
+
+block tbasic:
+  type
+    MyEnum = enum
+      A,B,C,D
+  # trick the optimizer with an seq:
+  var x = @[A,B,C,D]
+  echo x[0],x[1],x[2],x[3],MyEnum(2)
+
+
+
+block talias:
+  # bug #5148
+  type
+    A = enum foo, bar
+    B = A
+
+  echo B.foo
+
+
+
+block thole:
+  type Holed = enum
+    hFirst = (0,"first")
+    hSecond = (32,"second")
+    hThird = (64,"third")
+    
+  var x = @[0,32,64] # This is just to avoid the compiler inlining the value of the enum
+
+  echo Holed(x[0]),ord Holed(x[0]),Holed(x[1]),ord Holed(x[1]),Holed(x[2]),ord Holed(x[2])
+
+
+
+block toffset:
+  const
+    strValB = "my value B"
+
+  type
+    TMyEnum = enum
+      valueA = (1, "my value A"),
+      valueB = strValB & "conc",
+      valueC,
+      valueD = (4, "abc")
+
+  proc getValue(i:int): TMyEnum = TMyEnum(i)
+
+  # trick the optimizer with a variable:
+  var x = getValue(4)
+  echo getValue(1), ord(valueA), getValue(2), ord(valueB), getValue(3), getValue(4), ord(valueD), x
+
+
+
+block tnamedfields:
+  const strValB = "my value B"
+
+  type
+    TMyEnum = enum
+      valueA = (0, "my value A"),
+      valueB = strValB & "conc",
+      valueC,
+      valueD = (3, "abc"),
+      valueE = 4
+
+  # trick the optimizer with a variable:
+  var x = valueD
+  echo valueA, ord(valueA), valueB, ord(valueB), valueC, valueD, ord(valueD), x
+  doAssert $x == $valueD, $x
+  doAssert $x == "abc", $x
+
+
+block tfakeOptions:
+  type
+    TFakeOption = enum
+      fakeNone, fakeForceFullMake, fakeBoehmGC, fakeRefcGC, fakeRangeCheck,
+      fakeBoundsCheck, fakeOverflowCheck, fakeNilCheck, fakeAssert, fakeLineDir,
+      fakeWarns, fakeHints, fakeListCmd, fakeCompileOnly,
+      fakeSafeCode,             # only allow safe code
+      fakeStyleCheck, fakeOptimizeSpeed, fakeOptimizeSize, fakeGenDynLib,
+      fakeGenGuiApp, fakeStackTrace
+
+    TFakeOptionset = set[TFakeOption]
+
+  var
+    gFakeOptions: TFakeOptionset = {fakeRefcGC, fakeRangeCheck, fakeBoundsCheck,
+      fakeOverflowCheck, fakeAssert, fakeWarns, fakeHints, fakeLineDir, fakeStackTrace}
+    compilerArgs: int
+    gExitcode: int8
+
+
+
+block nonzero: # bug #6959
+  type SomeEnum = enum
+    A = 10
+    B
+    C
+  let slice = SomeEnum.low..SomeEnum.high
+
+block size_one_byte: # bug #15752
+  type
+    Flag = enum
+      Disabled = 0x00
+      Enabled = 0xFF
+
+  static:
+    assert 1 == sizeof(Flag)
+
+block: # bug #12589
+  when not defined(i386):
+    type
+      OGRwkbGeometryType {.size: sizeof(cuint).} = enum
+        wkbPoint25D = 0x80000001.cuint, wkbLineString25D = 0x80000002,
+        wkbPolygon25D = 0x80000003
+
+    proc typ(): OGRwkbGeometryType =
+      return wkbPoint25D
+
+    when not defined(gcRefc):
+      doAssert $typ() == "wkbPoint25D"
+
+    block: # bug #21280
+      type
+        Test = enum
+          B = 19
+          A = int64.high()
+
+      doAssert ord(A) == int64.high()
+
+import std/enumutils
+from std/sequtils import toSeq
+import std/macros
+
+block: # unordered enum
+  block:
+    type
+      unordered_enum = enum
+        a = 1
+        b = 0
+
+    doAssert (ord(a), ord(b)) == (1, 0)
+    doAssert unordered_enum.toSeq == @[a, b]
+
+  block:
+    type
+      unordered_enum = enum
+        a = 1
+        b = 0
+        c
+
+    doAssert (ord(a), ord(b), ord(c)) == (1, 0, 2)
+
+  block:
+    type
+      unordered_enum = enum
+        a = 100
+        b
+        c = 50
+        d
+
+    doAssert (ord(a), ord(b), ord(c), ord(d)) == (100, 101, 50, 51)
+
+  block:
+    type
+      unordered_enum = enum
+        a = 7
+        b = 6
+        c = 5
+        d
+
+    doAssert (ord(a), ord(b), ord(c), ord(d)) == (7, 6, 5, 8)
+    doAssert unordered_enum.toSeq == @[a, b, c, d]
+
+  block:
+    type
+      unordered_enum = enum
+        a = 100
+        b
+        c = 500
+        d
+        e
+        f = 50
+        g
+        h
+
+    doAssert (ord(a), ord(b), ord(c), ord(d), ord(e), ord(f), ord(g), ord(h)) == 
+             (100, 101, 500, 501, 502, 50, 51, 52)
+
+  block:
+    type
+      unordered_enum = enum
+        A
+        B
+        C = -1
+        D
+        E
+        G = -999
+
+    doAssert (ord(A), ord(B), ord(C), ord(D), ord(E), ord(G)) ==
+             (0, 1, -1, 2, 3, -999)
+
+  block:
+    type
+      SomeEnum = enum
+        seA = 3
+        seB = 2
+        seC = "foo"
+
+    doAssert (ord(seA), ord(seB), ord(seC)) == (3, 2, 4)
diff --git a/tests/enum/tenum_duplicate.nim b/tests/enum/tenum_duplicate.nim
new file mode 100644
index 000000000..4bcad7f6f
--- /dev/null
+++ b/tests/enum/tenum_duplicate.nim
@@ -0,0 +1,10 @@
+discard """
+  errormsg: "duplicate value in enum 'd'"
+"""
+
+type
+  unordered_enum = enum
+    a = 1
+    b = 0
+    c
+    d = 2
diff --git a/tests/enum/tenum_invalid.nim b/tests/enum/tenum_invalid.nim
new file mode 100644
index 000000000..8ae0a1057
--- /dev/null
+++ b/tests/enum/tenum_invalid.nim
@@ -0,0 +1,8 @@
+discard """
+cmd: "nim check $file"
+"""
+
+type
+  Test = enum
+    A = 9.0 #[tt.Error
+        ^ ordinal type expected; given: float]#
diff --git a/tests/enum/tenum_no_rtti.nim b/tests/enum/tenum_no_rtti.nim
new file mode 100644
index 000000000..2e5c74b35
--- /dev/null
+++ b/tests/enum/tenum_no_rtti.nim
@@ -0,0 +1,12 @@
+discard """
+  output: '''A
+B'''
+  cmd: '''nim c --gc:arc $file'''
+"""
+type
+  Enum = enum A, B, C
+  EnumRange = range[A .. B]
+proc test_a(x: Enum): string = $x
+proc test_b(x: EnumRange): string = $x
+echo test_a(A)
+echo test_b(B)
diff --git a/tests/enum/tenum_self.nim b/tests/enum/tenum_self.nim
new file mode 100644
index 000000000..27b1c3204
--- /dev/null
+++ b/tests/enum/tenum_self.nim
@@ -0,0 +1,11 @@
+discard """
+  errormsg: "1 can't be converted to ErrorFoo"
+"""
+
+
+type
+  Foo = enum
+    Bar = 0.Foo
+
+  ErrorFoo = enum
+    eBar = 1.ErrorFoo
diff --git a/tests/enum/tenumfieldpragma.nim b/tests/enum/tenumfieldpragma.nim
new file mode 100644
index 000000000..604a8f019
--- /dev/null
+++ b/tests/enum/tenumfieldpragma.nim
@@ -0,0 +1,22 @@
+discard """
+  nimout: '''tenumfieldpragma.nim(20, 10) Warning: d is deprecated [Deprecated]
+tenumfieldpragma.nim(21, 10) Warning: e is deprecated [Deprecated]
+tenumfieldpragma.nim(22, 10) Warning: f is deprecated [Deprecated]
+'''
+"""
+
+type
+  A = enum
+    a
+    b = "abc"
+    c = (10, "def")
+    d {.deprecated.}
+    e {.deprecated.} = "ghi"
+    f {.deprecated.} = (20, "jkl")
+
+var v1 = a
+var v2 = b
+var v3 = c
+var v4 = d
+var v5 = e
+var v6 = f
diff --git a/tests/enum/tenumfieldpragmanoannot.nim b/tests/enum/tenumfieldpragmanoannot.nim
new file mode 100644
index 000000000..47f920827
--- /dev/null
+++ b/tests/enum/tenumfieldpragmanoannot.nim
@@ -0,0 +1,10 @@
+discard """
+  errormsg: "annotation to deprecated not supported here"
+  line: 8
+"""
+
+type
+  A = enum
+    a {.deprecated: "njshd".}
+
+var v1 = a
diff --git a/tests/enum/tenumitems.nim b/tests/enum/tenumitems.nim
new file mode 100644
index 000000000..76f368f8a
--- /dev/null
+++ b/tests/enum/tenumitems.nim
@@ -0,0 +1,7 @@
+discard """
+  errormsg: "attempting to call routine: 'items'"
+  line: 7
+"""
+
+type a = enum b,c,d
+a.items()
diff --git a/tests/enum/tenumitems2.nim b/tests/enum/tenumitems2.nim
new file mode 100644
index 000000000..db4c6b554
--- /dev/null
+++ b/tests/enum/tenumitems2.nim
@@ -0,0 +1,14 @@
+discard """
+  output: "A\nB\nC"
+"""
+
+type TAlphabet = enum
+  A, B, C
+
+iterator items(E: typedesc[enum]): E =
+  for v in low(E)..high(E):
+    yield v
+
+for c in TAlphabet:
+  echo($c)
+
diff --git a/tests/enum/tenummix.nim b/tests/enum/tenummix.nim
new file mode 100644
index 000000000..8c306bae1
--- /dev/null
+++ b/tests/enum/tenummix.nim
@@ -0,0 +1,11 @@
+discard """
+  errormsg: "type mismatch"
+  file: "tenummix.nim"
+  line: 11
+"""
+
+type
+  TE1 = enum eA, eB
+  TE2 = enum eC, eD
+
+assert eA != eC
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)
diff --git a/tests/enum/toverloadedname.nim b/tests/enum/toverloadedname.nim
new file mode 100644
index 000000000..d11b0fb83
--- /dev/null
+++ b/tests/enum/toverloadedname.nim
@@ -0,0 +1,7 @@
+block: # issue #23998
+  type
+    Enum {.pure.} = enum
+      a
+    Obj = object
+      a: Enum
+  proc test(a: Enum) = discard Obj(a: a)
diff --git a/tests/enum/tpure_enums_conflict.nim b/tests/enum/tpure_enums_conflict.nim
new file mode 100644
index 000000000..3cf335440
--- /dev/null
+++ b/tests/enum/tpure_enums_conflict.nim
@@ -0,0 +1,27 @@
+discard """
+  matrix: "-d:testsConciseTypeMismatch"
+"""
+
+# 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 #[tt.Error
+  ^ type mismatch
+Expression: echo amb
+  [1] amb: MyEnum | OtherEnum
+
+Expected one of (first mismatch at [position]):
+[1] proc echo(x: varargs[typed, `$$`])
+  ambiguous identifier: 'amb' -- use one of the following:
+    MyEnum.amb: MyEnum
+    OtherEnum.amb: OtherEnum]#
diff --git a/tests/enum/tpure_enums_conflict_legacy.nim b/tests/enum/tpure_enums_conflict_legacy.nim
new file mode 100644
index 000000000..e592925bc
--- /dev/null
+++ b/tests/enum/tpure_enums_conflict_legacy.nim
@@ -0,0 +1,25 @@
+# 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 #[tt.Error
+  ^ type mismatch: got <MyEnum | OtherEnum>
+but expected one of:
+proc echo(x: varargs[typed, `$$`])
+  first type mismatch at position: 1
+  required type for x: varargs[typed]
+  but expression 'amb' is of type: None
+  ambiguous identifier: 'amb' -- use one of the following:
+    MyEnum.amb: MyEnum
+    OtherEnum.amb: OtherEnum
+
+expression: echo amb]#
diff --git a/tests/enum/tredefinition.nim b/tests/enum/tredefinition.nim
new file mode 100644
index 000000000..615ca6b1c
--- /dev/null
+++ b/tests/enum/tredefinition.nim
@@ -0,0 +1,9 @@
+discard """
+  cmd: '''nim check --hints:off $file'''
+  action: reject
+nimout: '''
+tredefinition.nim(9, 25) Error: redefinition of 'Key_a'; previous declaration here: tredefinition.nim(9, 18)
+'''
+"""
+
+type Key* = enum Key_A, Key_a
\ No newline at end of file
diff --git a/tests/enum/ttypenameconflict.nim b/tests/enum/ttypenameconflict.nim
new file mode 100644
index 000000000..b13bf00ce
--- /dev/null
+++ b/tests/enum/ttypenameconflict.nim
@@ -0,0 +1,13 @@
+# issue #23689
+
+type
+  MyEnum {.pure.} = enum
+    A, B, C, D
+
+  B = object
+    field: int
+
+let x: MyEnum = B
+doAssert $x == "B"
+doAssert typeof(x) is MyEnum
+doAssert x in {A, B}