From ddff13f01b4704dbe22d8b6c86a606675a1700b0 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Tue, 18 Aug 2020 12:45:22 +0200 Subject: [PATCH] better strict funcs, WIP (#15199) * better strict funcs, WIP * progress --- compiler/types.nim | 2 +- compiler/varpartitions.nim | 26 +++++++++++++++++++++----- lib/impure/nre.nim | 6 ++++-- lib/pure/mimetypes.nim | 3 ++- lib/pure/strtabs.nim | 13 ++++++++----- 5 files changed, 36 insertions(+), 14 deletions(-) diff --git a/compiler/types.nim b/compiler/types.nim index 3545b0703f..b8452c3ea2 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -543,7 +543,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = else: result = "" of tyBuiltInTypeClass: - result = case t.base.kind: + result = case t.base.kind of tyVar: "var" of tyRef: "ref" of tyPtr: "ptr" diff --git a/compiler/varpartitions.nim b/compiler/varpartitions.nim index 6857e1b57a..fd6751cdf5 100644 --- a/compiler/varpartitions.nim +++ b/compiler/varpartitions.nim @@ -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.. 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: diff --git a/lib/pure/strtabs.nim b/lib/pure/strtabs.nim index 676e8eb1dc..4c2dd1451a 100644 --- a/lib/pure/strtabs.nim +++ b/lib/pure/strtabs.nim @@ -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)