Files
Nim/tests/arc/topt_no_cursor.nim
ringabout 379299a5ac fixes #22286; enforce Non-var T destructors by nimPreviewNonVarDestructor (#22975)
fixes #22286
ref https://forum.nim-lang.org/t/10642

For backwards compatibilities, we might need to keep the changes under a
preview compiler flag. Let's see how many packags it break.

**TODO** in the following PRs

- [ ] Turn the `var T` destructors warning into an error with
`nimPreviewNonVarDestructor`

---------

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
2023-11-25 18:27:27 +01:00

377 lines
7.6 KiB
Nim

discard """
nimoutFull: true
cmd: '''nim c -r --warnings:off --hints:off --mm:arc --expandArc:newTarget --expandArc:delete --expandArc:p1 --expandArc:tt --hint:Performance:off --assertions:off --expandArc:extractConfig --expandArc:mergeShadowScope --expandArc:check $file'''
nimout: '''
--expandArc: newTarget
var
splat
:tmp
:tmp_1
splat = splitDrive do:
let blitTmp = path
blitTmp
:tmp = splat.drive
`=wasMoved`(splat.drive)
:tmp_1 = splat.path_1
`=wasMoved`(splat.path_1)
result = (
let blitTmp_1 = :tmp
blitTmp_1,
let blitTmp_2 = :tmp_1
blitTmp_2)
`=destroy`(splat)
-- end of expandArc ------------------------
--expandArc: delete
var
sibling
saved
`=copy`(sibling, target.parent.left)
`=copy`(saved, sibling.right)
`=copy`(sibling.right, saved.left)
`=sink`(sibling.parent, saved)
`=destroy`(sibling)
-- end of expandArc ------------------------
--expandArc: p1
var
lresult
lvalue
lnext
tmpTupleAsgn
lresult = @[123]
tmpTupleAsgn = (
let blitTmp = lresult
blitTmp, ";")
lvalue = tmpTupleAsgn[0]
lnext = tmpTupleAsgn[1]
`=sink`(result.value, move lvalue)
`=destroy`(lnext)
`=destroy_1`(lvalue)
-- end of expandArc ------------------------
--expandArc: tt
var
it_cursor
a
:tmpD
:tmpD_1
:tmpD_2
try:
it_cursor = x
a = (
:tmpD = `=dup`(it_cursor.key)
:tmpD,
:tmpD_1 = `=dup`(it_cursor.val)
:tmpD_1)
echo [
:tmpD_2 = `$$`(a)
:tmpD_2]
finally:
`=destroy`(:tmpD_2)
`=destroy_1`(a)
-- end of expandArc ------------------------
--expandArc: extractConfig
var lan_ip
try:
lan_ip = ""
block :tmp:
var line
var i = 0
let L = len(txt)
block :tmp_1:
while i < L:
var splitted
try:
line = txt[i]
splitted = split(line, " ", -1)
if splitted[0] == "opt":
`=copy`(lan_ip, splitted[1])
echo [lan_ip]
echo [splitted[1]]
{.push, overflowChecks: false.}
inc(i, 1)
{.pop.}
finally:
`=destroy`(splitted)
finally:
`=destroy_1`(lan_ip)
-- end of expandArc ------------------------
--expandArc: mergeShadowScope
var shadowScope
`=copy`(shadowScope, c.currentScope)
rawCloseScope(c)
block :tmp:
var sym
var i = 0
let L = len(shadowScope.symbols)
block :tmp_1:
while i < L:
var :tmpD
sym = shadowScope.symbols[i]
addInterfaceDecl(c):
:tmpD = `=dup`(sym)
:tmpD
{.push, overflowChecks: false.}
inc(i, 1)
{.pop.}
`=destroy`(shadowScope)
-- end of expandArc ------------------------
--expandArc: check
var par
this.isValid = fileExists(this.value)
if dirExists(this.value):
var :tmpD
par = (dir:
:tmpD = `=dup`(this.value)
:tmpD, front: "") else:
var
:tmpD_1
:tmpD_2
:tmpD_3
par = (dir_1: parentDir(this.value), front_1:
:tmpD_1 = `=dup`(
:tmpD_3 = splitDrive do:
:tmpD_2 = `=dup`(this.value)
:tmpD_2
:tmpD_3.path)
:tmpD_1)
`=destroy`(:tmpD_3)
if dirExists(par.dir):
`=sink`(this.matchDirs, getSubDirs(par.dir, par.front))
else:
`=sink`(this.matchDirs, [])
`=destroy`(par)
-- end of expandArc ------------------------
--expandArc: check
check(this)
-- end of expandArc ------------------------
(package: "", ext: "meo")
doing shady stuff...
3
6
(@[1], @[2])
192.168.0.1
192.168.0.1
192.168.0.1
192.168.0.1
'''
"""
import os, std/private/ntpath
type Target = tuple[package, ext: string]
proc newTarget*(path: string): Target =
let splat = path.splitDrive
result = (package: splat.drive, ext: splat.path)
echo newTarget("meo")
type
Node = ref object
left, right, parent: Node
value: int
proc delete(target: var Node) =
var sibling = target.parent.left # b3
var saved = sibling.right # b3.right -> r4
sibling.right = saved.left # b3.right -> r4.left = nil
sibling.parent = saved # b3.parent -> r5 = r4
#[after this proc:
b 5
/ \
b 3 b 6
]#
#[before:
r 5
/ \
b 3 b 6 - to delete
/ \
empty r 4
]#
proc main =
var five = Node(value: 5)
var six = Node(value: 6)
six.parent = five
five.right = six
var three = Node(value: 3)
three.parent = five
five.left = three
var four = Node(value: 4)
four.parent = three
three.right = four
echo "doing shady stuff..."
delete(six)
# need both of these echos
echo five.left.value
echo five.right.value
main()
type
Maybe = object
value: seq[int]
proc p1(): Maybe =
let lresult = @[123]
var lvalue: seq[int]
var lnext: string
(lvalue, lnext) = (lresult, ";")
result.value = move lvalue
proc tissue15130 =
doAssert p1().value == @[123]
tissue15130()
type
KeyValue = tuple[key, val: seq[int]]
proc tt(x: KeyValue) =
var it = x
let a = (it.key, it.val)
echo a
proc encodedQuery =
var query: seq[KeyValue]
query.add (key: @[1], val: @[2])
for elem in query:
elem.tt()
encodedQuery()
# bug #15147
proc s(input: string): (string, string) =
result = (";", "")
proc charmatch(input: string): (string, string) =
result = ("123", input[0 .. input.high])
proc plus(input: string) =
var
lvalue, rvalue: string # cursors
lnext: string # must be cursor!!!
rnext: string # cursor
let lresult = charmatch(input)
(lvalue, lnext) = lresult
let rresult = s(lnext)
(rvalue, rnext) = rresult
plus("123;")
func substrEq(s: string, pos: int, substr: string): bool =
var i = 0
var length = substr.len
while i < length and pos+i < s.len and s[pos+i] == substr[i]:
inc i
return i == length
template stringHasSep(s: string, index: int, sep: string): bool =
s.substrEq(index, sep)
template splitCommon(s, sep, maxsplit, sepLen) =
var last = 0
var splits = maxsplit
while last <= len(s):
var first = last
while last < len(s) and not stringHasSep(s, last, sep):
inc(last)
if splits == 0: last = len(s)
yield substr(s, first, last-1)
if splits == 0: break
dec(splits)
inc(last, sepLen)
iterator split(s: string, sep: string, maxsplit = -1): string =
splitCommon(s, sep, maxsplit, sep.len)
template accResult(iter: untyped) =
result = @[]
for x in iter: add(result, x)
func split*(s: string, sep: string, maxsplit = -1): seq[string] =
accResult(split(s, sep, maxsplit))
let txt = @["opt 192.168.0.1", "static_lease 192.168.0.1"]
# bug #17033
proc extractConfig() =
var lan_ip = ""
for line in txt:
let splitted = line.split(" ")
if splitted[0] == "opt":
lan_ip = splitted[1] # "borrow" is conditional and inside a loop.
# Not good enough...
# we need a flag that live-ranges are disjoint
echo lan_ip
echo splitted[1] # Without this line everything works
extractConfig()
type
Symbol = ref object
name: string
Scope = ref object
parent: Scope
symbols: seq[Symbol]
PContext = ref object
currentScope: Scope
proc rawCloseScope(c: PContext) =
c.currentScope = c.currentScope.parent
proc addInterfaceDecl(c: PContext; s: Symbol) =
c.currentScope.symbols.add s
proc mergeShadowScope*(c: PContext) =
let shadowScope = c.currentScope
c.rawCloseScope
for sym in shadowScope.symbols:
c.addInterfaceDecl(sym)
mergeShadowScope(PContext(currentScope: Scope(parent: Scope())))
type
Foo = ref object
isValid*: bool
value*: string
matchDirs*: seq[string]
proc getSubDirs(parent, front: string): seq[string] = @[]
method check(this: Foo) {.base.} =
this.isValid = fileExists(this.value)
let par = if dirExists(this.value): (dir: this.value, front: "")
else: (dir: parentDir(this.value), front: splitDrive(this.value).path)
if dirExists(par.dir):
this.matchDirs = getSubDirs(par.dir, par.front)
else:
this.matchDirs = @[]
check(Foo())