diff options
Diffstat (limited to 'tests/objects')
39 files changed, 1560 insertions, 299 deletions
diff --git a/tests/objects/m19342.c b/tests/objects/m19342.c new file mode 100644 index 000000000..113f65309 --- /dev/null +++ b/tests/objects/m19342.c @@ -0,0 +1,12 @@ +struct Node +{ + int data[25]; +}; + + +struct Node hello(int name) { + struct Node x = {999, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 1, 2, 3, 4, 5, 6, 7 ,8, 9, + 1, 2, 3, 4, 5}; + return x; +} \ No newline at end of file diff --git a/tests/objects/mobject_default_value.nim b/tests/objects/mobject_default_value.nim new file mode 100644 index 000000000..224549501 --- /dev/null +++ b/tests/objects/mobject_default_value.nim @@ -0,0 +1,15 @@ +type + Clean = object + mem: int + Default* = object + poi: int = 12 + clc: Clean + se*: range[0'i32 .. high(int32)] + + NonDefault* = object + poi: int + + PrellDeque*[T] = object + pendingTasks*: range[0'i32 .. high(int32)] + head: T + tail: T diff --git a/tests/objects/t12753.nim b/tests/objects/t12753.nim new file mode 100644 index 000000000..1009433be --- /dev/null +++ b/tests/objects/t12753.nim @@ -0,0 +1,22 @@ +discard """ + output: ''' +(v: [(v: [0.0, 1.1]), (v: [2.2, 3.3])]) +(v: [(v: [0.0, 1.1]), (v: [2.2, 3.3])]) +''' +""" + +type + V = object + v:array[2,float] + M = object + v:array[2,V] + +var + a = M(v:[ V(v:[0.0,1.0]), V(v:[2.0,3.0]) ]) + b = M(v:[ V(v:[0.0,0.1]), V(v:[0.2,0.3]) ]) + +echo M(v: [V(v: [b.v[0].v[0] + a.v[0].v[0], b.v[0].v[1] + a.v[0].v[1]]), + V(v: [b.v[1].v[0] + a.v[1].v[0], b.v[1].v[1] + a.v[1].v[1]])]) +b = M(v: [V(v: [b.v[0].v[0] + a.v[0].v[0], b.v[0].v[1] + a.v[0].v[1]]), + V(v: [b.v[1].v[0] + a.v[1].v[0], b.v[1].v[1] + a.v[1].v[1]])]) +echo b diff --git a/tests/objects/t17437.nim b/tests/objects/t17437.nim new file mode 100644 index 000000000..b5c0e0525 --- /dev/null +++ b/tests/objects/t17437.nim @@ -0,0 +1,22 @@ +discard """ + cmd: "nim check $file" + errormsg: "" + nimout: ''' +t17437.nim(20, 16) Error: undeclared identifier: 'x' +t17437.nim(20, 16) Error: expression 'x' has no type (or is ambiguous) +t17437.nim(20, 19) Error: incorrect object construction syntax +t17437.nim(20, 19) Error: incorrect object construction syntax +t17437.nim(20, 12) Error: expression '' has no type (or is ambiguous) +''' +""" + +# bug #17437 invalid object construction should result in error + +type + V = ref object + x, y: int + +proc m = + var v = V(x: x, y) + +m() diff --git a/tests/objects/t19342.nim b/tests/objects/t19342.nim new file mode 100644 index 000000000..d40d15a4b --- /dev/null +++ b/tests/objects/t19342.nim @@ -0,0 +1,18 @@ +discard """ + targets: "c cpp" +""" + +{.compile: "m19342.c".} + +# bug #19342 +type + Node* {.bycopy.} = object + data: array[25, cint] + +proc myproc(name: cint): Node {.importc: "hello", cdecl.} + +proc parse = + let node = myproc(10) + doAssert node.data[0] == 999 + +parse() diff --git a/tests/objects/t19342_2.nim b/tests/objects/t19342_2.nim new file mode 100644 index 000000000..6f6d0f2b3 --- /dev/null +++ b/tests/objects/t19342_2.nim @@ -0,0 +1,18 @@ +discard """ + targets: "c cpp" +""" + +{.compile: "m19342.c".} + +# bug #19342 +type + Node* {.byRef.} = object + data: array[25, cint] + +proc myproc(name: cint): Node {.importc: "hello", cdecl.} + +proc parse = + let node = myproc(10) + doAssert node.data[0] == 999 + +parse() \ No newline at end of file diff --git a/tests/objects/t20972.nim b/tests/objects/t20972.nim new file mode 100644 index 000000000..6383dc9b1 --- /dev/null +++ b/tests/objects/t20972.nim @@ -0,0 +1,15 @@ +discard """ + matrix: "--mm:refc -d:release; --mm:orc -d:release" +""" + +{.passC: "-fsanitize=undefined -fsanitize-undefined-trap-on-error -Wall -Wextra -pedantic -flto".} +{.passL: "-fsanitize=undefined -fsanitize-undefined-trap-on-error -flto".} + +# bug #20972 +type ForkedEpochInfo = object + case kind: bool + of true, false: discard +var info = ForkedEpochInfo(kind: true) +doAssert info.kind +info.kind = false +doAssert not info.kind diff --git a/tests/objects/t22301.nim b/tests/objects/t22301.nim new file mode 100644 index 000000000..8746bf584 --- /dev/null +++ b/tests/objects/t22301.nim @@ -0,0 +1,17 @@ +discard """ + errormsg: "branch initialization with a runtime discriminator is not supported for a branch whose fields have default values." +""" + +# bug #22301 +type + Enum = enum A, B + Object = object + case a: Enum + of A: + integer: int = 200 + of B: + time: string + +let x = A +let s = Object(a: x) +echo s \ No newline at end of file diff --git a/tests/objects/t3734.nim b/tests/objects/t3734.nim new file mode 100644 index 000000000..cebef6081 --- /dev/null +++ b/tests/objects/t3734.nim @@ -0,0 +1,17 @@ +discard """ +output: "i0" +""" + +type + Application = object + config: void + i: int + f: void + +proc printFields(rec: Application) = + for k, v in fieldPairs(rec): + echo k, v + +var app: Application + +printFields(app) diff --git a/tests/objects/t4318.nim b/tests/objects/t4318.nim new file mode 100644 index 000000000..beadd6909 --- /dev/null +++ b/tests/objects/t4318.nim @@ -0,0 +1,17 @@ +discard """ + matrix: "--mm:refc" +""" + + +type + A = object of RootObj + B = object of A + +method identify(a:A) {.base.} = echo "A" +method identify(b:B) = echo "B" + +var b: B + +doAssertRaises(ObjectAssignmentDefect): + var a: A = b + discard a diff --git a/tests/objects/tdefaultfieldscheck.nim b/tests/objects/tdefaultfieldscheck.nim new file mode 100644 index 000000000..8a05439d9 --- /dev/null +++ b/tests/objects/tdefaultfieldscheck.nim @@ -0,0 +1,16 @@ +discard """ + cmd: "nim check --hints:off $file" + errormsg: "" + nimout: +''' +tdefaultfieldscheck.nim(14, 17) Error: type mismatch: got <string> but expected 'int' +''' +""" + + +type + Date* = object + goal: float = 7 + name: int = "string" + +echo default(Date) diff --git a/tests/objects/tdefaultrangetypescheck.nim b/tests/objects/tdefaultrangetypescheck.nim new file mode 100644 index 000000000..71e7ac59b --- /dev/null +++ b/tests/objects/tdefaultrangetypescheck.nim @@ -0,0 +1,11 @@ +discard """ + errormsg: "cannot convert 0 to range 1..5(int)" + line: 9 +""" + +type + Point = object + y: int + x: range[1..5] = 0 + +echo default(Point) diff --git a/tests/objects/tillegal_recursion.nim b/tests/objects/tillegal_recursion.nim index 222139101..428c2e445 100644 --- a/tests/objects/tillegal_recursion.nim +++ b/tests/objects/tillegal_recursion.nim @@ -1,5 +1,5 @@ discard """ - errormsg: "inheritance only works with non-final objects" + errormsg: "Cannot inherit from: 'Foo:ObjectType'" line: 7 """ # bug #1691 diff --git a/tests/objects/tillegal_recursion2.nim b/tests/objects/tillegal_recursion2.nim new file mode 100644 index 000000000..ce2279f04 --- /dev/null +++ b/tests/objects/tillegal_recursion2.nim @@ -0,0 +1,6 @@ +discard """ + errormsg: "Cannot inherit from: 'Foo'" + line: 6 +""" +type + Foo = object of Foo diff --git a/tests/objects/tillegal_recursion3.nim b/tests/objects/tillegal_recursion3.nim new file mode 100644 index 000000000..c80f29e28 --- /dev/null +++ b/tests/objects/tillegal_recursion3.nim @@ -0,0 +1,6 @@ +discard """ + errormsg: "Cannot inherit from: 'Foo'" + line: 6 +""" +type + Foo = object of ref Foo diff --git a/tests/objects/tinherentedvalues.nim b/tests/objects/tinherentedvalues.nim deleted file mode 100644 index c96a0fd6d..000000000 --- a/tests/objects/tinherentedvalues.nim +++ /dev/null @@ -1,55 +0,0 @@ -discard """ - output: '''tbObj of TC false -false -true -5 -false''' -""" - -# bug #1053 -type - TA = object of TObject - a: int - - TB = object of TA - b: int - - TC = object of TB - c: int - -proc test(p: TA) = - #echo "p of TB ", p of TB - if p of TB: - var tbObj = TB(p) - - # tbObj is actually no longer compatible with TC: - echo "tbObj of TC ", tbObj of TC - -var v = TC() -v.a = 1 -v.b = 2 -v.c = 3 -test(v) - - -# bug #924 -type - MyObject = object of TObject - x: int - -var - asd: MyObject - -proc isMyObject(obj: TObject) = - echo obj of MyObject - if obj of MyObject: - let a = MyObject(obj) - echo a.x - -asd.x = 5 - -var asdCopy = TObject(asd) -echo asdCopy of MyObject - -isMyObject(asd) -isMyObject(asdCopy) diff --git a/tests/objects/tobj_asgn_dont_slice.nim b/tests/objects/tobj_asgn_dont_slice.nim new file mode 100644 index 000000000..ce67c4490 --- /dev/null +++ b/tests/objects/tobj_asgn_dont_slice.nim @@ -0,0 +1,25 @@ +discard """ + matrix: "--mm:refc" + outputsub: '''ObjectAssignmentDefect''' + exitcode: "1" +""" + +# bug #7637 +type + Fruit = object of RootObj + name*: string + Apple = object of Fruit + Pear = object of Fruit + +method eat(f: Fruit) {.base.} = + raise newException(Exception, "PURE VIRTUAL CALL") + +method eat(f: Apple) = + echo "fruity" + +method eat(f: Pear) = + echo "juicy" + +let basket = [Apple(name:"a"), Pear(name:"b")] + +eat(basket[0]) diff --git a/tests/objects/tobjconstr.nim b/tests/objects/tobjconstr.nim index 226fe98f7..ee5a5b221 100644 --- a/tests/objects/tobjconstr.nim +++ b/tests/objects/tobjconstr.nim @@ -1,14 +1,24 @@ discard """ - output: '''(k: kindA, a: (x: abc, z: [1, 1, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 2, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 3, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 4, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 5, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 6, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 7, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 8, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 9, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 10, 3]), method: ())''' + output: ''' +(k: kindA, a: (x: "abc", z: @[1, 1, 3]), method: ()) +(k: kindA, a: (x: "abc", z: @[1, 2, 3]), method: ()) +(k: kindA, a: (x: "abc", z: @[1, 3, 3]), method: ()) +(k: kindA, a: (x: "abc", z: @[1, 4, 3]), method: ()) +(k: kindA, a: (x: "abc", z: @[1, 5, 3]), method: ()) +(k: kindA, a: (x: "abc", z: @[1, 6, 3]), method: ()) +(k: kindA, a: (x: "abc", z: @[1, 7, 3]), method: ()) +(k: kindA, a: (x: "abc", z: @[1, 8, 3]), method: ()) +(k: kindA, a: (x: "abc", z: @[1, 9, 3]), method: ()) +(k: kindA, a: (x: "abc", z: @[1, 10, 3]), method: ()) +(y: 0, x: 123) +(y: 678, x: 123) +(z: 89, y: 0, x: 128) +(y: 678, x: 123) +(y: 678, x: 123) +(y: 0, x: 123) +(y: 678, x: 123) +(y: 123, x: 678) +''' """ type @@ -24,14 +34,6 @@ type a: TArg `method`: TEmpty # bug #1791 -proc `$`[T](s: seq[T]): string = - # XXX why is that not in the stdlib? - result = "[" - for i, x in s: - if i > 0: result.add(", ") - result.add($x) - result.add("]") - proc main() = for i in 1..10: let d = TDummy(k: kindA, a: TArg(x: "abc", z: @[1,i,3]), `method`: TEmpty()) @@ -39,3 +41,39 @@ proc main() = main() +# bug #6294 +type + A = object of RootObj + x*: int + B = object of A + y*: int + BS = object of B + C = object of BS + z*: int + +proc main2 = + # inherited fields are ignored, so no fields are set + when true: + var + o: B + o = B(x: 123) + echo o + o = B(y: 678, x: 123) + echo o + + # inherited fields are ignored + echo C(x: 128, z: 89) # (y: 0, x: 0) + echo B(y: 678, x: 123) # (y: 678, x: 0) + echo B(x: 123, y: 678) # (y: 678, x: 0) + + when true: + # correct, both with `var` and `let`; + var b=B(x: 123) + echo b # (y: 0, x: 123) + b=B(y: 678, x: 123) + echo b # (y: 678, x: 123) + b=B(y: b.x, x: b.y) + echo b # (y: 123, x: 678) + +main2() +GC_fullCollect() diff --git a/tests/objects/tobjconstr2.nim b/tests/objects/tobjconstr2.nim index f6805190b..cf4a694b4 100644 --- a/tests/objects/tobjconstr2.nim +++ b/tests/objects/tobjconstr2.nim @@ -1,3 +1,8 @@ +discard """ + output: '''42 +Foo''' +""" + type TFoo{.exportc.} = object x:int @@ -10,8 +15,8 @@ echo s[0].x # bug #563 type - Foo = - object {.inheritable.} + Foo {.inheritable.} = + object x: int Bar = @@ -48,3 +53,5 @@ type NamedGraphic = object of Graphic2 var ngr = NamedGraphic(kind: Koo, radius: 6.9, name: "Foo") echo ngr.name + +GC_fullCollect() diff --git a/tests/objects/tobjcov.nim b/tests/objects/tobjcov.nim index cf2e5becf..a12f74702 100644 --- a/tests/objects/tobjcov.nim +++ b/tests/objects/tobjcov.nim @@ -1,7 +1,15 @@ +discard """ +action: compile +targets: "c" +""" + # Covariance is not type safe: +# Note: `nim cpp` makes it a compile error (after codegen), even with: +# `var f = cast[proc (x: var TA) {.nimcall.}](cast[pointer](bp))`, which +# currently removes all the `cast` in cgen'd code, hence the compile error. type - TA = object of TObject + TA = object of RootObj a: int TB = object of TA b: array[0..5000_000, int] @@ -14,4 +22,3 @@ proc bp(x: var TB) = x.b[high(x.b)] = -1 var f = cast[proc (x: var TA) {.nimcall.}](bp) var a: TA f(a) # bp expects a TB, but gets a TA - diff --git a/tests/objects/tobject.nim b/tests/objects/tobject.nim index cdb8f80db..a185bebcb 100644 --- a/tests/objects/tobject.nim +++ b/tests/objects/tobject.nim @@ -1,4 +1,3 @@ -import unittest type Obj = object foo: int @@ -6,10 +5,70 @@ type Obj = object proc makeObj(x: int): Obj = result.foo = x -suite "object basic methods": - test "it should convert an object to a string": +block: # object basic methods + block: # it should convert an object to a string var obj = makeObj(1) # Should be "obj: (foo: 1)" or similar. - check($obj == "(foo: 1)") - test "it should test equality based on fields": - check(makeObj(1) == makeObj(1)) + doAssert($obj == "(foo: 1)") + block: # it should test equality based on fields + doAssert(makeObj(1) == makeObj(1)) + +# bug #10203 + +type + TMyObj = TYourObj + TYourObj = object of RootObj + x, y: int + +proc init: TYourObj = + result.x = 0 + result.y = -1 + +proc f(x: var TYourObj) = + discard + +var m: TMyObj = init() +f(m) + +var a: TYourObj = m +var b: TMyObj = a + +# bug #10195 +type + InheritableFoo {.inheritable.} = ref object + InheritableBar = ref object of InheritableFoo # ERROR. + +block: # bug #14698 + const N = 3 + type Foo[T] = ref object + x1: int + when N == 2: + x2: float + when N == 3: + x3: seq[int] + else: + x4: char + x4b: array[9, char] + + let t = Foo[float](x1: 1) + doAssert $(t[]) == "(x1: 1, x3: @[])" + doAssert t.sizeof == int.sizeof + type Foo1 = object + x1: int + x3: seq[int] + doAssert t[].sizeof == Foo1.sizeof + +# bug #147 +type + TValue* {.pure, final.} = object of RootObj + a: int + PValue = ref TValue + PPValue = ptr PValue + + +var x: PValue +new x +var sp: PPValue = addr x + +sp.a = 2 +doAssert sp.a == 2 diff --git a/tests/objects/tobject2.nim b/tests/objects/tobject2.nim deleted file mode 100644 index a49296843..000000000 --- a/tests/objects/tobject2.nim +++ /dev/null @@ -1,21 +0,0 @@ -# Tests the object implementation - -type - TPoint2d {.inheritable.} = object - x, y: int - - TPoint3d = object of TPoint2d - z: int # added a field - -proc getPoint( p: var TPoint2d) = - {.breakpoint.} - writeLine(stdout, p.x) - -var - p: TPoint3d - -TPoint2d(p).x = 34 -p.y = 98 -p.z = 343 - -getPoint(p) diff --git a/tests/objects/tobject3.nim b/tests/objects/tobject3.nim index 15dd8ea24..9ff1743ce 100644 --- a/tests/objects/tobject3.nim +++ b/tests/objects/tobject3.nim @@ -1,3 +1,10 @@ +discard """ + output: '''TBar2 +TFoo +''' +""" + +## XXX this output needs to be adapted for VCC which produces different results. # It turned out that it's hard to generate correct for these two test cases at # the same time. @@ -57,3 +64,32 @@ var aa = makeWindow() thisCausesError(dd, aa) +# bug #5892 +type + Foo6 = distinct array[4, float32] + AnotherFoo = distinct array[4, float32] + + AbstractAnimationSampler* = ref object of RootObj + + AnimationSampler*[T] = ref object of AbstractAnimationSampler + sampleImpl: proc(s: AnimationSampler[T], p: float): T + + ArrayAnimationSampler*[T] = ref object of AnimationSampler[T] + +proc newArrayAnimationSampler*[T](): ArrayAnimationSampler[T] = + result.new() + result.sampleImpl = nil + +discard newArrayAnimationSampler[Foo6]() +discard newArrayAnimationSampler[AnotherFoo]() + +type + DefaultIsNone* = pointer | ptr | ref | proc {.nimcall.} | cstring | cstringArray + OptionKind* {.pure.} = enum None, Some + OptionA* [T] = object of RootObj + when T is DefaultIsNone: + value: T + else: + value: T + kind: OptionKind + SomeA* [T] = object of OptionA[T] diff --git a/tests/objects/tobject_default_value.nim b/tests/objects/tobject_default_value.nim new file mode 100644 index 000000000..0cd05e4f3 --- /dev/null +++ b/tests/objects/tobject_default_value.nim @@ -0,0 +1,780 @@ +discard """ + matrix: "-d:nimPreviewRangeDefault --mm:refc; -d:nimPreviewRangeDefault --warningAsError:ProveInit --mm:orc" + targets: "c cpp js" +""" + +import std/[times, macros, tables] + +type + Guess = object + poi: DateTime + + GuessDistinct = distinct Guess + +block: + var x: Guess + discard Guess() + + var y: GuessDistinct + + discard y + + discard GuessDistinct(x) + + +import mobject_default_value + +block: + let x = Default() + doAssert x.se == 0'i32 + +block: + let x = default(Default) + doAssert x.se == 0'i32 +# echo Default(poi: 12) +# echo Default(poi: 17) + +# echo NonDefault(poi: 77) + +block: + var x: Default + doAssert x.se == 0'i32 + +type + ObjectBase = object of RootObj + value = 12 + + ObjectBaseDistinct = distinct ObjectBase + + DinstinctInObject = object + data: ObjectBaseDistinct + + Object = object of ObjectBase + time: float = 1.2 + date: int + scale: range[1..10] + + Object2 = object + name: Object + + Object3 = object + obj: Object2 + + ObjectTuple = tuple + base: ObjectBase + typ: int + obj: Object + + TupleInObject = object + size = 777 + data: ObjectTuple + + Ref = ref object of ObjectBase + + RefInt = ref object of Ref + data = 73 + + Ref2 = ref object of ObjectBase + + RefInt2 = ref object of Ref + data = 73 + +var t {.threadvar.}: Default +# var m1, m2 {.threadvar.}: Default + +block: + doAssert t.se == 0'i32 + +block: # ARC/ORC cannot bind destructors twice, so it cannot + # be moved into main + block: + var x: Ref + new(x) + doAssert x.value == 12, "Ref.value = " & $x.value + + var y: RefInt + new(y) + doAssert y.value == 12 + doAssert y.data == 73 + + block: + var x: Ref2 + new(x, proc (x: Ref2) {.nimcall.} = discard "call Ref") + doAssert x.value == 12, "Ref.value = " & $x.value + + proc call(x: RefInt2) = + discard "call RefInt" + + var y: RefInt2 + new(y, call) + doAssert y.value == 12 + doAssert y.data == 73 + +template main {.dirty.} = + block: # bug #16744 + type + R = range[1..10] + Obj = object + r: R + + var + rVal: R = default(R) # Works fine + objVal = default(Obj) + + doAssert rVal == 1 + doAssert objVal.r == 1 + + block: # bug #16744 + type + R = range[1..10] + Obj = object + r: R + + var + rVal: R = default(R) # Works fine + objVal = Obj() + + doAssert rVal == 1 # it should be 1 + doAssert objVal.r == 1 + + block: # bug #3608 + type + abc = ref object + w: range[2..100] + + proc createABC(): abc = + new(result) + result.w = 20 + + doAssert createABC().w == 20 + + block: + var x = new ObjectBase + doAssert x.value == 12 + + proc hello(): ref ObjectBase = + new result + + let z = hello() + doAssert z.value == 12 + + block: + var base = ObjectBase() + var x: ObjectBaseDistinct = ObjectBaseDistinct(base) + doAssert ObjectBase(x).value == 12 + let y = ObjectBaseDistinct(default(ObjectBase)) + doAssert ObjectBase(y).value == 12 + + let m = ObjectBaseDistinct(ObjectBase()) + doAssert ObjectBase(m).value == 12 + + proc hello(): ObjectBaseDistinct = + result = ObjectBaseDistinct(default(ObjectBase)) + + let z = hello() + doAssert ObjectBase(z).value == 12 + + block: + var x: DinstinctInObject + x.data = ObjectBaseDistinct(default(ObjectBase)) + + doAssert ObjectBase(x.data).value == 12 + + block: + var x = Object() + doAssert x.value == 12 + doAssert x.time == 1.2 + doAssert x.scale == 1 + + let y = default(Object) + doAssert y.value == 12 + doAssert y.time == 1.2 + doAssert y.scale == 1 + + var x1, x2, x3 = default(Object) + doAssert x1.value == 12 + doAssert x1.time == 1.2 + doAssert x1.scale == 1 + doAssert x2.value == 12 + doAssert x2.time == 1.2 + doAssert x2.scale == 1 + doAssert x3.value == 12 + doAssert x3.time == 1.2 + doAssert x3.scale == 1 + + block: + var x = new Object + doAssert x[] == default(Object) + + block: + var x = default(Object2) + doAssert x.name.value == 12 + doAssert x.name.time == 1.2 + doAssert x.name.scale == 1 + + block: + let x = Object2() + doAssert x.name.value == 12 + doAssert x.name.time == 1.2 + doAssert x.name.scale == 1 + + block: + var x: ref Object2 + new x + doAssert x[] == default(Object2) + + block: + var x = default(Object3) + doAssert x.obj.name.value == 12 + doAssert x.obj.name.time == 1.2 + doAssert x.obj.name.scale == 1 + + block: + var x = Object3() + doAssert x.obj.name.value == 12 + doAssert x.obj.name.time == 1.2 + doAssert x.obj.name.scale == 1 + + when nimvm: + # todo + discard "fixme" + else: + when defined(gcArc) or defined(gcOrc): + block: #seq + var x = newSeq[Object](10) + let y = x[0] + doAssert y.value == 12 + doAssert y.time == 1.2 + doAssert y.scale == 1 + + block: + var x: seq[Object] + setLen(x, 5) + let y = x[^1] + doAssert y.value == 12 + doAssert y.time == 1.2 + doAssert y.scale == 1 + + block: + var my = @[1, 2, 3, 4, 5] + my.setLen(0) + my.setLen(5) + doAssert my == @[0, 0, 0, 0, 0] + + block: + var my = "hello" + my.setLen(0) + my.setLen(5) + doAssert $(@my) == """@['\x00', '\x00', '\x00', '\x00', '\x00']""" + + block: # array + var x: array[10, Object] = default(array[10, Object]) + let y = x[0] + doAssert y.value == 12 + doAssert y.time == 1.2 + doAssert y.scale == 1 + + block: # array + var x {.noinit.}: array[10, Object] + discard x + + block: # tuple + var x = default(ObjectTuple) + doAssert x.base.value == 12 + doAssert x.typ == 0 + doAssert x.obj.time == 1.2 + doAssert x.obj.date == 0 + doAssert x.obj.scale == 1 + doAssert x.obj.value == 12 + + block: # tuple in object + var x = default(TupleInObject) + doAssert x.data.base.value == 12 + doAssert x.data.typ == 0 + doAssert x.data.obj.time == 1.2 + doAssert x.data.obj.date == 0 + doAssert x.data.obj.scale == 1 + doAssert x.data.obj.value == 12 + doAssert x.size == 777 + + type + ObjectArray = object + data: array[10, Object] + + block: + var x = default(ObjectArray) + let y = x.data[0] + doAssert y.value == 12 + doAssert y.time == 1.2 + doAssert y.scale == 1 + + block: + var x: PrellDeque[int] + doAssert x.pendingTasks == 0 + + type + Color = enum + Red, Blue, Yellow + + ObjectVarint = object + case kind: Color + of Red: + data: int = 10 + of Blue: + fill = "123" + of Yellow: + time = 1.8'f32 + + ObjectVarint1 = object + case kind: Color = Blue + of Red: + data1: int = 10 + of Blue: + fill2 = "123" + cry: float + of Yellow: + time3 = 1.8'f32 + him: int + + block: + var x = ObjectVarint(kind: Red) + doAssert x.kind == Red + doAssert x.data == 10 + + block: + var x = ObjectVarint(kind: Blue) + doAssert x.kind == Blue + doAssert x.fill == "123" + + block: + var x = ObjectVarint(kind: Yellow) + doAssert x.kind == Yellow + doAssert typeof(x.time) is float32 + + block: + var x = default(ObjectVarint1) + doAssert x.kind == Blue + doAssert x.fill2 == "123" + x.cry = 326 + + type + ObjectVarint2 = object + case kind: Color + of Red: + data: int = 10 + of Blue: + fill = "123" + of Yellow: + time = 1.8'f32 + + block: + var x = ObjectVarint2(kind: Blue) + doAssert x.fill == "123" + + block: + type + Color = enum + Red, Blue, Yellow + + type + ObjectVarint3 = object + case kind: Color = Blue + of Red: + data1: int = 10 + of Blue: + case name: Color = Blue + of Blue: + go = 12 + else: + temp = 66 + fill2 = "123" + cry: float + of Yellow: + time3 = 1.8'f32 + him: int + + block: + var x = default(ObjectVarint3) + doAssert x.kind == Blue + doAssert x.name == Blue + doAssert x.go == 12 + + block: + var x = ObjectVarint3(kind: Blue, name: Red, temp: 99) + doAssert x.kind == Blue + doAssert x.name == Red + doAssert x.temp == 99 + + block: + type + Default = tuple + id: int = 1 + obj: ObjectBase + name: string + + Class = object + def: Default + + Member = object + def: Default = (id: 777, obj: ObjectBase(), name: "fine") + + block: + var x = default(Default) + doAssert x.id == 1 + doAssert x.obj == default(ObjectBase) + doAssert x.name == "" + + block: + var x = default(Class) + doAssert x.def == default(Default) + doAssert x.def.id == 1 + doAssert x.def.obj == default(ObjectBase) + doAssert x.def.name == "" + + block: + var x = default(Member) + doAssert x.def.id == 777 + doAssert x.def.obj == default(ObjectBase) + doAssert x.def.name == "fine" + + block: + var x {.noinit.} = 12 + doAssert x == 12 + + type + Pure = object + id: int = 12 + + var y {.noinit.}: Pure + doAssert y.id == 0 + + var z {.noinit.}: Pure = Pure(id: 77) + doAssert z.id == 77 + + block: # bug #20681 + type A = object + d: DateTime = DateTime() + + let x = default(A) + doAssert $x == "(d: Uninitialized DateTime)" + + block: # bug #20715 + block: + type + Foo = enum + A + B + + Bar = object + case foo: Foo + of A: + t: range[-1..2] + else: discard + + var d = default(Bar) + doAssert d.t == -1 + + block: + type + Foo = enum + A + B + + Bar = object + case foo: Foo + of A: + t: range[0..2] + else: discard + + var d = default(Bar) + doAssert d.t == 0 + + block: # bug #20740 + block: + proc foo(x: static DateTime = Datetime()) = + discard + + foo() + + block: + macro foo(x: static DateTime) = + discard x + + macro foo2: untyped = + var x = DateTime() + + result = quote do: + foo(`x`) + + foo2() + + + block: # issue #20699 + type + Either[A,B] = object + case kind:bool + of false: + b: B + of true: + a: A + O = object of RootRef + + proc oToEither(o:O):Either[O,void] = + Either[O,void](kind:true,a: o) + + discard oToEither(O()) + + block: # bug #20695 + type + Default = object + tabs: Table[string, int] = initTable[string, int]() + + let d = default(Default) + doAssert d.tabs.len == 0 + + block: + type + Default = object + tabs: Table[string, int] = Table[string, int]() + + let d = default(Default) + doAssert d.tabs.len == 0 + + + block: + type DjangoDateTime = distinct DateTime + + type Default = object + data: DjangoDateTime = DjangoDateTime(DateTime()) + + let x = default(Default) + doAssert x.data is DjangoDateTime + + block: + type DjangoDateTime = distinct DateTime + + type Default = object + data = DjangoDateTime(DateTime()) + + let x = default(Default) + doAssert x.data is DjangoDateTime + + block: + type + Result2 = object + case o: bool + of false: + e: float + of true: + v {.requiresInit.} : int = 1 + + proc startSessionSync(): Result2 = + return Result2(o: true) + + proc mainSync = + let ff = startSessionSync() + doAssert ff.v == 1 + + mainSync() + + block: + type + Result2 = object + v {.requiresInit.} : int = 1 + + proc startSessionSync(): Result2 = + return Result2() + + proc mainSync = + let ff = startSessionSync() + doAssert ff.v == 1 + + mainSync() + + block: # bug #21801 + func evaluate(i: int): float = + 0.0 + + func evaluate(): float = + 0.0 + + type SearchOptions = object + evaluation: proc(): float = evaluate + + block: + func evaluate(): float = + 0.0 + + type SearchOptions = object + evaluation: proc(): float = evaluate + + block: + func evaluate(i: int): float = + 0.0 + + type SearchOptions = object + evaluation = evaluate + block: + type + Result[T, E] = object + when T is void: + when E is void: + oResultPrivate: bool + else: + case oResultPrivate: bool + of false: + eResultPrivate: E + of true: + discard + else: + when E is void: + case oResultPrivate: bool + of false: + discard + of true: + vResultPrivate: T + else: + case oResultPrivate: bool + of false: + eResultPrivate: E + of true: + vResultPrivate: T + + + template `?`[T, E](self: Result[T, E]): auto = + let v = (self) + if not v.oResultPrivate: + when compiles(`assignResult?`(default(typeof(result)))): + when typeof(result) is typeof(v): + `assignResult?`(v) + elif E is void: + `assignResult?`(err(typeof(result))) + else: + `assignResult?`(err(typeof(result), v.eResultPrivate)) + return + else: + return + when typeof(result) is typeof(v): + v + elif E is void: + err(typeof(result)) + else: + err(typeof(result), v.eResultPrivate) + + when not(T is void): + v.vResultPrivate + + type R = Result[int, string] + + proc testAssignResult() = + var assigned: bool + template `assignResult?`(v: Result) = + assigned = true + result = v + + proc failed(): Result[int, string] = + discard + + proc calling(): Result[int, string] = + let _ = ? failed() + doAssert false + + let r = calling() + doAssert assigned + + when nimvm: + when not defined(js): + testAssignResult() + else: + testAssignResult() + + block: # bug #22123 + type Thing = object + x: float32 = 1 + + type ThingWithArray = object + arr: array[256, float32] + n: float32 = 1 + + type Container = ref object + thing: array[5, Thing] + thing_with_array: array[5, ThingWithArray] + + var foo = new Container + doAssert int(foo.thing[0].x) == 1 + + block: # bug #22613 + type + K = enum + A = "a" + B = "b" + T = object + case kind: K = B + of A: + a: int + of B: + b: float + + doAssert T().kind == B + + block: # bug #22926 + type + Direction = enum + North + South + East + West + + ArrayObj1 = object + list: array[Direction, int] + + ArrayObj2 = object + list: array[Direction, int] = [1, 2, 3, 4] + + block: + var a: ArrayObj1 + doAssert a.list[West] == 0 + var b = default ArrayObj1 + doAssert b.list[North] == 0 + + + block: + var a: ArrayObj2 + doAssert a.list[West] == 0 + var b = default ArrayObj2 + doAssert b.list[North] == 1 + + block: + type limited_float = range[1.2..20.0] + doAssert default(limited_float) == 1.2 + + + block: + type + range1 = range[1..10] + range2 = range[-1..10] + + proc foo = + doAssert default(range1) == 1 + doAssert default(range2) == -1 + + let s = default(array[5, range1]) + doAssert s == [range1 1, 1, 1, 1, 1] + + foo() + + block: + type + Object = object + id: range[1.2..29.3] + + var s = default(Object) + doAssert s.id == 1.2 + + block: # bug #23943 + type limited_int = range[1..20] + var d: limited_int; + doAssert d == 1 + +static: main() +main() diff --git a/tests/objects/tobjects.nim b/tests/objects/tobjects.nim deleted file mode 100644 index 2f46b46b5..000000000 --- a/tests/objects/tobjects.nim +++ /dev/null @@ -1,52 +0,0 @@ -type - TBase = object of TObject - x, y: int - - TSubclassKind = enum ka, kb, kc, kd, ke, kf - TSubclass = object of TBase - case c: TSubclassKind - of ka, kb, kc, kd: - a, b: int - of ke: - d, e, f: char - else: nil - n: bool - -type - TMyObject = object of TObject - case disp: range[0..4] - of 0: arg: char - of 1: s: string - else: wtf: bool - -var - x: TMyObject - -var - global: int - -var - s: string - r: float = 0.0 - i: int = 500 + 400 - -case i -of 500..999: write(stdout, "ha!\n") -of 1000..3000, 12: write(stdout, "ganz schön groß\n") -of 1, 2, 3: write(stdout, "1 2 oder 3\n") -else: write(stdout, "sollte nicht passieren\n") - -case readLine(stdin) -of "Rumpf": write(stdout, "Hallo Meister!\n") -of "Andreas": write(stdout, "Hallo Meister!\n") -else: write(stdout, "Nicht mein Meister!\n") - -global = global + 1 -write(stdout, "Hallo wie heißt du? \n") -s = readLine(stdin) -i = 0 -while i < len(s): - if s[i] == 'c': write(stdout, "'c' in deinem Namen gefunden\n") - i = i + 1 - -write(stdout, "Du heißt " & s) diff --git a/tests/objects/tobjects_issues.nim b/tests/objects/tobjects_issues.nim new file mode 100644 index 000000000..f1a416d04 --- /dev/null +++ b/tests/objects/tobjects_issues.nim @@ -0,0 +1,117 @@ +discard """ + output: ''' +tbObj of TC true +true +5 +true +is Nil false +''' +""" + + +block t1053: + type + TA = object of RootObj + a: int + TB = object of TA + b: int + TC = object of TB + c: int + + proc test(p: TA) = + if p of TB: + echo "tbObj of TC ", p of TC + + var v = TC() + v.a = 1 + v.b = 2 + v.c = 3 + test(v) + + + +block t924: + type + MyObject = object of RootObj + x: int + var asd: MyObject + + proc isMyObject(obj: RootObj) = + echo obj of MyObject + if obj of MyObject: + let a = MyObject(obj) + echo a.x + + asd.x = 5 + isMyObject(asd) + + + +block t4673: + type + BaseObj[T] = ref object of RootObj + SomeObj = ref object of BaseObj[int] + + proc doSomething[T](o: BaseObj[T]) = + echo "true" + var o = new(SomeObj) + o.doSomething() # Error: cannot instantiate: 'T' + + + +block t1658: + type + Loop = ref object + onBeforeSelect: proc (L: Loop) + + var L: Loop + new L + L.onBeforeSelect = proc (bar: Loop) = + echo "is Nil ", bar.isNil + + L.onBeforeSelect(L) + + + +block t2508: + type + GenericNodeObj[T] = ref object + obj: T + Node = ref object + children: seq[Node] + parent: Node + nodeObj: GenericNodeObj[int] + + proc newNode(nodeObj: GenericNodeObj): Node = + result = Node(nodeObj: nodeObj) + newSeq(result.children, 10) + + var genericObj = GenericNodeObj[int]() + var myNode = newNode(genericObj) + + + +block t2540: + type + BaseSceneNode[T] = ref object of RootObj + children: seq[BaseSceneNode[T]] + parent: BaseSceneNode[T] + SceneNode[T] = ref object of BaseSceneNode[T] + SomeObj = ref object + + proc newSceneNode[T](): SceneNode[T] = + new result + result.children = @[] + + var aNode = newSceneNode[SomeObj]() + + +block t3038: + type + Data[T] = ref object of RootObj + data: T + Type = ref object of RootObj + SubType[T] = ref object of Type + data: Data[T] + SubSubType = ref object of SubType[int] + SubSubSubType = ref object of SubSubType diff --git a/tests/objects/tobjects_various.nim b/tests/objects/tobjects_various.nim new file mode 100644 index 000000000..55db9312e --- /dev/null +++ b/tests/objects/tobjects_various.nim @@ -0,0 +1,120 @@ +discard """ + output: ''' +34 +b +wohoo +baz +''' +""" + + +block tobject2: + # Tests the object implementation + type + TPoint2d {.inheritable.} = object + x, y: int + TPoint3d = object of TPoint2d + z: int # added a field + + proc getPoint( p: var TPoint2d) = + writeLine(stdout, p.x) + + var p: TPoint3d + + TPoint2d(p).x = 34 + p.y = 98 + p.z = 343 + + getPoint(p) + + + +block tofopr: + type + TMyType {.inheritable.} = object + len: int + data: string + + TOtherType = object of TMyType + + proc p(x: TMyType): bool = + return x of TOtherType + + var + m: TMyType + n: TOtherType + + doAssert p(m) == false + doAssert p(n) + + + +block toop: + type + TA = object of RootObj + x, y: int + TB = object of TA + z: int + TC = object of TB + whatever: string + + proc p(a: var TA) = echo "a" + proc p(b: var TB) = echo "b" + + var c: TC + p(c) + + + +block tfefobjsyntax: + type + Foo = object + a, b: int + s: string + FooBar = object of RootObj + n, m: string + Baz = object of FooBar + + proc invoke(a: ref Baz) = + echo "baz" + + # check object construction: + let x = (ref Foo)(a: 0, b: 45, s: "wohoo") + echo x.s + + var y: ref FooBar = (ref Baz)(n: "n", m: "m") + invoke((ref Baz)(y)) + + + +block t3012: + type + A {.inheritable.} = object + C {.inheritable.} = ref object + + type + AA = ref object of A + CC = ref object of C + + + +block t7244: + type + Foo = ref object of RootRef + Bar = ref object of Foo + + proc test(foo: var Foo) = discard + proc test(bar: var Bar) = test(Foo(bar)) + + +import std/macros + +#bug #20856 +macro ensureImplWorksOnConstr(t: typed): untyped = + expectKind(t, nnkObjConstr) + doAssert t[0].getTypeInst.getImpl.repr == "A = object" + doAssert t[0].getImpl.repr == "A = object" + +type A = object + +ensureImplWorksOnConstr(A()) diff --git a/tests/objects/tobjloop.nim b/tests/objects/tobjloop.nim deleted file mode 100644 index 9fea1e2fb..000000000 --- a/tests/objects/tobjloop.nim +++ /dev/null @@ -1,15 +0,0 @@ -discard """ - output: "is Nil false" -""" -# bug #1658 - -type - Loop* = ref object - onBeforeSelect*: proc (L: Loop) - -var L: Loop -new L -L.onBeforeSelect = proc (bar: Loop) = - echo "is Nil ", bar.isNil - -L.onBeforeSelect(L) diff --git a/tests/objects/tobjpragma.nim b/tests/objects/tobjpragma.nim index 0a6cc893b..789b3ec4e 100644 --- a/tests/objects/tobjpragma.nim +++ b/tests/objects/tobjpragma.nim @@ -1,13 +1,14 @@ discard """ - file: "tobjpragma.nim" - output: '''2 + output: ''' +2 3 9 257 1 2 -3''' - disabled: "true" +3 +''' +disabled: "true" """ # Disabled since some versions of GCC ignore the 'packed' attribute diff --git a/tests/objects/tofopr.nim b/tests/objects/tofopr.nim deleted file mode 100644 index ab2854571..000000000 --- a/tests/objects/tofopr.nim +++ /dev/null @@ -1,26 +0,0 @@ -discard """ - file: "tofopr.nim" - output: "falsetrue" -""" -# Test is operator - -type - TMyType = object {.inheritable.} - len: int - data: string - - TOtherType = object of TMyType - -proc p(x: TMyType): bool = - return x of TOtherType - -var - m: TMyType - n: TOtherType - -write(stdout, p(m)) -write(stdout, p(n)) - -#OUT falsetrue - - diff --git a/tests/objects/toop.nim b/tests/objects/toop.nim deleted file mode 100644 index ebc59f637..000000000 --- a/tests/objects/toop.nim +++ /dev/null @@ -1,21 +0,0 @@ -discard """ - output: "b" -""" - -type - TA = object of TObject - x, y: int - - TB = object of TA - z: int - - TC = object of TB - whatever: string - -proc p(a: var TA) = echo "a" -proc p(b: var TB) = echo "b" - -var c: TC - -p(c) - diff --git a/tests/objects/toop1.nim b/tests/objects/toop1.nim index 4727d146d..3e9b24990 100644 --- a/tests/objects/toop1.nim +++ b/tests/objects/toop1.nim @@ -1,5 +1,4 @@ discard """ - file: "toop1.nim" output: "34[]o 5" """ # Test the stuff in the tutorial @@ -35,7 +34,7 @@ proc init(my: var TRectangle) = my.height = 10 my.draw = cast[proc (my: var TFigure) {.nimcall.}](drawRectangle) -macro `!` (n: expr): stmt {.immediate.} = +macro `!` (n: varargs[untyped]): typed = let n = callsite() result = newNimNode(nnkCall, n) var dot = newNimNode(nnkDotExpr, n) diff --git a/tests/objects/trefobjsyntax.nim b/tests/objects/trefobjsyntax.nim deleted file mode 100644 index 9b48de718..000000000 --- a/tests/objects/trefobjsyntax.nim +++ /dev/null @@ -1,27 +0,0 @@ -discard """ - output: '''wohoo -baz''' -""" - -# Test to ensure the popular 'ref T' syntax works everywhere - -type - Foo = object - a, b: int - s: string - - FooBar = object of RootObj - n, m: string - Baz = object of FooBar - -proc invoke(a: ref Baz) = - echo "baz" - -# check object construction: -let x = (ref Foo)(a: 0, b: 45, s: "wohoo") -echo x.s - -var y: ref FooBar = (ref Baz)(n: "n", m: "m") - -invoke((ref Baz)(y)) - diff --git a/tests/objects/trefobjsyntax2.nim b/tests/objects/trefobjsyntax2.nim deleted file mode 100644 index 8ee209cc7..000000000 --- a/tests/objects/trefobjsyntax2.nim +++ /dev/null @@ -1,19 +0,0 @@ -# bug #2508 - -type - GenericNodeObj[T] = ref object - obj: T - - Node* = ref object - children*: seq[Node] - parent*: Node - - nodeObj*: GenericNodeObj[int] - -proc newNode*(nodeObj: GenericNodeObj): Node = - result = Node(nodeObj: nodeObj) - newSeq(result.children, 10) - -var genericObj = GenericNodeObj[int]() - -var myNode = newNode(genericObj) diff --git a/tests/objects/trefobjsyntax3.nim b/tests/objects/trefobjsyntax3.nim deleted file mode 100644 index 2d466eeda..000000000 --- a/tests/objects/trefobjsyntax3.nim +++ /dev/null @@ -1,28 +0,0 @@ -# bug #2540 - -type - BaseSceneNode[T] = ref object of RootObj - children*: seq[BaseSceneNode[T]] - parent*: BaseSceneNode[T] - - SceneNode[T] = ref object of BaseSceneNode[T] - - SomeObj = ref object - -proc newSceneNode[T](): SceneNode[T] = - new result - result.children = @[] - -var aNode = newSceneNode[SomeObj]() - - -# bug #3038 - -type - Data[T] = ref object of RootObj - data: T - Type = ref object of RootObj - SubType[T] = ref object of Type - data: Data[T] - SubSubType = ref object of SubType - SubSubSubType = ref object of SubSubType diff --git a/tests/objects/trequireinit.nim b/tests/objects/trequireinit.nim new file mode 100644 index 000000000..202667b02 --- /dev/null +++ b/tests/objects/trequireinit.nim @@ -0,0 +1,10 @@ +discard """ + errormsg: "The MPlayerObj type doesn't have a default value. The following fields must be initialized: foo." +""" + +type + MPlayerObj* {.requiresInit.} = object + foo: range[5..10] = 5 + +var a: MPlayerObj +echo a.foo \ No newline at end of file diff --git a/tests/objects/tunsafenew.nim b/tests/objects/tunsafenew.nim new file mode 100644 index 000000000..6c1b33cd9 --- /dev/null +++ b/tests/objects/tunsafenew.nim @@ -0,0 +1,10 @@ +discard """ + errormsg: "conversion from int literal(-1) to Natural is invalid" +""" + +type + Obj = object + case b: bool + else: discard +var o: ref Obj +unsafeNew(o, -1) \ No newline at end of file diff --git a/tests/objects/tunsafenew2.nim b/tests/objects/tunsafenew2.nim new file mode 100644 index 000000000..83112bcfc --- /dev/null +++ b/tests/objects/tunsafenew2.nim @@ -0,0 +1,15 @@ +discard """ +valgrind: "leaks" +matrix: "-d:useMalloc" +targets: "c cpp" +""" + +type + Obj = object + case b: bool + else: discard + a: UncheckedArray[byte] + +var o: ref Obj +unsafeNew(o, sizeof(Obj) + 512) +zeroMem(addr o.a, 512) diff --git a/tests/objects/twhen1.nim b/tests/objects/twhen1.nim new file mode 100644 index 000000000..fe072a46b --- /dev/null +++ b/tests/objects/twhen1.nim @@ -0,0 +1,89 @@ +const Z = 0 + +type + Foo[T] = object + when true: + u: int + else: + v: int + Foo1[T] = object + when T is int: + x: T + elif true: + z: char + Foo2[x:static[int]] = object + when (x and 1) == 1: + x: array[x+1,int] + else: + x: array[x,int] + + Foo3 = Foo2[128] + + # #8417 + Foo4[A: static[int]] = object + when Z == 0: + discard + else: + discard + +block: + var x: Foo[int] = Foo[int](u: 42) + doAssert x.u == 42 + +# Don't evaluate `when` branches before the type is instantiated +block: + var x: Foo1[bool] = Foo1[bool](z: 'o') + doAssert x.z == 'o' + +block: + var x: Foo2[3] + doAssert x.x.len == 4 + +block: + var x: Foo2[4] + doAssert x.x.len == 4 + +block: + var x: Foo3 + doAssert x.x.len == 128 + +block: + var x: Foo4[0] + +type + MyObject = object + x: int + when (NimMajor, NimMinor) >= (1, 1): + y: int +discard MyObject(x: 100, y: 200) + +block: # Ensure when evaluates properly in objects + type X[bits: static int] = object #22474 + when bits >= 256: + data32: byte + else: + data16: byte + + static: + discard X[255]().data16 + discard X[256]().data32 + + + type ComplexExprObject[S: static string, I: static int, Y: static auto] = object + when 'h' in S and I < 10 and Y isnot float: + a: int + elif I > 30: + b: int + elif typeof(Y) is float: + c: int + else: + d: int + + static: + discard ComplexExprObject["hello", 9, 300i32]().a + discard ComplexExprObject["", 40, 30f]().b + discard ComplexExprObject["", 20, float 30]().c + discard ComplexExprObject["", 20, ""]().d + + + |