Skip to content

{.global.} var calls destroy when goes out of scope (unlike {.threadvar.}) #14986

@timotheecour

Description

@timotheecour

{.global.} var calls destroy when goes out of scope (unlike {.threadvar.})

Example 1

when true: # D20200714T182349
  type Foo = object
    x: seq[int]
  proc `=destroy`(a: var Foo) =
    echo ("dtor", a.x)
    a.x.reset
  proc main() =
    var g1: ptr Foo
    var g2: ptr Foo
    block:
      var f1 {.threadvar.}: Foo
      var f2 {.global.}: Foo
      f1 = Foo(x: @[1])
      f2 = Foo(x: @[2])
      g1 = f1.addr
      g2 = f2.addr
      doAssert g1.x == @[1]
      doAssert g2.x == @[2]
    doAssert g1.x == @[1]
    doAssert g2.x == @[2] # fails because dtor called, but should not
  main()

Current Output

`doAssert g2.x == @[2]` fails

Expected Output

works

Example 2

see comments in this example:

when defined case2:
  type Foo = object
    x: seq[int]
  proc `=destroy`(a: var Foo) =
    echo ("dtor", a.x)
    a.x.reset
  var g1: ptr Foo
  var g2: ptr Foo
  var g3: ptr Foo
  block:
    var f1 {.threadvar.}: Foo
    var f2 {.global.}: Foo
    var f3: Foo
    f1 = Foo(x: @[1])
    f2 = Foo(x: @[2])
    f3 = Foo(x: @[3])
    g1 = f1.addr
    g2 = f2.addr
    g3 = f3.addr
    doAssert g1.x == @[1]
    doAssert g2.x == @[2]
    doAssert g3.x == @[3]
  doAssert g1.x == @[1]
  doAssert g2.x == @[2] # fails because dtor called, but should not
  doAssert g3.x == @[3]
    # fails, but unclear whether it should fail or succeed, and not clear how
    # to tell whether `f3` is global at block scope or a {.global.}, in case
    # it makes a semantic difference

Additional Information

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions