Skip to content

Commit 73112d6

Browse files
authored
fixes #24793; Revert "remove special treatments of sinking const sequences (#24812)
fixes #24793 There doesn't seem to have a better solution
1 parent b82d7e8 commit 73112d6

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

compiler/injectdestructors.nim

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,25 @@ proc passCopyToSink(n: PNode; c: var Con; s: var Scope): PNode =
493493
# no need to destroy it.
494494
result.add tmp
495495

496+
proc isDangerousSeq(t: PType): bool {.inline.} =
497+
let t = t.skipTypes(abstractInst)
498+
result = t.kind == tySequence and tfHasOwned notin t.elementType.flags
499+
500+
proc containsConstSeq(n: PNode): bool =
501+
if n.kind == nkBracket and n.len > 0 and n.typ != nil and isDangerousSeq(n.typ):
502+
return true
503+
result = false
504+
case n.kind
505+
of nkExprEqExpr, nkExprColonExpr, nkHiddenStdConv, nkHiddenSubConv, nkCast:
506+
result = containsConstSeq(n[1])
507+
of nkObjConstr, nkClosure:
508+
for i in 1..<n.len:
509+
if containsConstSeq(n[i]): return true
510+
of nkCurly, nkBracket, nkPar, nkTupleConstr:
511+
for son in n:
512+
if containsConstSeq(son): return true
513+
else: discard
514+
496515
proc ensureDestruction(arg, orig: PNode; c: var Con; s: var Scope): PNode =
497516
# it can happen that we need to destroy expression contructors
498517
# like [], (), closures explicitly in order to not leak them.
@@ -776,7 +795,12 @@ proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode; tmpFlags = {sfSing
776795
template process(child, s): untyped = p(child, c, s, mode)
777796
handleNestedTempl(n, process, tmpFlags = tmpFlags)
778797
elif mode == sinkArg:
779-
if n.kind in {nkBracket, nkObjConstr, nkTupleConstr, nkClosure, nkNilLit} +
798+
if n.containsConstSeq:
799+
# const sequences are not mutable and so we need to pass a copy to the
800+
# sink parameter (bug #11524). Note that the string implementation is
801+
# different and can deal with 'const string sunk into var'.
802+
result = passCopyToSink(n, c, s)
803+
elif n.kind in {nkBracket, nkObjConstr, nkTupleConstr, nkClosure, nkNilLit} +
780804
nkCallKinds + nkLiterals:
781805
result = p(n, c, s, consumed)
782806
elif ((n.kind == nkSym and isSinkParam(n.sym)) or isAnalysableFieldAccess(n, c.owner)) and
@@ -1143,7 +1167,17 @@ proc moveOrCopy(dest, ri: PNode; c: var Con; s: var Scope, flags: set[MoveOrCopy
11431167
dec c.inEnsureMove, isEnsureMove
11441168
result.add p(ri, c, s, consumed)
11451169
c.finishCopy(result, dest, flags, isFromSink = false)
1146-
of nkBracket, nkObjConstr, nkTupleConstr, nkClosure, nkCharLit..nkNilLit:
1170+
of nkBracket:
1171+
# array constructor
1172+
if ri.len > 0 and isDangerousSeq(ri.typ):
1173+
inc c.inEnsureMove, isEnsureMove
1174+
result = c.genCopy(dest, ri, flags)
1175+
dec c.inEnsureMove, isEnsureMove
1176+
result.add p(ri, c, s, consumed)
1177+
c.finishCopy(result, dest, flags, isFromSink = false)
1178+
else:
1179+
result = c.genSink(s, dest, p(ri, c, s, consumed), flags)
1180+
of nkObjConstr, nkTupleConstr, nkClosure, nkCharLit..nkNilLit:
11471181
result = c.genSink(s, dest, p(ri, c, s, consumed), flags)
11481182
of nkSym:
11491183
if isSinkParam(ri.sym) and isLastRead(ri, c, s):

tests/objects/tobject_default_value.nim

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -811,3 +811,11 @@ template main {.dirty.} =
811811

812812
static: main()
813813
main()
814+
815+
block:
816+
type
817+
MyTyp = ref object
818+
thing = initTable[string,string]()
819+
820+
var t = MyTyp()
821+
t.thing[""] = ""

0 commit comments

Comments
 (0)