diff options
Diffstat (limited to 'tests/objects')
-rw-r--r-- | tests/objects/m19342.c | 12 | ||||
-rw-r--r-- | tests/objects/mobject_default_value.nim | 15 | ||||
-rw-r--r-- | tests/objects/t17437.nim | 22 | ||||
-rw-r--r-- | tests/objects/t19342.nim | 18 | ||||
-rw-r--r-- | tests/objects/t19342_2.nim | 18 | ||||
-rw-r--r-- | tests/objects/t20972.nim | 15 | ||||
-rw-r--r-- | tests/objects/t22301.nim | 17 | ||||
-rw-r--r-- | tests/objects/t4318.nim | 5 | ||||
-rw-r--r-- | tests/objects/tdefaultfieldscheck.nim | 16 | ||||
-rw-r--r-- | tests/objects/tdefaultrangetypescheck.nim | 11 | ||||
-rw-r--r-- | tests/objects/tillegal_recursion.nim | 2 | ||||
-rw-r--r-- | tests/objects/tillegal_recursion2.nim | 6 | ||||
-rw-r--r-- | tests/objects/tillegal_recursion3.nim | 6 | ||||
-rw-r--r-- | tests/objects/tobj_asgn_dont_slice.nim | 1 | ||||
-rw-r--r-- | tests/objects/tobjconstr.nim | 43 | ||||
-rw-r--r-- | tests/objects/tobjconstr2.nim | 4 | ||||
-rw-r--r-- | tests/objects/tobject.nim | 20 | ||||
-rw-r--r-- | tests/objects/tobject_default_value.nim | 780 | ||||
-rw-r--r-- | tests/objects/tobjects_various.nim | 15 | ||||
-rw-r--r-- | tests/objects/trequireinit.nim | 10 | ||||
-rw-r--r-- | tests/objects/tunsafenew.nim | 10 | ||||
-rw-r--r-- | tests/objects/tunsafenew2.nim | 15 | ||||
-rw-r--r-- | tests/objects/twhen1.nim | 32 |
23 files changed, 1066 insertions, 27 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/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/t4318.nim b/tests/objects/t4318.nim index 34ff722f5..beadd6909 100644 --- a/tests/objects/t4318.nim +++ b/tests/objects/t4318.nim @@ -1,3 +1,8 @@ +discard """ + matrix: "--mm:refc" +""" + + type A = object of RootObj B = object of 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/tobj_asgn_dont_slice.nim b/tests/objects/tobj_asgn_dont_slice.nim index 2e36b65a3..ce67c4490 100644 --- a/tests/objects/tobj_asgn_dont_slice.nim +++ b/tests/objects/tobj_asgn_dont_slice.nim @@ -1,4 +1,5 @@ discard """ + matrix: "--mm:refc" outputsub: '''ObjectAssignmentDefect''' exitcode: "1" """ diff --git a/tests/objects/tobjconstr.nim b/tests/objects/tobjconstr.nim index 1e4d89d68..ee5a5b221 100644 --- a/tests/objects/tobjconstr.nim +++ b/tests/objects/tobjconstr.nim @@ -50,27 +50,30 @@ type BS = object of B C = object of BS z*: int -# 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) +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 -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) + # 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 6253edab0..cf4a694b4 100644 --- a/tests/objects/tobjconstr2.nim +++ b/tests/objects/tobjconstr2.nim @@ -15,8 +15,8 @@ echo s[0].x # bug #563 type - Foo = - object {.inheritable.} + Foo {.inheritable.} = + object x: int Bar = diff --git a/tests/objects/tobject.nim b/tests/objects/tobject.nim index 543a86376..a185bebcb 100644 --- a/tests/objects/tobject.nim +++ b/tests/objects/tobject.nim @@ -1,4 +1,3 @@ -import unittest type Obj = object foo: int @@ -10,9 +9,9 @@ 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)") + doAssert($obj == "(foo: 1)") block: # it should test equality based on fields - check(makeObj(1) == makeObj(1)) + doAssert(makeObj(1) == makeObj(1)) # bug #10203 @@ -58,3 +57,18 @@ block: # bug #14698 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/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_various.nim b/tests/objects/tobjects_various.nim index 315193de9..55db9312e 100644 --- a/tests/objects/tobjects_various.nim +++ b/tests/objects/tobjects_various.nim @@ -31,7 +31,7 @@ block tobject2: block tofopr: type - TMyType = object {.inheritable.} + TMyType {.inheritable.} = object len: int data: string @@ -105,3 +105,16 @@ block t7244: 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/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 index 5b8eea3f4..fe072a46b 100644 --- a/tests/objects/twhen1.nim +++ b/tests/objects/twhen1.nim @@ -55,3 +55,35 @@ type 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 + + + |