fixes #11254
This commit is contained in:
parent
c9c28bf85e
commit
289b5e9ef9
4 changed files with 26 additions and 12 deletions
|
|
@ -437,17 +437,6 @@ proc sinkParamIsLastReadCheck(c: var Con, s: PNode) =
|
||||||
localError(c.graph.config, c.otherRead.info, "sink parameter `" & $s.sym.name.s &
|
localError(c.graph.config, c.otherRead.info, "sink parameter `" & $s.sym.name.s &
|
||||||
"` is already consumed at " & toFileLineCol(c. graph.config, s.info))
|
"` 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 =
|
proc passCopyToSink(n: PNode; c: var Con): PNode =
|
||||||
result = newNodeIT(nkStmtListExpr, n.info, n.typ)
|
result = newNodeIT(nkStmtListExpr, n.info, n.typ)
|
||||||
let tmp = getTemp(c, n.typ, n.info)
|
let tmp = getTemp(c, n.typ, n.info)
|
||||||
|
|
|
||||||
|
|
@ -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.
|
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.
|
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
|
var t: TEffects
|
||||||
initEffects(g, effects, s, t, c)
|
initEffects(g, effects, s, t, c)
|
||||||
track(t, body)
|
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
|
if not isEmptyType(s.typ.sons[0]) and
|
||||||
({tfNeedsInit, tfNotNil} * s.typ.sons[0].flags != {} or
|
({tfNeedsInit, tfNotNil} * s.typ.sons[0].flags != {} or
|
||||||
s.typ.sons[0].skipTypes(abstractInst).kind == tyVar) and
|
s.typ.sons[0].skipTypes(abstractInst).kind == tyVar) and
|
||||||
|
|
|
||||||
|
|
@ -1600,3 +1600,14 @@ proc isException*(t: PType): bool =
|
||||||
if t.sons[0] == nil: break
|
if t.sons[0] == nil: break
|
||||||
t = skipTypes(t.sons[0], abstractPtrs)
|
t = skipTypes(t.sons[0], abstractPtrs)
|
||||||
return false
|
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
|
||||||
|
|
|
||||||
|
|
@ -52,5 +52,11 @@ type
|
||||||
x*: int
|
x*: int
|
||||||
var t: MyType
|
var t: MyType
|
||||||
|
|
||||||
|
# bug #11254
|
||||||
|
proc test(p: owned proc()) =
|
||||||
|
let x = (proc())p
|
||||||
|
|
||||||
|
test(proc() = discard)
|
||||||
|
|
||||||
let (a, d) = allocCounters()
|
let (a, d) = allocCounters()
|
||||||
discard cprintf("%ld new: %ld\n", a - unpairedEnvAllocs() - d, allocs)
|
discard cprintf("%ld new: %ld\n", a - unpairedEnvAllocs() - d, allocs)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue