-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
[ARC] Global variable declared in a block is destroyed too early #15005
Comments
Cannot reproduce. |
If you cannot minimize, please provide a different program that also fails for wNim, hopefully it crashes on my machine too then. |
Can reproduce in Wine on latest devel :) Seems like it's not a cursorifier bug (crashes with cursorifier disabled) |
After removing all macros and templates, the code looks like this. It works without --gc:arc, but crashes with --gc:arc. import wNim/[wApp, wFrame, wButton, wResizer]
let app = App()
let frame = Frame()
let button = Button(frame)
proc layout() =
block:
var resizer {.inject, global.}: wResizer
if resizer == nil:
resizer = Resizer(frame)
resizer.addObject(button)
resizer.addConstraint(frame.mLeft == button.mLeft)
resizer.addConstraint(frame.mTop == button.mTop)
resizer.addConstraint(frame.mWidth == button.mWidth)
resizer.addConstraint(frame.mHeight == button.mHeight)
resizer.resolve()
resizer.rearrange()
frame.wEvent_Size do ():
layout()
layout()
frame.show()
frame.center()
app.mainLoop() However, these code always works: proc layout() =
# block:
var resizer {.inject, global.}: wResizer proc layout() =
block:
var resizer {.inject.}: wResizer In summary, the problem is related to |
@khchen thanks for the simplification, it allowed me to repro it without any dependencies, can you please rename the issue (to something like "[ARC] Global variable declared in a block is destroyed too early") and add the repro to the first post ? :) type
Resizer = ref object
data: string
proc layout() =
block:
var resizer {.global.}: Resizer
if resizer == nil:
resizer = Resizer(data: "hi")
discard resizer.data == "hi"
layout()
layout() expandArc: block :tmp:
var resizer
if resizer == nil:
`=sink`(resizer, Resizer(data: "hi"))
discard resizer.data == "hi"
`=destroy`(resizer) The issue seems to be that the compiler doesn't recognize (or "forgets") about global pragma of a variable if it's in a block. |
This bug is caused by this line: https://github.com/nim-lang/Nim/blob/devel/compiler/injectdestructors.nim#L530 I think they are a minefield and I don't really see a usecase for them where a normal top-level global wouldn't do it (except for the part that they are initialized before those other globals, but maybe a |
Similar problem: type
T = ref object
data: string
template foo(): T =
var a {.global.}: T
once:
a = T(data: "hi")
echo "init"
a
proc test() =
var a = foo()
echo a.data
test()
test() Compile without --gc:arc
Compile with --gc:arc
|
Following code works well before the update: An optimizer for ARC (#14962).
Compiling with --gc:arc.
Example
Current Output
Thanks to @Yardanico, the simplified code is
The text was updated successfully, but these errors were encountered: