Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixes #12989 #12992

Merged
merged 6 commits into from
Dec 31, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions compiler/injectdestructors.nim
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,10 @@ proc initialized(code: ControlFlowGraph; pc: int,
inc pc
return pc

template isUnpackedTuple(s: PSym): bool =
template isUnpackedTuple(n: PNode): bool =
## we move out all elements of unpacked tuples,
## hence unpacked tuples themselves don't need to be destroyed
s.kind == skTemp and s.typ.kind == tyTuple
n.kind == nkSym and n.sym.kind == skTemp and n.sym.typ.kind == tyTuple

proc checkForErrorPragma(c: Con; t: PType; ri: PNode; opname: string) =
var m = "'" & opname & "' is not available for type <" & typeToString(t) & ">"
Expand Down Expand Up @@ -542,7 +542,7 @@ proc p(n: PNode; c: var Con; mode: ProcessMode): PNode =
# move the variable declaration to the top of the frame:
c.addTopVar v
# make sure it's destroyed at the end of the proc:
if not isUnpackedTuple(it[0].sym):
if not isUnpackedTuple(v):
c.destroys.add genDestroy(c, v)
if ri.kind == nkEmpty and c.inLoop > 0:
ri = genDefaultCall(v.typ, c, v.info)
Expand Down Expand Up @@ -612,10 +612,13 @@ proc p(n: PNode; c: var Con; mode: ProcessMode): PNode =
proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
case ri.kind
of nkCallKinds:
result = genSink(c, dest, ri)
result.add p(ri, c, consumed)
if isUnpackedTuple(dest):
result = newTree(nkFastAsgn, dest, p(ri, c, consumed))
else:
result = genSink(c, dest, ri)
result.add p(ri, c, consumed)
of nkBracketExpr:
if ri[0].kind == nkSym and isUnpackedTuple(ri[0].sym):
if isUnpackedTuple(ri[0]):
# unpacking of tuple: move out the elements
result = genSink(c, dest, ri)
result.add p(ri, c, consumed)
Expand Down
1 change: 0 additions & 1 deletion compiler/lowerings.nim
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ proc lowerTupleUnpacking*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
var temp = newSym(skTemp, getIdent(g.cache, genPrefix), owner, value.info, g.config.options)
temp.typ = skipTypes(value.typ, abstractInst)
incl(temp.flags, sfFromGeneric)
incl(temp.flags, sfCursor)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awww, still not correct? :-)

Copy link
Member Author

@cooldome cooldome Dec 31, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, it can't be correct because following counter example can't work if every unpacked tuple is a cursor:

proc xx(arg: tuple[XX]) = 
  let (x, y) = arg   # arg needs to be copied here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bad example, but fair enough.


var v = newNodeI(nkVarSection, value.info)
let tempAsNode = newSymNode(temp)
Expand Down
9 changes: 9 additions & 0 deletions tests/destructor/t12037.nim
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,12 @@ test()
import tables
var t = initTable[string, seq[ptr int]]()
discard t.hasKeyOrPut("f1", @[])


#############################################
### bug #12989
proc bug(start: (seq[int], int)) =
let (s, i) = start

let input = @[0]
bug((input, 0))