Skip to content

Commit

Permalink
fixes #22923; fixes =dup issues (#23182)
Browse files Browse the repository at this point in the history
fixes #22923

(cherry picked from commit 29ac3c9)
  • Loading branch information
ringabout authored and narimiran committed Apr 20, 2024
1 parent 7673514 commit fbb9ce4
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 2 deletions.
2 changes: 2 additions & 0 deletions compiler/ccgexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2642,6 +2642,8 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
of mTrace: discard "no code to generate"
of mEnsureMove:
expr(p, e[1], d)
of mDup:
expr(p, e[1], d)
else:
when defined(debugMagics):
echo p.prc.name.s, " ", p.prc.id, " ", p.prc.flags, " ", p.prc.ast[genericParamsPos].kind
Expand Down
10 changes: 9 additions & 1 deletion compiler/liftdestructors.nim
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ proc boolLit*(g: ModuleGraph; info: TLineInfo; value: bool): PNode =

proc getCycleParam(c: TLiftCtx): PNode =
assert c.kind in {attachedAsgn, attachedDup}
if c.fn.typ.len == 4:
if c.fn.typ.len == 3 + ord(c.kind == attachedAsgn):
result = c.fn.typ.n.lastSon
assert result.kind == nkSym
assert result.sym.name.s == "cyclic"
Expand Down Expand Up @@ -322,6 +322,14 @@ proc newOpCall(c: var TLiftCtx; op: PSym; x: PNode): PNode =
if sfNeverRaises notin op.flags:
c.canRaise = true

if c.kind == attachedDup and op.typ.len == 3:
assert x != nil
if c.fn.typ.len == 3:
result.add getCycleParam(c)
else:
# assume the worst: A cycle is created:
result.add boolLit(c.g, x.info, true)

proc newDeepCopyCall(c: var TLiftCtx; op: PSym; x, y: PNode): PNode =
result = newAsgnStmt(x, newOpCall(c, op, y))

Expand Down
10 changes: 10 additions & 0 deletions compiler/semmagic.nim
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,16 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
let op = getAttachedOp(c.graph, t, attachedTrace)
if op != nil:
result[0] = newSymNode(op)
of mDup:
result = n
let t = n[1].typ.skipTypes(abstractVar)
let op = getAttachedOp(c.graph, t, attachedDup)
if op != nil:
result[0] = newSymNode(op)
if op.typ.len == 3:
let boolLit = newIntLit(c.graph, n.info, 1)
boolLit.typ = getSysType(c.graph, n.info, tyBool)
result.add boolLit
of mWasMoved:
result = n
let t = n[1].typ.skipTypes(abstractVar)
Expand Down
3 changes: 2 additions & 1 deletion lib/system.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2829,4 +2829,5 @@ proc arrayWith*[T](y: T, size: static int): array[size, T] {.raises: [].} =
when nimvm:
result[i] = y
else:
result[i] = `=dup`(y)
{.cast(raises: []).}: # TODO: fixme bug #23129
result[i] = `=dup`(y)
26 changes: 26 additions & 0 deletions tests/arc/tarcmisc.nim
Original file line number Diff line number Diff line change
Expand Up @@ -688,3 +688,29 @@ block: # bug #22259
f(wrapper)

main()

block:
block: # bug #22923
block:
let
a: int = 100
b: int32 = 200'i32

let
x = arrayWith(a, 8) # compiles
y = arrayWith(b, 8) # internal error
z = arrayWith(14, 8) # integer literal also results in a crash

doAssert x == [100, 100, 100, 100, 100, 100, 100, 100]
doAssert $y == "[200, 200, 200, 200, 200, 200, 200, 200]"
doAssert z == [14, 14, 14, 14, 14, 14, 14, 14]

block:
let a: string = "nim"
doAssert arrayWith(a, 3) == ["nim", "nim", "nim"]

let b: char = 'c'
doAssert arrayWith(b, 3) == ['c', 'c', 'c']

let c: uint = 300'u
doAssert $arrayWith(c, 3) == "[300, 300, 300]"

0 comments on commit fbb9ce4

Please sign in to comment.