diff --git a/doc/stdlib.dgn.md b/doc/stdlib.dgn.md index 0de46e0f2..99ee992df 100644 --- a/doc/stdlib.dgn.md +++ b/doc/stdlib.dgn.md @@ -327,6 +327,10 @@ Converts a Nim string to a C string. Prepares a string for mutation. String literals are "copy on write", so you need to call `prepareMutation` before modifying strings via `addr`. +####prepareMutationAt + +Prepares the given string for mutation and returns an addressable +reference to the character at index `i`. ####& diff --git a/lib/std/system/stringimpl.nim b/lib/std/system/stringimpl.nim index afa8a48e4..848f22352 100644 --- a/lib/std/system/stringimpl.nim +++ b/lib/std/system/stringimpl.nim @@ -287,6 +287,10 @@ proc prepareMutation*(s: var string) = s.i = EmptyI s.a = a # also do this for `a == nil` +proc prepareMutationAt*(s: var string; i: int): var char {.requires: (i < len(s) and i >= 0), inline.} = + prepareMutation(s) + result = s.a[i] + proc newString*(len: int): string = let a = cast[StrData](alloc(len)) if a != nil: diff --git a/src/nimony/derefs.nim b/src/nimony/derefs.nim index 78ba8774b..536606a10 100644 --- a/src/nimony/derefs.nim +++ b/src/nimony/derefs.nim @@ -383,7 +383,7 @@ proc trProcDecl(c: var Context; n: var Cursor) = takeParRi c, n else: var body = n - trSons c, n, c.r.returnExpects + tr c, n, c.r.returnExpects if c.r.dangerousLocations.len > 0: checkForDangerousLocations c, body takeParRi c, n diff --git a/tests/nimony/sysbasics/tstrings.nim b/tests/nimony/sysbasics/tstrings.nim index d871e048a..57511cccf 100644 --- a/tests/nimony/sysbasics/tstrings.nim +++ b/tests/nimony/sysbasics/tstrings.nim @@ -143,3 +143,8 @@ block: # issue #1444 assert substr("abc", 3, 1) == "" assert substr("abc", 3, 2) == "" assert substr("abc", 3, 3) == "" + +block: + var s = "12234" + var m = prepareMutationAt(s, 1) + assert m == '2'