nim-lang / Nim

Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula. Its design focuses on efficiency, expressiveness, and elegance (in that order of priority).
https://nim-lang.org
Other
16.44k stars 1.47k forks source link

Broken overload resolution between proc and iterator for `iterable` #22098

Open ZoomRmc opened 1 year ago

ZoomRmc commented 1 year ago

Description

The following code compiles and runs fine unless the proc is uncommented. If it is, the error is: Error: undeclared identifier: 'it'. Until the RFC#397 is implemented, the proc shouldn't even affect this code, because currently it works only when the resulting seq is followed by implicit items.

from std/sequtils import toSeq
template moopIt[T](iter: iterable[T]; expr: untyped): untyped =
  iterator internal(): auto {.gensym.} =
    for it {.inject.} in iter:
      yield expr
  internal()

iterator splat(s: string): string = (for i in @["X", "Y", "Z"]: yield i)
#proc splat(s: string): seq[string] = @["A", "B", "C"]

assert splat("").moopIt(it[0]).toSeq() == @['X', 'Y', 'Z']

Nim Version

Nim Compiler Version 1.9.3 [Linux: amd64] Compiled at 2023-06-14 Copyright (c) 2006-2023 by Andreas Rumpf

git hash: 20dfdba2df7c0d4f65c90561ebf75c2084bbd64f active boot switches: -d:release

Current Output

No response

Expected Output

* proc doesn't affect resolution, as it doesn't fit itself
* iterator given precedence when resolving `iterable`

Possible Solution

No response

Additional Information

Possibly relevant: https://github.com/nim-lang/Nim/issues/19206

beef331 commented 1 year ago

Typical issue with iterators splat(..) is not in a place that requires an iterator so:

assert moopIt(splat(""), it[0]).toSeq() == @['X', 'Y', 'Z']

is required.