From 55f57cd0e005668c2ec7b2137a9b86dd4d713e74 Mon Sep 17 00:00:00 2001 From: Lancer Date: Sun, 17 Jul 2022 15:53:50 +0200 Subject: [PATCH 01/19] .forbids pragma: defining illegal effects for proc types This patch intends to define the opposite of the .tags pragma: a way to define effects which are not allowed in a proc. --- compiler/ast.nim | 3 +- compiler/docgen.nim | 4 ++- compiler/pragmas.nim | 12 ++++---- compiler/semcall.nim | 4 ++- compiler/sempass2.nim | 54 ++++++++++++++++++++++++++++++++---- compiler/semstmts.nim | 2 +- compiler/types.nim | 17 ++++++++++++ compiler/vmops.nim | 2 ++ compiler/wordrecg.nim | 4 +-- lib/std/effecttraits.nim | 9 ++++++ tests/effects/teffects11.nim | 21 ++++++++++++++ tests/effects/teffects12.nim | 52 ++++++++++++++++++++++++++++++++++ 12 files changed, 167 insertions(+), 17 deletions(-) create mode 100644 tests/effects/teffects11.nim create mode 100644 tests/effects/teffects12.nim diff --git a/compiler/ast.nim b/compiler/ast.nim index 6610a1333d327..40e235a471f97 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -347,7 +347,8 @@ const ensuresEffects* = 2 # 'ensures' annotation tagEffects* = 3 # user defined tag ('gc', 'time' etc.) pragmasEffects* = 4 # not an effect, but a slot for pragmas in proc type - effectListLen* = 5 # list of effects list + notTagEffects* = 5 # list of illegal effects + effectListLen* = 6 # list of effects list nkLastBlockStmts* = {nkRaiseStmt, nkReturnStmt, nkBreakStmt, nkContinueStmt} # these must be last statements in a block diff --git a/compiler/docgen.nim b/compiler/docgen.nim index d728c535fb0db..34b70ec9a9154 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -1212,8 +1212,9 @@ proc documentRaises*(cache: IdentCache; n: PNode) = let p3 = documentWriteEffect(cache, n, sfWrittenTo, "writes") let p4 = documentNewEffect(cache, n) let p5 = documentWriteEffect(cache, n, sfEscapes, "escapes") + let p6 = documentEffect(cache, n, pragmas, wForbids, notTagEffects) - if p1 != nil or p2 != nil or p3 != nil or p4 != nil or p5 != nil: + if p1 != nil or p2 != nil or p3 != nil or p4 != nil or p5 != nil or p6 != nil: if pragmas.kind == nkEmpty: n[pragmasPos] = newNodeI(nkPragma, n.info) if p1 != nil: n[pragmasPos].add p1 @@ -1221,6 +1222,7 @@ proc documentRaises*(cache: IdentCache; n: PNode) = if p3 != nil: n[pragmasPos].add p3 if p4 != nil: n[pragmasPos].add p4 if p5 != nil: n[pragmasPos].add p5 + if p6 != nil: n[pragmasPos].add p6 proc generateDoc*(d: PDoc, n, orig: PNode, docFlags: DocFlags = kDefault) = ## Goes through nim nodes recursively and collects doc comments. diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 1487a871d2f4f..417941cd1b59e 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -32,7 +32,7 @@ const wCompilerProc, wNonReloadable, wCore, wProcVar, wVarargs, wCompileTime, wMerge, wBorrow, wImportCompilerProc, wThread, wAsmNoStackFrame, wDiscardable, wNoInit, wCodegenDecl, - wGensym, wInject, wRaises, wEffectsOf, wTags, wLocks, wDelegator, wGcSafe, + wGensym, wInject, wRaises, wEffectsOf, wTags, wForbids, wLocks, wDelegator, wGcSafe, wConstructor, wLiftLocals, wStackTrace, wLineTrace, wNoDestroy, wRequires, wEnsures, wEnforceNoRaises} converterPragmas* = procPragmas @@ -45,7 +45,7 @@ const iteratorPragmas* = declPragmas + {FirstCallConv..LastCallConv, wNoSideEffect, wSideEffect, wMagic, wBorrow, wDiscardable, wGensym, wInject, wRaises, wEffectsOf, - wTags, wLocks, wGcSafe, wRequires, wEnsures} + wTags, wForbids, wLocks, wGcSafe, wRequires, wEnsures} exprPragmas* = {wLine, wLocks, wNoRewrite, wGcSafe, wNoSideEffect} stmtPragmas* = { wHint, wWarning, wError, @@ -65,7 +65,7 @@ const lambdaPragmas* = {FirstCallConv..LastCallConv, wNoSideEffect, wSideEffect, wNoreturn, wNosinks, wDynlib, wHeader, wThread, wAsmNoStackFrame, - wRaises, wLocks, wTags, wRequires, wEnsures, wEffectsOf, + wRaises, wLocks, wTags, wForbids, wRequires, wEnsures, wEffectsOf, wGcSafe, wCodegenDecl, wNoInit, wCompileTime} typePragmas* = declPragmas + {wMagic, wAcyclic, wPure, wHeader, wCompilerProc, wCore, wFinal, wSize, wShallow, @@ -85,7 +85,7 @@ const paramPragmas* = {wNoalias, wInject, wGensym} letPragmas* = varPragmas procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNoSideEffect, - wThread, wRaises, wEffectsOf, wLocks, wTags, wGcSafe, + wThread, wRaises, wEffectsOf, wLocks, wTags, wForbids, wGcSafe, wRequires, wEnsures} forVarPragmas* = {wInject, wGensym} allRoutinePragmas* = methodPragmas + iteratorPragmas + lambdaPragmas @@ -820,7 +820,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, elif not isStatement: localError(c.config, n.info, "'cast' pragma only allowed in a statement context") case whichPragma(key[1]) - of wRaises, wTags: pragmaRaisesOrTags(c, key[1]) + of wRaises, wTags, wForbids: pragmaRaisesOrTags(c, key[1]) else: discard return elif key.kind notin nkIdentKinds: @@ -1184,7 +1184,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, noVal(c, it) if sym == nil: invalidPragma(c, it) of wLine: pragmaLine(c, it) - of wRaises, wTags: pragmaRaisesOrTags(c, it) + of wRaises, wTags, wForbids: pragmaRaisesOrTags(c, it) of wLocks: if sym == nil: pragmaLockStmt(c, it) elif sym.typ == nil: invalidPragma(c, it) diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 36658d472d610..2db897f1ce466 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -154,6 +154,8 @@ proc effectProblem(f, a: PType; result: var string; c: PContext) = "proc with {.locks: 0.} to get extended error information." of efEffectsDelayed: result.add "\n The `.effectsOf` annotations differ." + of efTagsIllegal: + result.add "\n The `.forbids` requirements catched an illegal tag." when defined(drnim): if not c.graph.compatibleProps(c.graph, f, a): result.add "\n The `.requires` or `.ensures` properties are incompatible." @@ -730,4 +732,4 @@ proc searchForBorrowProc(c: PContext, startScope: PScope, fn: PSym): PSym = result = nil elif result.magic in {mArrPut, mArrGet}: # cannot borrow these magics for now - result = nil \ No newline at end of file + result = nil diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 0ee806f3678fc..2ae0e97b35332 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -66,6 +66,7 @@ type TEffects = object exc: PNode # stack of exceptions tags: PNode # list of tags + forbids: PNode # list of tags bottom, inTryStmt, inExceptOrFinallyStmt, leftPartOfAsgn: int owner: PSym ownerModule: PSym @@ -388,6 +389,12 @@ proc addTag(a: PEffects, e, comesFrom: PNode) = if sameType(aa[i].typ.skipTypes(skipPtrs), e.typ.skipTypes(skipPtrs)): return throws(a.tags, e, comesFrom) +proc addNotTag(a: PEffects, e, comesFrom: PNode) = + var aa = a.forbids + for i in 0.." +line: 21 +""" + +type + Effect1 = object + Effect2 = object + Effect3 = object + +proc test(fnc: proc(x: int): void {.forbids: [Effect2].}) {.tags: [Effect1, Effect3, RootEffect].} = + fnc(1) + +proc t1(x: int): void = echo $x +proc t2(x: int): void {.tags: [Effect2].} = echo $x +proc t3(x: int): void {.tags: [Effect3].} = echo $x + +test(t1) +test(t3) +test(t2) diff --git a/tests/effects/teffects12.nim b/tests/effects/teffects12.nim new file mode 100644 index 0000000000000..5f5499c3853b1 --- /dev/null +++ b/tests/effects/teffects12.nim @@ -0,0 +1,52 @@ +discard """ +action: compile +""" + +import std/locks + +type + Test2Effect* = object + Test2* = object + value2*: int + Test1Effect* = object + Test1* = object + value1*: int + Main* = object + test1Lock: Lock + test1: Test1 + test2Lock: Lock + test2: Test2 + +proc `=copy`(obj1: var Test2, obj2: Test2) {.error.} +proc `=copy`(obj1: var Test1, obj2: Test1) {.error.} +proc `=copy`(obj1: var Main, obj2: Main) {.error.} + +proc withTest1(main: var Main, + fn: proc(test1: var Test1) {.gcsafe, forbids: [Test1Effect].}) {.gcsafe, tags: [Test1Effect, RootEffect].} = + withLock(main.test1Lock): + fn(main.test1) + +proc withTest2(main: var Main, + fn: proc(test1: var Test2) {.gcsafe, forbids: [Test2Effect].}) {.gcsafe, tags: [Test2Effect, RootEffect].} = + withLock(main.test2Lock): + fn(main.test2) + +proc newMain(): Main = + var test1lock: Lock + initLock(test1Lock) + var test2lock: Lock + initLock(test2Lock) + var main = Main(test1Lock: move(test1Lock), test1: Test1(value1: 1), + test2Lock: move(test2Lock), test2: Test2(value2: 2)) + main.withTest1(proc(test1: var Test1) = test1.value1 += 1) + main.withTest2(proc(test2: var Test2) = test2.value2 += 1) + move main + +var main = newMain() +main.withTest1(proc(test1: var Test1) = + test1.value1 += 1 + main.withTest2(proc(test2: var Test2) = test2.value2 += 1) +) + +main.withTest1(proc(test1: var Test1) {.tags: [].} = echo $test1.value1) +main.withTest2(proc(test2: var Test2) {.tags: [].} = echo $test2.value2) From 6961b555d6e1a1fbf771072232f1068fd6535ee6 Mon Sep 17 00:00:00 2001 From: Lancer Date: Sun, 17 Jul 2022 17:24:10 +0200 Subject: [PATCH 02/19] updated documentation and changelogs for the forbids pragma --- changelog.md | 2 ++ doc/manual.md | 20 +++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index d8f3ccb928b17..21d46a4dfb1c1 100644 --- a/changelog.md +++ b/changelog.md @@ -67,6 +67,8 @@ becomes an alias for `addr`. ## Language changes +- [Tag tracking](manual.html#tag-tracking) supports the definition of forbidden tags by the `.forbids`˛pragma + it can be used to disable certain effects in proc types - [Case statement macros](manual.html#macros-case-statement-macros) are no longer experimental, meaning you no longer need to enable the experimental switch `caseStmtMacros` to use them. - Templates now accept [macro pragmas](https://nim-lang.github.io/Nim/manual.html#userminusdefined-pragmas-macro-pragmas). diff --git a/doc/manual.md b/doc/manual.md index 503b9538b02c9..53c23da616d55 100644 --- a/doc/manual.md +++ b/doc/manual.md @@ -4945,7 +4945,7 @@ means to *tag* a routine and to perform checks against this tag: type IO = object ## input/output effect proc readLine(): string {.tags: [IO].} = discard - proc no_IO_please() {.tags: [].} = + proc no_effects_please() {.tags: [].} = # the compiler prevents this: let x = readLine() @@ -4955,6 +4955,24 @@ also be attached to a proc type. This affects type compatibility. The inference for tag tracking is analogous to the inference for exception tracking. +There is also a way which can be used to forbid certain effects: + +.. code-block:: nim + :test: "nim c --warningAsError:Effect:on $1" + :status: 1 + + type IO = object ## input/output effect + proc readLine(): string {.tags: [IO].} = discard + proc echoLine(): void = discard + + proc no_IO_please() {.forbids: [IO].} = + # this is OK because it didn't define any tag: + echoLine() + # the compiler prevents this: + let y = readLine() + +The `forbids` pragma defines a list if illegal effects - proc types not using that effect are all valid use cases. + Side effects ------------ From ee9cfaebd459b286b64a197b1207abc043271a6d Mon Sep 17 00:00:00 2001 From: Lancer Date: Sun, 17 Jul 2022 17:29:08 +0200 Subject: [PATCH 03/19] renamed notTagEffects to forbiddenEffects --- compiler/ast.nim | 2 +- compiler/docgen.nim | 2 +- compiler/sempass2.nim | 16 ++++++++-------- compiler/types.nim | 2 +- compiler/vmops.nim | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index 40e235a471f97..27e4fab63374b 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -347,7 +347,7 @@ const ensuresEffects* = 2 # 'ensures' annotation tagEffects* = 3 # user defined tag ('gc', 'time' etc.) pragmasEffects* = 4 # not an effect, but a slot for pragmas in proc type - notTagEffects* = 5 # list of illegal effects + forbiddenEffects* = 5 # list of illegal effects effectListLen* = 6 # list of effects list nkLastBlockStmts* = {nkRaiseStmt, nkReturnStmt, nkBreakStmt, nkContinueStmt} # these must be last statements in a block diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 34b70ec9a9154..0ca1b8c52a4e9 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -1212,7 +1212,7 @@ proc documentRaises*(cache: IdentCache; n: PNode) = let p3 = documentWriteEffect(cache, n, sfWrittenTo, "writes") let p4 = documentNewEffect(cache, n) let p5 = documentWriteEffect(cache, n, sfEscapes, "escapes") - let p6 = documentEffect(cache, n, pragmas, wForbids, notTagEffects) + let p6 = documentEffect(cache, n, pragmas, wForbids, forbiddenEffects) if p1 != nil or p2 != nil or p3 != nil or p4 != nil or p5 != nil or p6 != nil: if pragmas.kind == nkEmpty: diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 2ae0e97b35332..5d92737ce5966 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -612,7 +612,7 @@ proc isOwnedProcVar(tracked: PEffects; n: PNode): bool = proc isNoEffectList(n: PNode): bool {.inline.} = assert n.kind == nkEffectList - n.len == 0 or (n[tagEffects] == nil and n[exceptionEffects] == nil and n[notTagEffects] == nil) + n.len == 0 or (n[tagEffects] == nil and n[exceptionEffects] == nil and n[forbiddenEffects] == nil) proc isTrival(caller: PNode): bool {.inline.} = result = caller.kind == nkSym and caller.sym.magic in {mEqProc, mIsNil, mMove, mWasMoved, mSwap} @@ -1337,7 +1337,7 @@ proc checkMethodEffects*(g: ModuleGraph; disp, branch: PSym) = "can have an unlisted effect: ", hints=off, subtypeRelation) let forbidsSpec = effectSpec(p, wForbids) if not isNil(forbidsSpec): - checkRaisesSpec(g, false, forbidsSpec, actual[notTagEffects], + checkRaisesSpec(g, false, forbidsSpec, actual[forbiddenEffects], "has an illegal effect: ", hints=off, subtypeRelation, isForbids=true) if sfThread in disp.flags and notGcSafe(branch.typ): localError(g.config, branch.info, "base method is GC-safe, but '$1' is not" % @@ -1378,9 +1378,9 @@ proc setEffectsForProcType*(g: ModuleGraph; t: PType, n: PNode; s: PSym = nil) = let forbidsSpec = effectSpec(n, wForbids) if not isNil(forbidsSpec): - effects[notTagEffects] = forbidsSpec + effects[forbiddenEffects] = forbidsSpec elif s != nil and (s.magic != mNone or {sfImportc, sfExportc} * s.flags == {sfImportc}): - effects[notTagEffects] = newNodeI(nkArgList, effects.info) + effects[forbiddenEffects] = newNodeI(nkArgList, effects.info) let requiresSpec = propSpec(n, wRequires) if not isNil(requiresSpec): @@ -1398,7 +1398,7 @@ proc rawInitEffects(g: ModuleGraph; effects: PNode) = newSeq(effects.sons, effectListLen) effects[exceptionEffects] = newNodeI(nkArgList, effects.info) effects[tagEffects] = newNodeI(nkArgList, effects.info) - effects[notTagEffects] = newNodeI(nkArgList, effects.info) + effects[forbiddenEffects] = newNodeI(nkArgList, effects.info) effects[requiresEffects] = g.emptyNode effects[ensuresEffects] = g.emptyNode effects[pragmasEffects] = g.emptyNode @@ -1408,7 +1408,7 @@ proc initEffects(g: ModuleGraph; effects: PNode; s: PSym; t: var TEffects; c: PC t.exc = effects[exceptionEffects] t.tags = effects[tagEffects] - t.forbids = effects[notTagEffects] + t.forbids = effects[forbiddenEffects] t.owner = s t.ownerModule = s.getModule t.init = @[] @@ -1488,9 +1488,9 @@ proc trackProc*(c: PContext; s: PSym, body: PNode) = checkRaisesSpec(g, false, forbidsSpec, t.forbids, "has an illegal effect: ", hints=off, subtypeRelation, isForbids=true) # after the check, use the formal spec: - effects[notTagEffects] = forbidsSpec + effects[forbiddenEffects] = forbidsSpec else: - effects[notTagEffects] = t.forbids + effects[forbiddenEffects] = t.forbids let requiresSpec = propSpec(p, wRequires) if not isNil(requiresSpec): diff --git a/compiler/types.nim b/compiler/types.nim index f4857a2d8e416..8df52f41bf57a 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -1423,7 +1423,7 @@ proc compatibleEffects*(formal, actual: PType): EffectsCompat = #if tfEffectSystemWorkaround notin actual.flags: return efTagsDiffer - let sn = spec[notTagEffects] + let sn = spec[forbiddenEffects] if not isNil(sn) and sn.kind != nkArgList: if hasIncompatibleEffect(sn, real[tagEffects]): writeFile("/tmp/x.log", $formal & "\n" & $real[tagEffects]) diff --git a/compiler/vmops.nim b/compiler/vmops.nim index 45ad64ccec6a8..7c7f02006e248 100644 --- a/compiler/vmops.nim +++ b/compiler/vmops.nim @@ -325,7 +325,7 @@ proc registerAdditionalOps*(c: PCtx) = registerCallback c, "stdlib.effecttraits.getTagsListImpl", proc (a: VmArgs) = getEffectList(c, a, tagEffects) registerCallback c, "stdlib.effecttraits.getForbidsListImpl", proc (a: VmArgs) = - getEffectList(c, a, notTagEffects) + getEffectList(c, a, forbiddenEffects) registerCallback c, "stdlib.effecttraits.isGcSafeImpl", proc (a: VmArgs) = let fn = getNode(a, 0) From f89f019e8f066dd84b171a4294679ab2d6e01579 Mon Sep 17 00:00:00 2001 From: Lancer Date: Sun, 17 Jul 2022 18:20:32 +0200 Subject: [PATCH 04/19] corrected issues of forbids pragma the forbids pragma didn't handle simple restrictions properly and it also had issues with subtyping --- compiler/sempass2.nim | 6 ++++-- tests/effects/teffects13.nim | 19 +++++++++++++++++++ tests/effects/teffects14.nim | 15 +++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 tests/effects/teffects13.nim create mode 100644 tests/effects/teffects14.nim diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 5d92737ce5966..1e3e4135080ba 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -1307,6 +1307,8 @@ proc checkRaisesSpec(g: ModuleGraph; emitWarnings: bool; spec, real: PNode, msg: if isForbids: break used.incl(s) break search + if isForbids: + break search # XXX call graph analysis would be nice here! pushInfoContext(g.config, spec.info) var rr = if r.kind == nkRaiseStmt: r[0] else: r @@ -1337,7 +1339,7 @@ proc checkMethodEffects*(g: ModuleGraph; disp, branch: PSym) = "can have an unlisted effect: ", hints=off, subtypeRelation) let forbidsSpec = effectSpec(p, wForbids) if not isNil(forbidsSpec): - checkRaisesSpec(g, false, forbidsSpec, actual[forbiddenEffects], + checkRaisesSpec(g, false, forbidsSpec, actual[tagEffects], "has an illegal effect: ", hints=off, subtypeRelation, isForbids=true) if sfThread in disp.flags and notGcSafe(branch.typ): localError(g.config, branch.info, "base method is GC-safe, but '$1' is not" % @@ -1485,7 +1487,7 @@ proc trackProc*(c: PContext; s: PSym, body: PNode) = let forbidsSpec = effectSpec(p, wForbids) if not isNil(forbidsSpec): - checkRaisesSpec(g, false, forbidsSpec, t.forbids, "has an illegal effect: ", + checkRaisesSpec(g, false, forbidsSpec, t.tags, "has an illegal effect: ", hints=off, subtypeRelation, isForbids=true) # after the check, use the formal spec: effects[forbiddenEffects] = forbidsSpec diff --git a/tests/effects/teffects13.nim b/tests/effects/teffects13.nim new file mode 100644 index 0000000000000..73082f99784e6 --- /dev/null +++ b/tests/effects/teffects13.nim @@ -0,0 +1,19 @@ +discard """ +action: compile +errormsg: "writeSomething() has an illegal effect: WriteIO" +line: 19 +""" + +type + IO = object of RootEffect ## input/output effect + ReadIO = object of IO ## input effect + WriteIO = object of IO ## output effect + +proc readSomething(): string {.tags: [ReadIO].} = "" +proc writeSomething(): void {.tags: [WriteIO].} = echo "..." + +proc noWritesPlease() {.forbids: [WriteIO].} = + # this is OK: + echo readSomething() + # the compiler prevents this: + writeSomething() diff --git a/tests/effects/teffects14.nim b/tests/effects/teffects14.nim new file mode 100644 index 0000000000000..6291d95696dd1 --- /dev/null +++ b/tests/effects/teffects14.nim @@ -0,0 +1,15 @@ +discard """ +action: compile +errormsg: "func1() has an illegal effect: IO" +line: 15 +""" + +type IO = object ## input/output effect +proc func1(): string {.tags: [IO].} = discard +proc func2(): string = discard + +proc no_IO_please() {.forbids: [IO].} = + # this is OK because it didn't define any tag: + discard func2() + # the compiler prevents this: + let y = func1() From 1e9f08aea949342d6a80e050495e4df5bc28f38d Mon Sep 17 00:00:00 2001 From: Lancer Date: Sun, 17 Jul 2022 18:26:54 +0200 Subject: [PATCH 05/19] removed incorrect character from changelog --- changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index 21d46a4dfb1c1..dcd1e4e96c00a 100644 --- a/changelog.md +++ b/changelog.md @@ -67,7 +67,7 @@ becomes an alias for `addr`. ## Language changes -- [Tag tracking](manual.html#tag-tracking) supports the definition of forbidden tags by the `.forbids`˛pragma +- [Tag tracking](manual.html#tag-tracking) supports the definition of forbidden tags by the `.forbids` pragma it can be used to disable certain effects in proc types - [Case statement macros](manual.html#macros-case-statement-macros) are no longer experimental, meaning you no longer need to enable the experimental switch `caseStmtMacros` to use them. From 4c321e106043ff3ad91784dd00dc7e5d65fb45b2 Mon Sep 17 00:00:00 2001 From: Lancer Date: Sun, 17 Jul 2022 18:40:51 +0200 Subject: [PATCH 06/19] added test to cover the interaction of methods and the forbids pragma --- tests/effects/teffects15.nim | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 tests/effects/teffects15.nim diff --git a/tests/effects/teffects15.nim b/tests/effects/teffects15.nim new file mode 100644 index 0000000000000..c3079cdbc1d75 --- /dev/null +++ b/tests/effects/teffects15.nim @@ -0,0 +1,18 @@ +discard """ +action: compile +errormsg: "method1(c) has an illegal effect: IO" +line: 18 +""" + +type + IO = object ## input/output effect + CustomObject* = object of RootObj + text: string + +method method1(obj: var CustomObject): string {.tags: [IO].} = obj.text & "." +method method2(obj: var CustomObject): string = obj.text & ":" + +proc noIO() {.forbids: [IO].} = + var c = CustomObject(text: "a") + echo c.method2() + echo c.method1() From 1f5f59633b0a57019ca564756138814b00ba7291 Mon Sep 17 00:00:00 2001 From: Lancer Date: Sun, 17 Jul 2022 19:04:38 +0200 Subject: [PATCH 07/19] covering the interaction of the tags and forbids pragmas --- tests/effects/teffects16.nim | 20 ++++++++++++++++++++ tests/effects/teffects17.nim | 17 +++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 tests/effects/teffects16.nim create mode 100644 tests/effects/teffects17.nim diff --git a/tests/effects/teffects16.nim b/tests/effects/teffects16.nim new file mode 100644 index 0000000000000..ee8f782a3a89a --- /dev/null +++ b/tests/effects/teffects16.nim @@ -0,0 +1,20 @@ +discard """ +action: compile +errormsg: "writeSomething(\"a\") can have an unlisted effect: WriteIO" +line: 20 +""" + +type + IO = object of RootEffect ## input/output effect + ReadIO = object of IO ## input effect + WriteIO = object of IO ## output effect + LogIO = object of IO ## another output effect + +proc readSomething(): string {.tags: [ReadIO].} = "" +proc writeSomething(msg: string): void {.tags: [WriteIO].} = echo msg +proc logSomething(msg: string): void {.tags: [LogIo].} = echo msg + +proc noWritesPlease() {.forbids: [WriteIO], tags: [LogIO, ReadIO].} = + echo readSomething() + logSomething("a") + writeSomething("a") diff --git a/tests/effects/teffects17.nim b/tests/effects/teffects17.nim new file mode 100644 index 0000000000000..5e6b838962d15 --- /dev/null +++ b/tests/effects/teffects17.nim @@ -0,0 +1,17 @@ +discard """ +action: compile +errormsg: "writeSomething(\"a\") has an illegal effect: WriteIO" +line: 17 +""" + +type + IO = object of RootEffect ## input/output effect + ReadIO = object of IO ## input effect + WriteIO = object of IO ## output effect + +proc readSomething(): string {.tags: [ReadIO].} = "" +proc writeSomething(msg: string): void {.tags: [WriteIO].} = echo msg + +proc illegalEffectNegation() {.forbids: [WriteIO], tags: [ReadIO, WriteIO].} = + echo readSomething() + writeSomething("a") From 139b4d724ff75211e92a0c6b328207a6dd3e5f4f Mon Sep 17 00:00:00 2001 From: Lancer Date: Mon, 18 Jul 2022 00:29:19 +0200 Subject: [PATCH 08/19] updated manual about the forbids pragma --- doc/manual.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/manual.md b/doc/manual.md index 53c23da616d55..310a1ca6e1480 100644 --- a/doc/manual.md +++ b/doc/manual.md @@ -4973,6 +4973,15 @@ There is also a way which can be used to forbid certain effects: The `forbids` pragma defines a list if illegal effects - proc types not using that effect are all valid use cases. +In the example below, the `ProcType1` procedure type is a subtype of `ProcType1`: + +.. code-block:: nim + type MyEffect = object + type ProcType1 = proc (i: int) {.forbids: [MyEffect].} + type ProcType2 = proc (i: int) + +Calling `ProcType2` in place of `ProcType1` is valid because `ProcType2` doesn't support any tag, and thus it doesn't allow `MyEffect` either. + Side effects ------------ From 22d8df8accc7fc440c8ffa704bc2a45ef160360e Mon Sep 17 00:00:00 2001 From: Lancer Date: Mon, 18 Jul 2022 16:21:03 +0200 Subject: [PATCH 09/19] removed useless statement --- compiler/types.nim | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/types.nim b/compiler/types.nim index 8df52f41bf57a..425e9b4fa02ca 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -1426,7 +1426,6 @@ proc compatibleEffects*(formal, actual: PType): EffectsCompat = let sn = spec[forbiddenEffects] if not isNil(sn) and sn.kind != nkArgList: if hasIncompatibleEffect(sn, real[tagEffects]): - writeFile("/tmp/x.log", $formal & "\n" & $real[tagEffects]) return efTagsIllegal if formal.lockLevel.ord < 0 or From 5b5cfcfde188add061a85edab6bef34a58e12062 Mon Sep 17 00:00:00 2001 From: Lancer Date: Mon, 18 Jul 2022 16:24:29 +0200 Subject: [PATCH 10/19] corrected the subtyping of proc types using the forbids pragma --- compiler/types.nim | 4 +++- tests/effects/teffects18.nim | 19 +++++++++++++++++++ tests/effects/teffects19.nim | 23 +++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 tests/effects/teffects18.nim create mode 100644 tests/effects/teffects19.nim diff --git a/compiler/types.nim b/compiler/types.nim index 425e9b4fa02ca..6855776412e37 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -1425,7 +1425,9 @@ proc compatibleEffects*(formal, actual: PType): EffectsCompat = let sn = spec[forbiddenEffects] if not isNil(sn) and sn.kind != nkArgList: - if hasIncompatibleEffect(sn, real[tagEffects]): + if 0 == real.len: + return efTagsUnknown + elif hasIncompatibleEffect(sn, real[tagEffects]): return efTagsIllegal if formal.lockLevel.ord < 0 or diff --git a/tests/effects/teffects18.nim b/tests/effects/teffects18.nim new file mode 100644 index 0000000000000..576e766358200 --- /dev/null +++ b/tests/effects/teffects18.nim @@ -0,0 +1,19 @@ +discard """ +action: compile +errormsg: "type mismatch: got " +line: 19 +""" + +type MyEffect = object +type ProcType1 = proc (i: int): void {.forbids: [MyEffect].} +type ProcType2 = proc (i: int): void + +proc testFunc(p: ProcType1): void = p(1) + +proc toBeCalled(i: int): void {.tags: [MyEffect].} = echo $i + +let emptyTags = proc(i: int): void {.tags: [].} = echo $i +let noTags: ProcType2 = proc(i: int): void = toBeCalled(i) + +testFunc(emptyTags) +testFunc(noTags) diff --git a/tests/effects/teffects19.nim b/tests/effects/teffects19.nim new file mode 100644 index 0000000000000..49fb87523b39d --- /dev/null +++ b/tests/effects/teffects19.nim @@ -0,0 +1,23 @@ +discard """ +action: compile +errormsg: "type mismatch: got " +line: 23 +""" + +type MyEffect = object +type ProcType1 = proc (i: int): void {.forbids: [MyEffect].} +type ProcType2 = proc (i: int): void + +proc caller1(p: ProcType1): void = p(1) +proc caller2(p: ProcType2): void = p(1) + +proc effectful(i: int): void {.tags: [MyEffect].} = echo $i +proc effectless(i: int): void {.forbids: [MyEffect].} = echo $i + +proc toBeCalled1(i: int): void = effectful(i) +proc toBeCalled2(i: int): void = effectless(i) + +caller1(toBeCalled2) +caller2(toBeCalled1) +caller2(toBeCalled2) +caller1(toBeCalled1) From 3fc7865c1b706a71cb13662d7e72d32599c61ca8 Mon Sep 17 00:00:00 2001 From: Lancer Date: Mon, 18 Jul 2022 16:28:34 +0200 Subject: [PATCH 11/19] updated manual for the forbids pragma --- doc/manual.md | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/doc/manual.md b/doc/manual.md index 310a1ca6e1480..a86a0a95e8e0f 100644 --- a/doc/manual.md +++ b/doc/manual.md @@ -4971,16 +4971,35 @@ There is also a way which can be used to forbid certain effects: # the compiler prevents this: let y = readLine() -The `forbids` pragma defines a list if illegal effects - proc types not using that effect are all valid use cases. - -In the example below, the `ProcType1` procedure type is a subtype of `ProcType1`: +The `forbids` pragma defines a list of illegal effects - if any statement +invokes any of those effects, the compilation will fail. +Procedure types with any disallowed effect are the subtypes of equal +procedure types without such lists: .. code-block:: nim type MyEffect = object - type ProcType1 = proc (i: int) {.forbids: [MyEffect].} - type ProcType2 = proc (i: int) + type ProcType1 = proc (i: int): void {.forbids: [MyEffect].} + type ProcType2 = proc (i: int): void + + proc caller1(p: ProcType1): void = p(1) + proc caller2(p: ProcType2): void = p(1) + + proc effectful(i: int): void {.tags: [MyEffect].} = echo $i + proc effectless(i: int): void {.forbids: [MyEffect].} = echo $i + + proc toBeCalled1(i: int): void = effectful(i) + proc toBeCalled2(i: int): void = effectless(i) + + ## this will fail because toBeCalled1 uses MyEffect which was forbidden by ProcType1: + caller1(toBeCalled1) + ## this is OK because both toBeCalled1 and ProcType1 have the same requirements: + caller1(toBeCalled2) + ## these are OK because ProcType2 doesn't have any effect requirement: + caller2(toBeCalled1) + caller2(toBeCalled2) -Calling `ProcType2` in place of `ProcType1` is valid because `ProcType2` doesn't support any tag, and thus it doesn't allow `MyEffect` either. +`ProcType2` is a subtype of `ProcType1`. Unlike with tags, the parent context +doesn't inherit the forbidden list of effects. Side effects From 0fc3ccb7c3ac3b942c32e9924ac81a8de65c243f Mon Sep 17 00:00:00 2001 From: Lancer Date: Tue, 19 Jul 2022 16:01:46 +0200 Subject: [PATCH 12/19] updated documentations for forbids pragma --- doc/manual.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/manual.md b/doc/manual.md index a86a0a95e8e0f..bef827d395406 100644 --- a/doc/manual.md +++ b/doc/manual.md @@ -4998,8 +4998,7 @@ procedure types without such lists: caller2(toBeCalled1) caller2(toBeCalled2) -`ProcType2` is a subtype of `ProcType1`. Unlike with tags, the parent context -doesn't inherit the forbidden list of effects. +`ProcType2` is a subtype of `ProcType1`. Unlike with tags, the parent context - the function which calls other functions with forbidden effects - doesn't inherit the forbidden list of effects. Side effects From 288a208818a15f43800184422a2231867e6cf61b Mon Sep 17 00:00:00 2001 From: Lancer Date: Wed, 20 Jul 2022 18:52:06 +0200 Subject: [PATCH 13/19] updated nim docs --- .../expected/index.html | 163 +- .../expected/theindex.html | 67 +- nimdoc/testproject/expected/nimdoc.out.css | 201 +-- .../expected/subdir/subdir_b/utils.html | 862 +++++---- nimdoc/testproject/expected/testproject.html | 1576 ++++++++--------- nimdoc/testproject/expected/theindex.html | 67 +- 6 files changed, 1498 insertions(+), 1438 deletions(-) diff --git a/nimdoc/test_out_index_dot_html/expected/index.html b/nimdoc/test_out_index_dot_html/expected/index.html index 43285db6b6c90..3499b5326d272 100644 --- a/nimdoc/test_out_index_dot_html/expected/index.html +++ b/nimdoc/test_out_index_dot_html/expected/index.html @@ -1,11 +1,12 @@ - + - + + -nimdoc/test_out_index_dot_html/foo @@ -16,89 +17,133 @@ +nimdoc/test_out_index_dot_html/foo - + + + -
-
-

