summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorringabout <43030857+ringabout@users.noreply.github.com>2023-10-14 03:34:13 +0800
committerGitHub <noreply@github.com>2023-10-13 21:34:13 +0200
commitf5d70e7fa7195658e3200f71a1653e07fe81275a (patch)
treec682be9710eaf951e7f494498e4108778aa6d7e9
parent61145b1d4bd60712dbaeaca19d01f3696546046c (diff)
downloadNim-f5d70e7fa7195658e3200f71a1653e07fe81275a.tar.gz
fixes #19250; fixes #22259; ORC AssertionDefect not containsManagedMemory(n.typ) (#22823)
fixes #19250
fixes #22259

The strings, seqs, refs types all have this flag, why should closures be
treated differently?

follow up https://github.com/nim-lang/Nim/pull/14336
-rw-r--r--compiler/semtypes.nim2
-rw-r--r--tests/arc/tarcmisc.nim53
2 files changed, 55 insertions, 0 deletions
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index dda78c69f..65eaf1a89 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -2161,6 +2161,8 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
       result = semProcTypeWithScope(c, n, prev, symKind)
       if n.kind == nkIteratorTy and result.kind == tyProc:
         result.flags.incl(tfIterator)
+      if result.callConv == ccClosure and c.config.selectedGC in {gcArc, gcOrc, gcAtomicArc}:
+        result.flags.incl tfHasAsgn
   of nkEnumTy: result = semEnum(c, n, prev)
   of nkType: result = n.typ
   of nkStmtListType: result = semStmtListType(c, n, prev)
diff --git a/tests/arc/tarcmisc.nim b/tests/arc/tarcmisc.nim
index 525c8c3a6..3b60fcd02 100644
--- a/tests/arc/tarcmisc.nim
+++ b/tests/arc/tarcmisc.nim
@@ -635,3 +635,56 @@ block: # bug #22664
   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)]"
+
+block: # bug #19250
+  type
+    Bar[T] = object
+      err: proc(): string
+
+    Foo[T] = object
+      run: proc(): Bar[T]
+
+  proc bar[T](err: proc(): string): Bar[T] =
+    assert not err.isNil
+    Bar[T](err: err)
+
+  proc foo(): Foo[char] = 
+    result.run = proc(): Bar[char] =
+      # works
+      # result = Bar[char](err: proc(): string = "x")
+      # not work
+      result = bar[char](proc(): string = "x")
+
+  proc bug[T](fs: Foo[T]): Foo[T] =
+    result.run = proc(): Bar[T] =
+      let res = fs.run()
+      
+      # works
+      # var errors = @[res.err] 
+      
+      # not work
+      var errors: seq[proc(): string]
+      errors.add res.err
+      
+      return bar[T] do () -> string:
+        for err in errors:
+          result.add res.err()
+
+  doAssert bug(foo()).run().err() == "x"
+
+block: # bug #22259
+  type
+    ProcWrapper = tuple
+      p: proc() {.closure.}
+
+
+  proc f(wrapper: ProcWrapper) =
+    let s = @[wrapper.p]
+    let a = [wrapper.p]
+
+  proc main =
+    # let wrapper: ProcWrapper = ProcWrapper(p: proc {.closure.} = echo 10)
+    let wrapper: ProcWrapper = (p: proc {.closure.} = echo 10)
+    f(wrapper)
+
+  main()