diff options
author | Araq <rumpf_a@web.de> | 2019-04-25 13:54:04 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2019-04-25 13:54:04 +0200 |
commit | a36d8bbf6c493e30df45bbb0a17fd793e7c1f12e (patch) | |
tree | 1043223235a88fddff45e8178d702d61185d8e24 | |
parent | eb9043c0e9f835cb42b83d3a954058cdde01a72b (diff) | |
download | Nim-a36d8bbf6c493e30df45bbb0a17fd793e7c1f12e.tar.gz |
introduce a special typing rule that makes seq[owned ref T] easier to use; remains to be investigated...
-rw-r--r-- | compiler/injectdestructors.nim | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index 5958d89ae..73ff0869c 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -419,6 +419,15 @@ 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: + 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) @@ -452,7 +461,7 @@ proc pArg(arg: PNode; c: var Con; isSink: bool): PNode = let L = if parameters != nil: parameters.len else: 0 result.add arg[0] for i in 1..<arg.len: - result.add pArg(arg[i], c, i < L and isSinkType(parameters[i])) + result.add pArg(arg[i], c, i < L and isSinkTypeForParam(parameters[i])) elif arg.kind in {nkBracket, nkObjConstr, nkTupleConstr, nkBracket, nkCharLit..nkTripleStrLit}: discard "object construction to sink parameter: nothing to do" result = arg @@ -529,7 +538,7 @@ proc moveOrCopy(dest, ri: PNode; c: var Con): PNode = let L = if parameters != nil: parameters.len else: 0 ri2.add ri[0] for i in 1..<ri.len: - ri2.add pArg(ri[i], c, i < L and isSinkType(parameters[i])) + ri2.add pArg(ri[i], c, i < L and isSinkTypeForParam(parameters[i])) #recurse(ri, ri2) result.add ri2 of nkBracketExpr: @@ -730,7 +739,7 @@ proc p(n: PNode; c: var Con): PNode = let parameters = n[0].typ let L = if parameters != nil: parameters.len else: 0 for i in 1 ..< n.len: - n.sons[i] = pArg(n[i], c, i < L and isSinkType(parameters[i])) + n.sons[i] = pArg(n[i], c, i < L and isSinkTypeForParam(parameters[i])) if n.typ != nil and hasDestructor(n.typ): discard "produce temp creation" result = newNodeIT(nkStmtListExpr, n.info, n.typ) |