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

fix #22218 copy generated for non-copyable type #22447

Closed
wants to merge 1 commit into from
Closed
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
1 change: 0 additions & 1 deletion compiler/ast.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1270,7 +1270,6 @@ proc extractPragma*(s: PSym): PNode =
result = nil
else:
result = nil
assert result == nil or result.kind == nkPragma

proc skipPragmaExpr*(n: PNode): PNode =
## if pragma expr, give the node the pragmas are applied to,
Expand Down
13 changes: 13 additions & 0 deletions compiler/injectdestructors.nim
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,18 @@ template isUnpackedTuple(n: PNode): bool =
## hence unpacked tuples themselves don't need to be destroyed
(n.kind == nkSym and n.sym.kind == skTemp and n.sym.typ.kind == tyTuple)

proc checkOpError(c: Con; n: PNode; op: TTypeAttachedOp) =
let op = getAttachedOp(c.graph, n.typ, op)
let pragmaNode = extractPragma(op)
var prefix = ""
for it in pragmaNode:
if whichPragma(it) == wError and it.safeLen == 2 and
it[1].kind in {nkStrLit..nkTripleStrLit}:
prefix.add it[1].strVal & "; "
if sfError in op.flags:
localError(c.graph.config, n.info, "$1usage of '$2' is an {.error.} defined at $3" %
[prefix, op.name.s, toFileLineCol(c.graph.config, op.ast.info)])

proc checkForErrorPragma(c: Con; t: PType; ri: PNode; opname: string; inferredFromCopy = false) =
var m = "'" & opname & "' is not available for type <" & typeToString(t) & ">"
if inferredFromCopy:
Expand Down Expand Up @@ -1113,6 +1125,7 @@ proc moveOrCopy(dest, ri: PNode; c: var Con; s: var Scope, flags: set[MoveOrCopy
# We know the result will be a stmt so we use that fact to optimize
handleNestedTempl(ri, process, willProduceStmt = true)
else:
c.checkOpError(ri, attachedAsgn)
Copy link
Member

Choose a reason for hiding this comment

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

Instead it should not have been computed to be a cursor. Also, only in this one case we now get a more informative error message. Sorry, but you need to stop hacking things into random places just to make tests pass but instead need to understand the overall architecture of the compiler and look into existing logic and why it fails.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

for whatever reason it will fails, the user code want do an assignment, but have already defined =copy as error.

result = newTree(nkFastAsgn, dest, p(ri, c, s, normal))
else:
let ri2 = if ri.kind == nkWhen: ri[1][0] else: ri
Expand Down
24 changes: 24 additions & 0 deletions tests/arc/t22218.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
discard """
cmd: "nim c --gc:arc $file"
errormsg: "A channel cannot be copied; usage of '=copy' is an {.error.} defined at t22218.nim(9, 1)"
"""

type Obj[T] = object
v: T

proc `=copy`[T](
dest: var Obj[T],
source: Obj[T]
) {.error: "A channel cannot be copied".}

from system/ansi_c import c_calloc

proc test() =
var v: bool = true
var chan = cast[ptr Obj[int]](c_calloc(1, csize_t sizeof(Obj[int])))
var copy = chan[]

echo chan.v
echo v

test()