Files
Nim/tests/objects/tobject_default_value.nim
ringabout affd3f7858 fixes #22613; Default value does not work with object's discriminator (#22614)
* fixes #22613; Default value does not work with object's discriminator

fixes #22613

* merge branches

* add a test case

* fixes status

* remove outdated comments

* move collectBranchFields into the global scope
2023-09-01 08:55:19 +02:00

723 lines
14 KiB
Nim

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 == 0 # it should be 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 == 0 # 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
static: main()
main()