summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ast.nim2
-rw-r--r--compiler/ccgexprs.nim4
-rw-r--r--compiler/jsgen.nim2
-rw-r--r--compiler/sempass2.nim13
-rw-r--r--compiler/semstmts.nim5
-rw-r--r--compiler/vmgen.nim2
-rw-r--r--lib/system.nim2
-rw-r--r--tests/effects/tgcsafe3.nim2
8 files changed, 20 insertions, 12 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 50d048edd..0a3b1b72d 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -673,7 +673,7 @@ type
     mSwap, mIsNil, mArrToSeq,
     mNewString, mNewStringOfCap, mParseBiggestFloat,
     mMove, mWasMoved, mDestroy, mTrace,
-    mDefault, mUnown, mIsolate, mAccessEnv, mReset,
+    mDefault, mUnown, mFinished, mIsolate, mAccessEnv, mReset,
     mArray, mOpenArray, mRange, mSet, mSeq, mVarargs,
     mRef, mPtr, mVar, mDistinct, mVoid, mTuple,
     mOrdinal, mIterableType,
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 7a3d769aa..ac4a26bd6 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -2335,7 +2335,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
       genDollar(p, e, d, "#nimFloatToStr($1)")
   of mCStrToStr: genDollar(p, e, d, "#cstrToNimstr($1)")
   of mStrToStr, mUnown: expr(p, e[1], d)
-  of mIsolate: genCall(p, e, d)
+  of mIsolate, mFinished: genCall(p, e, d)
   of mEnumToStr:
     if optTinyRtti in p.config.globalOptions:
       genEnumToStr(p, e, d)
@@ -2929,7 +2929,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
     if n[genericParamsPos].kind == nkEmpty:
       var prc = n[namePos].sym
       if useAliveDataFromDce in p.module.flags:
-        if p.module.alive.contains(prc.itemId.item) and prc.magic in {mNone, mIsolate}:
+        if p.module.alive.contains(prc.itemId.item) and prc.magic in {mNone, mIsolate, mFinished}:
           genProc(p.module, prc)
       elif prc.skipGenericOwner.kind == skModule and sfCompileTime notin prc.flags:
         if ({sfExportc, sfCompilerProc} * prc.flags == {sfExportc}) or
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim
index f009c83f2..ff4d2839e 100644
--- a/compiler/jsgen.nim
+++ b/compiler/jsgen.nim
@@ -657,7 +657,7 @@ proc arithAux(p: PProc, n: PNode, r: var TCompRes, op: TMagic) =
   of mIntToStr: applyFormat("cstrToNimstr(($1) + \"\")", "cstrToNimstr(($1) + \"\")")
   of mInt64ToStr: applyFormat("cstrToNimstr(($1) + \"\")", "cstrToNimstr(($1) + \"\")")
   of mCStrToStr: applyFormat("cstrToNimstr($1)", "cstrToNimstr($1)")
-  of mStrToStr, mUnown, mIsolate: applyFormat("$1", "$1")
+  of mStrToStr, mUnown, mIsolate, mFinished: applyFormat("$1", "$1")
   else:
     assert false, $op
 
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim
index 6a0e8772a..9a27d14fa 100644
--- a/compiler/sempass2.nim
+++ b/compiler/sempass2.nim
@@ -245,9 +245,14 @@ proc listGcUnsafety(s: PSym; onlyWarning: bool; cycleCheck: var IntSet; conf: Co
     let msgKind = if onlyWarning: warnGcUnsafe2 else: errGenerated
     case u.kind
     of skLet, skVar:
-      message(conf, s.info, msgKind,
-        ("'$#' is not GC-safe as it accesses '$#'" &
-        " which is a global using GC'ed memory") % [s.name.s, u.name.s])
+      if u.typ.skipTypes(abstractInst).kind == tyProc:
+        message(conf, s.info, msgKind,
+          "'$#' is not GC-safe as it calls '$#'" %
+          [s.name.s, u.name.s])
+      else:
+        message(conf, s.info, msgKind,
+          ("'$#' is not GC-safe as it accesses '$#'" &
+          " which is a global using GC'ed memory") % [s.name.s, u.name.s])
     of routineKinds:
       # recursive call *always* produces only a warning so the full error
       # message is printed:
@@ -850,7 +855,7 @@ proc trackCall(tracked: PEffects; n: PNode) =
         mergeRaises(tracked, effectList[exceptionEffects], n)
         mergeTags(tracked, effectList[tagEffects], n)
         gcsafeAndSideeffectCheck()
-    if a.kind != nkSym or a.sym.magic != mNBindSym:
+    if a.kind != nkSym or a.sym.magic notin {mNBindSym, mFinished}:
       for i in 1..<n.len:
         trackOperandForIndirectCall(tracked, n[i], op, i, a)
     if a.kind == nkSym and a.sym.magic in {mNew, mNewFinalize, mNewSeq}:
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index 81d6eeda2..3b699f6c8 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -1474,6 +1474,9 @@ proc semBorrow(c: PContext, n: PNode, s: PSym) =
     # Carry over the original symbol magic, this is necessary in order to ensure
     # the semantic pass is correct
     s.magic = b.magic
+    if b.typ != nil and b.typ.len > 0:
+      s.typ.n[0] = b.typ.n[0]
+    s.typ.flags = b.typ.flags
   else:
     localError(c.config, n.info, errNoSymbolToBorrowFromFound)
 
@@ -1954,7 +1957,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
   if not hasProto:
     implicitPragmas(c, s, n.info, validPragmas)
 
-  if n[pragmasPos].kind != nkEmpty:
+  if n[pragmasPos].kind != nkEmpty and sfBorrow notin s.flags:
     setEffectsForProcType(c.graph, s.typ, n[pragmasPos], s)
   s.typ.flags.incl tfEffectSystemWorkaround
 
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index f2758ff37..bb095d3ee 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -1029,7 +1029,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
     c.genAsgnPatch(n[1], d)
     c.freeTemp(d)
   of mOrd, mChr, mArrToSeq, mUnown: c.gen(n[1], dest)
-  of mIsolate:
+  of mIsolate, mFinished:
     genCall(c, n, dest)
   of mNew, mNewFinalize:
     unused(c, n, dest)
diff --git a/lib/system.nim b/lib/system.nim
index c93af0854..a5356cb54 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -2453,7 +2453,7 @@ when notJSnotNims:
     else:
       {.error: "Only closure function and iterator are allowed!".}
 
-  proc finished*[T: proc](x: T): bool {.noSideEffect, inline.} =
+  proc finished*[T: proc](x: T): bool {.noSideEffect, inline, magic: "Finished".} =
     ## It can be used to determine if a first class iterator has finished.
     when T is "iterator":
       {.emit: """
diff --git a/tests/effects/tgcsafe3.nim b/tests/effects/tgcsafe3.nim
index 5137efe4c..36ea5112c 100644
--- a/tests/effects/tgcsafe3.nim
+++ b/tests/effects/tgcsafe3.nim
@@ -1,5 +1,5 @@
 discard """
-  errormsg: "'myproc' is not GC-safe as it accesses 'global_proc' which is a global using GC'ed memory"
+  errormsg: "'myproc' is not GC-safe as it calls 'global_proc'"
   line: 12
   cmd: "nim $target --hints:on --threads:on $options $file"
 """