mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-10 05:38:10 +00:00
* enable stricteffects * add gcsafe * fix tests * use func * fixes pegs tests * explicitly mark repr related procs with noSideEffect * add nimLegacyEffects * change URL * fixes docopt * add `raises: []` to repr * fixes weave * fixes nimyaml * fixes glob * fixes parsetoml * Apply suggestions from code review * Update testament/important_packages.nim * add legacy:laxEffects
This commit is contained in:
@@ -89,6 +89,9 @@
|
||||
- ORC is now the default memory management strategy. Use
|
||||
`--mm:refc` for a transition period.
|
||||
|
||||
- `strictEffects` are no longer experimental.
|
||||
Use `legacy:laxEffects` to keep backward compatibility.
|
||||
|
||||
- The `gorge`/`staticExec` calls will now return a descriptive message in the output
|
||||
if the execution fails for whatever reason. To get back legacy behaviour use `-d:nimLegacyGorgeErrors`.
|
||||
|
||||
|
||||
@@ -30,11 +30,6 @@ define:useStdoutAsStdmsg
|
||||
warning[ObservableStores]: off
|
||||
@end
|
||||
|
||||
@if nimHasEffectsOf:
|
||||
experimental:strictEffects
|
||||
warningAsError:Effect:on
|
||||
@end
|
||||
|
||||
@if nimHasWarningAsError:
|
||||
warningAsError:GcUnsafe2:on
|
||||
@end
|
||||
|
||||
@@ -228,6 +228,8 @@ type
|
||||
## Historically and especially in version 1.0.0 of the language
|
||||
## conversions to unsigned numbers were checked. In 1.0.4 they
|
||||
## are not anymore.
|
||||
laxEffects
|
||||
## Lax effects system prior to Nim 2.0.
|
||||
|
||||
SymbolFilesOption* = enum
|
||||
disabledSf, writeOnlySf, readOnlySf, v2Sf, stressTest
|
||||
|
||||
@@ -495,7 +495,7 @@ proc isIndirectCall(tracked: PEffects; n: PNode): bool =
|
||||
if n.kind != nkSym:
|
||||
result = true
|
||||
elif n.sym.kind == skParam:
|
||||
if strictEffects in tracked.c.features:
|
||||
if laxEffects notin tracked.c.config.legacyFeatures:
|
||||
if tracked.owner == n.sym.owner and sfEffectsDelayed in n.sym.flags:
|
||||
result = false # it is not a harmful call
|
||||
else:
|
||||
@@ -581,7 +581,7 @@ proc isOwnedProcVar(tracked: PEffects; n: PNode): bool =
|
||||
tracked.owner == n.sym.owner
|
||||
#if result and sfPolymorphic notin n.sym.flags:
|
||||
# echo tracked.config $ n.info, " different here!"
|
||||
if strictEffects in tracked.c.features:
|
||||
if laxEffects notin tracked.c.config.legacyFeatures:
|
||||
result = result and sfEffectsDelayed in n.sym.flags
|
||||
|
||||
proc isNoEffectList(n: PNode): bool {.inline.} =
|
||||
@@ -598,7 +598,7 @@ proc trackOperandForIndirectCall(tracked: PEffects, n: PNode, formals: PType; ar
|
||||
# assume indirect calls are taken here:
|
||||
if op != nil and op.kind == tyProc and n.skipConv.kind != nkNilLit and
|
||||
not isTrival(caller) and
|
||||
((param != nil and sfEffectsDelayed in param.flags) or strictEffects notin tracked.c.features):
|
||||
((param != nil and sfEffectsDelayed in param.flags) or laxEffects in tracked.c.config.legacyFeatures):
|
||||
|
||||
internalAssert tracked.config, op.n[0].kind == nkEffectList
|
||||
var effectList = op.n[0]
|
||||
@@ -844,7 +844,7 @@ proc trackCall(tracked: PEffects; n: PNode) =
|
||||
assumeTheWorst(tracked, n, op)
|
||||
gcsafeAndSideeffectCheck()
|
||||
else:
|
||||
if strictEffects in tracked.c.features and a.kind == nkSym and
|
||||
if laxEffects notin tracked.c.config.legacyFeatures and a.kind == nkSym and
|
||||
a.sym.kind in routineKinds:
|
||||
propagateEffects(tracked, n, a.sym)
|
||||
else:
|
||||
|
||||
@@ -26,3 +26,4 @@ when defined(windows) and not defined(booting):
|
||||
switch("define", "nimRawSetjmp")
|
||||
|
||||
switch("define", "nimVersion:" & NimVersion)
|
||||
|
||||
|
||||
@@ -4952,8 +4952,7 @@ Effect system
|
||||
=============
|
||||
|
||||
**Note**: The rules for effect tracking changed with the release of version
|
||||
1.6 of the Nim compiler. This section describes the new rules that are activated
|
||||
via `--experimental:strictEffects`.
|
||||
1.6 of the Nim compiler.
|
||||
|
||||
|
||||
Exception tracking
|
||||
@@ -5073,7 +5072,6 @@ conservative in its effect analysis:
|
||||
|
||||
```nim test = "nim c $1" status = 1
|
||||
{.push warningAsError[Effect]: on.}
|
||||
{.experimental: "strictEffects".}
|
||||
|
||||
import algorithm
|
||||
|
||||
|
||||
@@ -561,7 +561,7 @@ template matchOrParse(mopProc: untyped) =
|
||||
# procs. For the former, *enter* and *leave* event handler code generators
|
||||
# are provided which just return *discard*.
|
||||
|
||||
proc mopProc(s: string, p: Peg, start: int, c: var Captures): int =
|
||||
proc mopProc(s: string, p: Peg, start: int, c: var Captures): int {.gcsafe.} =
|
||||
proc matchBackRef(s: string, p: Peg, start: int, c: var Captures): int =
|
||||
# Parse handler code must run in an *of* clause of its own for each
|
||||
# *PegKind*, so we encapsulate the identical clause body for
|
||||
|
||||
@@ -1701,7 +1701,7 @@ proc pop*[T](s: var seq[T]): T {.inline, noSideEffect.} =
|
||||
result = s[L]
|
||||
setLen(s, L)
|
||||
|
||||
proc `==`*[T: tuple|object](x, y: T): bool =
|
||||
func `==`*[T: tuple|object](x, y: T): bool =
|
||||
## Generic `==` operator for tuples that is lifted from the components.
|
||||
## of `x` and `y`.
|
||||
for a, b in fields(x, y):
|
||||
|
||||
@@ -31,7 +31,7 @@ proc repr*(x: bool): string {.magic: "BoolToStr", noSideEffect.}
|
||||
## repr for a boolean argument. Returns `x`
|
||||
## converted to the string "false" or "true".
|
||||
|
||||
proc repr*(x: char): string {.noSideEffect.} =
|
||||
proc repr*(x: char): string {.noSideEffect, raises: [].} =
|
||||
## repr for a character argument. Returns `x`
|
||||
## converted to an escaped string.
|
||||
##
|
||||
@@ -47,7 +47,7 @@ proc repr*(x: char): string {.noSideEffect.} =
|
||||
result.add x
|
||||
result.add '\''
|
||||
|
||||
proc repr*(x: string | cstring): string {.noSideEffect.} =
|
||||
proc repr*(x: string | cstring): string {.noSideEffect, raises: [].} =
|
||||
## repr for a string argument. Returns `x`
|
||||
## converted to a quoted and escaped string.
|
||||
result.add '\"'
|
||||
@@ -63,7 +63,7 @@ proc repr*(x: string | cstring): string {.noSideEffect.} =
|
||||
result.add x[i]
|
||||
result.add '\"'
|
||||
|
||||
proc repr*[Enum: enum](x: Enum): string {.magic: "EnumToStr", noSideEffect.}
|
||||
proc repr*[Enum: enum](x: Enum): string {.magic: "EnumToStr", noSideEffect, raises: [].}
|
||||
## repr for an enumeration argument. This works for
|
||||
## any enumeration type thanks to compiler magic.
|
||||
##
|
||||
@@ -100,7 +100,7 @@ template repr*(x: distinct): string =
|
||||
|
||||
template repr*(t: typedesc): string = $t
|
||||
|
||||
proc reprObject[T: tuple|object](res: var string, x: T) =
|
||||
proc reprObject[T: tuple|object](res: var string, x: T) {.noSideEffect, raises: [].} =
|
||||
res.add '('
|
||||
var firstElement = true
|
||||
const isNamed = T is object or isNamedTuple(T)
|
||||
@@ -121,7 +121,7 @@ proc reprObject[T: tuple|object](res: var string, x: T) =
|
||||
res.add(')')
|
||||
|
||||
|
||||
proc repr*[T: tuple|object](x: T): string =
|
||||
proc repr*[T: tuple|object](x: T): string {.noSideEffect, raises: [].} =
|
||||
## Generic `repr` operator for tuples that is lifted from the components
|
||||
## of `x`. Example:
|
||||
##
|
||||
@@ -133,7 +133,7 @@ proc repr*[T: tuple|object](x: T): string =
|
||||
result = $typeof(x)
|
||||
reprObject(result, x)
|
||||
|
||||
proc repr*[T](x: ref T | ptr T): string =
|
||||
proc repr*[T](x: ref T | ptr T): string {.noSideEffect, raises: [].} =
|
||||
if isNil(x): return "nil"
|
||||
when T is object:
|
||||
result = $typeof(x)
|
||||
@@ -142,7 +142,7 @@ proc repr*[T](x: ref T | ptr T): string =
|
||||
result = when typeof(x) is ref: "ref " else: "ptr "
|
||||
result.add repr(x[])
|
||||
|
||||
proc collectionToRepr[T](x: T, prefix, separator, suffix: string): string =
|
||||
proc collectionToRepr[T](x: T, prefix, separator, suffix: string): string {.noSideEffect, raises: [].} =
|
||||
result = prefix
|
||||
var firstElement = true
|
||||
for value in items(x):
|
||||
@@ -189,4 +189,4 @@ proc repr*[T](x: openArray[T]): string =
|
||||
##
|
||||
## .. code-block:: Nim
|
||||
## $(@[23, 45].toOpenArray(0, 1)) == "[23, 45]"
|
||||
collectionToRepr(x, "[", ", ", "]")
|
||||
collectionToRepr(x, "[", ", ", "]")
|
||||
@@ -401,7 +401,7 @@ macro convertSexp*(x: untyped): untyped =
|
||||
## `%` for every element.
|
||||
result = toSexp(x)
|
||||
|
||||
proc `==`* (a, b: SexpNode): bool {.noSideEffect.} =
|
||||
func `==`* (a, b: SexpNode): bool =
|
||||
## Check two nodes for equality
|
||||
if a.isNil:
|
||||
if b.isNil: return true
|
||||
|
||||
@@ -60,15 +60,15 @@ pkg "criterion", allowFailure = true # pending https://github.com/disruptek/crit
|
||||
pkg "datamancer"
|
||||
pkg "dashing", "nim c tests/functional.nim"
|
||||
pkg "delaunay", url = "https://github.com/nim-lang/DelaunayNim", useHead = true
|
||||
pkg "docopt"
|
||||
pkg "docopt", url = "https://github.com/nim-lang/docopt.nim", useHead = true
|
||||
pkg "easygl", "nim c -o:egl -r src/easygl.nim", "https://github.com/jackmott/easygl"
|
||||
pkg "elvis"
|
||||
pkg "fidget"
|
||||
pkg "fragments", "nim c -r fragments/dsl.nim", allowFailure = true # pending https://github.com/nim-lang/packages/issues/2115
|
||||
pkg "fusion"
|
||||
pkg "gara"
|
||||
pkg "glob"
|
||||
pkg "ggplotnim", "nim c -d:noCairo -r tests/tests.nim"
|
||||
pkg "glob", url = "https://github.com/nim-lang/glob", useHead = true
|
||||
pkg "ggplotnim", "nim c -d:noCairo -r tests/tests.nim", url = "https://github.com/nim-lang/ggplotnim", useHead = true
|
||||
pkg "gittyup", "nimble test", "https://github.com/disruptek/gittyup", allowFailure = true
|
||||
pkg "gnuplot", "nim c gnuplot.nim"
|
||||
# pkg "gram", "nim c -r --gc:arc --define:danger tests/test.nim", "https://github.com/disruptek/gram"
|
||||
@@ -109,7 +109,7 @@ pkg "nimongo", "nimble test_ci", allowFailure = true
|
||||
pkg "nimph", "nimble test", "https://github.com/disruptek/nimph", allowFailure = true
|
||||
pkg "nimPNG", useHead = true
|
||||
pkg "nimpy", "nim c -r tests/nimfrompy.nim"
|
||||
pkg "nimquery"
|
||||
pkg "nimquery", url = "https://github.com/nim-lang/nimquery", useHead = true
|
||||
pkg "nimsl"
|
||||
pkg "nimsvg"
|
||||
pkg "nimterop", "nimble minitest"
|
||||
@@ -121,7 +121,7 @@ pkg "npeg", "nimble testarc"
|
||||
pkg "numericalnim", "nimble nimCI"
|
||||
pkg "optionsutils"
|
||||
pkg "ormin", "nim c -o:orminn ormin.nim"
|
||||
pkg "parsetoml"
|
||||
pkg "parsetoml", url = "https://github.com/nim-lang/parsetoml", useHead = true
|
||||
pkg "patty"
|
||||
pkg "pixie"
|
||||
pkg "plotly", "nim c examples/all.nim"
|
||||
@@ -146,7 +146,7 @@ pkg "strslice"
|
||||
pkg "strunicode", "nim c -r --mm:refc src/strunicode.nim"
|
||||
pkg "supersnappy"
|
||||
pkg "synthesis"
|
||||
pkg "telebot", "nim c -o:tbot -r src/telebot.nim"
|
||||
pkg "telebot", "nim c -o:tbot -r src/telebot.nim", url = "https://github.com/nim-lang/telebot.nim", useHead = true
|
||||
pkg "tempdir"
|
||||
pkg "templates"
|
||||
pkg "tensordsl", "nim c -r --mm:refc tests/tests.nim", "https://krux02@bitbucket.org/krux02/tensordslnim.git"
|
||||
@@ -158,11 +158,11 @@ pkg "tiny_sqlite"
|
||||
pkg "unicodedb", "nim c -d:release -r tests/tests.nim"
|
||||
pkg "unicodeplus", "nim c -d:release -r tests/tests.nim"
|
||||
pkg "unpack"
|
||||
pkg "weave", "nimble install -y cligen synthesis;nimble test_gc_arc"
|
||||
pkg "weave", "nimble install -y cligen synthesis;nimble test_gc_arc", url = "https://github.com/nim-lang/weave", useHead = true
|
||||
pkg "websocket", "nim c websocket.nim"
|
||||
pkg "winim", "nim c winim.nim"
|
||||
pkg "with"
|
||||
pkg "ws", allowFailure = true
|
||||
pkg "yaml", "nim c -r test/tserialization.nim"
|
||||
pkg "yaml", "nim c -r test/tserialization.nim", url = "https://github.com/nim-lang/NimYAML", useHead = true
|
||||
pkg "zero_functional", "nim c -r -d:nimNoLentIterators test.nim"
|
||||
pkg "zippy"
|
||||
|
||||
@@ -33,7 +33,7 @@ py
|
||||
py
|
||||
px
|
||||
6
|
||||
proc (){.closure, gcsafe.}
|
||||
proc (){.closure, noSideEffect, gcsafe.}
|
||||
'''
|
||||
"""
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ createMenuItem(s, "Go to definition...",
|
||||
)
|
||||
|
||||
|
||||
proc noRaise(x: proc()) {.raises: [].} =
|
||||
proc noRaise(x: proc()) {.raises: [], effectsOf: x.} =
|
||||
# unknown call that might raise anything, but valid:
|
||||
x()
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
discard """
|
||||
errormsg: "'mainUnsafe' is not GC-safe"
|
||||
errormsg: "'mainUnsafe' is not GC-safe as it performs an indirect call here"
|
||||
line: 26
|
||||
cmd: "nim $target --hints:on --threads:on $options $file"
|
||||
"""
|
||||
@@ -13,7 +13,7 @@ proc myproc(i: int) {.gcsafe.} =
|
||||
if isNil(global_proc):
|
||||
return
|
||||
|
||||
proc mymap(x: proc ()) =
|
||||
proc mymap(x: proc ()) {.effectsOf: x.} =
|
||||
x()
|
||||
|
||||
var
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
block: # `.noSideEffect`
|
||||
func foo(bar: proc(): int): int = bar()
|
||||
func foo(bar: proc(): int): int {.effectsOf: bar.} = bar()
|
||||
var count = 0
|
||||
proc fn1(): int = 1
|
||||
proc fn2(): int = (count.inc; count)
|
||||
|
||||
@@ -106,9 +106,9 @@ block:
|
||||
|
||||
block:
|
||||
var
|
||||
pStack: seq[string] = @[]
|
||||
valStack: seq[float] = @[]
|
||||
opStack = ""
|
||||
pStack {.threadvar.}: seq[string]
|
||||
valStack {.threadvar.}: seq[float]
|
||||
opStack {.threadvar.}: string
|
||||
let
|
||||
parseArithExpr = pegAst.eventParser:
|
||||
pkNonTerminal:
|
||||
|
||||
Reference in New Issue
Block a user