diff --git a/changelog.md b/changelog.md index f3cc3fee4d..08c4bd097d 100644 --- a/changelog.md +++ b/changelog.md @@ -34,6 +34,7 @@ errors. - `std/math` The `^` symbol now supports floating-point as exponent in addition to the Natural type. - `system.substr` implementation now uses `copymem` (wrapped C `memcpy`) for copying data, if available at compilation. +- `system.newStringUninit` is now considered free of side-effects allowing it to be used with `--experimental:strictFuncs`. ## Language changes diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index c941afd085..4e2ae306f8 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -2356,8 +2356,7 @@ func multiReplace*(s: openArray[char]; replacements: varargs[(set[char], char)]) # Sanitize a filename with Windows-incompatible characters const file = "a/file:with?invalid*chars.txt" doAssert file.multiReplace(WinSanitationRules) == "a-file-with_invalid_chars.txt" - {.cast(noSideEffect).}: - result = newStringUninit(s.len) + result = newStringUninit(s.len) for i in 0.. 0: + {.cast(noSideEffect).}: + when defined(nimSeqsV2): + let s = cast[ptr NimStringV2](addr result) + if len > 0: + s.len = len + s.p.data[len] = '\0' + else: + let s = cast[NimString](result) s.len = len - s.p.data[len] = '\0' - else: - let s = cast[NimString](result) - s.len = len - s.data[len] = '\0' + s.data[len] = '\0' else: proc newStringUninit*(len: Natural): string {. magic: "NewString", importc: "mnewString", noSideEffect.} @@ -2794,8 +2795,7 @@ proc substr*(a: openArray[char]): string = assert a.toOpenArray(2, 5).substr() == "cdef" assert a.toOpenArray(2, high(a)).substr() == "cdefgh" # From index 2 to `high(a)` doAssertRaises(IndexDefect): discard a.toOpenArray(5, 99).substr() - {.cast(noSideEffect).}: - result = newStringUninit(a.len) + result = newStringUninit(a.len) when NotJSnotVMnotNims: if a.len > 0: copyMem(result[0].addr, a[0].unsafeAddr, a.len) @@ -2830,8 +2830,7 @@ proc substr*(s: string; first, last: int): string = # A bug with `magic: Slice` first = max(first, 0) last = min(last, high(s)) L = max(last - first + 1, 0) - {.cast(noSideEffect).}: - result = newStringUninit(L) + result = newStringUninit(L) when NotJSnotVMnotNims: if L > 0: copyMem(result[0].addr, s[first].unsafeAddr, L)