mirror of
https://github.com/nim-lang/Nim.git
synced 2026-09-05 13:10:50 +00:00
265 lines
6.0 KiB
Nim
265 lines
6.0 KiB
Nim
discard """
|
|
output: '''
|
|
----1
|
|
myobj constructed
|
|
myobj destroyed
|
|
----2
|
|
mygeneric1 constructed
|
|
mygeneric1 destroyed
|
|
----3
|
|
mygeneric2 constructed
|
|
mygeneric2 destroyed
|
|
myobj destroyed
|
|
----4
|
|
mygeneric3 constructed
|
|
mygeneric1 destroyed
|
|
----5
|
|
mydistinctObj constructed
|
|
mygeneric2 destroyed
|
|
myobj destroyed
|
|
------------------8
|
|
mygeneric1 destroyed
|
|
----6
|
|
myobj destroyed
|
|
----7
|
|
---9
|
|
myobj destroyed
|
|
myobj destroyed
|
|
'''
|
|
"""
|
|
|
|
type
|
|
TMyObj = object
|
|
x, y: int
|
|
p: pointer
|
|
|
|
proc `=destroy`(o: var TMyObj) =
|
|
if o.p != nil:
|
|
dealloc o.p
|
|
o.p = nil
|
|
echo "myobj destroyed"
|
|
|
|
type
|
|
TMyGeneric1[T] = object
|
|
x: T
|
|
|
|
TMyGeneric2[A, B] = object
|
|
x: A
|
|
y: B
|
|
|
|
proc `=destroy`(o: var TMyGeneric1[int]) =
|
|
echo "mygeneric1 destroyed"
|
|
|
|
proc `=destroy`[A, B](o: var TMyGeneric2[A, B]) =
|
|
echo "mygeneric2 destroyed"
|
|
|
|
type
|
|
TMyGeneric3[A, B, C] = object
|
|
x: A
|
|
y: B
|
|
z: C
|
|
|
|
TDistinctObjX = distinct TMyGeneric3[TMyObj, TMyGeneric2[int, int], int]
|
|
TDistinctObj = TDistinctObjX
|
|
|
|
TObjKind = enum Z, A, B, C, D
|
|
|
|
TCaseObj = object
|
|
z: TMyGeneric3[TMyObj, float, int]
|
|
case kind: TObjKind
|
|
of Z: discard
|
|
of A:
|
|
x: TMyGeneric1[int]
|
|
of B, C:
|
|
y: TMyObj
|
|
else:
|
|
case innerKind: TObjKind
|
|
of Z: discard
|
|
of A, B, C:
|
|
p: TMyGeneric3[int, float, string]
|
|
of D:
|
|
q: TMyGeneric3[TMyObj, int, int]
|
|
r: string
|
|
|
|
proc open: TMyObj =
|
|
# allow for superfluous ()
|
|
result = (TMyObj(x: 1, y: 2, p: alloc(3)))
|
|
|
|
proc `$`(x: TMyObj): string = $x.y
|
|
|
|
proc myobj() =
|
|
var x = open()
|
|
echo "myobj constructed"
|
|
|
|
proc mygeneric1() =
|
|
var x = TMyGeneric1[int](x: 10)
|
|
echo "mygeneric1 constructed"
|
|
|
|
proc mygeneric2[T](val: T) =
|
|
var a = open()
|
|
|
|
var b = TMyGeneric2[int, T](x: 10, y: val)
|
|
echo "mygeneric2 constructed"
|
|
|
|
var c = TMyGeneric3[int, int, string](x: 10, y: 20, z: "test")
|
|
|
|
proc mygeneric3 =
|
|
var x = TMyGeneric3[int, string, TMyGeneric1[int]](
|
|
x: 10, y: "test", z: TMyGeneric1[int](x: 10))
|
|
|
|
echo "mygeneric3 constructed"
|
|
|
|
proc mydistinctObj =
|
|
var x = TMyGeneric3[TMyObj, TMyGeneric2[int, int], int](
|
|
x: open(), y: TMyGeneric2[int, int](x: 5, y: 15), z: 20)
|
|
|
|
echo "mydistinctObj constructed"
|
|
|
|
echo "----1"
|
|
myobj()
|
|
|
|
echo "----2"
|
|
mygeneric1()
|
|
|
|
echo "----3"
|
|
mygeneric2[int](10)
|
|
|
|
echo "----4"
|
|
mygeneric3()
|
|
|
|
echo "----5"
|
|
mydistinctObj()
|
|
|
|
proc caseobj =
|
|
block:
|
|
var o1 = TCaseObj(kind: A, x: TMyGeneric1[int](x: 10))
|
|
|
|
block:
|
|
echo "----6"
|
|
var o2 = TCaseObj(kind: B, y: open())
|
|
|
|
block:
|
|
echo "----7"
|
|
var o3 = TCaseObj(kind: D, innerKind: B, r: "test",
|
|
p: TMyGeneric3[int, float, string](x: 10, y: 1.0, z: "test"))
|
|
|
|
|
|
echo "------------------8"
|
|
caseobj()
|
|
|
|
proc caseobj_test_sink: TCaseObj =
|
|
# check that lifted sink can destroy case val correctly
|
|
result = TCaseObj(kind: D, innerKind: D, r: "test",
|
|
q: TMyGeneric3[TMyObj, int, int](x: open(), y: 1, z: 0))
|
|
result = TCaseObj(kind: B, y: open())
|
|
|
|
|
|
echo "---9"
|
|
discard caseobj_test_sink()
|
|
|
|
# issue #14315
|
|
|
|
type Vector*[T] = object
|
|
x1: int
|
|
# x2: T # uncomment will remove error
|
|
|
|
# proc `=destroy`*(x: var Vector[int]) = discard # this will remove error
|
|
proc `=destroy`*[T](x: var Vector[T]) = discard
|
|
var a: Vector[int] # Error: unresolved generic parameter
|
|
|
|
# issue #26132
|
|
|
|
block:
|
|
type UnparameterizedGeneric[T] = object
|
|
|
|
proc `=destroy`(x: var UnparameterizedGeneric) = discard
|
|
proc `=wasMoved`(x: var UnparameterizedGeneric) = discard
|
|
proc `=trace`(x: var UnparameterizedGeneric; env: pointer) = discard
|
|
|
|
var x: UnparameterizedGeneric[int]
|
|
discard x
|
|
|
|
# Exercise every type-bound hook with the generic parameter omitted.
|
|
block:
|
|
type
|
|
Generic[T] = object
|
|
value: T
|
|
|
|
var destroys, moves, traces, copies, sinks, dups: int
|
|
|
|
proc `=destroy`(x: var Generic) = inc destroys
|
|
proc `=wasMoved`(x: var Generic) =
|
|
inc moves
|
|
x.value = default(typeof(x.value))
|
|
proc `=trace`(x: var Generic; env: pointer) = inc traces
|
|
proc `=copy`(dest: var Generic; src: Generic) =
|
|
inc copies
|
|
dest.value = src.value
|
|
proc `=sink`(dest: var Generic; src: Generic) =
|
|
inc sinks
|
|
dest.value = src.value
|
|
proc `=dup`(src: Generic): Generic =
|
|
inc dups
|
|
Generic(value: src.value)
|
|
proc deepCopy(src: ref Generic): ref Generic = src
|
|
|
|
proc exercise[T]() =
|
|
var first = Generic[T](value: default(T))
|
|
var second = Generic[T](value: default(T))
|
|
second = first
|
|
doAssert second.value == first.value
|
|
second = Generic[T](value: default(T))
|
|
doAssert second.value == default(T)
|
|
`=trace`(first, nil)
|
|
`=wasMoved`(first)
|
|
let implicitDuplicate = first
|
|
discard implicitDuplicate
|
|
let duplicate = `=dup`(first)
|
|
discard duplicate
|
|
let original = new(Generic[T])
|
|
doAssert deepCopy(original) == original
|
|
|
|
exercise[string]()
|
|
exercise[int]()
|
|
exercise[seq[int]]()
|
|
|
|
doAssert copies > 0
|
|
doAssert sinks > 0
|
|
doAssert dups > 0
|
|
doAssert moves > 0
|
|
doAssert traces > 0
|
|
doAssert destroys > 0
|
|
|
|
block:
|
|
type GenericDistinct[T] = distinct Generic[T]
|
|
|
|
proc `=destroy`(x: var GenericDistinct) = discard
|
|
proc `=wasMoved`(x: var GenericDistinct) = discard
|
|
proc `=trace`(x: var GenericDistinct; env: pointer) = discard
|
|
proc `=copy`(dest: var GenericDistinct; src: GenericDistinct) = discard
|
|
proc `=sink`(dest: var GenericDistinct; src: GenericDistinct) = discard
|
|
proc `=dup`(src: GenericDistinct): GenericDistinct = src
|
|
proc deepCopy(src: ref GenericDistinct): ref GenericDistinct = src
|
|
|
|
var first = GenericDistinct[string](Generic[string](value: "first"))
|
|
var second = GenericDistinct[string](Generic[string](value: "second"))
|
|
second = first
|
|
second = GenericDistinct[string](Generic[string](value: "third"))
|
|
`=trace`(first, nil)
|
|
`=wasMoved`(first)
|
|
let moved = move(first)
|
|
let duplicate = `=dup`(moved)
|
|
discard duplicate
|
|
let original = new(GenericDistinct[string])
|
|
doAssert deepCopy(original) == original
|
|
|
|
block:
|
|
type GenericPair[A, B] = object
|
|
left: A
|
|
right: B
|
|
|
|
proc `=destroy`(x: var GenericPair) = discard
|
|
|
|
var pair = GenericPair[int, string](left: 42, right: "pair")
|
|
discard pair
|