-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot pass inline iterator to inline iterator #4516
Comments
Relevant forum post: https://forum.nim-lang.org/t/2972 and pinging @cooldome who located the issue here in Adding cooldome test case: type InlineIterator[T] = iterator: T {.inline.}
let s = @[1, 2, 3, 4, 5]
iterator values: type(s[0]) {.inline.} =
# Make argumentless iterator
for val in s:
yield val
iterator enumerate[T](it: InlineIterator[T]): (int,T) {.inline.} =
var i = 0
for val in it():
yield (i, val)
inc i
for tup in enumerate(values):
echo tup Error playground_it.nim(17, 21) template/generic instantiation from here
playground_it.nim(13, 16) Error: type mismatch: got (int)
but expected one of:
iterator items[IX, T](a: array[IX, T]): T
iterator items(E: typedesc[enum]): E:type
iterator items(a: string): char
iterator items[T](s: Slice[T]): T
iterator items[T](a: openArray[T]): T
iterator items[T](a: set[T]): T
iterator items[T](a: seq[T]): T
iterator items(a: cstring): char And my 2 test cases: let s = @[1, 2, 3, 4, 5]
iterator values[T](s: seq[T]): T {.inline.}=
# copy of `items` to test without its special meaning
for val in s:
yield val
iterator enumerate[T](it: iterator {. inline .}): auto {.inline.}=
var i = 0
for val in it:
yield (i, val)
inc i
iterator enumerate2[T](s: seq[T], it: iterator(a: seq[T]): T {. inline .}): T {.inline.}=
var i = 0
for val in s.it:
yield (i, val)
inc i
# for tup in s.values.enumerate:
# echo tup
# inline_it.nim(21, 20) Error: type mismatch: got (int)
# but expected one of:
# iterator enumerate[T](it: iterator): auto
for tup in enumerate2(s, values):
echo tup
# inline_it.nim(27, 22) template/generic instantiation from here
# inline_it.nim(16, 15) Error: type mismatch: got (int)
# but expected one of:
# iterator items[IX, T](a: array[IX, T]): T
# iterator items(E: typedesc[enum]): E:type
# iterator items(a: string): char
# iterator items[T](s: Slice[T]): T
# iterator items[T](a: openArray[T]): T
# iterator items[T](a: set[T]): T
# iterator items[T](a: seq[T]): T
# iterator items(a: cstring): char |
Related requests for inline iterator chaining on the forum: |
I mean it doesn't make much sense as a runtime argument, but you can use it as a compile time argument: iterator test2(it: static(iterator(): int {.inline.})): int =
for i in it():
yield i*2
iterator test1(): int =
yield 10
yield 20
yield 30
for i in test2(test1):
echo i |
That works if you only want a specific interface, but really With #21627 we can atleast write code like https://github.com/beef331/slicerator/blob/itermacros/src/itermacros.nim#L45-L115 That allows abstracting over iterators. As can be seen here https://github.com/beef331/slicerator/blob/itermacros/tests/titermacros.nim |
This code works:
But this does not:
Error message:
The manual states that:
This seems to happen here although
it
is an iterator. The manual also states thatSo it should be possible to pass an inline iterator to another inline iterator. Therefore, I think this is a bug. This issue is originally a StackOverflow question.
The text was updated successfully, but these errors were encountered: