diff options
author | Araq <rumpf_a@web.de> | 2019-08-12 13:58:35 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2019-08-12 13:58:35 +0200 |
commit | 289b5e9ef93cd350e75f4d90d264e56df64c5a8d (patch) | |
tree | 21f47f7c927cb3e9cde69cdd4e52c39c81cc99a5 /compiler | |
parent | c9c28bf85ee428e710a510a9825e514d30b0e298 (diff) | |
download | Nim-289b5e9ef93cd350e75f4d90d264e56df64c5a8d.tar.gz |
fixes #11254
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/injectdestructors.nim | 11 | ||||
-rw-r--r-- | compiler/sempass2.nim | 10 | ||||
-rw-r--r-- | compiler/types.nim | 11 |
3 files changed, 20 insertions, 12 deletions
diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index 6f1da37fb..4f96d236f 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -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) diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 8252a7857..c31f86f98 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -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 diff --git a/compiler/types.nim b/compiler/types.nim index fcf21fc54..11006de30 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -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 |