nimdoc/test_out_index_dot_html/foo

-
+
+
+

nimdoc/test_out_index_dot_html/foo

+
-
- -     Dark Mode -
- -
- Search: -
-
- Group by: - -
-
    -
  • -
    - Procs -
      +
      + +     Dark Mode +
      + +
      + Search: +
      +
      + Group by: + +
      + -
    +
+
- -
- -

-
-

Procs

-
-
-
-
proc foo() {....raises: [], tags: [].}
-
- - I do foo - -
-
+
+ +

+
+

Procs

+
+
+
proc foo() {....raises: [], tags: [].}
+
-
+I do foo -
+
+
+
+
- +
+ diff --git a/nimdoc/test_out_index_dot_html/expected/theindex.html b/nimdoc/test_out_index_dot_html/expected/theindex.html index 00c81189eda45..34ddf8f6ad9ba 100644 --- a/nimdoc/test_out_index_dot_html/expected/theindex.html +++ b/nimdoc/test_out_index_dot_html/expected/theindex.html @@ -1,11 +1,12 @@ - + - + + -Index @@ -16,28 +17,74 @@ +Index - + + + -
-
-

Index

- Modules: index.

API symbols

+
+
+

Index

+ Modules: index.

API symbols

foo:
+
- +
+ diff --git a/nimdoc/testproject/expected/nimdoc.out.css b/nimdoc/testproject/expected/nimdoc.out.css index e72c4a213c971..4abea9ce0a6a4 100644 --- a/nimdoc/testproject/expected/nimdoc.out.css +++ b/nimdoc/testproject/expected/nimdoc.out.css @@ -38,10 +38,6 @@ Modified by Boyd Greenfield and narimiran --program: #6060c0; --option: #508000; --raw-data: #a4255b; - - --clipboard-image-normal: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' style='color: black' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E %3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2' /%3E %3C/svg%3E"); - --clipboard-image-selected: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' style='color: black' viewBox='0 0 20 20' fill='currentColor'%3E %3Cpath d='M8 3a1 1 0 011-1h2a1 1 0 110 2H9a1 1 0 01-1-1z' /%3E %3Cpath d='M6 3a2 2 0 00-2 2v11a2 2 0 002 2h8a2 2 0 002-2V5a2 2 0 00-2-2 3 3 0 01-3 3H9a3 3 0 01-3-3z' /%3E %3C/svg%3E"); - --clipboard-image: var(--clipboard-image-normal) } [data-theme="dark"] { @@ -72,10 +68,6 @@ Modified by Boyd Greenfield and narimiran --program: #9090c0; --option: #90b010; --raw-data: #8be9fd; - - --clipboard-image-normal: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' style='color: lightgray' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E %3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2' /%3E %3C/svg%3E"); - --clipboard-image-selected: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' style='color: lightgray' viewBox='0 0 20 20' fill='currentColor'%3E %3Cpath d='M8 3a1 1 0 011-1h2a1 1 0 110 2H9a1 1 0 01-1-1z' /%3E %3Cpath d='M6 3a2 2 0 00-2 2v11a2 2 0 002 2h8a2 2 0 002-2V5a2 2 0 00-2-2 3 3 0 01-3 3H9a3 3 0 01-3-3z' /%3E %3C/svg%3E"); - --clipboard-image: var(--clipboard-image-normal); } .theme-switch-wrapper { @@ -159,28 +151,24 @@ body { padding: 0; box-sizing: border-box; } -.column, .columns { +.column, +.columns { width: 100%; float: left; box-sizing: border-box; - margin-left: 1%; } + margin-left: 1%; +} -.column:first-child, .columns:first-child { +.column:first-child, +.columns:first-child { margin-left: 0; } -.container .row { - display: flex; } - .three.columns { - width: 25.0%; - height: 100vh; - position: sticky; - top: 0px; - overflow-y: auto; } + width: 22%; +} .nine.columns { - width: 75.0%; - padding-left: 1.5em; } + width: 77.0%; } .twelve.columns { width: 100%; @@ -267,32 +255,27 @@ a.reference-toplevel { font-weight: bold; } -a.nimdoc { - word-spacing: 0.3em; -} - a.toc-backref { text-decoration: none; - color: var(--text); -} + color: var(--text); } a.link-seesrc { color: #607c9f; font-size: 0.9em; - font-style: italic; -} + font-style: italic; } -a:hover, a:focus { +a:hover, +a:focus { color: var(--anchor-focus); - text-decoration: underline; -} + text-decoration: underline; } a:hover span.Identifier { color: var(--anchor); } -sub, sup { +sub, +sup { position: relative; font-size: 75%; line-height: 0; @@ -319,7 +302,8 @@ img { background: transparent !important; box-shadow: none !important; } - a, a:visited { + a, + a:visited { text-decoration: underline; } a[href]:after { @@ -333,14 +317,16 @@ img { a[href^="#"]:after { content: ""; } - pre, blockquote { + pre, + blockquote { border: 1px solid #999; page-break-inside: avoid; } thead { display: table-header-group; } - tr, img { + tr, + img { page-break-inside: avoid; } img { @@ -355,18 +341,22 @@ img { h1.title { page-break-before: avoid; } - p, h2, h3 { + p, + h2, + h3 { orphans: 3; widows: 3; } - h2, h3 { + h2, + h3 { page-break-after: avoid; } } p { margin-top: 0.5em; - margin-bottom: 0.5em; } + margin-bottom: 0.5em; +} small { font-size: 85%; } @@ -374,7 +364,8 @@ small { strong { font-weight: 600; font-size: 0.95em; - color: var(--strong); } + color: var(--strong); +} em { font-style: italic; } @@ -395,7 +386,8 @@ h1.title { text-align: center; font-weight: 900; margin-top: 0.75em; - margin-bottom: 0em; } + margin-bottom: 0em; +} h2 { font-size: 1.3em; @@ -422,29 +414,36 @@ h6 { font-size: 1.1em; } -ul, ol { +ul, +ol { padding: 0; margin-top: 0.5em; margin-left: 0.75em; } -ul ul, ul ol, ol ol, ol ul { +ul ul, +ul ol, +ol ol, +ol ul { margin-bottom: 0; margin-left: 1.25em; } ul.simple > li { - list-style-type: circle; } + list-style-type: circle; +} ul.simple-boot li { - list-style-type: none; - margin-left: 0em; - margin-bottom: 0.5em; } + list-style-type: none; + margin-left: 0em; + margin-bottom: 0.5em; +} ol.simple > li, ul.simple > li { margin-bottom: 0.2em; margin-left: 0.4em } ul.simple.simple-toc > li { - margin-top: 1em; } + margin-top: 1em; +} ul.simple-toc { list-style: none; @@ -453,7 +452,8 @@ ul.simple-toc { margin-top: 1em; } ul.simple-toc > li { - list-style-type: none; } + list-style-type: none; +} ul.simple-toc-section { list-style-type: circle; @@ -463,10 +463,12 @@ ul.simple-toc-section { ul.nested-toc-section { list-style-type: circle; margin-left: -0.75em; - color: var(--text); } + color: var(--text); +} ul.nested-toc-section > li { - margin-left: 1.25em; } + margin-left: 1.25em; +} ol.arabic { @@ -513,8 +515,7 @@ hr.footnote { margin-top: 0.15em; } div.footnote-group { - margin-left: 1em; -} + margin-left: 1em; } div.footnote-label { display: inline-block; min-width: 1.7em; @@ -554,11 +555,6 @@ blockquote { border-left: 5px solid #bbc; } -blockquote.markdown-quote { - font-size: 0.9rem; /* use rem to avoid recursion */ - font-style: normal; -} - .pre, span.tok { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; font-weight: 500; @@ -576,10 +572,6 @@ span.tok { margin-right: 0.2em; } -.copyToClipBoard { - position: relative; -} - pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; color: var(--text); @@ -598,25 +590,7 @@ pre { border: 1px solid var(--border); -webkit-border-radius: 6px; -moz-border-radius: 6px; - border-radius: 6px; -} - -.copyToClipBoardBtn { - visibility: hidden; - position: absolute; - width: 24px; - border-radius: 4px; - background-image: var(--clipboard-image); - right: 5px; - top: 13px; - background-color: var(--secondary-background); - padding: 11px; - border: 0; -} - -.copyToClipBoard:hover .copyToClipBoardBtn { - visibility: visible; -} + border-radius: 6px; } .pre-scrollable { max-height: 340px; @@ -681,8 +655,8 @@ table th { font-weight: bold; } table th.docinfo-name { - background-color: transparent; - text-align: right; + background-color: transparent; + text-align: right; } table tr:hover { @@ -699,31 +673,31 @@ table.borderless td, table.borderless th { padding: 0 0.5em 0 0 !important; } .admonition { - padding: 0.3em; - background-color: var(--secondary-background); - border-left: 0.4em solid #7f7f84; - margin-bottom: 0.5em; - -webkit-box-shadow: 0 5px 8px -6px rgba(0,0,0,.2); - -moz-box-shadow: 0 5px 8px -6px rgba(0,0,0,.2); - box-shadow: 0 5px 8px -6px rgba(0,0,0,.2); + padding: 0.3em; + background-color: var(--secondary-background); + border-left: 0.4em solid #7f7f84; + margin-bottom: 0.5em; + -webkit-box-shadow: 0 5px 8px -6px rgba(0,0,0,.2); + -moz-box-shadow: 0 5px 8px -6px rgba(0,0,0,.2); + box-shadow: 0 5px 8px -6px rgba(0,0,0,.2); } .admonition-info { - border-color: var(--info-background); + border-color: var(--info-background); } .admonition-info-text { - color: var(--info-background); + color: var(--info-background); } .admonition-warning { - border-color: var(--warning-background); + border-color: var(--warning-background); } .admonition-warning-text { - color: var(--warning-background); + color: var(--warning-background); } .admonition-error { - border-color: var(--error-background); + border-color: var(--error-background); } .admonition-error-text { - color: var(--error-background); + color: var(--error-background); } .first { @@ -757,7 +731,8 @@ div.footer, div.header { font-size: smaller; } div.footer { - padding-top: 5em; } + padding-top: 5em; +} div.line-block { display: block; @@ -776,14 +751,17 @@ div.search_results { background-color: var(--third-background); margin: 3em; padding: 1em; - border: 1px solid #4d4d4d; } + border: 1px solid #4d4d4d; +} div#global-links ul { margin-left: 0; - list-style-type: none; } + list-style-type: none; +} div#global-links > simple-boot { - margin-left: 3em; } + margin-left: 3em; +} hr.docutils { width: 75%; } @@ -963,7 +941,8 @@ span.Directive { span.option { font-weight: bold; font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - color: var(--option); } + color: var(--option); +} span.Prompt { font-weight: bold; @@ -979,10 +958,11 @@ span.program { text-decoration: underline; text-decoration-color: var(--hint); text-decoration-thickness: 0.05em; - text-underline-offset: 0.15em; } + text-underline-offset: 0.15em; +} -span.Command, span.Rule, span.Hyperlink, -span.Label, span.Reference, span.Other { +span.Command, span.Rule, span.Hyperlink, span.Label, span.Reference, +span.Other { color: var(--other); } /* Pop type, const, proc, and iterator defs in nim def blocks */ @@ -1020,14 +1000,17 @@ span.pragmadots { border-radius: 4px; margin: 0 2px; cursor: pointer; - font-size: 0.8em; } + font-size: 0.8em; +} span.pragmadots:hover { - background-color: var(--hint); } - + background-color: var(--hint); +} span.pragmawrap { - display: none; } + display: none; +} span.attachedType { display: none; - visibility: hidden; } + visibility: hidden; +} diff --git a/nimdoc/testproject/expected/subdir/subdir_b/utils.html b/nimdoc/testproject/expected/subdir/subdir_b/utils.html index 4d753ad8f8925..15cdd8bc72841 100644 --- a/nimdoc/testproject/expected/subdir/subdir_b/utils.html +++ b/nimdoc/testproject/expected/subdir/subdir_b/utils.html @@ -1,11 +1,12 @@ - + - + + -subdir/subdir_b/utils @@ -16,193 +17,262 @@ +subdir/subdir_b/utils - + + + -
-
-

