mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
Mark system.newStringUninit sideeffect-free (#24813)
- Allows using with `--experimental:strictFuncs`
- `{.cast(noSideEffect).}:` inside the proc was required to mutate
`s.len`, same as used in `newSeqImpl`.
- Removed now unnecessary `noSideEffect` casts in `system.nim`
-
Closes #24811
Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com>
(cherry picked from commit ecdcffed4b)
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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..<s.len:
|
||||
var nextChar = s[i]
|
||||
for subs, by in replacements.items:
|
||||
|
||||
@@ -1685,7 +1685,7 @@ when not defined(js):
|
||||
else:
|
||||
{.error: "The type T cannot contain managed memory or have destructors".}
|
||||
|
||||
proc newStringUninit*(len: Natural): string =
|
||||
proc newStringUninit*(len: Natural): string {.noSideEffect.} =
|
||||
## Returns a new string of length `len` but with uninitialized
|
||||
## content. One needs to fill the string character after character
|
||||
## with the index operator `s[i]`.
|
||||
@@ -1696,15 +1696,16 @@ when not defined(js):
|
||||
result = newString(len)
|
||||
else:
|
||||
result = newStringOfCap(len)
|
||||
when defined(nimSeqsV2):
|
||||
let s = cast[ptr NimStringV2](addr result)
|
||||
if len > 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.}
|
||||
@@ -2792,8 +2793,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)
|
||||
@@ -2828,8 +2828,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)
|
||||
|
||||
Reference in New Issue
Block a user