summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2021-06-10 16:49:17 +0200
committerGitHub <noreply@github.com>2021-06-10 16:49:17 +0200
commit2ea7287217ffe3ad6c3790ff1233845de2aedcf4 (patch)
tree272e77e540c687a7abb9957bb1624118fcc87f9e
parent3481ff6172a2e11c990cc67a7fd74a2f0a2445d2 (diff)
downloadNim-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.nim5
-rw-r--r--doc/manual_experimental.rst31
-rw-r--r--tests/views/tdont_mutate.nim9
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)