diff options
-rw-r--r-- | compiler/types.nim | 2 | ||||
-rw-r--r-- | compiler/varpartitions.nim | 26 | ||||
-rw-r--r-- | lib/impure/nre.nim | 6 | ||||
-rw-r--r-- | lib/pure/mimetypes.nim | 3 | ||||
-rw-r--r-- | lib/pure/strtabs.nim | 13 |
5 files changed, 36 insertions, 14 deletions
diff --git a/compiler/types.nim b/compiler/types.nim index 3545b0703..b8452c3ea 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -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" diff --git a/compiler/varpartitions.nim b/compiler/varpartitions.nim index 6857e1b57..fd6751cdf 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..<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) diff --git a/lib/impure/nre.nim b/lib/impure/nre.nim index 0817ca4ec..88fa0b323 100644 --- a/lib/impure/nre.nim +++ b/lib/impure/nre.nim @@ -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: diff --git a/lib/pure/mimetypes.nim b/lib/pure/mimetypes.nim index 3bbd0d243..206783929 100644 --- a/lib/pure/mimetypes.nim +++ b/lib/pure/mimetypes.nim @@ -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: diff --git a/lib/pure/strtabs.nim b/lib/pure/strtabs.nim index 676e8eb1d..4c2dd1451 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) |