subdir/subdir_b/utils

-
+
+
+

subdir/subdir_b/utils

+
-
- -     Dark Mode -
- -
- Search: -
-
- Group by: - -
- + + + + + + + + + + + + + + + +
  • -
    - Iterators - -
    +
  • -
    - Templates - -
    +
  • +
    - -
    - -

    This is a description of the utils module.

    +
    + +

    This is a description of the utils module.

    Links work:

    This is now a header

    @@ -216,369 +286,291 @@
  • Other case value
  • Second case.
  • -

    Ref group fn2 or specific function like fn2() or fn2( int ) or fn2(int, float).

    -

    Ref generics like this: binarySearch or binarySearch(openArray[T], K, proc (T, K)) or proc binarySearch(openArray[T], K, proc (T, K)) or in different style: proc binarysearch(openarray[T], K, proc(T, K)). Can be combined with export symbols and type parameters: binarysearch*[T, K](openArray[T], K, proc (T, K)). With spaces binary search.

    -

    Note that proc can be used in postfix form: binarySearch proc.

    -

    Ref. type like G and type G and G[T] and type G*[T].

    -

    Group ref. with capital letters works: fN11 or fn11

    -Ref. [] is the same as proc `[]`(G[T]) because there are no overloads. The full form: proc `[]`*[T](x: G[T]): TRef. []= aka `[]=`(G[T], int, T).Ref. $ aka proc $ or proc `$`.Ref. $(a: ref SomeType).Ref. foo_bar aka iterator foo_bar_.Ref. fn[T; U,V: SomeFloat]().Ref. 'big or func `'big` or `'big`(string).

    -
    -

    Types

    -
    -
    -
    G[T] = object
    +

    Ref group fn2 or specific function like fn2 or fn2 or fn2.

    +

    Ref generics like this: binarySearch or binarySearch or proc or in different style: proc. Can be combined with export symbols and type parameters: binarysearch. With spaces binary.

    +

    Note that proc can be used in postfix form: binarySearch.

    +

    Ref. type like G and type and G and type.

    +

    Group ref. with capital letters works: fN11 or fn11

    +Ref. [ is the same as proc because there are no overloads. The full form: procRef. [ aka `.Ref. $ aka proc or proc.Ref. $.Ref. foo aka iterator.Ref. fn.Ref. ' or func or `.

    +
    +

    Types

    +
    +
    +
    G[T] = object
       val: T
     
    -
    - - - -
    +
    + + + +
    -
    SomeType = enum
    +
    SomeType = enum
       enumValueA, enumValueB, enumValueC
    -
    - - - -
    -
    +
    + -
    + +
    + +
    -

    Procs

    -
    -
    -
    -
    proc `$`[T](a: G[T]): string
    -
    - - - -
    +

    Procs

    +
    +
    +
    proc `$`[T](a: G[T]): string
    +
    + + + +
    -
    proc `$`[T](a: ref SomeType): string
    -
    - - - -
    -
    +
    proc `$`[T](a: ref SomeType): string
    +
    -
    -
    -
    -
    func `'big`(a: string): SomeType {....raises: [], tags: [].}
    -
    - - - -
    -
    + +
    -
    -
    -
    proc `[]`[T](x: G[T]): T
    -
    - - - -
    -
    +
    +
    func `'big`(a: string): SomeType {....raises: [], tags: [].}
    +
    + + +
    -
    -
    -
    proc `[]=`[T](a: var G[T]; index: int; value: T)
    -
    - - - -
    +
    +
    proc `[]=`[T](a: var G[T]; index: int; value: T)
    +
    + + + +
    +
    +
    proc `[]`[T](x: G[T]): T
    +
    + + +
    -
    -
    -
    proc binarySearch[T, K](a: openArray[T]; key: K;
    +
    +
    proc binarySearch[T, K](a: openArray[T]; key: K;
                             cmp: proc (x: T; y: K): int {.closure.}): int
    -
    - - - -
    -
    +
    + + +
    -
    -
    -
    proc f(x: G[int]) {....raises: [], tags: [].}
    -
    - - There is also variant f(G[string]) - -
    +
    +
    proc f(x: G[int]) {....raises: [], tags: [].}
    +
    + +There is also variant f + +
    -
    proc f(x: G[string]) {....raises: [], tags: [].}
    -
    - - See also f(G[int]). - -
    -
    +
    proc f(x: G[string]) {....raises: [], tags: [].}
    +
    -
    -
    -
    -
    proc fn[T; U, V: SomeFloat]()
    -
    - - - -
    -
    +See also f. +
    -
    -
    -
    proc fn2() {....raises: [], tags: [].}
    -
    - - comment - -
    +
    +
    proc fn2() {....raises: [], tags: [].}
    +
    + +comment + +
    -
    proc fn2(x: int) {....raises: [], tags: [].}
    -
    - - fn2 comment - -
    +
    proc fn2(x: int) {....raises: [], tags: [].}
    +
    + +fn2 comment + +
    -
    proc fn2(x: int; y: float) {....raises: [], tags: [].}
    -
    - - - -
    -
    +
    proc fn2(x: int; y: float) {....raises: [], tags: [].}
    +
    -
    -
    -
    -
    proc fn3(): auto {....raises: [], tags: [].}
    -
    - - comment - -
    -
    -
    -
    -
    -
    proc fn4(): auto {....raises: [], tags: [].}
    -
    - - comment - -
    -
    +
    -
    -
    -
    proc fn5() {....raises: [], tags: [].}
    -
    - - comment - -
    -
    +
    +
    proc fn3(): auto {....raises: [], tags: [].}
    +
    -
    -
    -
    -
    proc fn6() {....raises: [], tags: [].}
    -
    - - comment - -
    -
    +comment +
    -
    -
    -
    proc fn7() {....raises: [], tags: [].}
    -
    - - comment - -
    -
    +
    +
    proc fn4(): auto {....raises: [], tags: [].}
    +
    +comment + +
    -
    -
    -
    proc fn8(): auto {....raises: [], tags: [].}
    -
    - - comment - -
    +
    +
    proc fn5() {....raises: [], tags: [].}
    +
    + +comment + +
    +
    +
    proc fn6() {....raises: [], tags: [].}
    +
    + +comment +
    -
    -
    -
    func fn9(a: int): int {....raises: [], tags: [].}
    -
    - - comment - -
    +
    +
    proc fn7() {....raises: [], tags: [].}
    +
    + +comment + +
    +
    +
    proc fn8(): auto {....raises: [], tags: [].}
    +
    + +comment +
    -
    -
    -
    func fn10(a: int): int {....raises: [], tags: [].}
    -
    - - comment - -
    +
    +
    func fn9(a: int): int {....raises: [], tags: [].}
    +
    + +comment + +
    +
    +
    func fn10(a: int): int {....raises: [], tags: [].}
    +
    +comment + +
    -
    -
    -
    func fN11() {....raises: [], tags: [].}
    -
    - - - -
    +
    +
    func fN11() {....raises: [], tags: [].}
    +
    + + + +
    -
    func fN11(x: int) {....raises: [], tags: [].}
    -
    - - - -
    -
    +
    func fN11(x: int) {....raises: [], tags: [].}
    +
    -
    -
    -
    -
    proc funWithGenerics[T, U: SomeFloat](a: T; b: U)
    -
    - - - -
    -
    + +
    -
    -
    -
    proc someType(): SomeType {....raises: [], tags: [].}
    -
    - - constructor. - -
    +
    +
    proc fn[T; U, V: SomeFloat]()
    +
    + + + +
    +
    +
    proc funWithGenerics[T, U: SomeFloat](a: T; b: U)
    +
    + + +
    +
    +
    proc someType(): SomeType {....raises: [], tags: [].}
    +
    -
    +constructor. + +
    + +
    -

    Iterators

    -
    -
    -
    -
    iterator fooBar(a: seq[SomeType]): int {....raises: [], tags: [].}
    -
    - - - -
    +

    Iterators

    +
    +
    +
    iterator fooBar(a: seq[SomeType]): int {....raises: [], tags: [].}
    +
    + + + +
    +
    +
    +

    Templates

    +
    +
    +
    template aEnum(): untyped
    +
    + + + +
    +
    +
    template bEnum(): untyped
    +
    -
    + + +
    -
    -

    Templates

    -
    -
    -
    -
    template aEnum(): untyped
    -
    - - - -
    -
    - -
    -
    -
    -
    template bEnum(): untyped
    -
    - - - -
    -
    - -
    -
    -
    -
    template fromUtilsGen(): untyped
    -
    - - should be shown in utils.html only +
    +
    template fromUtilsGen(): untyped
    +
    + +should be shown in utils.html only

    Example:

    discard "should be in utils.html only, not in module that calls fromUtilsGen"
    ditto - -
    -
    +
    -
    -
    +
    +
    - +
    + diff --git a/nimdoc/testproject/expected/testproject.html b/nimdoc/testproject/expected/testproject.html index 5fb9e697cb5e7..dbacb57a7493e 100644 --- a/nimdoc/testproject/expected/testproject.html +++ b/nimdoc/testproject/expected/testproject.html @@ -1,11 +1,12 @@ - + - + + -testproject @@ -16,322 +17,415 @@ +testproject - + + + -
    -
    -

    testproject

    -
    +
    +
    +

    testproject

    +
    -
    - -     Dark Mode -
    - -
    - Search: -
    -
    - Group by: - -
    - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • -
    - Methods - -
    +
  • -
    - Iterators - -
    +
  • -
    - Macros - -
    +
  • -
    - Templates -
    +
  • foo(a, b: SomeType)
  • + + + + + + + + + +
    +
    - -
    - -

    This is the top level module. +

    + +

    This is the top level module.

    Example:

    import testproject
     import subdir / subdir_b / utils
    @@ -345,136 +439,131 @@ 

    testproject

    Example:

    import testproject
     discard "in top3"
    top3 after

    - +
    -

    Types

    -
    -
    -
    A {.inject.} = enum
    +

    Types

    +
    +
    +
    A {.inject.} = enum
       aA
    -
    - - The enum A. - -
    +
    + +The enum A. + +
    -
    B {.inject.} = enum
    +
    B {.inject.} = enum
       bB
    -
    - - The enum B. - -
    +
    + +The enum B. + +
    -
    Foo = enum
    +
    Foo = enum
       enumValueA2
    -
    - - - -
    +
    + + + +
    -
    FooBuzz {....deprecated: "FooBuzz msg".} = int
    -
    -
    - Deprecated: FooBuzz msg -
    +
    FooBuzz {....deprecated: "FooBuzz msg".} = int
    +
    +
    + Deprecated: FooBuzz msg +
    - - -
    + + +
    -
    Shapes = enum
    +
    Shapes = enum
       Circle,                   ## A circle
       Triangle,                 ## A three-sided shape
       Rectangle                  ## A four-sided shape
    -
    - - Some shapes. - -
    -
    +
    + +Some shapes. -
    +
    + +
    -

    Vars

    -
    -
    -
    aVariable: array[1, int]
    -
    - - - -
    +

    Vars

    +
    +
    +
    aVariable: array[1, int]
    +
    + + + +
    -
    someVariable: bool
    -
    - - This should be visible. - -
    -
    +
    someVariable: bool
    +
    + +This should be visible. -
    +
    + +
    -

    Consts

    -
    -
    -
    C_A = 0x7FF0000000000000'f64
    -
    - - - -
    +

    Consts

    +
    +
    +
    C_A = 0x7FF0000000000000'f64
    +
    + + + +
    -
    C_B = 0o377'i8
    -
    - - - -
    +
    C_B = 0o377'i8
    +
    + + + +
    -
    C_C = 0o277'i8
    -
    - - - -
    +
    C_C = 0o277'i8
    +
    + + + +
    -
    C_D = 0o177777'i16
    -
    - - - -
    -
    +
    C_D = 0o177777'i16
    +
    -
    + + +
    + +
    -

    Procs

    -
    -
    -
    -
    proc addfBug14485() {....raises: [], tags: [].}
    -
    - - Some proc +

    Procs

    +
    +
    +
    proc addfBug14485() {....raises: [], tags: [].}
    +
    + +Some proc

    Example:

    discard "foo() = " & $[1]
     #[
    @@ -487,194 +576,152 @@ 

    Procs

    6: </script 7: end of broken html ]#
    - -
    -
    +
    -
    -
    -
    proc anything() {....raises: [], tags: [].}
    -
    - - There is no block quote after blank lines at the beginning. - -
    -
    +
    +
    proc anything() {....raises: [], tags: [].}
    +
    + +There is no block quote after blank lines at the beginning. +
    -
    -
    -
    proc asyncFun1(): Future[int] {....raises: [Exception, ValueError],
    +
    +
    proc asyncFun1(): Future[int] {....raises: [Exception, ValueError],
                                     tags: [RootEffect].}
    -
    - - ok1 - -
    -
    +
    +ok1 + +
    -
    -
    -
    proc asyncFun2(): owned(Future[void]) {....raises: [Exception], tags: [RootEffect].}
    -
    - - - -
    -
    +
    +
    proc asyncFun2(): owned(Future[void]) {....raises: [Exception], tags: [RootEffect].}
    +
    + + +
    -
    -
    -
    proc asyncFun3(): owned(Future[void]) {....raises: [Exception], tags: [RootEffect].}
    -
    - - +
    +
    proc asyncFun3(): owned(Future[void]) {....raises: [Exception], tags: [RootEffect].}
    +
    + +

    Example:

    discard
    ok1 - -
    -
    +
    -
    -
    -
    proc bar[T](a, b: T): T
    -
    - - - -
    -
    +
    +
    proc bar[T](a, b: T): T
    +
    + + +
    -
    -
    -
    proc baz() {....raises: [], tags: [].}
    -
    - - - -
    +
    +
    proc baz() {....raises: [], tags: [].}
    +
    + + + +
    -
    proc baz[T](a, b: T): T {....deprecated.}
    -
    -
    - Deprecated -
    +
    proc baz[T](a, b: T): T {....deprecated.}
    +
    +
    + Deprecated +
    - This is deprecated without message. - -
    -
    +This is deprecated without message. +
    -
    -
    -
    proc buzz[T](a, b: T): T {....deprecated: "since v0.20".}
    -
    -
    - Deprecated: since v0.20 -
    +
    +
    proc buzz[T](a, b: T): T {....deprecated: "since v0.20".}
    +
    +
    + Deprecated: since v0.20 +
    - This is deprecated with a message. - -
    -
    +This is deprecated with a message. +
    -
    -
    -
    proc c_nonexistent(frmt: cstring): cint {.importc: "nonexistent",
    +
    +
    proc c_nonexistent(frmt: cstring): cint {.importc: "nonexistent",
         header: "<stdio.h>", varargs, discardable, ...raises: [], tags: [].}
    -
    - - - -
    -
    +
    + + +
    -
    -
    -
    proc c_printf(frmt: cstring): cint {.importc: "printf", header: "<stdio.h>",
    +
    +
    proc c_printf(frmt: cstring): cint {.importc: "printf", header: "<stdio.h>",
                                          varargs, discardable, ...raises: [], tags: [].}
    -
    - - the c printf. etc. - -
    -
    +
    +the c printf. etc. + +
    -
    -
    -
    proc fromUtils3() {....raises: [], tags: [].}
    -
    - - came form utils but should be shown where fromUtilsGen is called +
    +
    proc fromUtils3() {....raises: [], tags: [].}
    +
    + +came form utils but should be shown where fromUtilsGen is called

    Example:

    discard """should be shown as examples for fromUtils3
            in module calling fromUtilsGen"""
    - -
    -
    +
    -
    -
    -
    proc isValid[T](x: T): bool
    -
    - - - -
    -
    +
    +
    proc isValid[T](x: T): bool
    +
    + -
    -
    -
    -
    proc low[T: Ordinal | enum | range](x: T): T {.magic: "Low", noSideEffect,
    -    ...raises: [], tags: [].}
    -
    - -

    Returns the lowest possible value of an ordinal value x. As a special semantic rule, x may also be a type identifier.

    -

    See also:

    - -
    low(2) # => -9223372036854775808
    - -
    -
    +
    -
    -
    -
    proc low2[T: Ordinal | enum | range](x: T): T {.magic: "Low", noSideEffect,
    +
    +
    proc low2[T: Ordinal | enum | range](x: T): T {.magic: "Low", noSideEffect,
         ...raises: [], tags: [].}
    -
    - -

    Returns the lowest possible value of an ordinal value x. As a special semantic rule, x may also be a type identifier.

    +
    + +

    Returns the lowest possible value of an ordinal value x. As a special semantic rule, x may also be a type identifier.

    See also:

    low2(2) # => -9223372036854775808

    Example:

    discard "in low2"
    - -
    + +
    +
    +
    proc low[T: Ordinal | enum | range](x: T): T {.magic: "Low", noSideEffect,
    +    ...raises: [], tags: [].}
    +
    +

    Returns the lowest possible value of an ordinal value x. As a special semantic rule, x may also be a type identifier.

    +

    See also:

    + +
    low(2) # => -9223372036854775808
    + +
    -
    -
    -
    proc p1() {....raises: [], tags: [].}
    -
    - - cp1 +
    +
    proc p1() {....raises: [], tags: [].}
    +
    + +cp1

    Example:

    doAssert 1 == 1 # regular comments work here
    c4

    Example:

    @@ -691,28 +738,22 @@

    Procs

    ]## discard "c9" # also work after
    - - -
    +
    -
    -
    -
    func someFunc() {....raises: [], tags: [].}
    -
    - - My someFunc. Stuff in quotes here. Some link - -
    -
    +
    +
    func someFunc() {....raises: [], tags: [].}
    +
    +My someFunc. Stuff in quotes here. Some link + +
    -
    -
    -
    proc tripleStrLitTest() {....raises: [], tags: [].}
    -
    - - +
    +
    proc tripleStrLitTest() {....raises: [], tags: [].}
    +
    + +

    Example: cmd: --hint:XDeclaredButNotUsed:off

    ## mullitline string litterals are tricky as their indentation can span
     ## below that of the runnableExamples
    @@ -749,343 +790,261 @@ 

    Procs

    """ ] discard # should be in
    - -
    -
    +
    -
    -
    -
    proc z1(): Foo {....raises: [], tags: [].}
    -
    - - cz1 - -
    -
    +
    +
    proc z1(): Foo {....raises: [], tags: [].}
    +
    + +cz1 +
    -
    -
    -
    proc z2() {....raises: [], tags: [].}
    -
    - - cz2 +
    +
    proc z2() {....raises: [], tags: [].}
    +
    + +cz2

    Example:

    discard "in cz2"
    - -
    -
    +
    -
    -
    -
    proc z3() {....raises: [], tags: [].}
    -
    - - cz3 - -
    -
    +
    +
    proc z3() {....raises: [], tags: [].}
    +
    -
    -
    -
    -
    proc z4() {....raises: [], tags: [].}
    -
    - - cz4 - -
    -
    +cz3 +
    -
    -
    -
    proc z5(): int {....raises: [], tags: [].}
    -
    - - cz5 - -
    -
    +
    +
    proc z4() {....raises: [], tags: [].}
    +
    -
    -
    -
    -
    proc z6(): int {....raises: [], tags: [].}
    -
    - - cz6 - -
    -
    +cz4 +
    -
    -
    -
    proc z7(): int {....raises: [], tags: [].}
    -
    - - cz7 - -
    +
    +
    proc z5(): int {....raises: [], tags: [].}
    +
    + +cz5 + +
    +
    +
    proc z6(): int {....raises: [], tags: [].}
    +
    + +cz6 +
    -
    -
    -
    proc z8(): int {....raises: [], tags: [].}
    -
    - - cz8 - -
    +
    +
    proc z7(): int {....raises: [], tags: [].}
    +
    + +cz7 + +
    +
    +
    proc z8(): int {....raises: [], tags: [].}
    +
    + +cz8 +
    -
    -
    -
    proc z9() {....raises: [], tags: [].}
    -
    - - +
    +
    proc z9() {....raises: [], tags: [].}
    +
    + +

    Example:

    doAssert 1 + 1 == 2
    - -
    -
    +
    -
    -
    -
    proc z10() {....raises: [], tags: [].}
    -
    - - +
    +
    proc z10() {....raises: [], tags: [].}
    +
    + +

    Example: cmd: -d:foobar

    discard 1
    cz10 - -
    -
    +
    -
    -
    -
    proc z11() {....raises: [], tags: [].}
    -
    - - +
    +
    proc z11() {....raises: [], tags: [].}
    +
    + +

    Example:

    discard 1
    - -
    -
    +
    -
    -
    -
    proc z12(): int {....raises: [], tags: [].}
    -
    - - +
    +
    proc z12(): int {....raises: [], tags: [].}
    +
    + +

    Example:

    discard 1
    - -
    -
    +
    -
    -
    -
    proc z13() {....raises: [], tags: [].}
    -
    - - cz13 +
    +
    proc z13() {....raises: [], tags: [].}
    +
    + +cz13

    Example:

    discard
    - -
    -
    +
    -
    -
    -
    proc z17() {....raises: [], tags: [].}
    -
    - - cz17 rest +
    +
    proc z17() {....raises: [], tags: [].}
    +
    + +cz17 rest

    Example:

    discard 1
    rest - -
    -
    +
    -
    -
    +
    -

    Methods

    -
    -
    -
    -
    method method1(self: Moo) {.base, ...raises: [], tags: [].}
    -
    - - foo1 - -
    -
    +

    Methods

    +
    +
    +
    method method1(self: Moo) {.base, ...raises: [], tags: [].}
    +
    -
    -
    -
    -
    method method2(self: Moo): int {.base, ...raises: [], tags: [].}
    -
    - - foo2 - -
    -
    +foo1 +
    -
    -
    -
    method method3(self: Moo): int {.base, ...raises: [], tags: [].}
    -
    - - foo3 - -
    -
    +
    +
    method method2(self: Moo): int {.base, ...raises: [], tags: [].}
    +
    +foo2 + +
    +
    +
    method method3(self: Moo): int {.base, ...raises: [], tags: [].}
    +
    + +foo3 -
    +
    + +
    -

    Iterators

    -
    -
    -
    -
    iterator fromUtils1(): int {....raises: [], tags: [].}
    -
    - - +

    Iterators

    +
    +
    +
    iterator fromUtils1(): int {....raises: [], tags: [].}
    +
    + +

    Example:

    # ok1
     assert 1 == 1
     # ok2
    - -
    -
    +
    -
    -
    -
    iterator iter1(n: int): int {....raises: [], tags: [].}
    -
    - - foo1 - -
    -
    +
    +
    iterator iter1(n: int): int {....raises: [], tags: [].}
    +
    + +foo1 +
    -
    -
    -
    iterator iter2(n: int): int {....raises: [], tags: [].}
    -
    - - foo2 +
    +
    iterator iter2(n: int): int {....raises: [], tags: [].}
    +
    + +foo2

    Example:

    discard # bar
    - -
    -
    +
    -
    -
    +
    -

    Macros

    -
    -
    -
    -
    macro bar(): untyped
    -
    - - - -
    -
    +

    Macros

    +
    +
    +
    macro bar(): untyped
    +
    + + +
    -
    -
    -
    macro z16()
    -
    - - +
    +
    macro z16()
    +
    + +

    Example:

    discard 1
    cz16 after

    Example:

    doAssert 2 == 1 + 1
    - -
    -
    +
    -
    -
    -
    macro z18(): int
    -
    - - cz18 - -
    -
    +
    +
    macro z18(): int
    +
    -
    +cz18 -
    +
    + +
    -

    Templates

    -
    -
    -
    -
    template foo(a, b: SomeType)
    -
    - - This does nothing - -
    -
    +

    Templates

    +
    +
    +
    template foo(a, b: SomeType)
    +
    + +This does nothing +
    -
    -
    -
    template fromUtils2()
    -
    - - ok3 +
    +
    template fromUtils2()
    +
    + +ok3

    Example:

    discard """should be shown as examples for fromUtils2
            in module calling fromUtilsGen"""
    - -
    -
    +
    -
    -
    -
    template myfn()
    -
    - - +
    +
    template myfn()
    +
    + +

    Example:

    import std/strutils
     ## issue #8871 preserve formatting
    @@ -1101,54 +1060,42 @@ 

    Templates

    block: discard 0xff # elu par cette crapule # should be in
    should be still in - -
    -
    +
    -
    -
    -
    template testNimDocTrailingExample()
    -
    - - +
    +
    template testNimDocTrailingExample()
    +
    + +

    Example:

    discard 2
    - -
    -
    +
    -
    -
    -
    template z6t(): int
    -
    - - cz6t - -
    -
    +
    +
    template z6t(): int
    +
    +cz6t + +
    -
    -
    -
    template z14()
    -
    - - cz14 +
    +
    template z14()
    +
    + +cz14

    Example:

    discard
    - -
    -
    +
    -
    -
    -
    template z15()
    -
    - - cz15 +
    +
    template z15()
    +
    + +cz15

    Example:

    discard

    Example:

    @@ -1159,25 +1106,24 @@

    Templates

    assert true

    Example:

    discard 1
    in or out? - -
    -
    +
    -
    -
    +
    +
    - +
    + diff --git a/nimdoc/testproject/expected/theindex.html b/nimdoc/testproject/expected/theindex.html index c62b4c7db7fbf..88d4b86aa7d06 100644 --- a/nimdoc/testproject/expected/theindex.html +++ b/nimdoc/testproject/expected/theindex.html @@ -1,11 +1,12 @@ - + - + + -Index @@ -16,16 +17,60 @@ +Index - + + + -
    -
    -

    Index

    - Modules: subdir/subdir_b/utils, testproject.

    API symbols

    +
    +
    +

    Index

    + Modules: subdir/subdir_b/utils, testproject.

    API symbols

    `$`:
    +
    - +
    + From 0cba30e1ce610fe7914ef87ac4fad9a5860cce90 Mon Sep 17 00:00:00 2001 From: Lancer Date: Wed, 20 Jul 2022 22:25:48 +0200 Subject: [PATCH 14/19] updated docs with rsttester.nim --- nimdoc/rst2html/expected/rst_examples.html | 128 ++++++++++++++------- 1 file changed, 89 insertions(+), 39 deletions(-) diff --git a/nimdoc/rst2html/expected/rst_examples.html b/nimdoc/rst2html/expected/rst_examples.html index efc8ac414f895..1df91ff1fd661 100644 --- a/nimdoc/rst2html/expected/rst_examples.html +++ b/nimdoc/rst2html/expected/rst_examples.html @@ -1,11 +1,12 @@ - + - + + -Not a Nim Manual @@ -16,41 +17,88 @@ +Not a Nim Manual - + + + -
    -
    -

    Not a Nim Manual

    -
    +
    +
    +

    Not a Nim Manual

    +
    -
    - -     Dark Mode -
    - -
    - Search: -
    -
    - Group by: - -
    -
    +
    - -
    - -

    +
    + +

    Authors:Andreas Rumpf, Zahary Karadjov
    Authors:Andreas Rumpf, Zahary Karadjov
    Version:|nimversion|

    "Complexity" seems to be a lot like "energy": you can transfer it from the end-user to one/some of the other players, but the total amount seems to remain pretty much constant for a given task. -- Ran

    @@ -257,17 +305,19 @@

    IntroductionF2 without pipe

    not in table

    - +

    +
    - +
    + From c923af7853d6fb6777318d270ddd7a6aa40b0d42 Mon Sep 17 00:00:00 2001 From: Lancer Date: Fri, 22 Jul 2022 17:42:29 +0200 Subject: [PATCH 15/19] regenerated documentation --- .../expected/index.html | 163 +- .../expected/theindex.html | 67 +- nimdoc/testproject/expected/nimdoc.out.css | 201 ++- .../expected/subdir/subdir_b/utils.html | 862 ++++----- nimdoc/testproject/expected/testproject.html | 1587 +++++++++-------- nimdoc/testproject/expected/theindex.html | 67 +- 6 files changed, 1445 insertions(+), 1502 deletions(-) diff --git a/nimdoc/test_out_index_dot_html/expected/index.html b/nimdoc/test_out_index_dot_html/expected/index.html index 3499b5326d272..d97f7092a6489 100644 --- a/nimdoc/test_out_index_dot_html/expected/index.html +++ b/nimdoc/test_out_index_dot_html/expected/index.html @@ -1,12 +1,11 @@ - + - + - +nimdoc/test_out_index_dot_html/foo @@ -17,133 +16,89 @@ -nimdoc/test_out_index_dot_html/foo + - - - -
    -
    -

    nimdoc/test_out_index_dot_html/foo

    -
    +
    +
    +

    nimdoc/test_out_index_dot_html/foo

    +
    -
    - -     Dark Mode -
    -
    -
    - Search: -
    -
    - Group by: - -
    -
      -
    • - Procs -
        +
        + +     Dark Mode +
        + +
        + Search: +
        +
        + Group by: + +
        + +
      +
    -
    -
    - -

    -
    -

    Procs

    -
    -
    -
    proc foo() {....raises: [], tags: [].}
    -
    - -I do foo + +
    + +

    +
    +

    Procs

    +
    +
    +
    +
    proc foo() {....raises: [], tags: [], forbids: [].}
    +
    + + I do foo + +
    +
    -
    -
    + +
    -
    -
    - + diff --git a/nimdoc/test_out_index_dot_html/expected/theindex.html b/nimdoc/test_out_index_dot_html/expected/theindex.html index 34ddf8f6ad9ba..00c81189eda45 100644 --- a/nimdoc/test_out_index_dot_html/expected/theindex.html +++ b/nimdoc/test_out_index_dot_html/expected/theindex.html @@ -1,12 +1,11 @@ - + - + - +Index @@ -17,74 +16,28 @@ -Index + - - - -
    -
    -

    Index

    - Modules: index.

    API symbols

    +
    +
    +

    Index

    + Modules: index.

    API symbols

    foo:
    -
    -
    - + diff --git a/nimdoc/testproject/expected/nimdoc.out.css b/nimdoc/testproject/expected/nimdoc.out.css index 4abea9ce0a6a4..e72c4a213c971 100644 --- a/nimdoc/testproject/expected/nimdoc.out.css +++ b/nimdoc/testproject/expected/nimdoc.out.css @@ -38,6 +38,10 @@ Modified by Boyd Greenfield and narimiran --program: #6060c0; --option: #508000; --raw-data: #a4255b; + + --clipboard-image-normal: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' style='color: black' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E %3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2' /%3E %3C/svg%3E"); + --clipboard-image-selected: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' style='color: black' viewBox='0 0 20 20' fill='currentColor'%3E %3Cpath d='M8 3a1 1 0 011-1h2a1 1 0 110 2H9a1 1 0 01-1-1z' /%3E %3Cpath d='M6 3a2 2 0 00-2 2v11a2 2 0 002 2h8a2 2 0 002-2V5a2 2 0 00-2-2 3 3 0 01-3 3H9a3 3 0 01-3-3z' /%3E %3C/svg%3E"); + --clipboard-image: var(--clipboard-image-normal) } [data-theme="dark"] { @@ -68,6 +72,10 @@ Modified by Boyd Greenfield and narimiran --program: #9090c0; --option: #90b010; --raw-data: #8be9fd; + + --clipboard-image-normal: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' style='color: lightgray' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E %3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2' /%3E %3C/svg%3E"); + --clipboard-image-selected: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' style='color: lightgray' viewBox='0 0 20 20' fill='currentColor'%3E %3Cpath d='M8 3a1 1 0 011-1h2a1 1 0 110 2H9a1 1 0 01-1-1z' /%3E %3Cpath d='M6 3a2 2 0 00-2 2v11a2 2 0 002 2h8a2 2 0 002-2V5a2 2 0 00-2-2 3 3 0 01-3 3H9a3 3 0 01-3-3z' /%3E %3C/svg%3E"); + --clipboard-image: var(--clipboard-image-normal); } .theme-switch-wrapper { @@ -151,24 +159,28 @@ body { padding: 0; box-sizing: border-box; } -.column, -.columns { +.column, .columns { width: 100%; float: left; box-sizing: border-box; - margin-left: 1%; -} + margin-left: 1%; } -.column:first-child, -.columns:first-child { +.column:first-child, .columns:first-child { margin-left: 0; } +.container .row { + display: flex; } + .three.columns { - width: 22%; -} + width: 25.0%; + height: 100vh; + position: sticky; + top: 0px; + overflow-y: auto; } .nine.columns { - width: 77.0%; } + width: 75.0%; + padding-left: 1.5em; } .twelve.columns { width: 100%; @@ -255,27 +267,32 @@ a.reference-toplevel { font-weight: bold; } +a.nimdoc { + word-spacing: 0.3em; +} + a.toc-backref { text-decoration: none; - color: var(--text); } + color: var(--text); +} a.link-seesrc { color: #607c9f; font-size: 0.9em; - font-style: italic; } + font-style: italic; +} -a:hover, -a:focus { +a:hover, a:focus { color: var(--anchor-focus); - text-decoration: underline; } + text-decoration: underline; +} a:hover span.Identifier { color: var(--anchor); } -sub, -sup { +sub, sup { position: relative; font-size: 75%; line-height: 0; @@ -302,8 +319,7 @@ img { background: transparent !important; box-shadow: none !important; } - a, - a:visited { + a, a:visited { text-decoration: underline; } a[href]:after { @@ -317,16 +333,14 @@ img { a[href^="#"]:after { content: ""; } - pre, - blockquote { + pre, blockquote { border: 1px solid #999; page-break-inside: avoid; } thead { display: table-header-group; } - tr, - img { + tr, img { page-break-inside: avoid; } img { @@ -341,22 +355,18 @@ img { h1.title { page-break-before: avoid; } - p, - h2, - h3 { + p, h2, h3 { orphans: 3; widows: 3; } - h2, - h3 { + h2, h3 { page-break-after: avoid; } } p { margin-top: 0.5em; - margin-bottom: 0.5em; -} + margin-bottom: 0.5em; } small { font-size: 85%; } @@ -364,8 +374,7 @@ small { strong { font-weight: 600; font-size: 0.95em; - color: var(--strong); -} + color: var(--strong); } em { font-style: italic; } @@ -386,8 +395,7 @@ h1.title { text-align: center; font-weight: 900; margin-top: 0.75em; - margin-bottom: 0em; -} + margin-bottom: 0em; } h2 { font-size: 1.3em; @@ -414,36 +422,29 @@ h6 { font-size: 1.1em; } -ul, -ol { +ul, ol { padding: 0; margin-top: 0.5em; margin-left: 0.75em; } -ul ul, -ul ol, -ol ol, -ol ul { +ul ul, ul ol, ol ol, ol ul { margin-bottom: 0; margin-left: 1.25em; } ul.simple > li { - list-style-type: circle; -} + list-style-type: circle; } ul.simple-boot li { - list-style-type: none; - margin-left: 0em; - margin-bottom: 0.5em; -} + list-style-type: none; + margin-left: 0em; + margin-bottom: 0.5em; } ol.simple > li, ul.simple > li { margin-bottom: 0.2em; margin-left: 0.4em } ul.simple.simple-toc > li { - margin-top: 1em; -} + margin-top: 1em; } ul.simple-toc { list-style: none; @@ -452,8 +453,7 @@ ul.simple-toc { margin-top: 1em; } ul.simple-toc > li { - list-style-type: none; -} + list-style-type: none; } ul.simple-toc-section { list-style-type: circle; @@ -463,12 +463,10 @@ ul.simple-toc-section { ul.nested-toc-section { list-style-type: circle; margin-left: -0.75em; - color: var(--text); -} + color: var(--text); } ul.nested-toc-section > li { - margin-left: 1.25em; -} + margin-left: 1.25em; } ol.arabic { @@ -515,7 +513,8 @@ hr.footnote { margin-top: 0.15em; } div.footnote-group { - margin-left: 1em; } + margin-left: 1em; +} div.footnote-label { display: inline-block; min-width: 1.7em; @@ -555,6 +554,11 @@ blockquote { border-left: 5px solid #bbc; } +blockquote.markdown-quote { + font-size: 0.9rem; /* use rem to avoid recursion */ + font-style: normal; +} + .pre, span.tok { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; font-weight: 500; @@ -572,6 +576,10 @@ span.tok { margin-right: 0.2em; } +.copyToClipBoard { + position: relative; +} + pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; color: var(--text); @@ -590,7 +598,25 @@ pre { border: 1px solid var(--border); -webkit-border-radius: 6px; -moz-border-radius: 6px; - border-radius: 6px; } + border-radius: 6px; +} + +.copyToClipBoardBtn { + visibility: hidden; + position: absolute; + width: 24px; + border-radius: 4px; + background-image: var(--clipboard-image); + right: 5px; + top: 13px; + background-color: var(--secondary-background); + padding: 11px; + border: 0; +} + +.copyToClipBoard:hover .copyToClipBoardBtn { + visibility: visible; +} .pre-scrollable { max-height: 340px; @@ -655,8 +681,8 @@ table th { font-weight: bold; } table th.docinfo-name { - background-color: transparent; - text-align: right; + background-color: transparent; + text-align: right; } table tr:hover { @@ -673,31 +699,31 @@ table.borderless td, table.borderless th { padding: 0 0.5em 0 0 !important; } .admonition { - padding: 0.3em; - background-color: var(--secondary-background); - border-left: 0.4em solid #7f7f84; - margin-bottom: 0.5em; - -webkit-box-shadow: 0 5px 8px -6px rgba(0,0,0,.2); - -moz-box-shadow: 0 5px 8px -6px rgba(0,0,0,.2); - box-shadow: 0 5px 8px -6px rgba(0,0,0,.2); + padding: 0.3em; + background-color: var(--secondary-background); + border-left: 0.4em solid #7f7f84; + margin-bottom: 0.5em; + -webkit-box-shadow: 0 5px 8px -6px rgba(0,0,0,.2); + -moz-box-shadow: 0 5px 8px -6px rgba(0,0,0,.2); + box-shadow: 0 5px 8px -6px rgba(0,0,0,.2); } .admonition-info { - border-color: var(--info-background); + border-color: var(--info-background); } .admonition-info-text { - color: var(--info-background); + color: var(--info-background); } .admonition-warning { - border-color: var(--warning-background); + border-color: var(--warning-background); } .admonition-warning-text { - color: var(--warning-background); + color: var(--warning-background); } .admonition-error { - border-color: var(--error-background); + border-color: var(--error-background); } .admonition-error-text { - color: var(--error-background); + color: var(--error-background); } .first { @@ -731,8 +757,7 @@ div.footer, div.header { font-size: smaller; } div.footer { - padding-top: 5em; -} + padding-top: 5em; } div.line-block { display: block; @@ -751,17 +776,14 @@ div.search_results { background-color: var(--third-background); margin: 3em; padding: 1em; - border: 1px solid #4d4d4d; -} + border: 1px solid #4d4d4d; } div#global-links ul { margin-left: 0; - list-style-type: none; -} + list-style-type: none; } div#global-links > simple-boot { - margin-left: 3em; -} + margin-left: 3em; } hr.docutils { width: 75%; } @@ -941,8 +963,7 @@ span.Directive { span.option { font-weight: bold; font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - color: var(--option); -} + color: var(--option); } span.Prompt { font-weight: bold; @@ -958,11 +979,10 @@ span.program { text-decoration: underline; text-decoration-color: var(--hint); text-decoration-thickness: 0.05em; - text-underline-offset: 0.15em; -} + text-underline-offset: 0.15em; } -span.Command, span.Rule, span.Hyperlink, span.Label, span.Reference, -span.Other { +span.Command, span.Rule, span.Hyperlink, +span.Label, span.Reference, span.Other { color: var(--other); } /* Pop type, const, proc, and iterator defs in nim def blocks */ @@ -1000,17 +1020,14 @@ span.pragmadots { border-radius: 4px; margin: 0 2px; cursor: pointer; - font-size: 0.8em; -} + font-size: 0.8em; } span.pragmadots:hover { - background-color: var(--hint); -} + background-color: var(--hint); } + span.pragmawrap { - display: none; -} + display: none; } span.attachedType { display: none; - visibility: hidden; -} + visibility: hidden; } diff --git a/nimdoc/testproject/expected/subdir/subdir_b/utils.html b/nimdoc/testproject/expected/subdir/subdir_b/utils.html index 15cdd8bc72841..c42f185905f84 100644 --- a/nimdoc/testproject/expected/subdir/subdir_b/utils.html +++ b/nimdoc/testproject/expected/subdir/subdir_b/utils.html @@ -1,12 +1,11 @@ - + - + - +subdir/subdir_b/utils @@ -17,262 +16,193 @@ -subdir/subdir_b/utils + - - - -
    -
    -

    subdir/subdir_b/utils

    -
    +
    +
    +

    subdir/subdir_b/utils

    +
    -
    - -     Dark Mode -
    - -
    - Search: -
    -
    - Group by: - -
    - +
  • - Templates - + +
  • -
    -
    - -

    This is a description of the utils module.

    + +
    + +

    This is a description of the utils module.

    Links work:

    This is now a header

    @@ -286,291 +216,369 @@
  • Other case value
  • Second case.
  • -

    Ref group fn2 or specific function like fn2 or fn2 or fn2.

    -

    Ref generics like this: binarySearch or binarySearch or proc or in different style: proc. Can be combined with export symbols and type parameters: binarysearch. With spaces binary.

    -

    Note that proc can be used in postfix form: binarySearch.

    -

    Ref. type like G and type and G and type.

    -

    Group ref. with capital letters works: fN11 or fn11

    -Ref. [ is the same as proc because there are no overloads. The full form: procRef. [ aka `.Ref. $ aka proc or proc.Ref. $.Ref. foo aka iterator.Ref. fn.Ref. ' or func or `.

    -
    -

    Types

    -
    -
    -
    G[T] = object
    +

    Ref group fn2 or specific function like fn2() or fn2( int ) or fn2(int, float).

    +

    Ref generics like this: binarySearch or binarySearch(openArray[T], K, proc (T, K)) or proc binarySearch(openArray[T], K, proc (T, K)) or in different style: proc binarysearch(openarray[T], K, proc(T, K)). Can be combined with export symbols and type parameters: binarysearch*[T, K](openArray[T], K, proc (T, K)). With spaces binary search.

    +

    Note that proc can be used in postfix form: binarySearch proc.

    +

    Ref. type like G and type G and G[T] and type G*[T].

    +

    Group ref. with capital letters works: fN11 or fn11

    +Ref. [] is the same as proc `[]`(G[T]) because there are no overloads. The full form: proc `[]`*[T](x: G[T]): TRef. []= aka `[]=`(G[T], int, T).Ref. $ aka proc $ or proc `$`.Ref. $(a: ref SomeType).Ref. foo_bar aka iterator foo_bar_.Ref. fn[T; U,V: SomeFloat]().Ref. 'big or func `'big` or `'big`(string).

    +
    +

    Types

    +
    +
    +
    G[T] = object
       val: T
     
    -
    - - - -
    +
    + + + +
    -
    SomeType = enum
    +  
    SomeType = enum
       enumValueA, enumValueB, enumValueC
    -
    - - - -
    +
    + + + +
    -
    +
    +
    -

    Procs

    -
    -
    -
    proc `$`[T](a: G[T]): string
    -
    - - - -
    +

    Procs

    +
    +
    +
    +
    proc `$`[T](a: G[T]): string
    +
    + + + +
    -
    proc `$`[T](a: ref SomeType): string
    -
    - - - -
    +
    proc `$`[T](a: ref SomeType): string
    +
    + + + +
    -
    -
    func `'big`(a: string): SomeType {....raises: [], tags: [].}
    -
    - - -
    -
    -
    proc `[]=`[T](a: var G[T]; index: int; value: T)
    -
    - - - -
    +
    +
    +
    func `'big`(a: string): SomeType {....raises: [], tags: [], forbids: [].}
    +
    + + + +
    -
    -
    proc `[]`[T](x: G[T]): T
    -
    +
    +
    +
    +
    proc `[]`[T](x: G[T]): T
    +
    + + + +
    +
    +
    +
    +
    +
    proc `[]=`[T](a: var G[T]; index: int; value: T)
    +
    + + + +
    +
    -
    -
    -
    proc binarySearch[T, K](a: openArray[T]; key: K;
    +
    +
    +
    proc binarySearch[T, K](a: openArray[T]; key: K;
                             cmp: proc (x: T; y: K): int {.closure.}): int
    -
    - - - -
    +
    + + + +
    -
    -
    proc f(x: G[int]) {....raises: [], tags: [].}
    -
    -There is also variant f - -
    +
    +
    +
    +
    proc f(x: G[int]) {....raises: [], tags: [], forbids: [].}
    +
    + + There is also variant f(G[string]) + +
    -
    proc f(x: G[string]) {....raises: [], tags: [].}
    -
    - -See also f. - -
    +
    proc f(x: G[string]) {....raises: [], tags: [], forbids: [].}
    +
    + + See also f(G[int]). + +
    -
    -
    proc fn2() {....raises: [], tags: [].}
    -
    -comment +
    +
    +
    +
    proc fn[T; U, V: SomeFloat]()
    +
    + + + +
    +
    - +
    +
    +
    +
    proc fn2() {....raises: [], tags: [], forbids: [].}
    +
    + + comment + +
    -
    proc fn2(x: int) {....raises: [], tags: [].}
    -
    - -fn2 comment - -
    +
    proc fn2(x: int) {....raises: [], tags: [], forbids: [].}
    +
    + + fn2 comment + +
    -
    proc fn2(x: int; y: float) {....raises: [], tags: [].}
    -
    - - - -
    +
    proc fn2(x: int; y: float) {....raises: [], tags: [], forbids: [].}
    +
    + + + +
    -
    -
    proc fn3(): auto {....raises: [], tags: [].}
    -
    - -comment -
    -
    -
    proc fn4(): auto {....raises: [], tags: [].}
    -
    - -comment - -
    +
    +
    +
    proc fn3(): auto {....raises: [], tags: [], forbids: [].}
    +
    + + comment + +
    -
    -
    proc fn5() {....raises: [], tags: [].}
    -
    - -comment -
    -
    -
    proc fn6() {....raises: [], tags: [].}
    -
    - -comment - -
    +
    +
    +
    proc fn4(): auto {....raises: [], tags: [], forbids: [].}
    +
    + + comment + +
    -
    -
    proc fn7() {....raises: [], tags: [].}
    -
    -comment - -
    -
    -
    proc fn8(): auto {....raises: [], tags: [].}
    -
    - -comment - -
    +
    +
    +
    proc fn5() {....raises: [], tags: [], forbids: [].}
    +
    + + comment + +
    -
    -
    func fn9(a: int): int {....raises: [], tags: [].}
    -
    - -comment -
    -
    -
    func fn10(a: int): int {....raises: [], tags: [].}
    -
    +
    +
    +
    proc fn6() {....raises: [], tags: [], forbids: [].}
    +
    + + comment + +
    +
    -comment +
    +
    +
    +
    proc fn7() {....raises: [], tags: [], forbids: [].}
    +
    + + comment + +
    +
    -
    -
    -
    func fN11() {....raises: [], tags: [].}
    -
    +
    +
    +
    proc fn8(): auto {....raises: [], tags: [], forbids: [].}
    +
    + + comment + +
    +
    +
    +
    +
    +
    func fn9(a: int): int {....raises: [], tags: [], forbids: [].}
    +
    + + comment + +
    +
    +
    +
    +
    +
    func fn10(a: int): int {....raises: [], tags: [], forbids: [].}
    +
    + + comment + +
    +
    - +
    +
    +
    +
    func fN11() {....raises: [], tags: [], forbids: [].}
    +
    + + + +
    -
    func fN11(x: int) {....raises: [], tags: [].}
    -
    - - - -
    +
    func fN11(x: int) {....raises: [], tags: [], forbids: [].}
    +
    + + + +
    -
    -
    proc fn[T; U, V: SomeFloat]()
    -
    - - -
    -
    -
    proc funWithGenerics[T, U: SomeFloat](a: T; b: U)
    -
    - - - -
    +
    +
    +
    proc funWithGenerics[T, U: SomeFloat](a: T; b: U)
    +
    + + + +
    -
    -
    proc someType(): SomeType {....raises: [], tags: [].}
    -
    -constructor. +
    +
    +
    +
    proc someType(): SomeType {....raises: [], tags: [], forbids: [].}
    +
    + + constructor. + +
    +
    -
    -
    +
    +
    -

    Iterators

    -
    -
    -
    iterator fooBar(a: seq[SomeType]): int {....raises: [], tags: [].}
    -
    - - - -
    +

    Iterators

    +
    +
    +
    +
    iterator fooBar(a: seq[SomeType]): int {....raises: [], tags: [], forbids: [].}
    +
    + + + +
    -
    -
    -

    Templates

    -
    -
    -
    template aEnum(): untyped
    -
    - - - -
    -
    -
    template bEnum(): untyped
    -
    - - -
    +
    -
    -
    template fromUtilsGen(): untyped
    -
    - -should be shown in utils.html only +
    +

    Templates

    +
    +
    +
    +
    template aEnum(): untyped
    +
    + + + +
    +
    + +
    +
    +
    +
    template bEnum(): untyped
    +
    + + + +
    +
    + +
    +
    +
    +
    template fromUtilsGen(): untyped
    +
    + + should be shown in utils.html only

    Example:

    discard "should be in utils.html only, not in module that calls fromUtilsGen"
    ditto + +
    +
    -
    -
    + +
    -
    -
    - + diff --git a/nimdoc/testproject/expected/testproject.html b/nimdoc/testproject/expected/testproject.html index dbacb57a7493e..e18625222e133 100644 --- a/nimdoc/testproject/expected/testproject.html +++ b/nimdoc/testproject/expected/testproject.html @@ -1,12 +1,11 @@ - + - + - +testproject @@ -17,415 +16,322 @@ -testproject + - - - -
    -
    -

    testproject

    -
    +
    +
    +

    testproject

    +
    -
    - -     Dark Mode -
    - -
    - Search: -
    -
    - Group by: - -
    - +
  • - Iterators - + +
  • - Macros - + +
  • - Templates - + + + + + + + + +
  • -
    -
    - -

    This is the top level module. + +

    + +

    This is the top level module.

    Example:

    import testproject
     import subdir / subdir_b / utils
    @@ -439,131 +345,136 @@ 

    testproject

    Example:

    import testproject
     discard "in top3"
    top3 after

    - +
    -

    Types

    -
    -
    -
    A {.inject.} = enum
    +  

    Types

    +
    +
    +
    A {.inject.} = enum
       aA
    -
    - -The enum A. - -
    +
    + + The enum A. + +
    -
    B {.inject.} = enum
    +  
    B {.inject.} = enum
       bB
    -
    - -The enum B. - -
    +
    + + The enum B. + +
    -
    Foo = enum
    +  
    Foo = enum
       enumValueA2
    -
    - - - -
    +
    + + + +
    -
    FooBuzz {....deprecated: "FooBuzz msg".} = int
    -
    -
    - Deprecated: FooBuzz msg -
    - - +
    FooBuzz {....deprecated: "FooBuzz msg".} = int
    +
    +
    + Deprecated: FooBuzz msg +
    -
    + + +
    -
    Shapes = enum
    +  
    Shapes = enum
       Circle,                   ## A circle
       Triangle,                 ## A three-sided shape
       Rectangle                  ## A four-sided shape
    -
    - -Some shapes. - -
    +
    + + Some shapes. + +
    -
    +
    +
    -

    Vars

    -
    -
    -
    aVariable: array[1, int]
    -
    - - - -
    +

    Vars

    +
    +
    +
    aVariable: array[1, int]
    +
    + + + +
    -
    someVariable: bool
    -
    - -This should be visible. - -
    +
    someVariable: bool
    +
    + + This should be visible. + +
    -
    +
    +
    -

    Consts

    -
    -
    -
    C_A = 0x7FF0000000000000'f64
    -
    - - - -
    +

    Consts

    +
    +
    +
    C_A = 0x7FF0000000000000'f64
    +
    + + + +
    -
    C_B = 0o377'i8
    -
    - - - -
    +
    C_B = 0o377'i8
    +
    + + + +
    -
    C_C = 0o277'i8
    -
    - - - -
    +
    C_C = 0o277'i8
    +
    + + + +
    -
    C_D = 0o177777'i16
    -
    - - - -
    +
    C_D = 0o177777'i16
    +
    + + + +
    -
    +
    +
    -

    Procs

    -
    -
    -
    proc addfBug14485() {....raises: [], tags: [].}
    -
    - -Some proc +

    Procs

    +
    +
    +
    +
    proc addfBug14485() {....raises: [], tags: [], forbids: [].}
    +
    + + Some proc

    Example:

    discard "foo() = " & $[1]
     #[
    @@ -576,152 +487,197 @@ 

    Procs

    6: </script 7: end of broken html ]#
    - -
    + +
    -
    -
    proc anything() {....raises: [], tags: [].}
    -
    - -There is no block quote after blank lines at the beginning. -
    -
    -
    proc asyncFun1(): Future[int] {....raises: [Exception, ValueError],
    -                                tags: [RootEffect].}
    -
    - -ok1 - -
    +
    +
    +
    proc anything() {....raises: [], tags: [], forbids: [].}
    +
    + + There is no block quote after blank lines at the beginning. + +
    -
    -
    proc asyncFun2(): owned(Future[void]) {....raises: [Exception], tags: [RootEffect].}
    -
    - - -
    -
    -
    proc asyncFun3(): owned(Future[void]) {....raises: [Exception], tags: [RootEffect].}
    -
    +
    +
    +
    proc asyncFun1(): Future[int] {....raises: [Exception, ValueError],
    +                                tags: [RootEffect], forbids: [].}
    +
    + + ok1 + +
    +
    +
    +
    +
    +
    proc asyncFun2(): owned(Future[void]) {....raises: [Exception], tags: [RootEffect],
    +                                        forbids: [].}
    +
    + + + +
    +
    +
    +
    +
    +
    proc asyncFun3(): owned(Future[void]) {....raises: [Exception], tags: [RootEffect],
    +                                        forbids: [].}
    +
    + +

    Example:

    discard
    ok1 - -
    + +
    -
    -
    proc bar[T](a, b: T): T
    -
    - - -
    -
    -
    proc baz() {....raises: [], tags: [].}
    -
    - - +
    +
    +
    proc bar[T](a, b: T): T
    +
    + + + +
    +
    - +
    +
    +
    +
    proc baz() {....raises: [], tags: [], forbids: [].}
    +
    + + + +
    -
    proc baz[T](a, b: T): T {....deprecated.}
    -
    -
    - Deprecated -
    - -This is deprecated without message. - -
    +
    proc baz[T](a, b: T): T {....deprecated.}
    +
    +
    + Deprecated
    -
    -
    proc buzz[T](a, b: T): T {....deprecated: "since v0.20".}
    -
    -
    - Deprecated: since v0.20 -
    -This is deprecated with a message. - -
    + This is deprecated without message. + +
    -
    -
    proc c_nonexistent(frmt: cstring): cint {.importc: "nonexistent",
    -    header: "<stdio.h>", varargs, discardable, ...raises: [], tags: [].}
    -
    - +
    +
    +
    +
    proc buzz[T](a, b: T): T {....deprecated: "since v0.20".}
    +
    +
    + Deprecated: since v0.20 +
    -
    + This is deprecated with a message. + +
    -
    -
    proc c_printf(frmt: cstring): cint {.importc: "printf", header: "<stdio.h>",
    -                                     varargs, discardable, ...raises: [], tags: [].}
    -
    -the c printf. etc. +
    +
    +
    +
    proc c_nonexistent(frmt: cstring): cint {.importc: "nonexistent",
    +    header: "<stdio.h>", varargs, discardable, ...raises: [], tags: [], forbids: [].}
    +
    + + + +
    +
    -
    -
    -
    proc fromUtils3() {....raises: [], tags: [].}
    -
    +
    +
    +
    proc c_printf(frmt: cstring): cint {.importc: "printf", header: "<stdio.h>",
    +                                     varargs, discardable, ...raises: [], tags: [],
    +                                     forbids: [].}
    +
    + + the c printf. etc. + +
    +
    -came form utils but should be shown where fromUtilsGen is called +
    +
    +
    +
    proc fromUtils3() {....raises: [], tags: [], forbids: [].}
    +
    + + came form utils but should be shown where fromUtilsGen is called

    Example:

    discard """should be shown as examples for fromUtils3
            in module calling fromUtilsGen"""
    - -
    + +
    -
    -
    proc isValid[T](x: T): bool
    -
    - +
    +
    +
    +
    proc isValid[T](x: T): bool
    +
    + + + +
    +
    -
    -
    -
    proc low2[T: Ordinal | enum | range](x: T): T {.magic: "Low", noSideEffect,
    -    ...raises: [], tags: [].}
    -
    +
    +
    +
    proc low[T: Ordinal | enum | range](x: T): T {.magic: "Low", noSideEffect,
    +    ...raises: [], tags: [], forbids: [].}
    +
    + +

    Returns the lowest possible value of an ordinal value x. As a special semantic rule, x may also be a type identifier.

    +

    See also:

    + +
    low(2) # => -9223372036854775808
    + +
    +
    -

    Returns the lowest possible value of an ordinal value x. As a special semantic rule, x may also be a type identifier.

    +
    +
    +
    +
    proc low2[T: Ordinal | enum | range](x: T): T {.magic: "Low", noSideEffect,
    +    ...raises: [], tags: [], forbids: [].}
    +
    + +

    Returns the lowest possible value of an ordinal value x. As a special semantic rule, x may also be a type identifier.

    See also:

    low2(2) # => -9223372036854775808

    Example:

    discard "in low2"
    - -
    + +
    -
    -
    proc low[T: Ordinal | enum | range](x: T): T {.magic: "Low", noSideEffect,
    -    ...raises: [], tags: [].}
    -
    -

    Returns the lowest possible value of an ordinal value x. As a special semantic rule, x may also be a type identifier.

    -

    See also:

    - -
    low(2) # => -9223372036854775808
    - -
    -
    -
    proc p1() {....raises: [], tags: [].}
    -
    - -cp1 +
    +
    +
    proc p1() {....raises: [], tags: [], forbids: [].}
    +
    + + cp1

    Example:

    doAssert 1 == 1 # regular comments work here
    c4

    Example:

    @@ -738,22 +694,28 @@

    Procs

    ]## discard "c9" # also work after
    - - + +
    -
    -
    func someFunc() {....raises: [], tags: [].}
    -
    -My someFunc. Stuff in quotes here. Some link - -
    -
    -
    proc tripleStrLitTest() {....raises: [], tags: [].}
    -
    - +
    +
    +
    func someFunc() {....raises: [], tags: [], forbids: [].}
    +
    + + My someFunc. Stuff in quotes here. Some link + +
    +
    +
    +
    +
    +
    proc tripleStrLitTest() {....raises: [], tags: [], forbids: [].}
    +
    + +

    Example: cmd: --hint:XDeclaredButNotUsed:off

    ## mullitline string litterals are tricky as their indentation can span
     ## below that of the runnableExamples
    @@ -790,261 +752,343 @@ 

    Procs

    """ ] discard # should be in
    - -
    + +
    -
    -
    proc z1(): Foo {....raises: [], tags: [].}
    -
    -cz1 - -
    -
    -
    proc z2() {....raises: [], tags: [].}
    -
    +
    +
    +
    proc z1(): Foo {....raises: [], tags: [], forbids: [].}
    +
    + + cz1 + +
    +
    -cz2 +
    +
    +
    +
    proc z2() {....raises: [], tags: [], forbids: [].}
    +
    + + cz2

    Example:

    discard "in cz2"
    - -
    + +
    -
    -
    proc z3() {....raises: [], tags: [].}
    -
    - -cz3 -
    -
    -
    proc z4() {....raises: [], tags: [].}
    -
    - -cz4 - -
    +
    +
    +
    proc z3() {....raises: [], tags: [], forbids: [].}
    +
    + + cz3 + +
    -
    -
    proc z5(): int {....raises: [], tags: [].}
    -
    -cz5 - -
    -
    -
    proc z6(): int {....raises: [], tags: [].}
    -
    - -cz6 - -
    +
    +
    +
    proc z4() {....raises: [], tags: [], forbids: [].}
    +
    + + cz4 + +
    -
    -
    proc z7(): int {....raises: [], tags: [].}
    -
    -cz7 - -
    -
    -
    proc z8(): int {....raises: [], tags: [].}
    -
    +
    +
    +
    proc z5(): int {....raises: [], tags: [], forbids: [].}
    +
    + + cz5 + +
    +
    -cz8 +
    +
    +
    +
    proc z6(): int {....raises: [], tags: [], forbids: [].}
    +
    + + cz6 + +
    +
    -
    -
    -
    proc z9() {....raises: [], tags: [].}
    -
    +
    +
    +
    proc z7(): int {....raises: [], tags: [], forbids: [].}
    +
    + + cz7 + +
    +
    +
    +
    +
    +
    proc z8(): int {....raises: [], tags: [], forbids: [].}
    +
    + + cz8 + +
    +
    +
    +
    +
    +
    proc z9() {....raises: [], tags: [], forbids: [].}
    +
    + +

    Example:

    doAssert 1 + 1 == 2
    - -
    + +
    -
    -
    proc z10() {....raises: [], tags: [].}
    -
    - +
    +
    +
    +
    proc z10() {....raises: [], tags: [], forbids: [].}
    +
    + +

    Example: cmd: -d:foobar

    discard 1
    cz10 - -
    + +
    -
    -
    proc z11() {....raises: [], tags: [].}
    -
    - +
    +
    +
    +
    proc z11() {....raises: [], tags: [], forbids: [].}
    +
    + +

    Example:

    discard 1
    - -
    + +
    -
    -
    proc z12(): int {....raises: [], tags: [].}
    -
    - +
    +
    +
    +
    proc z12(): int {....raises: [], tags: [], forbids: [].}
    +
    + +

    Example:

    discard 1
    - -
    + +
    -
    -
    proc z13() {....raises: [], tags: [].}
    -
    -cz13 +
    +
    +
    +
    proc z13() {....raises: [], tags: [], forbids: [].}
    +
    + + cz13

    Example:

    discard
    - -
    + +
    -
    -
    proc z17() {....raises: [], tags: [].}
    -
    -cz17 rest +
    +
    +
    +
    proc z17() {....raises: [], tags: [], forbids: [].}
    +
    + + cz17 rest

    Example:

    discard 1
    rest + +
    +
    -
    -
    + +
    -

    Methods

    -
    -
    -
    method method1(self: Moo) {.base, ...raises: [], tags: [].}
    -
    - -foo1 - -
    +

    Methods

    +
    +
    +
    +
    method method1(self: Moo) {.base, ...raises: [], tags: [], forbids: [].}
    +
    + + foo1 + +
    -
    -
    method method2(self: Moo): int {.base, ...raises: [], tags: [].}
    -
    - -foo2 -
    -
    -
    method method3(self: Moo): int {.base, ...raises: [], tags: [].}
    -
    +
    +
    +
    method method2(self: Moo): int {.base, ...raises: [], tags: [], forbids: [].}
    +
    + + foo2 + +
    +
    -foo3 +
    +
    +
    +
    method method3(self: Moo): int {.base, ...raises: [], tags: [], forbids: [].}
    +
    + + foo3 + +
    +
    -
    -
    +
    +
    -

    Iterators

    -
    -
    -
    iterator fromUtils1(): int {....raises: [], tags: [].}
    -
    - - +

    Iterators

    +
    +
    +
    +
    iterator fromUtils1(): int {....raises: [], tags: [], forbids: [].}
    +
    + +

    Example:

    # ok1
     assert 1 == 1
     # ok2
    - -
    + +
    -
    -
    iterator iter1(n: int): int {....raises: [], tags: [].}
    -
    - -foo1 -
    -
    -
    iterator iter2(n: int): int {....raises: [], tags: [].}
    -
    +
    +
    +
    iterator iter1(n: int): int {....raises: [], tags: [], forbids: [].}
    +
    + + foo1 + +
    +
    -foo2 +
    +
    +
    +
    iterator iter2(n: int): int {....raises: [], tags: [], forbids: [].}
    +
    + + foo2

    Example:

    discard # bar
    + +
    +
    -
    -
    + +
    -

    Macros

    -
    -
    -
    macro bar(): untyped
    -
    - - - -
    +

    Macros

    +
    +
    +
    +
    macro bar(): untyped
    +
    + + + +
    -
    -
    macro z16()
    -
    - +
    +
    +
    +
    macro z16()
    +
    + +

    Example:

    discard 1
    cz16 after

    Example:

    doAssert 2 == 1 + 1
    - -
    + +
    -
    -
    macro z18(): int
    -
    -cz18 +
    +
    +
    +
    macro z18(): int
    +
    + + cz18 + +
    +
    -
    -
    +
    +
    -

    Templates

    -
    -
    -
    template foo(a, b: SomeType)
    -
    - -This does nothing - -
    +

    Templates

    +
    +
    +
    +
    template foo(a, b: SomeType)
    +
    + + This does nothing + +
    -
    -
    template fromUtils2()
    -
    -ok3 +
    +
    +
    +
    template fromUtils2()
    +
    + + ok3

    Example:

    discard """should be shown as examples for fromUtils2
            in module calling fromUtilsGen"""
    - -
    + +
    -
    -
    template myfn()
    -
    - +
    +
    +
    +
    template myfn()
    +
    + +

    Example:

    import std/strutils
     ## issue #8871 preserve formatting
    @@ -1060,42 +1104,54 @@ 

    Templates

    block: discard 0xff # elu par cette crapule # should be in
    should be still in - -
    + +
    -
    -
    template testNimDocTrailingExample()
    -
    - +
    +
    +
    +
    template testNimDocTrailingExample()
    +
    + +

    Example:

    discard 2
    - -
    + +
    -
    -
    template z6t(): int
    -
    -cz6t - -
    -
    -
    template z14()
    -
    +
    +
    +
    template z6t(): int
    +
    + + cz6t + +
    +
    -cz14 +
    +
    +
    +
    template z14()
    +
    + + cz14

    Example:

    discard
    - -
    + +
    -
    -
    template z15()
    -
    -cz15 +
    +
    +
    +
    template z15()
    +
    + + cz15

    Example:

    discard

    Example:

    @@ -1106,24 +1162,25 @@

    Templates

    assert true

    Example:

    discard 1
    in or out? + +
    +
    -
    -
    +
    +
    -
    -
    - + diff --git a/nimdoc/testproject/expected/theindex.html b/nimdoc/testproject/expected/theindex.html index 88d4b86aa7d06..c62b4c7db7fbf 100644 --- a/nimdoc/testproject/expected/theindex.html +++ b/nimdoc/testproject/expected/theindex.html @@ -1,12 +1,11 @@ - + - + - +Index @@ -17,60 +16,16 @@ -Index + - - - -
    -
    -

    Index

    - Modules: subdir/subdir_b/utils, testproject.

    API symbols

    +
    +
    +

    Index

    + Modules: subdir/subdir_b/utils, testproject.

    API symbols

    `$`:
    -
    -
    - + From 4bbe4bd6207993135efe705098f66811e07362d1 Mon Sep 17 00:00:00 2001 From: Lancer Date: Fri, 22 Jul 2022 19:31:53 +0200 Subject: [PATCH 16/19] updated rst docs --- nimdoc/rst2html/expected/rst_examples.html | 128 +++++++-------------- 1 file changed, 39 insertions(+), 89 deletions(-) diff --git a/nimdoc/rst2html/expected/rst_examples.html b/nimdoc/rst2html/expected/rst_examples.html index 1df91ff1fd661..efc8ac414f895 100644 --- a/nimdoc/rst2html/expected/rst_examples.html +++ b/nimdoc/rst2html/expected/rst_examples.html @@ -1,12 +1,11 @@ - + - + - +Not a Nim Manual @@ -17,88 +16,41 @@ -Not a Nim Manual + - - - -
    -
    -

    Not a Nim Manual

    -
    +
    +
    +

    Not a Nim Manual

    +
    -
    - -     Dark Mode -
    - -
    - Search: -
    -
    - Group by: - -
    -
    -
    -
    - -

    + +
    + +

    Authors:Andreas Rumpf, Zahary Karadjov
    Authors:Andreas Rumpf, Zahary Karadjov
    Version:|nimversion|

    "Complexity" seems to be a lot like "energy": you can transfer it from the end-user to one/some of the other players, but the total amount seems to remain pretty much constant for a given task. -- Ran

    @@ -305,19 +257,17 @@

    IntroductionF2 without pipe

    not in table

    - +

    -
    -
    - + From 49616c99662a2b103c12ecef11539c2ee7567e04 Mon Sep 17 00:00:00 2001 From: Lancer11211 <109360848+Lancer11211@users.noreply.github.com> Date: Mon, 25 Jul 2022 14:55:18 +0200 Subject: [PATCH 17/19] Update changelog.md Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com> --- changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index dcd1e4e96c00a..1635fefa75d5b 100644 --- a/changelog.md +++ b/changelog.md @@ -68,7 +68,7 @@ becomes an alias for `addr`. ## Language changes - [Tag tracking](manual.html#tag-tracking) supports the definition of forbidden tags by the `.forbids` pragma - it can be used to disable certain effects in proc types + it can be used to disable certain effects in proc types. - [Case statement macros](manual.html#macros-case-statement-macros) are no longer experimental, meaning you no longer need to enable the experimental switch `caseStmtMacros` to use them. - Templates now accept [macro pragmas](https://nim-lang.github.io/Nim/manual.html#userminusdefined-pragmas-macro-pragmas). From 68c256e626674289128cac933df195b2b605c4d8 Mon Sep 17 00:00:00 2001 From: Lancer Date: Mon, 25 Jul 2022 16:00:07 +0200 Subject: [PATCH 18/19] updated changelog --- changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index 1635fefa75d5b..c698f09d7619b 100644 --- a/changelog.md +++ b/changelog.md @@ -68,7 +68,7 @@ becomes an alias for `addr`. ## Language changes - [Tag tracking](manual.html#tag-tracking) supports the definition of forbidden tags by the `.forbids` pragma - it can be used to disable certain effects in proc types. + which can be used to disable certain effects in proc types. - [Case statement macros](manual.html#macros-case-statement-macros) are no longer experimental, meaning you no longer need to enable the experimental switch `caseStmtMacros` to use them. - Templates now accept [macro pragmas](https://nim-lang.github.io/Nim/manual.html#userminusdefined-pragmas-macro-pragmas). From f9b8f4e36d8cdb6e3eb36d0f260f74a2259a93ec Mon Sep 17 00:00:00 2001 From: Lancer Date: Mon, 25 Jul 2022 19:20:10 +0200 Subject: [PATCH 19/19] corrected typo --- compiler/semcall.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 2db897f1ce466..4f956785e0fdd 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -155,7 +155,7 @@ proc effectProblem(f, a: PType; result: var string; c: PContext) = of efEffectsDelayed: result.add "\n The `.effectsOf` annotations differ." of efTagsIllegal: - result.add "\n The `.forbids` requirements catched an illegal tag." + result.add "\n The `.forbids` requirements caught an illegal tag." when defined(drnim): if not c.graph.compatibleProps(c.graph, f, a): result.add "\n The `.requires` or `.ensures` properties are incompatible."