better strict funcs, WIP (#15199)

* better strict funcs, WIP

* progress
This commit is contained in:
Andreas Rumpf
2020-08-18 12:45:22 +02:00
committed by GitHub
parent e194cb41a4
commit ddff13f01b
5 changed files with 36 additions and 14 deletions

View File

@@ -543,7 +543,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
else:
result = "<invalid tyUserTypeClass>"
of tyBuiltInTypeClass:
result = case t.base.kind:
result = case t.base.kind
of tyVar: "var"
of tyRef: "ref"
of tyPtr: "ptr"

View File

@@ -14,7 +14,8 @@
## The used data structure is "union find" with path compression.
import ast, types, lineinfos, options, msgs, renderer
from trees import getMagic
from trees import getMagic, whichPragma
from wordrecg import wNoSideEffect
from isolation_check import canAlias
type
@@ -48,7 +49,7 @@ type
s: seq[VarIndex]
graphs: seq[MutationInfo]
unanalysableMutation, performCursorInference: bool
inAsgnSource, inConstructor: int
inAsgnSource, inConstructor, inNoSideEffectSection: int
proc `$`*(config: ConfigRef; g: MutationInfo): string =
result = ""
@@ -336,12 +337,15 @@ proc deps(c: var Partitions; dest, src: PNode) =
var targets, sources: seq[PSym]
allRoots(dest, targets)
allRoots(src, sources)
proc wrap(t: PType): bool {.nimcall.} = t.kind in {tyRef, tyPtr}
let destIsComplex = types.searchTypeFor(dest.typ, wrap)
for t in targets:
if dest.kind != nkSym:
potentialMutation(c, t, dest.info)
proc wrap(t: PType): bool {.nimcall.} = t.kind in {tyRef, tyPtr}
if types.searchTypeFor(t.typ, wrap):
if destIsComplex:
for s in sources:
connect(c, t, s, dest.info)
@@ -399,7 +403,8 @@ proc traverse(c: var Partitions; n: PNode) =
var roots: seq[PSym]
allRoots(it, roots)
if paramType.kind == tyVar:
for r in roots: potentialMutation(c, r, it.info)
if c.inNoSideEffectSection == 0:
for r in roots: potentialMutation(c, r, it.info)
else:
for r in roots: noCursor(c, r)
@@ -434,6 +439,17 @@ proc traverse(c: var Partitions; n: PNode) =
# test arc/topt_no_cursor.nim
noCursor(c, it.sym)
of nkPragmaBlock:
let pragmaList = n[0]
var enforceNoSideEffects = 0
for i in 0..<pragmaList.len:
if whichPragma(pragmaList[i]) == wNoSideEffect:
enforceNoSideEffects = 1
break
inc c.inNoSideEffectSection, enforceNoSideEffects
traverse(c, n.lastSon)
dec c.inNoSideEffectSection, enforceNoSideEffects
else:
for child in n: traverse(c, child)

View File

@@ -374,12 +374,14 @@ func checkNamedCaptured(pattern: RegexMatch, name: string): void =
func `[]`*(pattern: CaptureBounds, name: string): HSlice[int, int] =
let pattern = RegexMatch(pattern)
checkNamedCaptured(pattern, name)
pattern.captureBounds[pattern.pattern.captureNameToId[name]]
{.noSideEffect.}:
result = pattern.captureBounds[pattern.pattern.captureNameToId[name]]
func `[]`*(pattern: Captures, name: string): string =
let pattern = RegexMatch(pattern)
checkNamedCaptured(pattern, name)
return pattern.captures[pattern.pattern.captureNameToId[name]]
{.noSideEffect.}:
result = pattern.captures[pattern.pattern.captureNameToId[name]]
template toTableImpl() {.dirty.} =
for key in RegexMatch(pattern).pattern.captureNameId.keys:

View File

@@ -1914,7 +1914,8 @@ func register*(mimedb: var MimeDB, ext: string, mimetype: string) =
## ``mimetype`` and ``ext`` are lowercased before registering on ``mimedb``.
assert ext.strip.len > 0, "ext argument can not be empty string"
assert mimetype.strip.len > 0, "mimetype argument can not be empty string"
mimedb.mimes[ext.toLowerAscii()] = mimetype.toLowerAscii()
{.noSideEffect.}:
mimedb.mimes[ext.toLowerAscii()] = mimetype.toLowerAscii()
runnableExamples:
static:

View File

@@ -252,7 +252,7 @@ proc `[]=`*(t: StringTableRef, key, val: string) {.
inc(t.counter)
proc newStringTable*(mode: StringTableMode): owned(StringTableRef) {.
rtlFunc, extern: "nst$1".} =
rtlFunc, extern: "nst$1", noSideEffect.} =
## Creates a new empty string table.
##
## See also:
@@ -265,7 +265,7 @@ proc newStringTable*(mode: StringTableMode): owned(StringTableRef) {.
proc newStringTable*(keyValuePairs: varargs[string],
mode: StringTableMode): owned(StringTableRef) {.
rtlFunc, extern: "nst$1WithPairs".} =
rtlFunc, extern: "nst$1WithPairs", noSideEffect.} =
## Creates a new string table with given `key, value` string pairs.
##
## `StringTableMode` must be specified.
@@ -276,12 +276,13 @@ proc newStringTable*(keyValuePairs: varargs[string],
result = newStringTable(mode)
var i = 0
while i < high(keyValuePairs):
result[keyValuePairs[i]] = keyValuePairs[i + 1]
{.noSideEffect.}:
result[keyValuePairs[i]] = keyValuePairs[i + 1]
inc(i, 2)
proc newStringTable*(keyValuePairs: varargs[tuple[key, val: string]],
mode: StringTableMode = modeCaseSensitive): owned(StringTableRef) {.
rtlFunc, extern: "nst$1WithTableConstr".} =
rtlFunc, extern: "nst$1WithTableConstr", noSideEffect.} =
## Creates a new string table with given `(key, value)` tuple pairs.
##
## The default mode is case sensitive.
@@ -291,7 +292,9 @@ proc newStringTable*(keyValuePairs: varargs[tuple[key, val: string]],
mytab2 = newStringTable([("key3", "val3"), ("key4", "val4")])
result = newStringTable(mode)
for key, val in items(keyValuePairs): result[key] = val
for key, val in items(keyValuePairs):
{.noSideEffect.}:
result[key] = val
proc raiseFormatException(s: string) =
raise newException(ValueError, "format string: key not found: " & s)