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 all 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
18 changes: 10 additions & 8 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,13 +612,15 @@ 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)
of nkBracketExpr:
if ri[0].kind == nkSym and isUnpackedTuple(ri[0].sym):
# unpacking of tuple: move out the elements
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 isUnpackedTuple(ri[0]):
# unpacking of tuple: take over elements
result = newTree(nkFastAsgn, dest, p(ri, c, consumed))
elif isAnalysableFieldAccess(ri, c.owner) and isLastRead(ri, c):
# Rule 3: `=sink`(x, z); wasMoved(z)
var snk = genSink(c, dest, ri)
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))
2 changes: 1 addition & 1 deletion tests/destructor/tmisc_destructors.nim
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ proc test(): auto =
var (a, b, _) = test()

doAssert assign_counter == 0
doAssert sink_counter == 9 # XXX this is still silly and needs to be investigated
doAssert sink_counter == 6

# bug #11510
proc main =
Expand Down