mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-17 16:38:33 +00:00
fixes #22664
This commit is contained in:
@@ -553,6 +553,14 @@ proc forallElements(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
else:
|
||||
body.sons.setLen counterIdx
|
||||
|
||||
proc checkSelfAssignment(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
var cond = callCodegenProc(c.g, "sameSeqPayload", c.info,
|
||||
newTreeIT(nkAddr, c.info, makePtrType(c.fn, x.typ, c.idgen), x),
|
||||
newTreeIT(nkAddr, c.info, makePtrType(c.fn, y.typ, c.idgen), y)
|
||||
)
|
||||
cond.typ = getSysType(c.g, c.info, tyBool)
|
||||
body.add genIf(c, cond, newTreeI(nkReturnStmt, c.info, newNodeI(nkEmpty, c.info)))
|
||||
|
||||
proc fillSeqOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
case c.kind
|
||||
of attachedDup:
|
||||
@@ -560,10 +568,13 @@ proc fillSeqOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
forallElements(c, t, body, x, y)
|
||||
of attachedAsgn, attachedDeepCopy:
|
||||
# we generate:
|
||||
# if x.p == y.p:
|
||||
# return
|
||||
# setLen(dest, y.len)
|
||||
# var i = 0
|
||||
# while i < y.len: dest[i] = y[i]; inc(i)
|
||||
# This is usually more efficient than a destroy/create pair.
|
||||
checkSelfAssignment(c, t, body, x, y)
|
||||
body.add setLenSeqCall(c, t, x, y)
|
||||
forallElements(c, t, body, x, y)
|
||||
of attachedSink:
|
||||
|
||||
@@ -32,6 +32,10 @@ type
|
||||
len: int
|
||||
p: ptr NimSeqPayload[T]
|
||||
|
||||
NimRawSeq = object
|
||||
len: int
|
||||
p: pointer
|
||||
|
||||
const nimSeqVersion {.core.} = 2
|
||||
|
||||
# XXX make code memory safe for overflows in '*'
|
||||
@@ -139,6 +143,8 @@ proc newSeq[T](s: var seq[T], len: Natural) =
|
||||
shrink(s, 0)
|
||||
setLen(s, len)
|
||||
|
||||
proc sameSeqPayload(x: pointer, y: pointer): bool {.compilerproc, inline.} =
|
||||
result = cast[ptr NimRawSeq](x)[].p == cast[ptr NimRawSeq](y)[].p
|
||||
|
||||
template capacityImpl(sek: NimSeqV2): int =
|
||||
if sek.p != nil: (sek.p.cap and not strlitFlag) else: 0
|
||||
|
||||
@@ -614,3 +614,24 @@ method process*(self: App): Option[Event] {.base.} =
|
||||
type Test2 = ref object of RootObj
|
||||
|
||||
method bug(t: Test2): seq[float] {.base.} = discard
|
||||
|
||||
block: # bug #22664
|
||||
type
|
||||
ElementKind = enum String, Number
|
||||
Element = object
|
||||
case kind: ElementKind
|
||||
of String:
|
||||
str: string
|
||||
of Number:
|
||||
num: float
|
||||
Calc = ref object
|
||||
stack: seq[Element]
|
||||
|
||||
var calc = new Calc
|
||||
|
||||
calc.stack.add Element(kind: Number, num: 200.0)
|
||||
doAssert $calc.stack == "@[(kind: Number, num: 200.0)]"
|
||||
let calc2 = calc
|
||||
calc2.stack = calc.stack # This nulls out the object in the stack
|
||||
doAssert $calc.stack == "@[(kind: Number, num: 200.0)]"
|
||||
doAssert $calc2.stack == "@[(kind: Number, num: 200.0)]"
|
||||
|
||||
Reference in New Issue
Block a user