implicit auto return type for inline iterators

This commit is contained in:
Zahary Karadjov 2014-03-08 23:27:33 +02:00
commit 518b794491
3 changed files with 20 additions and 10 deletions

View file

@ -849,9 +849,13 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
addParamOrResult(c, arg, kind) addParamOrResult(c, arg, kind)
if gCmd == cmdPretty: checkDef(a.sons[j], arg) if gCmd == cmdPretty: checkDef(a.sons[j], arg)
var r: PType
if n.sons[0].kind != nkEmpty: if n.sons[0].kind != nkEmpty:
var r = semTypeNode(c, n.sons[0], nil) r = semTypeNode(c, n.sons[0], nil)
elif kind == skIterator:
r = newTypeS(tyAnything, c)
if r != nil:
# turn explicit 'void' return type into 'nil' because the rest of the # turn explicit 'void' return type into 'nil' because the rest of the
# compiler only checks for 'nil': # compiler only checks for 'nil':
if skipTypes(r, {tyGenericInst}).kind != tyEmpty: if skipTypes(r, {tyGenericInst}).kind != tyEmpty:

View file

@ -2822,7 +2822,6 @@ as there are components in the tuple. The i'th iteration variable's type is
the type of the i'th component. In other words, implicit tuple unpacking in a the type of the i'th component. In other words, implicit tuple unpacking in a
for loop context is supported. for loop context is supported.
Implict items/pairs invocations Implict items/pairs invocations
------------------------------- -------------------------------
@ -2847,10 +2846,11 @@ First class iterators
There are 2 kinds of iterators in Nimrod: *inline* and *closure* iterators. There are 2 kinds of iterators in Nimrod: *inline* and *closure* iterators.
An `inline iterator`:idx: is an iterator that's always inlined by the compiler An `inline iterator`:idx: is an iterator that's always inlined by the compiler
leading to zero overhead for the abstraction, but may result in a heavy leading to zero overhead for the abstraction, but may result in a heavy
increase in code size. Inline iterators are second class increase in code size. Inline iterators are second class citizens;
citizens; one cannot pass them around like first class procs. They can be passed as parameters only to other inlining code facilities like
templates, macros and other inline iterators.
In contrast to that, a `closure iterator`:idx: can be passed around: In contrast to that, a `closure iterator`:idx: can be passed around more freely:
.. code-block:: nimrod .. code-block:: nimrod
iterator count0(): int {.closure.} = iterator count0(): int {.closure.} =
@ -2873,9 +2873,7 @@ Closure iterators have other restrictions than inline iterators:
1. ``yield`` in a closure iterator can not occur in a ``try`` statement. 1. ``yield`` in a closure iterator can not occur in a ``try`` statement.
2. For now, a closure iterator cannot be evaluated at compile time. 2. For now, a closure iterator cannot be evaluated at compile time.
3. ``return`` is allowed in a closure iterator (but rarely useful). 3. ``return`` is allowed in a closure iterator (but rarely useful).
4. Since closure iterators can be used as a collaborative tasking 4. Both inline and closure iterators cannot be recursive.
system, ``void`` is a valid return type for them.
5. Both inline and closure iterators cannot be recursive.
Iterators that are neither marked ``{.closure.}`` nor ``{.inline.}`` explicitly Iterators that are neither marked ``{.closure.}`` nor ``{.inline.}`` explicitly
default to being inline, but that this may change in future versions of the default to being inline, but that this may change in future versions of the
@ -2937,6 +2935,14 @@ parameters of an outer factory proc:
for f in foo(): for f in foo():
echo f echo f
Implicit return type
--------------------
Since inline interators must always produce values that will be consumed in
a for loop, the compiler will implicity use the ``auto`` return type if no
type is given by the user. In contrast, since closure iterators can be used
as a collaborative tasking system, ``void`` is a valid return type for them.
Type sections Type sections
============= =============

View file

@ -12,7 +12,7 @@ iterator gaz(it: iterator{.inline.}): type(it) =
for x in it: for x in it:
yield x*2 yield x*2
iterator baz(it: iterator{.inline.}): auto = iterator baz(it: iterator{.inline.}) =
for x in gaz(it): for x in gaz(it):
yield x*2 yield x*2