summary refs log tree commit diff stats
path: root/tests
diff options
context:
space:
mode:
authorJasper Jenkins <jasper.vs.jenkins@gmail.com>2019-05-26 12:22:02 -0700
committerAndreas Rumpf <rumpf_a@web.de>2019-05-26 21:22:02 +0200
commitf7744260959bbdaefdc5172aaf7ff4770f8f8c03 (patch)
tree071d38af9c1e9134292a17ef197d2bd7df81b28c /tests
parent16aa10dfe101da99c402657a420dbf2785ca4a2a (diff)
downloadNim-f7744260959bbdaefdc5172aaf7ff4770f8f8c03.tar.gz
Smarter variant object construction (#11273)
Diffstat (limited to 'tests')
-rw-r--r--tests/objvariant/trt_discrim.nim138
-rw-r--r--tests/objvariant/trt_discrim_err0.nim17
-rw-r--r--tests/objvariant/trt_discrim_err1.nim17
-rw-r--r--tests/objvariant/trt_discrim_err2.nim14
-rw-r--r--tests/objvariant/trt_discrim_err3.nim17
5 files changed, 203 insertions, 0 deletions
diff --git a/tests/objvariant/trt_discrim.nim b/tests/objvariant/trt_discrim.nim
new file mode 100644
index 000000000..612647fbe
--- /dev/null
+++ b/tests/objvariant/trt_discrim.nim
@@ -0,0 +1,138 @@
+template accept(x) =
+  static: assert(compiles(x))
+
+template reject(x) =
+  static: assert(not compiles(x))
+
+type
+  Kind = enum k1 = 2, k2 = 33, k3 = 84, k4 = 278, k5 = 1000 # Holed enum work!
+  KindObj = object
+    case kind: Kind
+    of k1, k2..k3: i32: int32
+    of k4: f32: float32
+    else: str: string
+
+  IntObj = object
+    case kind: int16
+    of low(int16) .. -1: bad: string
+    of 0: neutral: string
+    of 1 .. high(int16): good: string
+
+  OtherKind = enum ok1, ok2, ok3, ok4, ok5
+  NestedKindObj = object
+    case kind: Kind
+    of k3, k5: discard
+    of k2: str: string
+    of k1, k4:
+      case otherKind: OtherKind
+      of ok1, ok2..ok3: i32: int32
+      of ok4: f32: float32
+      else: nestedStr: string
+
+let kind = k4 # actual value should have no impact on the analysis.
+
+accept: # Mimics the structure of the type. The optimial case.
+  case kind
+  of k1, k2, k3: discard KindObj(kind: kind, i32: 1)
+  of k4: discard KindObj(kind: kind, f32: 2.0)
+  else: discard KindObj(kind: kind, str: "3")
+
+accept: # Specifying the else explicitly is fine too.
+  case kind
+  of k1, k2, k3: discard KindObj(kind: kind, i32: 1)
+  of k4: discard KindObj(kind: kind, f32: 2.0)
+  of k5: discard KindObj(kind: kind, str: "3")
+
+accept:
+  case kind
+  of k1..k3, k5: discard
+  else: discard KindObj(kind: kind, f32: 2.0)
+
+accept:
+  case kind
+  of k4, k5: discard
+  else: discard KindObj(kind: kind, i32: 1)
+
+accept: # elif branches are ignored
+  case kind
+  of k1, k2, k3: discard KindObj(kind: kind, i32: 1)
+  of k4: discard KindObj(kind: kind, f32: 2.0)
+  elif kind in {k1..k5}: discard
+  else: discard KindObj(kind: kind, str: "3")
+
+reject: # k4 conflicts with i32
+  case kind
+  of k1, k2, k3, k4: discard KindObj(kind: kind, i32: 1)
+  else: discard KindObj(kind: kind, str: "3")
+
+reject: # k4 is not caught, conflicts with str in the else branch
+  case kind
+  of k1, k2, k3: discard KindObj(kind: kind, i32: 1)
+  else: discard KindObj(kind: kind, str: "3")
+
+reject: # elif branches are ignored
+  case kind
+  of k1, k2, k3: discard KindObj(kind: kind, i32: 1)
+  elif kind == k4: discard
+  else: discard KindObj(kind: kind, str: "3")
+
+let intKind = 29'i16
+
+accept:
+  case intKind
+  of low(int16) .. -1: discard IntObj(kind: intKind, bad: "bad")
+  of 0: discard IntObj(kind: intKind, neutral: "neutral")
+  of 1 .. high(int16): discard IntObj(kind: intKind, good: "good")
+
+reject: # 0 leaks to else
+  case intKind
+  of low(int16) .. -1: discard IntObj(kind: intKind, bad: "bad")
+  of 1 .. high(int16): discard IntObj(kind: intKind, good: "good")
+
+accept:
+  case intKind
+  of low(int16) .. -1: discard IntObj(kind: intKind, bad: "bad")
+  of 0: discard IntObj(kind: intKind, neutral: "neutral")
+  of 10, 11 .. high(int16), 1 .. 9: discard IntObj(kind: intKind, good: "good")
+
+accept:
+  case kind
+  of {k1, k2}, [k3]: discard KindObj(kind: kind, i32: 1)
+  of k4: discard KindObj(kind: kind, f32: 2.0)
+  else: discard KindObj(kind: kind, str: "3")
+
+reject:
+  case kind
+  of {k1, k2, k3}, [k4]: discard KindObj(kind: kind, i32: 1)
+  else: discard KindObj(kind: kind, str: "3")
+
+accept:
+  case kind
+  of k3, k5: discard NestedKindObj(kind: kind)
+  of k2: discard NestedKindObj(kind: kind, str: "not nested")
+  of k1, k4:
+    let otherKind = ok5
+    case otherKind
+    of ok1..ok3: discard NestedKindObj(kind: kind, otherKind: otherKind, i32: 3)
+    of ok4: discard NestedKindObj(kind: kind, otherKind: otherKind, f32: 5.0)
+    else: discard NestedKindObj(kind: kind, otherKind: otherKind,
+                                nestedStr: "nested")
+
+reject:
+  case kind
+  of k3, k5: discard NestedKindObj(kind: kind)
+  of k2: discard NestedKindObj(kind: kind, str: "not nested")
+  of k1, k4:
+    let otherKind = ok5
+    case otherKind
+    of ok1..ok3: discard NestedKindObj(kind: kind, otherKind: otherKind, i32: 3)
+    else: discard NestedKindObj(kind: kind, otherKind: otherKind,
+                                nestedStr: "nested")
+
+var varkind = k4
+
+reject: # not immutable.
+  case varkind
+  of k1, k2, k3: discard KindObj(varkind: kind, i32: 1)
+  of k4: discard KindObj(varkind: kind, f32: 2.0)
+  else: discard KindObj(varkind: kind, str: "3")
diff --git a/tests/objvariant/trt_discrim_err0.nim b/tests/objvariant/trt_discrim_err0.nim
new file mode 100644
index 000000000..02b551cbc
--- /dev/null
+++ b/tests/objvariant/trt_discrim_err0.nim
@@ -0,0 +1,17 @@
+discard """
+  errormsg: "possible values {k1, k3, k4} are in conflict with discriminator values for selected object branch 3"
+  line: 17
+"""
+
+type
+  Kind = enum k1, k2, k3, k4, k5
+  KindObj = object
+    case kind: Kind
+    of k1, k2..k3: i32: int32
+    of k4: f32: float32
+    else: str: string
+
+let kind = k3
+case kind
+of k2: discard KindObj(kind: kind, i32: 1)
+else: discard KindObj(kind: kind, str: "3")
diff --git a/tests/objvariant/trt_discrim_err1.nim b/tests/objvariant/trt_discrim_err1.nim
new file mode 100644
index 000000000..de29420a2
--- /dev/null
+++ b/tests/objvariant/trt_discrim_err1.nim
@@ -0,0 +1,17 @@
+discard """
+  errormsg: "branch initialization with a runtime discriminator is not supported inside of an `elif` branch."
+  line: 16
+"""
+type
+  Color = enum Red, Green, Blue
+  ColorObj = object
+    case colorKind: Color
+    of Red: red: string
+    of Green: green: string
+    of Blue: blue: string
+
+let colorKind = Blue
+case colorKind
+of Red: echo ColorObj(colorKind: colorKind, red: "red")
+elif colorKind == Green: echo ColorObj(colorKind: colorKind, green: "green")
+else: echo ColorObj(colorKind: colorKind, blue: "blue")
diff --git a/tests/objvariant/trt_discrim_err2.nim b/tests/objvariant/trt_discrim_err2.nim
new file mode 100644
index 000000000..c5352014e
--- /dev/null
+++ b/tests/objvariant/trt_discrim_err2.nim
@@ -0,0 +1,14 @@
+discard """
+  errormsg: "branch initialization with a runtime discriminator only supports ordinal types with 2^16 elements or less."
+  line: 13
+"""
+type
+  HoledObj = object
+    case kind: int
+    of 0: a: int
+    else: discard
+
+let someInt = low(int)
+case someInt
+of 938: echo HoledObj(kind: someInt, a: 1)
+else: discard
diff --git a/tests/objvariant/trt_discrim_err3.nim b/tests/objvariant/trt_discrim_err3.nim
new file mode 100644
index 000000000..e739c3d50
--- /dev/null
+++ b/tests/objvariant/trt_discrim_err3.nim
@@ -0,0 +1,17 @@
+discard """
+  errormsg: "runtime discriminator must be immutable if branch fields are initialized, a 'let' binding is required."
+  line: 16
+"""
+
+type
+  Kind = enum k1, k2, k3, k4, k5
+  KindObj = object
+    case kind: Kind
+    of k1, k2..k3: i32: int32
+    of k4: f32: float32
+    else: str: string
+
+var kind = k3
+case kind
+of k2: discard KindObj(kind: kind, i32: 1)
+else: discard KindObj(kind: kind, str: "3")