This commit is contained in:
Araq
2019-08-12 13:58:35 +02:00
parent c9c28bf85e
commit 289b5e9ef9
4 changed files with 26 additions and 12 deletions

View File

@@ -437,17 +437,6 @@ proc sinkParamIsLastReadCheck(c: var Con, s: PNode) =
localError(c.graph.config, c.otherRead.info, "sink parameter `" & $s.sym.name.s &
"` is already consumed at " & toFileLineCol(c. graph.config, s.info))
proc isSinkTypeForParam(t: PType): bool =
# a parameter like 'seq[owned T]' must not be used only once, but its
# elements must, so we detect this case here:
result = t.skipTypes({tyGenericInst, tyAlias}).kind in {tySink, tyOwned}
when false:
if isSinkType(t):
if t.skipTypes({tyGenericInst, tyAlias}).kind in {tyArray, tyVarargs, tyOpenArray, tySequence}:
result = false
else:
result = true
proc passCopyToSink(n: PNode; c: var Con): PNode =
result = newNodeIT(nkStmtListExpr, n.info, n.typ)
let tmp = getTemp(c, n.typ, n.info)

View File

@@ -34,7 +34,7 @@ In the construct let/var x = expr() x's type is marked.
In x = y the type of x is marked.
For every sink parameter of type T T is marked. TODO!
For every sink parameter of type T T is marked.
For every call f() the return type of f() is marked.
@@ -977,6 +977,14 @@ proc trackProc*(c: PContext; s: PSym, body: PNode) =
var t: TEffects
initEffects(g, effects, s, t, c)
track(t, body)
if s.kind != skMacro:
let params = s.typ.n
for i in 1 ..< params.len:
let param = params[i].sym
if isSinkTypeForParam(param.typ):
createTypeBoundOps(t.graph, t.c, param.typ, param.info)
if not isEmptyType(s.typ.sons[0]) and
({tfNeedsInit, tfNotNil} * s.typ.sons[0].flags != {} or
s.typ.sons[0].skipTypes(abstractInst).kind == tyVar) and

View File

@@ -1600,3 +1600,14 @@ proc isException*(t: PType): bool =
if t.sons[0] == nil: break
t = skipTypes(t.sons[0], abstractPtrs)
return false
proc isSinkTypeForParam*(t: PType): bool =
# a parameter like 'seq[owned T]' must not be used only once, but its
# elements must, so we detect this case here:
result = t.skipTypes({tyGenericInst, tyAlias}).kind in {tySink, tyOwned}
when false:
if isSinkType(t):
if t.skipTypes({tyGenericInst, tyAlias}).kind in {tyArray, tyVarargs, tyOpenArray, tySequence}:
result = false
else:
result = true

View File

@@ -52,5 +52,11 @@ type
x*: int
var t: MyType
# bug #11254
proc test(p: owned proc()) =
let x = (proc())p
test(proc() = discard)
let (a, d) = allocCounters()
discard cprintf("%ld new: %ld\n", a - unpairedEnvAllocs() - d, allocs)