-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
renamed '=' to '=copy' [backport:1.2] (#15585)
* Assign hook name changed to `=copy` * Adapt destructors.rst * [nobackport] Duplicate tests for =copy hook * Fix tests * added a changelog entry Co-authored-by: Clyybber <darkmine956@gmail.com>
- Loading branch information
Showing
17 changed files
with
1,001 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,246 @@ | ||
discard """ | ||
valgrind: true | ||
cmd: "nim c --gc:arc -d:useMalloc $file" | ||
output: '''myobj destroyed | ||
myobj destroyed | ||
myobj destroyed | ||
A | ||
B | ||
begin | ||
end | ||
prevented | ||
(ok: true, value: "ok") | ||
myobj destroyed | ||
''' | ||
""" | ||
|
||
# bug #13102 | ||
|
||
type | ||
D = ref object | ||
R = object | ||
case o: bool | ||
of false: | ||
discard | ||
of true: | ||
field: D | ||
|
||
iterator things(): R = | ||
when true: | ||
var | ||
unit = D() | ||
while true: | ||
yield R(o: true, field: unit) | ||
else: | ||
while true: | ||
var | ||
unit = D() | ||
yield R(o: true, field: unit) | ||
|
||
proc main = | ||
var i = 0 | ||
for item in things(): | ||
discard item.field | ||
inc i | ||
if i == 2: break | ||
|
||
main() | ||
|
||
# bug #13149 | ||
|
||
type | ||
TMyObj = object | ||
p: pointer | ||
len: int | ||
|
||
proc `=destroy`(o: var TMyObj) = | ||
if o.p != nil: | ||
dealloc o.p | ||
o.p = nil | ||
echo "myobj destroyed" | ||
|
||
proc `=copy`(dst: var TMyObj, src: TMyObj) = | ||
`=destroy`(dst) | ||
dst.p = alloc(src.len) | ||
dst.len = src.len | ||
|
||
proc `=sink`(dst: var TMyObj, src: TMyObj) = | ||
`=destroy`(dst) | ||
dst.p = src.p | ||
dst.len = src.len | ||
|
||
type | ||
TObjKind = enum Z, A, B | ||
TCaseObj = object | ||
case kind: TObjKind | ||
of Z: discard | ||
of A: | ||
x1: int # this int plays important role | ||
x2: TMyObj | ||
of B: | ||
y: TMyObj | ||
|
||
proc testSinks: TCaseObj = | ||
result = TCaseObj(kind: A, x1: 5000, x2: TMyObj(len: 5, p: alloc(5))) | ||
result = TCaseObj(kind: B, y: TMyObj(len: 3, p: alloc(3))) | ||
|
||
proc use(x: TCaseObj) = discard | ||
|
||
proc testCopies(i: int) = | ||
var a: array[2, TCaseObj] | ||
a[i] = TCaseObj(kind: A, x1: 5000, x2: TMyObj(len: 5, p: alloc(5))) | ||
a[i+1] = a[i] # copy, cannot move | ||
use(a[i]) | ||
|
||
let x1 = testSinks() | ||
testCopies(0) | ||
|
||
# bug #12957 | ||
|
||
type | ||
PegKind* = enum | ||
pkCharChoice, | ||
pkSequence | ||
Peg* = object ## type that represents a PEG | ||
case kind: PegKind | ||
of pkCharChoice: charChoice: ref set[char] | ||
else: discard | ||
sons: seq[Peg] | ||
|
||
proc charSet*(s: set[char]): Peg = | ||
## constructs a PEG from a character set `s` | ||
result = Peg(kind: pkCharChoice) | ||
new(result.charChoice) | ||
result.charChoice[] = s | ||
|
||
proc len(a: Peg): int {.inline.} = return a.sons.len | ||
proc myadd(d: var Peg, s: Peg) {.inline.} = add(d.sons, s) | ||
|
||
proc sequence*(a: openArray[Peg]): Peg = | ||
result = Peg(kind: pkSequence, sons: @[]) | ||
when false: | ||
#works too: | ||
result.myadd(a[0]) | ||
result.myadd(a[1]) | ||
for x in items(a): | ||
# works: | ||
#result.sons.add(x) | ||
# fails: | ||
result.myadd x | ||
if result.len == 1: | ||
result = result.sons[0] # this must not move! | ||
|
||
when true: | ||
# bug #12957 | ||
|
||
proc p = | ||
echo "A" | ||
let x = sequence([charSet({'a'..'z', 'A'..'Z', '_'}), | ||
charSet({'a'..'z', 'A'..'Z', '0'..'9', '_'})]) | ||
echo "B" | ||
p() | ||
|
||
proc testSubObjAssignment = | ||
echo "begin" | ||
# There must be extactly one element in the array constructor! | ||
let x = sequence([charSet({'a'..'z', 'A'..'Z', '_'})]) | ||
echo "end" | ||
testSubObjAssignment() | ||
|
||
|
||
#------------------------------------------------ | ||
|
||
type | ||
MyObject = object | ||
x1: string | ||
case kind1: bool | ||
of false: y1: string | ||
of true: | ||
y2: seq[string] | ||
case kind2: bool | ||
of true: z1: string | ||
of false: | ||
z2: seq[string] | ||
flag: bool | ||
x2: string | ||
|
||
proc test_myobject = | ||
var x: MyObject | ||
x.x1 = "x1" | ||
x.x2 = "x2" | ||
x.y1 = "ljhkjhkjh" | ||
x.kind1 = true | ||
x.y2 = @["1", "2"] | ||
x.kind2 = true | ||
x.z1 = "yes" | ||
x.kind2 = false | ||
x.z2 = @["1", "2"] | ||
x.kind2 = true | ||
x.z1 = "yes" | ||
x.kind2 = true # should be no effect | ||
doAssert(x.z1 == "yes") | ||
x.kind2 = false | ||
x.kind1 = x.kind2 # support self assignment with effect | ||
|
||
try: | ||
x.kind1 = x.flag # flag is not accesible | ||
except FieldDefect: | ||
echo "prevented" | ||
|
||
doAssert(x.x1 == "x1") | ||
doAssert(x.x2 == "x2") | ||
|
||
|
||
test_myobject() | ||
|
||
|
||
#------------------------------------------------ | ||
# bug #14244 | ||
|
||
type | ||
RocksDBResult*[T] = object | ||
case ok*: bool | ||
of true: | ||
value*: T | ||
else: | ||
error*: string | ||
|
||
proc init(): RocksDBResult[string] = | ||
result.ok = true | ||
result.value = "ok" | ||
|
||
echo init() | ||
|
||
|
||
#------------------------------------------------ | ||
# bug #14312 | ||
|
||
type MyObj = object | ||
case kind: bool | ||
of false: x0: int # would work with a type like seq[int]; value would be reset | ||
of true: x1: string | ||
|
||
var a = MyObj(kind: false, x0: 1234) | ||
a.kind = true | ||
doAssert(a.x1 == "") | ||
|
||
block: | ||
# bug #15532 | ||
type Kind = enum | ||
k0, k1 | ||
|
||
type Foo = object | ||
y: int | ||
case kind: Kind | ||
of k0: x0: int | ||
of k1: x1: int | ||
|
||
const j0 = Foo(y: 1, kind: k0, x0: 2) | ||
const j1 = Foo(y: 1, kind: k1, x1: 2) | ||
|
||
doAssert j0.y == 1 | ||
doAssert j0.kind == k0 | ||
doAssert j1.kind == k1 | ||
|
||
doAssert j1.x1 == 2 | ||
doAssert j0.x0 == 2 |
Oops, something went wrong.