diff options
Diffstat (limited to 'tests/objvariant')
-rw-r--r-- | tests/objvariant/t14581.nim | 25 | ||||
-rw-r--r-- | tests/objvariant/tadrdisc.nim | 20 | ||||
-rw-r--r-- | tests/objvariant/tcheckedfield1.nim | 61 | ||||
-rw-r--r-- | tests/objvariant/tconstobjvariant.nim | 18 | ||||
-rw-r--r-- | tests/objvariant/tconstructionorder.nim | 114 | ||||
-rw-r--r-- | tests/objvariant/temptycaseobj.nim | 12 | ||||
-rw-r--r-- | tests/objvariant/tfloatrangeobj.nim | 14 | ||||
-rw-r--r-- | tests/objvariant/tnon_zero_discrim_err.nim | 14 | ||||
-rw-r--r-- | tests/objvariant/treassign.nim | 58 | ||||
-rw-r--r-- | tests/objvariant/trt_discrim.nim | 198 | ||||
-rw-r--r-- | tests/objvariant/trt_discrim_err0.nim | 17 | ||||
-rw-r--r-- | tests/objvariant/trt_discrim_err1.nim | 17 | ||||
-rw-r--r-- | tests/objvariant/trt_discrim_err2.nim | 14 | ||||
-rw-r--r-- | tests/objvariant/trt_discrim_err3.nim | 17 | ||||
-rw-r--r-- | tests/objvariant/tvariantstack.nim | 77 | ||||
-rw-r--r-- | tests/objvariant/tyaoption.nim | 70 |
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 |