diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2021-06-10 16:49:17 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-10 16:49:17 +0200 |
commit | 2ea7287217ffe3ad6c3790ff1233845de2aedcf4 (patch) | |
tree | 272e77e540c687a7abb9957bb1624118fcc87f9e | |
parent | 3481ff6172a2e11c990cc67a7fd74a2f0a2445d2 (diff) | |
download | Nim-2ea7287217ffe3ad6c3790ff1233845de2aedcf4.tar.gz |
view types: spec changes (#18226)
* view types: spec changes * Update doc/manual_experimental.rst Co-authored-by: konsumlamm <44230978+konsumlamm@users.noreply.github.com> * Update doc/manual_experimental.rst Co-authored-by: konsumlamm <44230978+konsumlamm@users.noreply.github.com> Co-authored-by: konsumlamm <44230978+konsumlamm@users.noreply.github.com>
-rw-r--r-- | compiler/varpartitions.nim | 5 | ||||
-rw-r--r-- | doc/manual_experimental.rst | 31 | ||||
-rw-r--r-- | tests/views/tdont_mutate.nim | 9 |
3 files changed, 21 insertions, 24 deletions
diff --git a/compiler/varpartitions.nim b/compiler/varpartitions.nim index 9cf1e38ad..04c7c629d 100644 --- a/compiler/varpartitions.nim +++ b/compiler/varpartitions.nim @@ -572,7 +572,7 @@ proc borrowingAsgn(c: var Partitions; dest, src: PNode) = borrowFrom(c, dest.sym, src) elif dest.kind in {nkHiddenDeref, nkDerefExpr, nkBracketExpr}: case directViewType(dest[0].typ) - of mutableView: + of mutableView, immutableView: # we do not borrow, but we use the view to mutate the borrowed # location: let viewOrigin = pathExpr(dest, c.owner) @@ -580,12 +580,13 @@ proc borrowingAsgn(c: var Partitions; dest, src: PNode) = let vid = variableId(c, viewOrigin.sym) if vid >= 0: c.s[vid].flags.incl viewDoesMutate - of immutableView: + #[of immutableView: if dest.kind == nkBracketExpr and dest[0].kind == nkHiddenDeref and mutableParameter(dest[0][0]): discard "remains a mutable location anyhow" else: localError(c.g.config, dest.info, "attempt to mutate a borrowed location from an immutable view") + ]# of noView: discard "nothing to do" proc containsPointer(t: PType): bool = diff --git a/doc/manual_experimental.rst b/doc/manual_experimental.rst index 2c1043ecb..3157708da 100644 --- a/doc/manual_experimental.rst +++ b/doc/manual_experimental.rst @@ -475,8 +475,8 @@ Not nil annotation **Note:** This is an experimental feature. It can be enabled with `{.experimental: "notnil"}`. -All types for which `nil` is a valid value can be annotated with the `not -nil` annotation to exclude `nil` as a valid value: +All types for which `nil` is a valid value can be annotated with the +`not nil` annotation to exclude `nil` as a valid value: .. code-block:: nim {.experimental: "notnil"} @@ -1837,8 +1837,7 @@ with `--experimental:strictFuncs`:option:. A view type is a type that is or contains one of the following types: -- `var T` (mutable view into `T`) -- `lent T` (immutable view into `T`) +- `lent T` (view into `T`) - `openArray[T]` (pair of (pointer to array of `T`, size)) For example: @@ -1846,10 +1845,9 @@ For example: .. code-block:: nim type - View1 = var int - View2 = openArray[byte] - View3 = lent string - View4 = Table[openArray[char], int] + View1 = openArray[byte] + View2 = lent string + View3 = Table[openArray[char], int] Exceptions to this rule are types constructed via `ptr` or `proc`. @@ -1860,11 +1858,11 @@ For example, the following types are **not** view types: type NotView1 = proc (x: openArray[int]) NotView2 = ptr openArray[char] - NotView3 = ptr array[4, var int] + NotView3 = ptr array[4, lent int] -A *mutable* view type is a type that is or contains a `var T` type. -An *immutable* view type is a view type that is not a mutable view type. +The mutability aspect of a view type is not part of the type but part +of the locations it's derived from. More on this later. A *view* is a symbol (a let, var, const, etc.) that has a view type. @@ -1948,11 +1946,14 @@ details about how this is done for `var T`. A mutable view can borrow from a mutable location, an immutable view can borrow from both a mutable or an immutable location. +If a view borrows from a mutable location, the view can be used to update the +location. Otherwise it cannot be used for mutations. + The *duration* of a borrow is the span of commands beginning from the assignment to the view and ending with the last usage of the view. For the duration of the borrow operation, no mutations to the borrowed locations -may be performed except via the potentially mutable view that borrowed from the +may be performed except via the view that borrowed from the location. The borrowed location is said to be *sealed* during the borrow. .. code-block:: nim @@ -2064,11 +2065,7 @@ and `b` the location that is borrowed from. - The lifetime of `v` must not exceed `b`'s lifetime. Note: The lifetime of a parameter is the complete proc body. -- If `v` is a mutable view and `v` is used to actually mutate the - borrowed location, then `b` has to be a mutable location. - Note: If it is not actually used for mutation, borrowing a mutable view from an - immutable location is allowed! This allows for many important idioms and will be - justified in an upcoming RFC. +- If `v` is used for a mutation, `b` must be a mutable location too. - During `v`'s lifetime, `G(b)` can only be modified by `v` (and only if `v` is a mutable view). - If `v` is `result` then `b` has to be a location derived from the first diff --git a/tests/views/tdont_mutate.nim b/tests/views/tdont_mutate.nim index d243c7c7a..43acaaf71 100644 --- a/tests/views/tdont_mutate.nim +++ b/tests/views/tdont_mutate.nim @@ -9,8 +9,9 @@ import tables const Whitespace = {' ', '\t', '\n', '\r'} -proc split*(s: string, seps: set[char] = Whitespace, - maxsplit: int = -1): Table[int, openArray[char]] = +proc split*(s: string, seps: set[char] = Whitespace, maxsplit: int = -1): Table[int, openArray[char]] #[tt.Error + 'result' borrows from the immutable location 's' and attempts to mutate it + ]# = var last = 0 var splits = maxsplit result = initTable[int, openArray[char]]() @@ -22,9 +23,7 @@ proc split*(s: string, seps: set[char] = Whitespace, if splits == 0: last = len(s) result[first] = toOpenArray(s, first, last-1) - result[first][0] = 'c' #[tt.Error - attempt to mutate a borrowed location from an immutable view - ]# + result[first][0] = 'c' if splits == 0: break dec(splits) |