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>
This commit is contained in:
parent
3481ff6172
commit
2ea7287217
3 changed files with 21 additions and 24 deletions
|
|
@ -572,7 +572,7 @@ proc borrowingAsgn(c: var Partitions; dest, src: PNode) =
|
||||||
borrowFrom(c, dest.sym, src)
|
borrowFrom(c, dest.sym, src)
|
||||||
elif dest.kind in {nkHiddenDeref, nkDerefExpr, nkBracketExpr}:
|
elif dest.kind in {nkHiddenDeref, nkDerefExpr, nkBracketExpr}:
|
||||||
case directViewType(dest[0].typ)
|
case directViewType(dest[0].typ)
|
||||||
of mutableView:
|
of mutableView, immutableView:
|
||||||
# we do not borrow, but we use the view to mutate the borrowed
|
# we do not borrow, but we use the view to mutate the borrowed
|
||||||
# location:
|
# location:
|
||||||
let viewOrigin = pathExpr(dest, c.owner)
|
let viewOrigin = pathExpr(dest, c.owner)
|
||||||
|
|
@ -580,12 +580,13 @@ proc borrowingAsgn(c: var Partitions; dest, src: PNode) =
|
||||||
let vid = variableId(c, viewOrigin.sym)
|
let vid = variableId(c, viewOrigin.sym)
|
||||||
if vid >= 0:
|
if vid >= 0:
|
||||||
c.s[vid].flags.incl viewDoesMutate
|
c.s[vid].flags.incl viewDoesMutate
|
||||||
of immutableView:
|
#[of immutableView:
|
||||||
if dest.kind == nkBracketExpr and dest[0].kind == nkHiddenDeref and
|
if dest.kind == nkBracketExpr and dest[0].kind == nkHiddenDeref and
|
||||||
mutableParameter(dest[0][0]):
|
mutableParameter(dest[0][0]):
|
||||||
discard "remains a mutable location anyhow"
|
discard "remains a mutable location anyhow"
|
||||||
else:
|
else:
|
||||||
localError(c.g.config, dest.info, "attempt to mutate a borrowed location from an immutable view")
|
localError(c.g.config, dest.info, "attempt to mutate a borrowed location from an immutable view")
|
||||||
|
]#
|
||||||
of noView: discard "nothing to do"
|
of noView: discard "nothing to do"
|
||||||
|
|
||||||
proc containsPointer(t: PType): bool =
|
proc containsPointer(t: PType): bool =
|
||||||
|
|
|
||||||
|
|
@ -475,8 +475,8 @@ Not nil annotation
|
||||||
**Note:** This is an experimental feature. It can be enabled with
|
**Note:** This is an experimental feature. It can be enabled with
|
||||||
`{.experimental: "notnil"}`.
|
`{.experimental: "notnil"}`.
|
||||||
|
|
||||||
All types for which `nil` is a valid value can be annotated with the `not
|
All types for which `nil` is a valid value can be annotated with the
|
||||||
nil` annotation to exclude `nil` as a valid value:
|
`not nil` annotation to exclude `nil` as a valid value:
|
||||||
|
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
{.experimental: "notnil"}
|
{.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:
|
A view type is a type that is or contains one of the following types:
|
||||||
|
|
||||||
- `var T` (mutable view into `T`)
|
- `lent T` (view into `T`)
|
||||||
- `lent T` (immutable view into `T`)
|
|
||||||
- `openArray[T]` (pair of (pointer to array of `T`, size))
|
- `openArray[T]` (pair of (pointer to array of `T`, size))
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
@ -1846,10 +1845,9 @@ For example:
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
|
|
||||||
type
|
type
|
||||||
View1 = var int
|
View1 = openArray[byte]
|
||||||
View2 = openArray[byte]
|
View2 = lent string
|
||||||
View3 = lent string
|
View3 = Table[openArray[char], int]
|
||||||
View4 = Table[openArray[char], int]
|
|
||||||
|
|
||||||
|
|
||||||
Exceptions to this rule are types constructed via `ptr` or `proc`.
|
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
|
type
|
||||||
NotView1 = proc (x: openArray[int])
|
NotView1 = proc (x: openArray[int])
|
||||||
NotView2 = ptr openArray[char]
|
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.
|
The mutability aspect of a view type is not part of the type but part
|
||||||
An *immutable* view type is a view type that is not a mutable view type.
|
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.
|
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
|
A mutable view can borrow from a mutable location, an immutable view can borrow
|
||||||
from both a mutable or an immutable location.
|
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
|
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.
|
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
|
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.
|
location. The borrowed location is said to be *sealed* during the borrow.
|
||||||
|
|
||||||
.. code-block:: nim
|
.. 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
|
- The lifetime of `v` must not exceed `b`'s lifetime. Note: The lifetime of
|
||||||
a parameter is the complete proc body.
|
a parameter is the complete proc body.
|
||||||
- If `v` is a mutable view and `v` is used to actually mutate the
|
- If `v` is used for a mutation, `b` must be a mutable location too.
|
||||||
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.
|
|
||||||
- During `v`'s lifetime, `G(b)` can only be modified by `v` (and only if
|
- During `v`'s lifetime, `G(b)` can only be modified by `v` (and only if
|
||||||
`v` is a mutable view).
|
`v` is a mutable view).
|
||||||
- If `v` is `result` then `b` has to be a location derived from the first
|
- If `v` is `result` then `b` has to be a location derived from the first
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,9 @@ import tables
|
||||||
const
|
const
|
||||||
Whitespace = {' ', '\t', '\n', '\r'}
|
Whitespace = {' ', '\t', '\n', '\r'}
|
||||||
|
|
||||||
proc split*(s: string, seps: set[char] = Whitespace,
|
proc split*(s: string, seps: set[char] = Whitespace, maxsplit: int = -1): Table[int, openArray[char]] #[tt.Error
|
||||||
maxsplit: int = -1): Table[int, openArray[char]] =
|
'result' borrows from the immutable location 's' and attempts to mutate it
|
||||||
|
]# =
|
||||||
var last = 0
|
var last = 0
|
||||||
var splits = maxsplit
|
var splits = maxsplit
|
||||||
result = initTable[int, openArray[char]]()
|
result = initTable[int, openArray[char]]()
|
||||||
|
|
@ -22,9 +23,7 @@ proc split*(s: string, seps: set[char] = Whitespace,
|
||||||
if splits == 0: last = len(s)
|
if splits == 0: last = len(s)
|
||||||
result[first] = toOpenArray(s, first, last-1)
|
result[first] = toOpenArray(s, first, last-1)
|
||||||
|
|
||||||
result[first][0] = 'c' #[tt.Error
|
result[first][0] = 'c'
|
||||||
attempt to mutate a borrowed location from an immutable view
|
|
||||||
]#
|
|
||||||
|
|
||||||
if splits == 0: break
|
if splits == 0: break
|
||||||
dec(splits)
|
dec(splits)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue