summary refs log tree commit diff stats
path: root/tests/objvariant
diff options
context:
space:
mode:
Diffstat (limited to 'tests/objvariant')
-rw-r--r--tests/objvariant/t14581.nim25
-rw-r--r--tests/objvariant/tadrdisc.nim20
-rw-r--r--tests/objvariant/tcheckedfield1.nim61
-rw-r--r--tests/objvariant/tconstobjvariant.nim18
-rw-r--r--tests/objvariant/tconstructionorder.nim114
-rw-r--r--tests/objvariant/temptycaseobj.nim12
-rw-r--r--tests/objvariant/tfloatrangeobj.nim14
-rw-r--r--tests/objvariant/tnon_zero_discrim_err.nim14
-rw-r--r--tests/objvariant/treassign.nim58
-rw-r--r--tests/objvariant/trt_discrim.nim198
-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
-rw-r--r--tests/objvariant/tvariantstack.nim77
-rw-r--r--tests/objvariant/tyaoption.nim70
16 files changed, 746 insertions, 0 deletions
diff --git a/tests/objvariant/t14581.nim b/tests/objvariant/t14581.nim
new file mode 100644
index 000000000..72ba32f18
--- /dev/null
+++ b/tests/objvariant/t14581.nim
@@ -0,0 +1,25 @@
+discard """
+  matrix: "--gc:refc; --gc:arc"
+  output: "abc: @[(kind: A, x: 0)]"
+"""
+
+import std/tables
+
+type E = enum
+  A, B
+
+type O = object
+  case kind: E
+  of A:
+    x: int
+  of B:
+    y: int 
+
+proc someTable(): Table[string, seq[O]] =
+  result = initTable[string, seq[O]]()
+  result["abc"] = @[O(kind: A)]
+
+const t = someTable()
+
+for k, v in t:
+  echo k, ": ", v
diff --git a/tests/objvariant/tadrdisc.nim b/tests/objvariant/tadrdisc.nim
new file mode 100644
index 000000000..5e4e39a44
--- /dev/null
+++ b/tests/objvariant/tadrdisc.nim
@@ -0,0 +1,20 @@
+discard """
+  errormsg: "type mismatch: got <TKind>"
+  file: "tadrdisc.nim"
+  line: 20
+"""
+# Test that the address of a discriminants cannot be taken
+
+type
+  TKind = enum ka, kb, kc
+  TA = object
+    case k: TKind
+    of ka: x, y: int
+    of kb: a, b: string
+    of kc: c, d: float
+
+proc setKind(k: var TKind) =
+  k = kc
+
+var a: TA
+setKind(a.k)
diff --git a/tests/objvariant/tcheckedfield1.nim b/tests/objvariant/tcheckedfield1.nim
new file mode 100644
index 000000000..4a6c49f66
--- /dev/null
+++ b/tests/objvariant/tcheckedfield1.nim
@@ -0,0 +1,61 @@
+discard """
+  nimout: "tcheckedfield1.nim(39, 6) Warning: cannot prove that field 'x.s' is accessible [ProveField]"
+  action: run
+  output: "abc abc"
+"""
+
+import strutils
+
+{.warning[ProveField]: on.}
+{.experimental: "notnil".}
+type
+  TNodeKind = enum
+    nkBinary, nkTernary, nkStr
+  PNode = ref TNode not nil
+  TNode = object
+    case k: TNodeKind
+    of nkBinary, nkTernary: a, b: PNode
+    of nkStr: s: string
+
+  PList = ref object
+    data: string
+    next: PList
+
+proc getData(x: PList not nil) =
+  echo x.data
+
+var head: PList
+
+proc processList() =
+  var it = head
+  while it != nil:
+    getData(it)
+    it = it.next
+
+proc toString2(x: PNode): string =
+  if x.k < nkStr:
+    toString2(x.a) & " " & toString2(x.b)
+  else:
+    x.s
+
+proc toString(x: PNode): string =
+  case x.k
+  of nkTernary, nkBinary:
+    toString(x.a) & " " & toString(x.b)
+  of nkStr:
+    x.s
+
+proc toString3(x: PNode): string =
+  if x.k <= nkBinary:
+    toString3(x.a) & " " & toString3(x.b)
+  else:
+    x.s # x.k in {nkStr}  --> fact:  not (x.k <= nkBinary)
+
+proc p() =
+  var x: PNode = PNode(k: nkStr, s: "abc")
+
+  let y = x
+  if not y.isNil:
+    echo toString(y), " ", toString2(y)
+
+p()
diff --git a/tests/objvariant/tconstobjvariant.nim b/tests/objvariant/tconstobjvariant.nim
new file mode 100644
index 000000000..45a647707
--- /dev/null
+++ b/tests/objvariant/tconstobjvariant.nim
@@ -0,0 +1,18 @@
+# This is a sample code, the first echo statement prints out the error
+type
+  A = object
+    case w: uint8
+    of 1:
+      n: int
+    else:
+      other: string
+
+const
+  a = A(w: 1, n: 5)
+
+proc foo =
+
+  let c = [a]
+  doAssert c[0].n == 5
+
+foo()
\ No newline at end of file
diff --git a/tests/objvariant/tconstructionorder.nim b/tests/objvariant/tconstructionorder.nim
new file mode 100644
index 000000000..5ca484884
--- /dev/null
+++ b/tests/objvariant/tconstructionorder.nim
@@ -0,0 +1,114 @@
+discard """
+  output: "SUCCESS"
+"""
+
+# A test to ensure that the order in which a variant
+# object is constructed doesn't matter.
+
+type
+  NodeKind = enum
+    Literal, Operator
+
+  Node = ref object
+    case kind: NodeKind
+    of Literal:
+      value: int
+    of Operator:
+      left, right: Node
+      operator: char
+
+# The trees used through out this test should
+# be the same after construction, the only difference
+# being the way we specify their construction.
+# This will test that all the values are what we expect.
+proc assertTree(root: Node) =
+  # check root of tree
+  doAssert root.kind == Operator
+  doAssert root.operator == '*'
+
+  # check left subtree
+  doAssert root.left.value == 5
+  doAssert root.left.kind == Literal
+
+  # check right subtree
+  doAssert root.right.kind == Operator
+  doAssert root.right.operator == '+'
+
+  doAssert root.right.left.value == 5
+  doAssert root.right.left.kind == Literal
+
+  doAssert root.right.right.value == 10
+  doAssert root.right.right.kind == Literal
+
+proc newLiteralNode(value: int): Node =
+  result = Node(
+    kind: Literal,
+    value: value
+  )
+
+var rootOrder1 = Node(
+  kind: Operator,
+  operator: '*',
+  left: newLiteralNode(5),
+  right: Node(
+    left: newLiteralNode(5),
+    right: newLiteralNode(10),
+    kind: Operator,
+    operator: '+'
+  )
+)
+assertTree(rootOrder1)
+
+var rootOrder2 = Node(
+  operator: '*',
+  kind: Operator,
+  left: newLiteralNode(5),
+  right: Node(
+    left: newLiteralNode(5),
+    right: newLiteralNode(10),
+    kind: Operator,
+    operator: '+'
+  )
+)
+assertTree(rootOrder2)
+
+var rootOrder3 = Node(
+  left: newLiteralNode(5),
+  operator: '*',
+  kind: Operator,
+  right: Node(
+    left: newLiteralNode(5),
+    right: newLiteralNode(10),
+    kind: Operator,
+    operator: '+'
+  )
+)
+assertTree(rootOrder3)
+
+var rootOrder4 = Node(
+  left: newLiteralNode(5),
+  operator: '*',
+  kind: Operator,
+  right: Node(
+    left: newLiteralNode(5),
+    kind: Operator,
+    operator: '+',
+    right: newLiteralNode(10)
+  )
+)
+assertTree(rootOrder4)
+
+var rootOrder5 = Node(
+  left: newLiteralNode(5),
+  operator: '*',
+  kind: Operator,
+  right: Node(
+    left: newLiteralNode(5),
+    operator: '+',
+    right: newLiteralNode(10),
+    kind: Operator
+  )
+)
+assertTree(rootOrder5)
+
+echo "SUCCESS"
diff --git a/tests/objvariant/temptycaseobj.nim b/tests/objvariant/temptycaseobj.nim
new file mode 100644
index 000000000..2b2c40514
--- /dev/null
+++ b/tests/objvariant/temptycaseobj.nim
@@ -0,0 +1,12 @@
+discard """
+  errormsg: "identifier expected, but got 'keyword of'"
+  line: 11
+"""
+
+type
+  TMyEnum = enum enA, enU, enO
+  TMyCase = object
+    case e: TMyEnum
+    of enA:
+    of enU: x, y: int
+    of enO: a, b: string
diff --git a/tests/objvariant/tfloatrangeobj.nim b/tests/objvariant/tfloatrangeobj.nim
new file mode 100644
index 000000000..67e886302
--- /dev/null
+++ b/tests/objvariant/tfloatrangeobj.nim
@@ -0,0 +1,14 @@
+discard """
+  output: '''(kind: 2.0, twoStr: "TWO STR")
+(kind: 1.0)
+'''
+disabled: "true"
+"""
+type
+  FloatRange = range[1.0..3.0]
+  VariantObj = object
+    case kind: FloatRange
+    of 2.0: twoStr: string
+
+echo VariantObj(kind: 2.0, twoStr: "TWO STR")
+echo VariantObj(kind: 1.0)
diff --git a/tests/objvariant/tnon_zero_discrim_err.nim b/tests/objvariant/tnon_zero_discrim_err.nim
new file mode 100644
index 000000000..c595bba1b
--- /dev/null
+++ b/tests/objvariant/tnon_zero_discrim_err.nim
@@ -0,0 +1,14 @@
+discard """
+  errormsg: "low(kind) must be 0 for discriminant"
+  line: 7
+"""
+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/treassign.nim b/tests/objvariant/treassign.nim
new file mode 100644
index 000000000..527204616
--- /dev/null
+++ b/tests/objvariant/treassign.nim
@@ -0,0 +1,58 @@
+discard """
+  output: "SUCCESS"
+"""
+
+type
+    BasicNumber = object of RootObj
+        value: float32
+    RefChild* = ref object
+        curr*: TokenObject
+    Token* {.pure.} = enum
+        foo,
+        bar,
+    TokenObject = object
+        case kind*: Token
+        of Token.foo:
+            foo*: string
+        of Token.bar:
+            bar*: BasicNumber
+
+
+var t = RefChild()
+
+t.curr = TokenObject(kind: Token.bar, bar: BasicNumber(value: 12.34))
+
+t.curr = TokenObject(kind: Token.foo, foo: "foo")
+
+echo "SUCCESS"
+
+proc passToVar(x: var Token) = discard
+
+{.cast(uncheckedAssign).}:
+  passToVar(t.curr.kind)
+
+  t.curr = TokenObject(kind: t.curr.kind, foo: "abc")
+
+  t.curr.kind = Token.foo
+
+
+block:
+  type
+    TokenKind = enum
+      strLit, intLit
+    Token = object
+      case kind*: TokenKind
+      of strLit:
+        s*: string
+      of intLit:
+        i*: int64
+
+  var t = Token(kind: strLit, s: "abc")
+
+  {.cast(uncheckedAssign).}:
+
+    # inside the 'cast' section it is allowed to assign to the 't.kind' field directly:
+    t.kind = intLit
+
+  {.cast(uncheckedAssign).}:
+    t.kind = strLit
\ No newline at end of file
diff --git a/tests/objvariant/trt_discrim.nim b/tests/objvariant/trt_discrim.nim
new file mode 100644
index 000000000..95b2a9f76
--- /dev/null
+++ b/tests/objvariant/trt_discrim.nim
@@ -0,0 +1,198 @@
+template accept(x) =
+  static: assert(compiles(x))
+
+template reject(x) =
+  static: assert(not compiles(x))
+
+type
+  Kind = enum k1 = 0, k2 = 33, k3 = 84, k4 = 278, k5 = 1000 # Holed enum work! #No they don't..
+  KindObj = object
+    case kind: Kind
+    of k1, k2..k3: i32: int32
+    of k4: f32: float32
+    else: str: string
+
+  IntObj = object
+    case kind: uint8
+    of low(uint8) .. 127: bad: string
+    of 128'u8: neutral: string
+    of 129 .. high(uint8): 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'u8
+
+accept:
+  case intKind
+  of low(uint8) .. 127: discard IntObj(kind: intKind, bad: "bad")
+  of 128'u8: discard IntObj(kind: intKind, neutral: "neutral")
+  of 129 .. high(uint8): discard IntObj(kind: intKind, good: "good")
+
+reject: # 0 leaks to else
+  case intKind
+  of low(uint8) .. 127: discard IntObj(kind: intKind, bad: "bad")
+  of 129 .. high(uint8): discard IntObj(kind: intKind, good: "good")
+
+accept:
+  case intKind
+  of low(uint8) .. 127: discard IntObj(kind: intKind, bad: "bad")
+  of 128'u8: discard IntObj(kind: intKind, neutral: "neutral")
+  of 139'u8, 140 .. high(uint8), 129'u8 .. 138'u8: 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")
+
+accept:
+  proc kindProc(kind: Kind): KindObj =
+    case kind:
+    of k1: result = KindObj(kind: kind, i32: 1)
+    else: discard
+
+reject:
+  proc varKindProc(kind: var Kind): KindObj =
+    case kind:
+    of k1: result = KindObj(kind: kind, i32: 1)
+    else: discard
+
+type
+  Kind3 = enum
+    A, B, C, E
+
+  OkRange = range[B..C]
+  NotOkRange = range[B..E]
+
+  CaseObject = object
+    case kind: Kind3
+    of B, C:
+      field: int
+    else: discard
+
+accept:
+  let rtDiscriminator: OkRange = B
+  discard CaseObject(kind: rtDiscriminator, field: 1)
+
+accept:
+  let rtDiscriminator = B
+  discard CaseObject(kind: OkRange(rtDiscriminator), field: 1)
+
+accept:
+  const rtDiscriminator: NotOkRange = B
+  discard CaseObject(kind: rtDiscriminator, field: 1)
+
+accept:
+  discard CaseObject(kind: NotOkRange(B), field: 1)
+
+reject:
+  let rtDiscriminator: NotOkRange = B
+  discard CaseObject(kind: rtDiscriminator, field: 1)
+
+reject:
+  let rtDiscriminator = B
+  discard CaseObject(kind: NotOkRange(rtDiscriminator), field: 1)
+
+reject:
+  type Obj = object
+    case x: int
+    of 0 .. 1000:
+      field: int
+    else:
+      discard
+
+  let x: range[0..15] = 1
+  let o = Obj(x: x, field: 1)
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..4f2790bc6
--- /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: range[0 .. 20000]
+    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")
diff --git a/tests/objvariant/tvariantstack.nim b/tests/objvariant/tvariantstack.nim
new file mode 100644
index 000000000..7fd41b476
--- /dev/null
+++ b/tests/objvariant/tvariantstack.nim
@@ -0,0 +1,77 @@
+discard """
+output: "came here"
+"""
+#BUG
+type
+  TAnyKind = enum
+    nkInt,
+    nkFloat,
+    nkString
+  PAny = ref TAny
+  TAny = object
+    case kind: TAnyKind
+    of nkInt: intVal: int
+    of nkFloat: floatVal: float
+    of nkString: strVal: string
+
+  TStack* = object
+    list*: seq[TAny]
+
+proc newStack(): TStack =
+  result.list = @[]
+
+proc push(Stack: var TStack, item: TAny) =
+  var nSeq: seq[TAny] = @[item]
+  for i in items(Stack.list):
+    nSeq.add(i)
+  Stack.list = nSeq
+
+proc pop(Stack: var TStack): TAny =
+  result = Stack.list[0]
+  Stack.list.delete(0)
+
+var stack = newStack()
+
+var s = TAny(kind: nkString, strVal: "test")
+
+stack.push(s)
+
+var nr = TAny(kind: nkInt, intVal: 78)
+
+stack.push(nr)
+
+var t = stack.pop()
+echo "came here"
+
+
+# another regression:
+type
+  LexerToken* = enum
+    ltYamlDirective, ltYamlVersion, ltTagDirective, ltTagShorthand,
+    ltTagUri, ltUnknownDirective, ltUnknownDirectiveParams, ltEmptyLine,
+    ltDirectivesEnd, ltDocumentEnd, ltStreamEnd, ltIndentation, ltQuotedScalar,
+    ltScalarPart, ltBlockScalarHeader, ltBlockScalar, ltSeqItemInd, ltMapKeyInd,
+    ltMapValInd, ltBraceOpen, ltBraceClose, ltBracketOpen, ltBracketClose,
+    ltComma, ltLiteralTag, ltTagHandle, ltAnchor, ltAlias
+
+const tokensWithValue =
+    {ltScalarPart, ltQuotedScalar, ltYamlVersion, ltTagShorthand, ltTagUri,
+     ltUnknownDirective, ltUnknownDirectiveParams, ltLiteralTag, ltAnchor,
+     ltAlias, ltBlockScalar}
+
+type
+  TokenWithValue = object
+    case kind: LexerToken
+    of tokensWithValue:
+      value: string
+    of ltIndentation:
+      indentation: int
+    of ltTagHandle:
+      handle, suffix: string
+    else: discard
+
+proc sp(v: string): TokenWithValue =
+  # test.nim(27, 17) Error: a case selecting discriminator 'kind' with value 'ltScalarPart' appears in the object construction, but the field(s) 'value' are in conflict with this value.
+  TokenWithValue(kind: ltScalarPart, value: v)
+
+let a = sp("test")
diff --git a/tests/objvariant/tyaoption.nim b/tests/objvariant/tyaoption.nim
new file mode 100644
index 000000000..80bfa4bae
--- /dev/null
+++ b/tests/objvariant/tyaoption.nim
@@ -0,0 +1,70 @@
+discard """
+  output: '''some(str), some(5), none
+some(5!)
+some(10)
+34'''
+"""
+
+import strutils
+
+type Option[A] = object
+  case isDefined*: bool
+    of true:
+      value*: A
+    of false:
+      nil
+
+proc some[A](value: A): Option[A] =
+  Option[A](isDefined: true, value: value)
+
+proc none[A](): Option[A] =
+  Option[A](isDefined: false)
+
+proc `$`[A](o: Option[A]): string =
+  if o.isDefined:
+    "some($1)" % [$o.value]
+  else:
+    "none"
+
+let x = some("str")
+let y = some(5)
+let z = none[int]()
+
+echo x, ", ", y, ", ", z
+
+proc intOrString[A : int | string](o: Option[A]): Option[A] =
+  when A is int:
+    some(o.value + 5)
+  elif A is string:
+    some(o.value & "!")
+  else:
+    o
+
+#let a1 = intOrString(none[String]())
+let a2 = intOrString(some("5"))
+let a3 = intOrString(some(5))
+#echo a1
+echo a2
+echo a3
+
+
+# bug #10033
+
+type
+  Token = enum
+    Int,
+    Float
+
+  Base = ref object of RootObj
+    case token: Token
+    of Int:
+      bInt: int
+    of Float:
+      bFloat: float
+
+  Child = ref object of Base
+
+let c = new Child
+c.token = Int
+c.bInt = 34
+echo c.bInt