diff options
author | ringabout <43030857+ringabout@users.noreply.github.com> | 2022-10-11 15:17:09 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-11 09:17:09 +0200 |
commit | 5602183234f59ece4fd668915da848f0753cbbb9 (patch) | |
tree | b955da8037206560cdc9628d94a3b604bd9ac631 | |
parent | 75873715546142a6f6f78180abdf1c1ddc0416e5 (diff) | |
download | Nim-5602183234f59ece4fd668915da848f0753cbbb9.tar.gz |
'lock levels' are deprecated, now a noop (#20539)
* 'lock levels' are deprecated, now a noop * fixes tests
57 files changed, 121 insertions, 372 deletions
diff --git a/changelog.md b/changelog.md index bcb5a6ba7..2e8460b7c 100644 --- a/changelog.md +++ b/changelog.md @@ -84,6 +84,8 @@ - `macros.getImpl` for `const` symbols now returns the full definition node (as `nnkConstDef`) rather than the AST of the constant value. +- Lock levels are deprecated, now a noop. + - ORC is now the default memory management strategy. Use `--mm:refc` for a transition period. diff --git a/compiler/ast.nim b/compiler/ast.nim index 2a9556693..c4c183932 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -929,7 +929,6 @@ type allUsages*: seq[TLineInfo] TTypeSeq* = seq[PType] - TLockLevel* = distinct int16 TTypeAttachedOp* = enum ## as usual, order is important here attachedDestructor, @@ -963,7 +962,6 @@ type # -1 means that the size is unkwown align*: int16 # the type's alignment requirements paddingAtEnd*: int16 # - lockLevel*: TLockLevel # lock level as required for deadlock checking loc*: TLoc typeInst*: PType # for generic instantiations the tyGenericInst that led to this # type. @@ -1499,17 +1497,9 @@ proc newProcNode*(kind: TNodeKind, info: TLineInfo, body: PNode, pragmas, exceptions, body] const - UnspecifiedLockLevel* = TLockLevel(-1'i16) - MaxLockLevel* = 1000'i16 - UnknownLockLevel* = TLockLevel(1001'i16) AttachedOpToStr*: array[TTypeAttachedOp, string] = [ "=destroy", "=copy", "=sink", "=trace", "=deepcopy"] -proc `$`*(x: TLockLevel): string = - if x.ord == UnspecifiedLockLevel.ord: result = "<unspecified>" - elif x.ord == UnknownLockLevel.ord: result = "<unknown>" - else: result = $int16(x) - proc `$`*(s: PSym): string = if s != nil: result = s.name.s & "@" & $s.id @@ -1519,7 +1509,6 @@ proc `$`*(s: PSym): string = proc newType*(kind: TTypeKind, id: ItemId; owner: PSym): PType = result = PType(kind: kind, owner: owner, size: defaultSize, align: defaultAlignment, itemId: id, - lockLevel: UnspecifiedLockLevel, uniqueId: id) when false: if result.itemId.module == 55 and result.itemId.item == 2: @@ -1544,7 +1533,6 @@ proc assignType*(dest, src: PType) = dest.n = src.n dest.size = src.size dest.align = src.align - dest.lockLevel = src.lockLevel # this fixes 'type TLock = TSysLock': if src.sym != nil: if dest.sym != nil: diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim index 6b4322a13..23dea1d18 100644 --- a/compiler/cgmeth.nim +++ b/compiler/cgmeth.nim @@ -147,23 +147,6 @@ proc fixupDispatcher(meth, disp: PSym; conf: ConfigRef) = disp.ast[resultPos].kind == nkEmpty: disp.ast[resultPos] = copyTree(meth.ast[resultPos]) - # The following code works only with lock levels, so we disable - # it when they're not available. - when declared(TLockLevel): - proc `<`(a, b: TLockLevel): bool {.borrow.} - proc `==`(a, b: TLockLevel): bool {.borrow.} - if disp.typ.lockLevel == UnspecifiedLockLevel: - disp.typ.lockLevel = meth.typ.lockLevel - elif meth.typ.lockLevel != UnspecifiedLockLevel and - meth.typ.lockLevel != disp.typ.lockLevel: - message(conf, meth.info, warnLockLevel, - "method has lock level $1, but another method has $2" % - [$meth.typ.lockLevel, $disp.typ.lockLevel]) - # XXX The following code silences a duplicate warning in - # checkMethodeffects() in sempass2.nim for now. - if disp.typ.lockLevel < meth.typ.lockLevel: - disp.typ.lockLevel = meth.typ.lockLevel - proc methodDef*(g: ModuleGraph; idgen: IdGenerator; s: PSym) = var witness: PSym for i in 0..<g.methods.len: diff --git a/compiler/ic/ic.nim b/compiler/ic/ic.nim index a745a9d83..36a57f11e 100644 --- a/compiler/ic/ic.nim +++ b/compiler/ic/ic.nim @@ -354,7 +354,7 @@ proc storeType(t: PType; c: var PackedEncoder; m: var PackedModule): PackedItemI var p = PackedType(kind: t.kind, flags: t.flags, callConv: t.callConv, size: t.size, align: t.align, nonUniqueId: t.itemId.item, - paddingAtEnd: t.paddingAtEnd, lockLevel: t.lockLevel) + paddingAtEnd: t.paddingAtEnd) storeNode(p, t, n) p.typeInst = t.typeInst.storeType(c, m) for kid in items t.sons: @@ -900,7 +900,7 @@ proc typeHeaderFromPacked(c: var PackedDecoder; g: var PackedModuleGraph; t: PackedType; si, item: int32): PType = result = PType(itemId: ItemId(module: si, item: t.nonUniqueId), kind: t.kind, flags: t.flags, size: t.size, align: t.align, - paddingAtEnd: t.paddingAtEnd, lockLevel: t.lockLevel, + paddingAtEnd: t.paddingAtEnd, uniqueId: ItemId(module: si, item: item), callConv: t.callConv) diff --git a/compiler/ic/packed_ast.nim b/compiler/ic/packed_ast.nim index c78fe56f5..87b1516fa 100644 --- a/compiler/ic/packed_ast.nim +++ b/compiler/ic/packed_ast.nim @@ -84,7 +84,6 @@ type size*: BiggestInt align*: int16 paddingAtEnd*: int16 - lockLevel*: TLockLevel # lock level as required for deadlock checking # not serialized: loc*: TLoc because it is backend-specific typeInst*: PackedItemId nonUniqueId*: int32 diff --git a/compiler/lineinfos.nim b/compiler/lineinfos.nim index fcc15606d..c117f5694 100644 --- a/compiler/lineinfos.nim +++ b/compiler/lineinfos.nim @@ -68,7 +68,8 @@ type warnUnreachableElse = "UnreachableElse", warnUnreachableCode = "UnreachableCode", warnStaticIndexCheck = "IndexCheck", warnGcUnsafe = "GcUnsafe", warnGcUnsafe2 = "GcUnsafe2", warnUninit = "Uninit", warnGcMem = "GcMem", warnDestructor = "Destructor", - warnLockLevel = "LockLevel", warnResultShadowed = "ResultShadowed", + warnLockLevel = "LockLevel", # deadcode + warnResultShadowed = "ResultShadowed", warnInconsistentSpacing = "Spacing", warnCaseTransition = "CaseTransition", warnCycleCreated = "CycleCreated", warnObservableStores = "ObservableStores", warnStrictNotNil = "StrictNotNil", @@ -161,7 +162,7 @@ const warnUninit: "use explicit initialization of '$1' for clarity", warnGcMem: "'$1' uses GC'ed memory", warnDestructor: "usage of a type with a destructor in a non destructible context. This will become a compile time error in the future.", - warnLockLevel: "$1", + warnLockLevel: "$1", # deadcode warnResultShadowed: "Special variable 'result' is shadowed.", warnInconsistentSpacing: "Number of spaces around '$#' is not consistent", warnCaseTransition: "Potential object case transition, instantiate new object instead", diff --git a/compiler/main.nim b/compiler/main.nim index 171521c7a..71e913d6c 100644 --- a/compiler/main.nim +++ b/compiler/main.nim @@ -294,7 +294,6 @@ proc mainCommand*(graph: ModuleGraph) = of cmdDoc0: docLikeCmd commandDoc(cache, conf) of cmdDoc: docLikeCmd(): - conf.setNoteDefaults(warnLockLevel, false) # issue #13218 conf.setNoteDefaults(warnRstRedefinitionOfLabel, false) # issue #13218 # because currently generates lots of false positives due to conflation # of labels links in doc comments, e.g. for random.rand: diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index d4932a877..bcc786703 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -684,23 +684,6 @@ proc pragmaLockStmt(c: PContext; it: PNode) = for i in 0..<n.len: n[i] = c.semExpr(c, n[i]) -proc pragmaLocks(c: PContext, it: PNode): TLockLevel = - if it.kind notin nkPragmaCallKinds or it.len != 2: - invalidPragma(c, it) - else: - case it[1].kind - of nkStrLit, nkRStrLit, nkTripleStrLit: - if it[1].strVal == "unknown": - result = UnknownLockLevel - else: - localError(c.config, it[1].info, "invalid string literal for locks pragma (only allowed string is \"unknown\")") - else: - let x = expectIntLit(c, it) - if x < 0 or x > MaxLockLevel: - localError(c.config, it[1].info, "integer must be within 0.." & $MaxLockLevel) - else: - result = TLockLevel(x) - proc typeBorrow(c: PContext; sym: PSym, n: PNode) = if n.kind in nkPragmaCallKinds and n.len == 2: let it = n[1] @@ -1196,7 +1179,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, of wLocks: if sym == nil: pragmaLockStmt(c, it) elif sym.typ == nil: invalidPragma(c, it) - else: sym.typ.lockLevel = pragmaLocks(c, it) + else: warningDeprecated(c.config, n.info, "'Lock levels' are deprecated, now a noop") of wBitsize: if sym == nil or sym.kind != skField: invalidPragma(c, it) diff --git a/compiler/semcall.nim b/compiler/semcall.nim index cd009ce69..ed8699a26 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -149,9 +149,6 @@ proc effectProblem(f, a: PType; result: var string; c: PContext) = of efTagsUnknown: result.add "\n The `.tags` requirements differ. Annotate the " & "proc with {.tags: [].} to get extended error information." - of efLockLevelsDiffer: - result.add "\n The `.locks` requirements differ. Annotate the " & - "proc with {.locks: 0.} to get extended error information." of efEffectsDelayed: result.add "\n The `.effectsOf` annotations differ." of efTagsIllegal: diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index a1887b20e..f2da33e8b 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -77,7 +77,6 @@ type gcUnsafe, isRecursive, isTopLevel, hasSideEffect, inEnforcedGcSafe: bool hasDangerousAssign, isInnerProc: bool inEnforcedNoSideEffects: bool - maxLockLevel, currLockLevel: TLockLevel currOptions: TOptions config: ConfigRef graph: ModuleGraph @@ -85,11 +84,6 @@ type escapingParams: IntSet PEffects = var TEffects -proc `<`(a, b: TLockLevel): bool {.borrow.} -proc `<=`(a, b: TLockLevel): bool {.borrow.} -proc `==`(a, b: TLockLevel): bool {.borrow.} -proc max(a, b: TLockLevel): TLockLevel {.borrow.} - proc createTypeBoundOps(tracked: PEffects, typ: PType; info: TLineInfo) = if typ == nil: return when false: @@ -107,33 +101,12 @@ proc isLocalVar(a: PEffects, s: PSym): bool = s.typ != nil and (s.kind in {skVar, skResult} or (s.kind == skParam and isOutParam(s.typ))) and sfGlobal notin s.flags and s.owner == a.owner -proc getLockLevel(t: PType): TLockLevel = - var t = t - # tyGenericInst(TLock {tyGenericBody}, tyStatic, tyObject): - if t.kind == tyGenericInst and t.len == 3: t = t[1] - if t.kind == tyStatic and t.n != nil and t.n.kind in {nkCharLit..nkInt64Lit}: - result = t.n.intVal.TLockLevel - proc lockLocations(a: PEffects; pragma: PNode) = if pragma.kind != nkExprColonExpr: localError(a.config, pragma.info, "locks pragma without argument") return - var firstLL = TLockLevel(-1'i16) for x in pragma[1]: - let thisLL = getLockLevel(x.typ) - if thisLL != 0.TLockLevel: - if thisLL < 0.TLockLevel or thisLL > MaxLockLevel.TLockLevel: - localError(a.config, x.info, "invalid lock level: " & $thisLL) - elif firstLL < 0.TLockLevel: firstLL = thisLL - elif firstLL != thisLL: - localError(a.config, x.info, - "multi-lock requires the same static lock level for every operand") - a.maxLockLevel = max(a.maxLockLevel, firstLL) a.locked.add x - if firstLL >= 0.TLockLevel and firstLL != a.currLockLevel: - if a.currLockLevel > 0.TLockLevel and a.currLockLevel <= firstLL: - localError(a.config, pragma.info, "invalid nested locking") - a.currLockLevel = firstLL proc guardGlobal(a: PEffects; n: PNode; guard: PSym) = # check whether the corresponding lock is held: @@ -438,8 +411,6 @@ proc listEffects(a: PEffects) = for e in items(a.exc): message(a.config, e.info, hintUser, typeToString(e.typ)) for e in items(a.tags): message(a.config, e.info, hintUser, typeToString(e.typ)) for e in items(a.forbids): message(a.config, e.info, hintUser, typeToString(e.typ)) - #if a.maxLockLevel != 0: - # message(e.info, hintUser, "lockLevel: " & a.maxLockLevel) proc catches(tracked: PEffects, e: PType) = let e = skipTypes(e, skipPtrs) @@ -551,25 +522,6 @@ proc importedFromC(n: PNode): bool = # when imported from C, we assume GC-safety. result = n.kind == nkSym and sfImportc in n.sym.flags -proc getLockLevel(s: PSym): TLockLevel = - result = s.typ.lockLevel - if result == UnspecifiedLockLevel: - if {sfImportc, sfNoSideEffect} * s.flags != {} or - tfNoSideEffect in s.typ.flags: - result = 0.TLockLevel - else: - result = UnknownLockLevel - #message(??.config, s.info, warnUser, "FOR THIS " & s.name.s) - -proc mergeLockLevels(tracked: PEffects, n: PNode, lockLevel: TLockLevel) = - if lockLevel >= tracked.currLockLevel: - # if in lock section: - if tracked.currLockLevel > 0.TLockLevel: - localError tracked.config, n.info, errGenerated, - "expected lock level < " & $tracked.currLockLevel & - " but got lock level " & $lockLevel - tracked.maxLockLevel = max(tracked.maxLockLevel, lockLevel) - proc propagateEffects(tracked: PEffects, n: PNode, s: PSym) = let pragma = s.ast[pragmasPos] let spec = effectSpec(pragma, wRaises) @@ -583,7 +535,6 @@ proc propagateEffects(tracked: PEffects, n: PNode, s: PSym) = markGcUnsafe(tracked, s) if tfNoSideEffect notin s.typ.flags: markSideEffect(tracked, s, n.info) - mergeLockLevels(tracked, n, s.getLockLevel) proc procVarCheck(n: PNode; conf: ConfigRef) = if n.kind in nkSymChoices: @@ -623,11 +574,6 @@ proc notNilCheck(tracked: PEffects, n: PNode, paramType: PType) = proc assumeTheWorst(tracked: PEffects; n: PNode; op: PType) = addRaiseEffect(tracked, createRaise(tracked.graph, n), nil) addTag(tracked, createTag(tracked.graph, n), nil) - let lockLevel = if op.lockLevel == UnspecifiedLockLevel: UnknownLockLevel - else: op.lockLevel - #if lockLevel == UnknownLockLevel: - # message(??.config, n.info, warnUser, "had to assume the worst here") - mergeLockLevels(tracked, n, lockLevel) proc isOwnedProcVar(tracked: PEffects; n: PNode): bool = # XXX prove the soundness of this effect system rule @@ -885,10 +831,9 @@ proc trackCall(tracked: PEffects; n: PNode) = if a.kind == nkSym: if a.sym == tracked.owner: tracked.isRecursive = true # even for recursive calls we need to check the lock levels (!): - mergeLockLevels(tracked, n, a.sym.getLockLevel) if sfSideEffect in a.sym.flags: markSideEffect(tracked, a, n.info) else: - mergeLockLevels(tracked, n, op.lockLevel) + discard var effectList = op.n[0] if a.kind == nkSym and a.sym.kind == skMethod: propagateEffects(tracked, n, a.sym) @@ -967,7 +912,6 @@ proc trackCall(tracked: PEffects; n: PNode) = type PragmaBlockContext = object oldLocked: int - oldLockLevel: TLockLevel enforcedGcSafety, enforceNoSideEffects: bool oldExc, oldTags, oldForbids: int exc, tags, forbids: PNode @@ -976,7 +920,6 @@ proc createBlockContext(tracked: PEffects): PragmaBlockContext = var oldForbidsLen = 0 if tracked.forbids != nil: oldForbidsLen = tracked.forbids.len result = PragmaBlockContext(oldLocked: tracked.locked.len, - oldLockLevel: tracked.currLockLevel, enforcedGcSafety: false, enforceNoSideEffects: false, oldExc: tracked.exc.len, oldTags: tracked.tags.len, oldForbids: oldForbidsLen) @@ -989,7 +932,6 @@ proc unapplyBlockContext(tracked: PEffects; bc: PragmaBlockContext) = if bc.enforcedGcSafety: tracked.inEnforcedGcSafe = false if bc.enforceNoSideEffects: tracked.inEnforcedNoSideEffects = false setLen(tracked.locked, bc.oldLocked) - tracked.currLockLevel = bc.oldLockLevel if bc.exc != nil: # beware that 'raises: []' is very different from not saying # anything about 'raises' in the 'cast' at all. Same applies for 'tags'. @@ -1396,17 +1338,6 @@ proc checkMethodEffects*(g: ModuleGraph; disp, branch: PSym) = localError(g.config, branch.info, "for method '" & branch.name.s & "' the `.requires` or `.ensures` properties are incompatible.") - if branch.typ.lockLevel > disp.typ.lockLevel: - when true: - message(g.config, branch.info, warnLockLevel, - "base method has lock level $1, but dispatcher has $2" % - [$branch.typ.lockLevel, $disp.typ.lockLevel]) - else: - # XXX make this an error after bigbreak has been released: - localError(g.config, branch.info, - "base method has lock level $1, but dispatcher has $2" % - [$branch.typ.lockLevel, $disp.typ.lockLevel]) - proc setEffectsForProcType*(g: ModuleGraph; t: PType, n: PNode; s: PSym = nil) = var effects = t.n[0] if t.kind != tyProc or effects.kind != nkEffectList: return @@ -1592,13 +1523,6 @@ proc trackProc*(c: PContext; s: PSym, body: PNode) = s.typ.flags.incl tfGcSafe if not t.hasSideEffect and sfSideEffect notin s.flags: s.typ.flags.incl tfNoSideEffect - if s.typ.lockLevel == UnspecifiedLockLevel: - s.typ.lockLevel = t.maxLockLevel - elif t.maxLockLevel > s.typ.lockLevel: - #localError(s.info, - message(g.config, s.info, warnLockLevel, - "declared lock level is $1, but real lock level is $2" % - [$s.typ.lockLevel, $t.maxLockLevel]) when defined(drnim): if c.graph.strongSemCheck != nil: c.graph.strongSemCheck(c.graph, s, body) when defined(useDfa): diff --git a/compiler/types.nim b/compiler/types.nim index 1737fd48b..44cbf7ae1 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -48,7 +48,6 @@ type ProcConvMismatch* = enum pcmNoSideEffect pcmNotGcSafe - pcmLockDifference pcmNotIterator pcmDifferentCallConv @@ -728,9 +727,6 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = if tfThread in t.flags: addSep(prag) prag.add("gcsafe") - if t.lockLevel.ord != UnspecifiedLockLevel.ord: - addSep(prag) - prag.add("locks: " & $t.lockLevel) if prag.len != 0: result.add("{." & prag & ".}") of tyVarargs: result = typeToStr[t.kind] % typeToString(t[0]) @@ -1386,7 +1382,6 @@ type efRaisesUnknown efTagsDiffer efTagsUnknown - efLockLevelsDiffer efEffectsDelayed efTagsIllegal @@ -1430,17 +1425,13 @@ proc compatibleEffects*(formal, actual: PType): EffectsCompat = elif hasIncompatibleEffect(sn, real[tagEffects]): return efTagsIllegal - if formal.lockLevel.ord < 0 or - actual.lockLevel.ord <= formal.lockLevel.ord: + for i in 1 ..< min(formal.n.len, actual.n.len): + if formal.n[i].sym.flags * {sfEffectsDelayed} != actual.n[i].sym.flags * {sfEffectsDelayed}: + result = efEffectsDelayed + break - for i in 1 ..< min(formal.n.len, actual.n.len): - if formal.n[i].sym.flags * {sfEffectsDelayed} != actual.n[i].sym.flags * {sfEffectsDelayed}: - result = efEffectsDelayed - break + result = efCompat - result = efCompat - else: - result = efLockLevelsDiffer proc isCompileTimeOnly*(t: PType): bool {.inline.} = result = t.kind in {tyTypeDesc, tyStatic} @@ -1577,13 +1568,6 @@ proc getProcConvMismatch*(c: ConfigRef, f, a: PType, rel = isNone): (set[ProcCon result[1] = isNone result[0].incl pcmDifferentCallConv - if f.lockLevel.ord != UnspecifiedLockLevel.ord and - a.lockLevel.ord != UnspecifiedLockLevel.ord: - # proctypeRel has more logic to catch this difference, - # so dont need to do `rel = isNone` - # but it's a pragma mismatch reason which is why it's here - result[0].incl pcmLockDifference - proc addPragmaAndCallConvMismatch*(message: var string, formal, actual: PType, conf: ConfigRef) = assert formal.kind == tyProc and actual.kind == tyProc let (convMismatch, _) = getProcConvMismatch(conf, formal, actual) @@ -1598,9 +1582,6 @@ proc addPragmaAndCallConvMismatch*(message: var string, formal, actual: PType, c expectedPragmas.add "noSideEffect, " of pcmNotGcSafe: expectedPragmas.add "gcsafe, " - of pcmLockDifference: - gotPragmas.add("locks: " & $actual.lockLevel & ", ") - expectedPragmas.add("locks: " & $formal.lockLevel & ", ") of pcmNotIterator: discard if expectedPragmas.len > 0: @@ -1621,8 +1602,6 @@ proc processPragmaAndCallConvMismatch(msg: var string, formal, actual: PType, co msg.add "\n.tag effects differ" of efTagsUnknown: msg.add "\n.tag effect is 'any tag allowed'" - of efLockLevelsDiffer: - msg.add "\nlock levels differ" of efEffectsDelayed: msg.add "\n.effectsOf annotations differ" of efTagsIllegal: diff --git a/doc/manual_experimental.md b/doc/manual_experimental.md index cef4ff265..59d6a407b 100644 --- a/doc/manual_experimental.md +++ b/doc/manual_experimental.md @@ -1817,105 +1817,6 @@ restrictions / changes: yet performed for ordinary slices outside of a `parallel` section. - -Lock levels -=========== - -Lock levels are used to enforce a global locking order in order to detect -potential deadlocks during semantic analysis. A lock level is an constant -integer in the range 0..1_000. Lock level 0 means that no lock is acquired at -all. - -If a section of code holds a lock of level `M`, it can also acquire any -lock of level `N < M`. Another lock of level `M` cannot be acquired. Locks -of the same level can only be acquired *at the same time* within a -single `locks` section: - - ```nim - var a, b: TLock[2] - var x: TLock[1] - # invalid locking order: TLock[1] cannot be acquired before TLock[2]: - {.locks: [x].}: - {.locks: [a].}: - ... - # valid locking order: TLock[2] acquired before TLock[1]: - {.locks: [a].}: - {.locks: [x].}: - ... - - # invalid locking order: TLock[2] acquired before TLock[2]: - {.locks: [a].}: - {.locks: [b].}: - ... - - # valid locking order, locks of the same level acquired at the same time: - {.locks: [a, b].}: - ... - ``` - - -Here is how a typical multilock statement can be implemented in Nim. Note how -the runtime check is required to ensure a global ordering for two locks `a` -and `b` of the same lock level: - - ```nim - template multilock(a, b: ptr TLock; body: untyped) = - if cast[ByteAddress](a) < cast[ByteAddress](b): - pthread_mutex_lock(a) - pthread_mutex_lock(b) - else: - pthread_mutex_lock(b) - pthread_mutex_lock(a) - {.locks: [a, b].}: - try: - body - finally: - pthread_mutex_unlock(a) - pthread_mutex_unlock(b) - ``` - - -Whole routines can also be annotated with a `locks` pragma that takes a lock -level. This then means that the routine may acquire locks of up to this level. -This is essential so that procs can be called within a `locks` section: - - ```nim - proc p() {.locks: 3.} = discard - - var a: TLock[4] - {.locks: [a].}: - # p's locklevel (3) is strictly less than a's (4) so the call is allowed: - p() - ``` - - -As usual, `locks` is an inferred effect and there is a subtype -relation: `proc () {.locks: N.}` is a subtype of `proc () {.locks: M.}` -iff (M <= N). - -The `locks` pragma can also take the special value `"unknown"`. This -is useful in the context of dynamic method dispatching. In the following -example, the compiler can infer a lock level of 0 for the `base` case. -However, one of the overloaded methods calls a procvar which is -potentially locking. Thus, the lock level of calling `g.testMethod` -cannot be inferred statically, leading to compiler warnings. By using -`{.locks: "unknown".}`, the base method can be marked explicitly as -having unknown lock level as well: - - ```nim - type SomeBase* = ref object of RootObj - type SomeDerived* = ref object of SomeBase - memberProc*: proc () - - method testMethod(g: SomeBase) {.base, locks: "unknown".} = discard - method testMethod(g: SomeDerived) = - if g.memberProc != nil: - g.memberProc() - ``` - -This feature may be removed in the future due to its practical difficulties. - - Strict definitions and `out` parameters ======================================= diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 595d4bab5..d09ea2fe2 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -215,12 +215,12 @@ template `or`*(x, y: NimNode): NimNode = y proc add*(father, child: NimNode): NimNode {.magic: "NAdd", discardable, - noSideEffect, locks: 0.} + noSideEffect.} ## Adds the `child` to the `father` node. Returns the ## father node so that calls can be nested. proc add*(father: NimNode, children: varargs[NimNode]): NimNode {. - magic: "NAddMultiple", discardable, noSideEffect, locks: 0.} + magic: "NAddMultiple", discardable, noSideEffect.} ## Adds each child of `children` to the `father` node. ## Returns the `father` node so that calls can be nested. diff --git a/lib/pure/net.nim b/lib/pure/net.nim index 16390d9af..8dd9e2c8b 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -1025,7 +1025,7 @@ proc bindAddr*(socket: Socket, port = Port(0), address = "") {. proc acceptAddr*(server: Socket, client: var owned(Socket), address: var string, flags = {SocketFlag.SafeDisconn}, inheritable = defined(nimInheritHandles)) {. - tags: [ReadIOEffect], gcsafe, locks: 0.} = + tags: [ReadIOEffect], gcsafe.} = ## Blocks until a connection is being made from a client. When a connection ## is made sets `client` to the client socket and `address` to the address ## of the connecting client. diff --git a/lib/pure/nimprof.nim b/lib/pure/nimprof.nim index 3b1f703e3..6ee9de0a4 100644 --- a/lib/pure/nimprof.nim +++ b/lib/pure/nimprof.nim @@ -122,13 +122,13 @@ when defined(memProfiler): var gTicker {.threadvar.}: int - proc requestedHook(): bool {.nimcall, locks: 0.} = + proc requestedHook(): bool {.nimcall.} = if gTicker == 0: gTicker = SamplingInterval result = true dec gTicker - proc hook(st: StackTrace, size: int) {.nimcall, locks: 0.} = + proc hook(st: StackTrace, size: int) {.nimcall.} = when defined(ignoreAllocationSize): hookAux(st, 1) else: @@ -140,7 +140,7 @@ else: gTicker: int # we use an additional counter to # avoid calling 'getTicks' too frequently - proc requestedHook(): bool {.nimcall, locks: 0.} = + proc requestedHook(): bool {.nimcall.} = if interval == 0: result = true elif gTicker == 0: gTicker = 500 @@ -149,7 +149,7 @@ else: else: dec gTicker - proc hook(st: StackTrace) {.nimcall, locks: 0.} = + proc hook(st: StackTrace) {.nimcall.} = #echo "profiling! ", interval if interval == 0: hookAux(st, 1) diff --git a/lib/pure/nimtracker.nim b/lib/pure/nimtracker.nim index a66dfc2ea..91bb07192 100644 --- a/lib/pure/nimtracker.nim +++ b/lib/pure/nimtracker.nim @@ -34,7 +34,7 @@ template sbind(x: int; value) = quit "could not bind value" when defined(memTracker): - proc logEntries(log: TrackLog) {.nimcall, locks: 0, tags: [], gcsafe.} = + proc logEntries(log: TrackLog) {.nimcall, tags: [], gcsafe.} = if insertStmt.isNil: if prepare_v2(dbHandle, insertQuery, insertQuery.len, insertStmt, nil) != SQLITE_OK: diff --git a/lib/system/cyclebreaker.nim b/lib/system/cyclebreaker.nim index 6ec0f01f7..4427ae53b 100644 --- a/lib/system/cyclebreaker.nim +++ b/lib/system/cyclebreaker.nim @@ -148,7 +148,7 @@ proc thinout*[T](x: ref T) {.inline.} = ## and thus would keep the graph from being freed are `nil`'ed. ## This is a form of cycle collection that works well with Nim's ARC ## and its associated cost model. - proc getDynamicTypeInfo[T](x: T): PNimTypeV2 {.magic: "GetTypeInfoV2", noSideEffect, locks: 0.} + proc getDynamicTypeInfo[T](x: T): PNimTypeV2 {.magic: "GetTypeInfoV2", noSideEffect.} breakCycles(head(cast[pointer](x)), getDynamicTypeInfo(x[])) diff --git a/lib/system/inclrtl.nim b/lib/system/inclrtl.nim index ca41f39c6..42c85ad26 100644 --- a/lib/system/inclrtl.nim +++ b/lib/system/inclrtl.nim @@ -45,7 +45,7 @@ else: {.pragma: inl, inline.} {.pragma: compilerRtl, compilerproc.} -{.pragma: benign, gcsafe, locks: 0.} +{.pragma: benign, gcsafe.} when defined(nimHasSinkInference): {.push sinkInference: on.} diff --git a/lib/system/memalloc.nim b/lib/system/memalloc.nim index f8ebc8c5f..7660bcd58 100644 --- a/lib/system/memalloc.nim +++ b/lib/system/memalloc.nim @@ -1,13 +1,13 @@ when notJSnotNims: proc zeroMem*(p: pointer, size: Natural) {.inline, noSideEffect, - tags: [], locks: 0, raises: [].} + tags: [], raises: [].} ## Overwrites the contents of the memory at `p` with the value 0. ## ## Exactly `size` bytes will be overwritten. Like any procedure ## dealing with raw memory this is **unsafe**. proc copyMem*(dest, source: pointer, size: Natural) {.inline, benign, - tags: [], locks: 0, raises: [].} + tags: [], raises: [].} ## Copies the contents from the memory at `source` to the memory ## at `dest`. ## Exactly `size` bytes will be copied. The memory @@ -15,7 +15,7 @@ when notJSnotNims: ## memory this is **unsafe**. proc moveMem*(dest, source: pointer, size: Natural) {.inline, benign, - tags: [], locks: 0, raises: [].} + tags: [], raises: [].} ## Copies the contents from the memory at `source` to the memory ## at `dest`. ## @@ -25,7 +25,7 @@ when notJSnotNims: ## dealing with raw memory this is still **unsafe**, though. proc equalMem*(a, b: pointer, size: Natural): bool {.inline, noSideEffect, - tags: [], locks: 0, raises: [].} + tags: [], raises: [].} ## Compares the memory blocks `a` and `b`. `size` bytes will ## be compared. ## @@ -34,7 +34,7 @@ when notJSnotNims: ## **unsafe**. proc cmpMem*(a, b: pointer, size: Natural): int {.inline, noSideEffect, - tags: [], locks: 0, raises: [].} + tags: [], raises: [].} ## Compares the memory blocks `a` and `b`. `size` bytes will ## be compared. ## diff --git a/lib/system/memtracker.nim b/lib/system/memtracker.nim index f0c83f1fa..9d2d7caee 100644 --- a/lib/system/memtracker.nim +++ b/lib/system/memtracker.nim @@ -35,7 +35,7 @@ type count*: int disabled: bool data*: array[400, LogEntry] - TrackLogger* = proc (log: TrackLog) {.nimcall, tags: [], locks: 0, gcsafe.} + TrackLogger* = proc (log: TrackLog) {.nimcall, tags: [], gcsafe.} var gLog*: TrackLog @@ -70,7 +70,7 @@ proc addEntry(entry: LogEntry) = if interesting: gLog.disabled = true cprintf("interesting %s:%ld %s\n", entry.file, entry.line, entry.op) - let x = cast[proc() {.nimcall, tags: [], gcsafe, locks: 0, raises: [].}](writeStackTrace) + let x = cast[proc() {.nimcall, tags: [], gcsafe, raises: [].}](writeStackTrace) x() quit 1 #if gLog.count > high(gLog.data): @@ -85,7 +85,7 @@ proc memTrackerWrite(address: pointer; size: int; file: cstring; line: int) {.co size: size, file: file, line: line, thread: myThreadId()) proc memTrackerOp*(op: cstring; address: pointer; size: int) {.tags: [], - locks: 0, gcsafe.} = + gcsafe.} = addEntry LogEntry(op: op, address: address, size: size, file: "", line: 0, thread: myThreadId()) diff --git a/lib/system/profiler.nim b/lib/system/profiler.nim index 0649f1176..e7eb6ac82 100644 --- a/lib/system/profiler.nim +++ b/lib/system/profiler.nim @@ -60,13 +60,13 @@ proc captureStackTrace(f: PFrame, st: var StackTrace) = b = b.prev var - profilingRequestedHook*: proc (): bool {.nimcall, locks: 0, gcsafe.} + profilingRequestedHook*: proc (): bool {.nimcall, gcsafe.} ## set this variable to provide a procedure that implements a profiler in ## user space. See the `nimprof` module for a reference implementation. when defined(memProfiler): type - MemProfilerHook* = proc (st: StackTrace, requestedSize: int) {.nimcall, locks: 0, gcsafe.} + MemProfilerHook* = proc (st: StackTrace, requestedSize: int) {.nimcall, gcsafe.} var profilerHook*: MemProfilerHook diff --git a/lib/system/stacktraces.nim b/lib/system/stacktraces.nim index 8142f8c7b..42be9d94f 100644 --- a/lib/system/stacktraces.nim +++ b/lib/system/stacktraces.nim @@ -22,26 +22,26 @@ when defined(nimStackTraceOverride): ## This is the same as the type `uintptr_t` in C. StackTraceOverrideGetTracebackProc* = proc (): string {. - nimcall, gcsafe, locks: 0, raises: [], tags: [], noinline.} + nimcall, gcsafe, raises: [], tags: [], noinline.} StackTraceOverrideGetProgramCountersProc* = proc (maxLength: cint): seq[cuintptr_t] {. - nimcall, gcsafe, locks: 0, raises: [], tags: [], noinline.} + nimcall, gcsafe, raises: [], tags: [], noinline.} StackTraceOverrideGetDebuggingInfoProc* = proc (programCounters: seq[cuintptr_t], maxLength: cint): seq[StackTraceEntry] {. - nimcall, gcsafe, locks: 0, raises: [], tags: [], noinline.} + nimcall, gcsafe, raises: [], tags: [], noinline.} # Default procedures (not normally used, because people opting in on this # override are supposed to register their own versions). var stackTraceOverrideGetTraceback: StackTraceOverrideGetTracebackProc = - proc (): string {.nimcall, gcsafe, locks: 0, raises: [], tags: [], noinline.} = + proc (): string {.nimcall, gcsafe, raises: [], tags: [], noinline.} = discard #result = "Stack trace override procedure not registered.\n" stackTraceOverrideGetProgramCounters: StackTraceOverrideGetProgramCountersProc = - proc (maxLength: cint): seq[cuintptr_t] {.nimcall, gcsafe, locks: 0, raises: [], tags: [], noinline.} = + proc (maxLength: cint): seq[cuintptr_t] {.nimcall, gcsafe, raises: [], tags: [], noinline.} = discard stackTraceOverrideGetDebuggingInfo: StackTraceOverrideGetDebuggingInfoProc = proc (programCounters: seq[cuintptr_t], maxLength: cint): seq[StackTraceEntry] {. - nimcall, gcsafe, locks: 0, raises: [], tags: [], noinline.} = + nimcall, gcsafe, raises: [], tags: [], noinline.} = discard # Custom procedure registration. diff --git a/lib/wrappers/sqlite3.nim b/lib/wrappers/sqlite3.nim index 71921c10b..96c37e09c 100644 --- a/lib/wrappers/sqlite3.nim +++ b/lib/wrappers/sqlite3.nim @@ -121,7 +121,7 @@ type Callback* = proc (para1: pointer, para2: int32, para3, para4: cstringArray): int32{.cdecl.} - Tbind_destructor_func* = proc (para1: pointer){.cdecl, locks: 0, tags: [], gcsafe.} + Tbind_destructor_func* = proc (para1: pointer){.cdecl, tags: [], gcsafe.} Create_function_step_func* = proc (para1: Pcontext, para2: int32, para3: PValueArg){.cdecl.} Create_function_func_func* = proc (para1: Pcontext, para2: int32, diff --git a/nimsuggest/tests/tdef1.nim b/nimsuggest/tests/tdef1.nim index 2cd040ea1..5c86923b6 100644 --- a/nimsuggest/tests/tdef1.nim +++ b/nimsuggest/tests/tdef1.nim @@ -1,9 +1,9 @@ discard """ $nimsuggest --tester $file >def $1 -def;;skProc;;tdef1.hello;;proc (): string{.noSideEffect, gcsafe, locks: 0.};;$file;;9;;5;;"Return hello";;100 +def;;skProc;;tdef1.hello;;proc (): string{.noSideEffect, gcsafe.};;$file;;9;;5;;"Return hello";;100 >def $1 -def;;skProc;;tdef1.hello;;proc (): string{.noSideEffect, gcsafe, locks: 0.};;$file;;9;;5;;"Return hello";;100 +def;;skProc;;tdef1.hello;;proc (): string{.noSideEffect, gcsafe.};;$file;;9;;5;;"Return hello";;100 """ proc hello(): string = diff --git a/nimsuggest/tests/tdot4.nim b/nimsuggest/tests/tdot4.nim index e1ff96553..8681d045a 100644 --- a/nimsuggest/tests/tdot4.nim +++ b/nimsuggest/tests/tdot4.nim @@ -15,7 +15,7 @@ discard """ $nimsuggest --tester --maxresults:2 $file >sug $1 sug;;skProc;;tdot4.main;;proc (inp: string): string;;$file;;6;;5;;"";;100;;None -sug;;skFunc;;mstrutils.replace;;proc (s: string, sub: string, by: string): string{.noSideEffect, gcsafe, locks: 0.};;*fixtures/mstrutils.nim;;9;;5;;"this is a test version of strutils.replace, it simply returns `by`";;100;;None +sug;;skFunc;;mstrutils.replace;;proc (s: string, sub: string, by: string): string{.noSideEffect, gcsafe.};;*fixtures/mstrutils.nim;;9;;5;;"this is a test version of strutils.replace, it simply returns `by`";;100;;None """ # TODO - determine appropriate behaviour for further suggest output and test it diff --git a/nimsuggest/tests/tinclude.nim b/nimsuggest/tests/tinclude.nim index b67440b9e..66726f907 100644 --- a/nimsuggest/tests/tinclude.nim +++ b/nimsuggest/tests/tinclude.nim @@ -11,7 +11,7 @@ go() discard """ $nimsuggest --tester $file >def $path/tinclude.nim:7:14 -def;;skProc;;minclude_import.create;;proc (greeting: string, subject: string): Greet{.noSideEffect, gcsafe, locks: 0.};;*fixtures/minclude_include.nim;;3;;5;;"";;100 +def;;skProc;;minclude_import.create;;proc (greeting: string, subject: string): Greet{.noSideEffect, gcsafe.};;*fixtures/minclude_include.nim;;3;;5;;"";;100 >def $path/fixtures/minclude_include.nim:3:71 def;;skType;;minclude_types.Greet;;Greet;;*fixtures/minclude_types.nim;;4;;2;;"";;100 >def $path/fixtures/minclude_include.nim:3:71 diff --git a/nimsuggest/tests/tsug_template.nim b/nimsuggest/tests/tsug_template.nim index 15615f0af..a2558c81c 100644 --- a/nimsuggest/tests/tsug_template.nim +++ b/nimsuggest/tests/tsug_template.nim @@ -6,7 +6,7 @@ tmp#[!]# discard """ $nimsuggest --tester $file >sug $1 -sug;;skMacro;;tsug_template.tmpb;;macro (){.noSideEffect, gcsafe, locks: 0.};;$file;;2;;6;;"";;100;;Prefix +sug;;skMacro;;tsug_template.tmpb;;macro (){.noSideEffect, gcsafe.};;$file;;2;;6;;"";;100;;Prefix sug;;skConverter;;tsug_template.tmpc;;converter ();;$file;;3;;10;;"";;100;;Prefix sug;;skTemplate;;tsug_template.tmpa;;template ();;$file;;1;;9;;"";;100;;Prefix """ diff --git a/nimsuggest/tests/tuse.nim b/nimsuggest/tests/tuse.nim index 89a9c151a..deaf81ef2 100644 --- a/nimsuggest/tests/tuse.nim +++ b/nimsuggest/tests/tuse.nim @@ -14,9 +14,9 @@ proc #[!]#someProc*() = discard """ $nimsuggest --tester $file >use $1 -def;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe, locks: 0.};;$file;;9;;5;;"";;100 -use;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe, locks: 0.};;$file;;12;;0;;"";;100 +def;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe.};;$file;;9;;5;;"";;100 +use;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe.};;$file;;12;;0;;"";;100 >use $2 -def;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe, locks: 0.};;$file;;9;;5;;"";;100 -use;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe, locks: 0.};;$file;;12;;0;;"";;100 +def;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe.};;$file;;9;;5;;"";;100 +use;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe.};;$file;;12;;0;;"";;100 """ diff --git a/nimsuggest/tests/tv3.nim b/nimsuggest/tests/tv3.nim index 57ad86e4d..9d8b1ef2d 100644 --- a/nimsuggest/tests/tv3.nim +++ b/nimsuggest/tests/tv3.nim @@ -19,11 +19,11 @@ def skField tv3.Foo.bar string $file 5 4 "" 100 >outline $1 outline skType tv3.Foo Foo $file 4 2 "" 100 outline skField tv3.Foo.bar string $file 5 4 "" 100 -outline skProc tv3.test proc (f: Foo){.gcsafe, locks: 0.} $file 7 5 "" 100 +outline skProc tv3.test proc (f: Foo){.gcsafe.} $file 7 5 "" 100 >sug $1 sug skField bar string $file 5 4 "" 100 Prefix >globalSymbols test -def skProc tv3.test proc (f: Foo){.gcsafe, locks: 0.} $file 7 5 "" 100 +def skProc tv3.test proc (f: Foo){.gcsafe.} $file 7 5 "" 100 >globalSymbols Foo def skType tv3.Foo Foo $file 4 2 "" 100 >def $2 diff --git a/nimsuggest/tests/tv3_forward_definition.nim b/nimsuggest/tests/tv3_forward_definition.nim index 14c0dc2e2..392e019ff 100644 --- a/nimsuggest/tests/tv3_forward_definition.nim +++ b/nimsuggest/tests/tv3_forward_definition.nim @@ -7,17 +7,17 @@ let a = de#[!]#mo() discard """ $nimsuggest --v3 --tester $file >use $1 -use skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, locks: 0.} $file 1 5 "" 100 -def skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, locks: 0.} $file 3 5 "" 100 -use skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, locks: 0.} $file 5 8 "" 100 +use skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 1 5 "" 100 +def skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 3 5 "" 100 +use skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 5 8 "" 100 >use $2 -use skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, locks: 0.} $file 1 5 "" 100 -def skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, locks: 0.} $file 3 5 "" 100 -use skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, locks: 0.} $file 5 8 "" 100 +use skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 1 5 "" 100 +def skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 3 5 "" 100 +use skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 5 8 "" 100 >declaration $1 -declaration skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, locks: 0.} $file 3 5 "" 100 +declaration skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 3 5 "" 100 >declaration $2 -declaration skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, locks: 0.} $file 1 5 "" 100 +declaration skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 1 5 "" 100 >declaration $3 -declaration skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, locks: 0.} $file 1 5 "" 100 +declaration skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 1 5 "" 100 """ diff --git a/nimsuggest/tests/tv3_globalSymbols.nim b/nimsuggest/tests/tv3_globalSymbols.nim index 85814cadd..f965a07aa 100644 --- a/nimsuggest/tests/tv3_globalSymbols.nim +++ b/nimsuggest/tests/tv3_globalSymbols.nim @@ -7,8 +7,8 @@ proc BBtokenA(): int = 5 discard """ $nimsuggest --v3 --tester $file >globalSymbols token -def skProc tv3_globalSymbols.token proc (): int{.noSideEffect, gcsafe, locks: 0.} $file 4 5 "" 100 -def skProc tv3_globalSymbols.tokenA proc (): int{.noSideEffect, gcsafe, locks: 0.} $file 3 5 "" 100 -def skProc tv3_globalSymbols.Btoken proc (): int{.noSideEffect, gcsafe, locks: 0.} $file 2 5 "" 100 -def skProc tv3_globalSymbols.BBtokenA proc (): int{.noSideEffect, gcsafe, locks: 0.} $file 5 5 "" 100 +def skProc tv3_globalSymbols.token proc (): int{.noSideEffect, gcsafe.} $file 4 5 "" 100 +def skProc tv3_globalSymbols.tokenA proc (): int{.noSideEffect, gcsafe.} $file 3 5 "" 100 +def skProc tv3_globalSymbols.Btoken proc (): int{.noSideEffect, gcsafe.} $file 2 5 "" 100 +def skProc tv3_globalSymbols.BBtokenA proc (): int{.noSideEffect, gcsafe.} $file 5 5 "" 100 """ diff --git a/tests/arc/twrong_sinkinference.nim b/tests/arc/twrong_sinkinference.nim index 59930a9fa..ecf09d28a 100644 --- a/tests/arc/twrong_sinkinference.nim +++ b/tests/arc/twrong_sinkinference.nim @@ -1,6 +1,6 @@ discard """ cmd: "nim c --gc:arc $file" - errormsg: "type mismatch: got <proc (a: string, b: sink string){.noSideEffect, gcsafe, locks: 0.}>" + errormsg: "type mismatch: got <proc (a: string, b: sink string){.noSideEffect, gcsafe.}>" line: 18 """ diff --git a/tests/bind/tnicerrorforsymchoice.nim b/tests/bind/tnicerrorforsymchoice.nim index 684b83239..6001b6b09 100644 --- a/tests/bind/tnicerrorforsymchoice.nim +++ b/tests/bind/tnicerrorforsymchoice.nim @@ -1,5 +1,5 @@ discard """ - errormsg: "type mismatch: got <proc (s: TScgi: ScgiState or AsyncScgiState) | proc (client: AsyncSocket, headers: StringTableRef, input: string){.noSideEffect, gcsafe, locks: 0.}>" + errormsg: "type mismatch: got <proc (s: TScgi: ScgiState or AsyncScgiState) | proc (client: AsyncSocket, headers: StringTableRef, input: string){.noSideEffect, gcsafe.}>" line: 23 """ diff --git a/tests/closure/tclosure.nim b/tests/closure/tclosure.nim index 8ae6c44bb..1bbe4cd0d 100644 --- a/tests/closure/tclosure.nim +++ b/tests/closure/tclosure.nim @@ -65,7 +65,7 @@ block tclosure: # bug #5015 - type Mutator = proc(matched: string): string {.noSideEffect, gcsafe, locks: 0.} + type Mutator = proc(matched: string): string {.noSideEffect, gcsafe.} proc putMutated( MutatorCount: static[int], diff --git a/tests/closure/tinvalidclosure.nim b/tests/closure/tinvalidclosure.nim index 47f3f105f..37d0f68a2 100644 --- a/tests/closure/tinvalidclosure.nim +++ b/tests/closure/tinvalidclosure.nim @@ -1,5 +1,5 @@ discard """ - errormsg: "type mismatch: got <proc (x: int){.nimcall, gcsafe, locks: 0.}>" + errormsg: "type mismatch: got <proc (x: int){.nimcall, gcsafe.}>" line: 12 """ diff --git a/tests/closure/tinvalidclosure5.nim b/tests/closure/tinvalidclosure5.nim index d03d93867..3b5f46a40 100644 --- a/tests/closure/tinvalidclosure5.nim +++ b/tests/closure/tinvalidclosure5.nim @@ -1,5 +1,5 @@ discard """ - errormsg: "type mismatch: got <proc (){.closure, gcsafe, locks: 0.}> but expected 'A = proc (){.nimcall.}'" + errormsg: "type mismatch: got <proc (){.closure, gcsafe.}> but expected 'A = proc (){.nimcall.}'" line: 9 """ diff --git a/tests/closure/tnested.nim b/tests/closure/tnested.nim index ca8d0e08b..405ebd9b9 100644 --- a/tests/closure/tnested.nim +++ b/tests/closure/tnested.nim @@ -33,7 +33,7 @@ py py px 6 -proc (){.closure, gcsafe, locks: 0.} +proc (){.closure, gcsafe.} ''' """ diff --git a/tests/effects/teffects1.nim b/tests/effects/teffects1.nim index ca9021999..68bafa94d 100644 --- a/tests/effects/teffects1.nim +++ b/tests/effects/teffects1.nim @@ -34,7 +34,7 @@ proc foo(x: int): string {.nimcall, raises: [ValueError].} = var p: MyProcType = foo #[tt.Error ^ -type mismatch: got <proc (x: int): string{.nimcall, noSideEffect, gcsafe, locks: 0.}> but expected 'MyProcType = proc (x: int): string{.closure.}' +type mismatch: got <proc (x: int): string{.nimcall, noSideEffect, gcsafe.}> but expected 'MyProcType = proc (x: int): string{.closure.}' Calling convention mismatch: got '{.nimcall.}', but expected '{.closure.}'. .raise effects differ ]# diff --git a/tests/effects/teffects11.nim b/tests/effects/teffects11.nim index e4098e959..20b7026ab 100644 --- a/tests/effects/teffects11.nim +++ b/tests/effects/teffects11.nim @@ -1,6 +1,6 @@ discard """ action: compile -errormsg: "type mismatch: got <proc (x: int){.gcsafe, locks: 0.}>" +errormsg: "type mismatch: got <proc (x: int){.gcsafe.}>" line: 21 """ diff --git a/tests/effects/teffects19.nim b/tests/effects/teffects19.nim index 49fb87523..6b4ab0819 100644 --- a/tests/effects/teffects19.nim +++ b/tests/effects/teffects19.nim @@ -1,6 +1,6 @@ discard """ action: compile -errormsg: "type mismatch: got <proc (i: int){.gcsafe, locks: 0.}>" +errormsg: "type mismatch: got <proc (i: int){.gcsafe.}>" line: 23 """ diff --git a/tests/effects/tgcsafe2.nim b/tests/effects/tgcsafe2.nim index 07da4e3f8..6268592a9 100644 --- a/tests/effects/tgcsafe2.nim +++ b/tests/effects/tgcsafe2.nim @@ -1,5 +1,5 @@ discard """ - errormsg: '''type mismatch: got <proc (s: string){.locks: 0.}>''' + errormsg: '''type mismatch: got <proc (s: string)>''' line: 11 """ #5620 diff --git a/tests/errmsgs/t10489_a.nim b/tests/errmsgs/t10489_a.nim index 71a6cc3c4..c762ce876 100644 --- a/tests/errmsgs/t10489_a.nim +++ b/tests/errmsgs/t10489_a.nim @@ -1,5 +1,5 @@ discard """ -errormsg: "invalid type: 'macro (body: untyped): untyped{.noSideEffect, gcsafe, locks: 0.}' for let. Did you mean to call the macro with '()'?" +errormsg: "invalid type: 'macro (body: untyped): untyped{.noSideEffect, gcsafe.}' for let. Did you mean to call the macro with '()'?" line: 9 """ diff --git a/tests/errmsgs/t10489_b.nim b/tests/errmsgs/t10489_b.nim index 4b0b876e5..df05f0e6e 100644 --- a/tests/errmsgs/t10489_b.nim +++ b/tests/errmsgs/t10489_b.nim @@ -1,5 +1,5 @@ discard """ -errormsg: "invalid type: 'macro (body: untyped): untyped{.noSideEffect, gcsafe, locks: 0.}' for const. Did you mean to call the macro with '()'?" +errormsg: "invalid type: 'macro (body: untyped): untyped{.noSideEffect, gcsafe.}' for const. Did you mean to call the macro with '()'?" line: 9 """ diff --git a/tests/errmsgs/t18886.nim b/tests/errmsgs/t18886.nim index cad62d431..8ed160c64 100644 --- a/tests/errmsgs/t18886.nim +++ b/tests/errmsgs/t18886.nim @@ -3,8 +3,8 @@ discard """ errormsg: "" nimout: ''' t18886.nim(18, 24) Error: ambiguous identifier: 'bar' -- you need a helper proc to disambiguate the following: - t18886.bar: proc (i: ptr int){.noSideEffect, gcsafe, locks: 0.} - t18886.bar: proc (i: ptr char){.noSideEffect, gcsafe, locks: 0.} + t18886.bar: proc (i: ptr int){.noSideEffect, gcsafe.} + t18886.bar: proc (i: ptr char){.noSideEffect, gcsafe.} ''' """ diff --git a/tests/errmsgs/t2614.nim b/tests/errmsgs/t2614.nim index 4034249e7..031ecb9d1 100644 --- a/tests/errmsgs/t2614.nim +++ b/tests/errmsgs/t2614.nim @@ -2,9 +2,9 @@ discard """ cmd: "nim check $options --hints:off $file" errormsg: "" nimout: ''' -t2614.nim(19, 27) Error: type mismatch: got <array[0..1, proc (){.locks: <unknown>.}]> but expected 'array[0..1, proc (){.closure.}]' +t2614.nim(19, 27) Error: type mismatch: got <array[0..1, proc ()]> but expected 'array[0..1, proc (){.closure.}]' Calling convention mismatch: got '{.nimcall.}', but expected '{.closure.}'. -t2614.nim(21, 22) Error: type mismatch: got <seq[proc (){.locks: <unknown>.}]> but expected 'seq[proc (){.closure.}]' +t2614.nim(21, 22) Error: type mismatch: got <seq[proc ()]> but expected 'seq[proc (){.closure.}]' Calling convention mismatch: got '{.nimcall.}', but expected '{.closure.}'. ''' """ diff --git a/tests/errmsgs/t5167_4.nim b/tests/errmsgs/t5167_4.nim index 7a263622b..dafd7754d 100644 --- a/tests/errmsgs/t5167_4.nim +++ b/tests/errmsgs/t5167_4.nim @@ -1,5 +1,5 @@ discard """ -errormsg: "type mismatch: got <proc [*missing parameters*](x: int) | proc (x: string){.gcsafe, locks: 0.}>" +errormsg: "type mismatch: got <proc [*missing parameters*](x: int) | proc (x: string){.gcsafe.}>" line: 19 """ diff --git a/tests/errmsgs/tgcsafety.nim b/tests/errmsgs/tgcsafety.nim index 701adeebf..66496d364 100644 --- a/tests/errmsgs/tgcsafety.nim +++ b/tests/errmsgs/tgcsafety.nim @@ -1,8 +1,8 @@ discard """ cmd: "nim check $file" -errormsg: "type mismatch: got <AsyncHttpServer, Port, proc (req: Request): Future[system.void]{.locks: <unknown>.}>" +errormsg: "type mismatch: got <AsyncHttpServer, Port, proc (req: Request): Future[system.void]>" nimout: ''' -tgcsafety.nim(31, 18) Error: type mismatch: got <AsyncHttpServer, Port, proc (req: Request): Future[system.void]{.locks: <unknown>.}> +tgcsafety.nim(31, 18) Error: type mismatch: got <AsyncHttpServer, Port, proc (req: Request): Future[system.void]> but expected one of: proc serve(server: AsyncHttpServer; port: Port; callback: proc (request: Request): Future[void] {.closure, gcsafe.}; @@ -10,7 +10,7 @@ proc serve(server: AsyncHttpServer; port: Port; Future[void]) first type mismatch at position: 3 required type for callback: proc (request: Request): Future[system.void]{.closure, gcsafe.} - but expression 'cb' is of type: proc (req: Request): Future[system.void]{.locks: <unknown>.} + but expression 'cb' is of type: proc (req: Request): Future[system.void] This expression is not GC-safe. Annotate the proc with {.gcsafe.} to get extended error information. expression: serve(server, Port(7898), cb) diff --git a/tests/errmsgs/tproc_mismatch.nim b/tests/errmsgs/tproc_mismatch.nim index f92589d96..16f319f3b 100644 --- a/tests/errmsgs/tproc_mismatch.nim +++ b/tests/errmsgs/tproc_mismatch.nim @@ -3,36 +3,36 @@ discard """ cmd: '''nim check --hints:off $options $file''' nimoutFull: true nimout: ''' -tproc_mismatch.nim(38, 52) Error: type mismatch: got <proc (a: int, c: float){.cdecl, noSideEffect, gcsafe, locks: 0.}> but expected 'proc (a: int, c: float){.closure, noSideEffect.}' +tproc_mismatch.nim(38, 52) Error: type mismatch: got <proc (a: int, c: float){.cdecl, noSideEffect, gcsafe.}> but expected 'proc (a: int, c: float){.closure, noSideEffect.}' Calling convention mismatch: got '{.cdecl.}', but expected '{.closure.}'. -tproc_mismatch.nim(42, 6) Error: type mismatch: got <proc (){.inline, noSideEffect, gcsafe, locks: 0.}> +tproc_mismatch.nim(42, 6) Error: type mismatch: got <proc (){.inline, noSideEffect, gcsafe.}> but expected one of: proc bar(a: proc ()) first type mismatch at position: 1 required type for a: proc (){.closure.} - but expression 'fn1' is of type: proc (){.inline, noSideEffect, gcsafe, locks: 0.} + but expression 'fn1' is of type: proc (){.inline, noSideEffect, gcsafe.} Calling convention mismatch: got '{.inline.}', but expected '{.closure.}'. expression: bar(fn1) -tproc_mismatch.nim(46, 8) Error: type mismatch: got <proc (){.inline, noSideEffect, gcsafe, locks: 0.}> but expected 'proc (){.closure.}' +tproc_mismatch.nim(46, 8) Error: type mismatch: got <proc (){.inline, noSideEffect, gcsafe.}> but expected 'proc (){.closure.}' Calling convention mismatch: got '{.inline.}', but expected '{.closure.}'. -tproc_mismatch.nim(51, 8) Error: type mismatch: got <proc (){.locks: 0.}> but expected 'proc (){.closure, noSideEffect.}' +tproc_mismatch.nim(51, 8) Error: type mismatch: got <proc ()> but expected 'proc (){.closure, noSideEffect.}' Calling convention mismatch: got '{.nimcall.}', but expected '{.closure.}'. Pragma mismatch: got '{..}', but expected '{.noSideEffect.}'. -tproc_mismatch.nim(55, 8) Error: type mismatch: got <proc (a: int){.noSideEffect, gcsafe, locks: 0.}> but expected 'proc (a: float){.closure.}' +tproc_mismatch.nim(55, 8) Error: type mismatch: got <proc (a: int){.noSideEffect, gcsafe.}> but expected 'proc (a: float){.closure.}' Calling convention mismatch: got '{.nimcall.}', but expected '{.closure.}'. -tproc_mismatch.nim(64, 9) Error: type mismatch: got <proc (a: int){.locks: 0.}> but expected 'proc (a: int){.closure, gcsafe.}' +tproc_mismatch.nim(64, 9) Error: type mismatch: got <proc (a: int)> but expected 'proc (a: int){.closure, gcsafe.}' Calling convention mismatch: got '{.nimcall.}', but expected '{.closure.}'. Pragma mismatch: got '{..}', but expected '{.gcsafe.}'. tproc_mismatch.nim(72, 9) Error: type mismatch: got <proc (a: int): int{.nimcall.}> but expected 'proc (a: int): int{.cdecl.}' Calling convention mismatch: got '{.nimcall.}', but expected '{.cdecl.}'. tproc_mismatch.nim(73, 9) Error: type mismatch: got <proc (a: int): int{.cdecl.}> but expected 'proc (a: int): int{.nimcall.}' Calling convention mismatch: got '{.cdecl.}', but expected '{.nimcall.}'. -tproc_mismatch.nim(77, 9) Error: type mismatch: got <proc (a: int){.closure, locks: 3.}> but expected 'proc (a: int){.closure, locks: 1.}' - Pragma mismatch: got '{.locks: 3.}', but expected '{.locks: 1.}'. -lock levels differ ''' """ + + + block: # CallConv mismatch func a(a: int, c: float) {.cdecl.} = discard var b: proc(a: int, c: float) {.noSideEffect.} = a @@ -71,7 +71,4 @@ block: # Indrection through pragmas var fn2: proc(a: int): int {.inl2, p2.} fn2 = fn1 fn1 = fn2 -block: # Lock levels differ - var fn1: proc(a: int){.locks: 3.} - var fn2: proc(a: int){.locks: 1.} - fn2 = fn1 + diff --git a/tests/errmsgs/tsigmatch.nim b/tests/errmsgs/tsigmatch.nim index 49b355982..85ed34169 100644 --- a/tests/errmsgs/tsigmatch.nim +++ b/tests/errmsgs/tsigmatch.nim @@ -12,34 +12,34 @@ proc f(b: B) but expression 'A()' is of type: A expression: f(A(), "extra") -tsigmatch.nim(125, 6) Error: type mismatch: got <(string, proc (){.gcsafe, locks: 0.})> +tsigmatch.nim(125, 6) Error: type mismatch: got <(string, proc (){.gcsafe.})> but expected one of: proc foo(x: (string, proc ())) first type mismatch at position: 1 required type for x: (string, proc (){.closure.}) - but expression '("foobar", proc () = echo(["Hello!"]))' is of type: (string, proc (){.gcsafe, locks: 0.}) + but expression '("foobar", proc () = echo(["Hello!"]))' is of type: (string, proc (){.gcsafe.}) expression: foo(("foobar", proc () = echo(["Hello!"]))) -tsigmatch.nim(132, 11) Error: type mismatch: got <proc (s: string): string{.noSideEffect, gcsafe, locks: 0.}> +tsigmatch.nim(132, 11) Error: type mismatch: got <proc (s: string): string{.noSideEffect, gcsafe.}> but expected one of: proc foo[T, S](op: proc (x: T): S {.cdecl.}): auto first type mismatch at position: 1 required type for op: proc (x: T): S{.cdecl.} - but expression 'fun' is of type: proc (s: string): string{.noSideEffect, gcsafe, locks: 0.} + but expression 'fun' is of type: proc (s: string): string{.noSideEffect, gcsafe.} proc foo[T, S](op: proc (x: T): S {.safecall.}): auto first type mismatch at position: 1 required type for op: proc (x: T): S{.safecall.} - but expression 'fun' is of type: proc (s: string): string{.noSideEffect, gcsafe, locks: 0.} + but expression 'fun' is of type: proc (s: string): string{.noSideEffect, gcsafe.} expression: foo(fun) -tsigmatch.nim(143, 13) Error: type mismatch: got <array[0..0, proc (x: int){.gcsafe, locks: 0.}]> +tsigmatch.nim(143, 13) Error: type mismatch: got <array[0..0, proc (x: int){.gcsafe.}]> but expected one of: -proc takesFuncs(fs: openArray[proc (x: int) {.gcsafe, locks: 0.}]) +proc takesFuncs(fs: openArray[proc (x: int) {.gcsafe.}]) first type mismatch at position: 1 - required type for fs: openArray[proc (x: int){.closure, gcsafe, locks: 0.}] - but expression '[proc (x: int) {.gcsafe, locks: 0.} = echo [x]]' is of type: array[0..0, proc (x: int){.gcsafe, locks: 0.}] + required type for fs: openArray[proc (x: int){.closure, gcsafe.}] + but expression '[proc (x: int) {.gcsafe.} = echo [x]]' is of type: array[0..0, proc (x: int){.gcsafe.}] -expression: takesFuncs([proc (x: int) {.gcsafe, locks: 0.} = echo [x]]) +expression: takesFuncs([proc (x: int) {.gcsafe.} = echo [x]]) tsigmatch.nim(149, 4) Error: type mismatch: got <int literal(10), a0: int literal(5), string> but expected one of: proc f(a0: uint8; b: string) @@ -135,12 +135,12 @@ block: # bug #10285 Function signature don't match when inside seq/array/openArray # Note: the error message now shows `closure` which helps debugging the issue # out why it doesn't match - proc takesFunc(f: proc (x: int) {.gcsafe, locks: 0.}) = + proc takesFunc(f: proc (x: int) {.gcsafe.}) = echo "takes single Func" - proc takesFuncs(fs: openArray[proc (x: int) {.gcsafe, locks: 0.}]) = + proc takesFuncs(fs: openArray[proc (x: int) {.gcsafe.}]) = echo "takes multiple Func" - takesFunc(proc (x: int) {.gcsafe, locks: 0.} = echo x) # works - takesFuncs([proc (x: int) {.gcsafe, locks: 0.} = echo x]) # fails + takesFunc(proc (x: int) {.gcsafe.} = echo x) # works + takesFuncs([proc (x: int) {.gcsafe.} = echo x]) # fails block: # bug https://github.com/nim-lang/Nim/issues/11061#issuecomment-508970465 diff --git a/tests/errmsgs/ttypeAllowed.nim b/tests/errmsgs/ttypeAllowed.nim index 516b616e0..fdb4c70b8 100644 --- a/tests/errmsgs/ttypeAllowed.nim +++ b/tests/errmsgs/ttypeAllowed.nim @@ -2,10 +2,10 @@ discard """ cmd: "nim check $file" errormsg: "" nimout: ''' -ttypeAllowed.nim(13, 5) Error: invalid type: 'iterator (a: int, b: int, step: Positive): int{.inline, noSideEffect, gcsafe, locks: 0.}' for let -ttypeAllowed.nim(17, 7) Error: invalid type: 'iterator (a: int, b: int, step: Positive): int{.inline, noSideEffect, gcsafe, locks: 0.}' for const -ttypeAllowed.nim(21, 5) Error: invalid type: 'iterator (a: int, b: int, step: Positive): int{.inline, noSideEffect, gcsafe, locks: 0.}' for var -ttypeAllowed.nim(26, 10) Error: invalid type: 'iterator (a: int, b: int, step: Positive): int{.inline, noSideEffect, gcsafe, locks: 0.}' for result +ttypeAllowed.nim(13, 5) Error: invalid type: 'iterator (a: int, b: int, step: Positive): int{.inline, noSideEffect, gcsafe.}' for let +ttypeAllowed.nim(17, 7) Error: invalid type: 'iterator (a: int, b: int, step: Positive): int{.inline, noSideEffect, gcsafe.}' for const +ttypeAllowed.nim(21, 5) Error: invalid type: 'iterator (a: int, b: int, step: Positive): int{.inline, noSideEffect, gcsafe.}' for var +ttypeAllowed.nim(26, 10) Error: invalid type: 'iterator (a: int, b: int, step: Positive): int{.inline, noSideEffect, gcsafe.}' for result ''' """ diff --git a/tests/generics/tprevent_double_bind.nim b/tests/generics/tprevent_double_bind.nim index 86e080ab6..d8fc6e5d3 100644 --- a/tests/generics/tprevent_double_bind.nim +++ b/tests/generics/tprevent_double_bind.nim @@ -1,5 +1,5 @@ discard """ - errormsg: "type mismatch: got <TT[seq[string]], proc (v: int){.gcsafe, locks: 0.}>" + errormsg: "type mismatch: got <TT[seq[string]], proc (v: int){.gcsafe.}>" line: 20 """ diff --git a/tests/lent/t16898.nim b/tests/lent/t16898.nim index ea7c934ef..a69c6d244 100644 --- a/tests/lent/t16898.nim +++ b/tests/lent/t16898.nim @@ -1,5 +1,5 @@ discard """ - errormsg: "invalid type: 'lent QuadraticExt' in this context: 'proc (r: var QuadraticExt, a: lent QuadraticExt, b: lent QuadraticExt){.noSideEffect, gcsafe, locks: 0.}' for proc" + errormsg: "invalid type: 'lent QuadraticExt' in this context: 'proc (r: var QuadraticExt, a: lent QuadraticExt, b: lent QuadraticExt){.noSideEffect, gcsafe.}' for proc" """ # bug #16898 diff --git a/tests/overload/tproc_types_dont_like_subtypes.nim b/tests/overload/tproc_types_dont_like_subtypes.nim index d322f41be..6774be156 100644 --- a/tests/overload/tproc_types_dont_like_subtypes.nim +++ b/tests/overload/tproc_types_dont_like_subtypes.nim @@ -1,5 +1,5 @@ discard """ - errormsg: "got <B, proc (b: B){.closure, gcsafe, locks: 0.}>" + errormsg: "got <B, proc (b: B){.closure, gcsafe.}>" line: 20 """ diff --git a/tests/pragmas/tlocks.nim b/tests/pragmas/tlocks.nim index 6c2a9f9e9..5d6fcdd9c 100644 --- a/tests/pragmas/tlocks.nim +++ b/tests/pragmas/tlocks.nim @@ -1,7 +1,3 @@ -discard """ - matrix: "--mm:arc; --mm:refc" -""" - type SomeBase* = ref object of RootObj type SomeDerived* = ref object of SomeBase memberProc*: proc () diff --git a/tests/statictypes/t9255.nim b/tests/statictypes/t9255.nim index 99ca2a23c..aec2fbaf5 100644 --- a/tests/statictypes/t9255.nim +++ b/tests/statictypes/t9255.nim @@ -1,6 +1,6 @@ discard """ errormsg: ''' -type mismatch: got <proc (a0: int): string{.noSideEffect, gcsafe, locks: 0.}> +type mismatch: got <proc (a0: int): string{.noSideEffect, gcsafe.}> ''' line: 13 """ diff --git a/tests/stdlib/ttimes.nim b/tests/stdlib/ttimes.nim index 4f396c735..f6159d942 100644 --- a/tests/stdlib/ttimes.nim +++ b/tests/stdlib/ttimes.nim @@ -11,12 +11,12 @@ when not defined(js): proc staticTz(hours, minutes, seconds: int = 0): Timezone {.noSideEffect.} = let offset = hours * 3600 + minutes * 60 + seconds - proc zonedTimeFromAdjTime(adjTime: Time): ZonedTime {.locks: 0.} = + proc zonedTimeFromAdjTime(adjTime: Time): ZonedTime = result.isDst = false result.utcOffset = offset result.time = adjTime + initDuration(seconds = offset) - proc zonedTimeFromTime(time: Time): ZonedTime {.locks: 0.}= + proc zonedTimeFromTime(time: Time): ZonedTime = result.isDst = false result.utcOffset = offset result.time = time diff --git a/tests/vm/tvmmisc.nim b/tests/vm/tvmmisc.nim index 25ec2cc12..ad1dfc3df 100644 --- a/tests/vm/tvmmisc.nim +++ b/tests/vm/tvmmisc.nim @@ -361,7 +361,7 @@ block: # bug #14340 envelopeSin[a]() block: - type Mutator = proc() {.noSideEffect, gcsafe, locks: 0.} + type Mutator = proc() {.noSideEffect, gcsafe.} proc mutator0() = discard const mTable = [Mutator(mutator0)] var i=0 |