Skip to content

Commit

Permalink
improve documentation for 'var T return values'; refs #7373
Browse files Browse the repository at this point in the history
  • Loading branch information
Araq committed Apr 21, 2018
1 parent e44c6d8 commit 4f10b5e
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 4 deletions.
24 changes: 21 additions & 3 deletions doc/manual.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3487,17 +3487,17 @@ returned value is an l-value and can be modified by the caller:
.. code-block:: nim
var g = 0
proc WriteAccessToG(): var int =
proc writeAccessToG(): var int =
result = g
WriteAccessToG() = 6
writeAccessToG() = 6
assert g == 6
It is a compile time error if the implicitly introduced pointer could be
used to access a location beyond its lifetime:

.. code-block:: nim
proc WriteAccessToG(): var int =
proc writeAccessToG(): var int =
var g = 0
result = g # Error!
Expand All @@ -3512,6 +3512,24 @@ In the standard library every name of a routine that returns a ``var`` type
starts with the prefix ``m`` per convention.


.. include:: manual/var_t_return.rst

Future directions
~~~~~~~~~~~~~~~~~

Later versions of Nim can be more precise about the borrowing rule with
a syntax like:

.. code-block:: nim
proc foo(other: Y; container: var X): var T from container
Here ``var T from container`` explicitly exposes that the
location is deviated from the second parameter (called
'container' in this case). The syntax ``var T from p`` specifies a type
``varTy[T, 2]`` which is incompatible with ``varTy[T, 1]``.



Overloading of the subscript operator
-------------------------------------

Expand Down
20 changes: 20 additions & 0 deletions doc/manual/var_t_return.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Memory safety for returning by ``var T`` is ensured by a simple borrowing
rule: If ``result`` does not refer to a location pointing to the heap
(that is in ``result = X`` the ``X`` involves a ``ptr`` or ``ref`` access)
then it has to be deviated by the routine's first parameter:

.. code-block:: nim
proc forward[T](x: var T): var T =
result = x # ok, deviated from the first parameter.
proc p(param: var int): var int =
var x: int
# we know 'forward' provides a view into the location deviated by
# its first argument 'x'.
result = forward(x) # Error: location is derived from ``x``
# which is not p's first parameter and lives
# on the stack.
In other words, the lifetime of what ``result`` points to is attached to the
lifetime of the first parameter and that is enough knowledge to verify
memory safety at the callsite.
2 changes: 1 addition & 1 deletion web/website.ini
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ file: ticker.html
[Documentation]
doc: "endb.rst;intern.txt;apis.txt;lib.rst;manual.rst;tut1.rst;tut2.rst;nimc.rst;overview.rst;filters.rst"
doc: "tools.txt;niminst.rst;nimgrep.rst;gc.rst;estp.rst;idetools.rst;docgen.rst;koch.rst;backends.txt"
doc: "nimfix.rst;nimsuggest.rst;nep1.rst;nims.rst;contributing.rst"
doc: "nimfix.rst;nimsuggest.rst;nep1.rst;nims.rst;contributing.rst;manual/*.rst"
pdf: "manual.rst;lib.rst;tut1.rst;tut2.rst;nimc.rst;niminst.rst;gc.rst"
srcdoc2: "system.nim;system/nimscript;pure/ospaths"
srcdoc2: "core/macros;pure/marshal;core/typeinfo"
Expand Down

0 comments on commit 4f10b5e

Please sign in to comment.