Skip to content
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

when Foo (of type iterator) is used where an expression is expected, show useful err msg instead of confusing `Error: attempting to call undeclared routine Foo` #8671

Closed
timotheecour opened this issue Aug 16, 2018 · 1 comment

Comments

Projects
None yet
2 participants
@timotheecour
Copy link
Contributor

commented Aug 16, 2018

TLDR: see proposal below.

motivation

the following example shows a regression (became a regression since forLoopMacros became controlled by experimental flag), see [1]

I DON'T care about this regression (it's easy to fix). What this issue is about is the more general root cause causing the error message to be so confusing:
Error: attempting to call undeclared routine: 'items' when in fact items is declared and works right above (see code), as an iterator.

The same error happens when using an iterator in place where an expression is expected, see case3 below.

I suspect the root cause is fact that iterators use their own namespace, and that, when an expression is expected, an expression involving an iterator will not typecheck (eg in [items([4, 5, 6]) in case3] or [items([1, 2, 3]) in case2 without .experimental: "forLoopMacros" ]), because it'll just give a lookup error.

bugs/compiler/t17_items_regression.nim:

import macros

when defined(case1):
  {.experimental: "forLoopMacros".}

macro enumerate*(x: ForLoopStmt): untyped = 
  expectKind x, nnkForStmt
  result = newStmtList()
  # we strip off the first for loop variable and use
  # it as an integer counter:
  result.add newVarStmt(x[0], newLit(0))
  var body = x[^1]
  if body.kind != nnkStmtList:
    body = newTree(nnkStmtList, body)
  body.add newCall(bindSym"inc", x[0])
  var newFor = newTree(nnkForStmt)
  for i in 1..x.len-3:
    newFor.add x[i]
  # transform enumerate(X) to 'X'
  newFor.add x[^2][1]
  newFor.add body
  result.add newFor
  # echo treeRepr(result)

proc test_enumerate*()=
  # ok
  for a in items([1, 2, 3]):
    echo a

  when defined(case2):
    # Error: attempting to call undeclared routine: 'items', unless -d:case1 is used
    for a, b in enumerate(items([1, 2, 3])):
      echo a, " ", b

  when defined(case3):
    # Error: attempting to call undeclared routine: 'items'
    let badUsage = items([4, 5, 6])

[1]
rnim -d:case2 bugs/compiler/t17_iterm_regression.nim
nim c --nimcache:/tmp/nim//nimcache/ -o:/tmp/nim//app -r -d:case2 bugs/compiler/t17_iterm_regression.nim
/Users/timothee/git_clone/nim/timn/bugs/compiler/t17_iterm_regression.nim(25, 1) template/generic instantiation from here
/Users/timothee/git_clone/nim/timn/bugs/compiler/t17_iterm_regression.nim(32, 32) Error: attempting to call undeclared routine: 'items'
for a, b in enumerate(items([1, 2, 3])):

proposal

when an expression is expected and a symbol lookup in regular namespace for Foo fails (eg items above), instead of Error: attempting to call undeclared routine: 'Foo', do this:

  • try to lookup in iterator namespace for Foo symbol; if it exists, show error:
Error: expected an expression but got `Foo`, which is an iterator

if it doesn't exist, show old error Error: attempting to call undeclared routine: 'Foo'

Likewise in opposite direction, when an iterator is expected but we get something that's in a different namespace.

Note:

this got me a number of times; I suspect I'm not the only one.

implementation

  • Nim/compiler/procfind.nim ?
@Araq

This comment has been minimized.

Copy link
Member

commented Aug 17, 2018

Ok, accepted.

timotheecour added a commit to timotheecour/Nim that referenced this issue Aug 26, 2018

timotheecour added a commit to timotheecour/Nim that referenced this issue Aug 27, 2018

timotheecour added a commit to timotheecour/Nim that referenced this issue Aug 29, 2018

timotheecour added a commit to timotheecour/Nim that referenced this issue Oct 10, 2018

timotheecour added a commit to timotheecour/Nim that referenced this issue Oct 13, 2018

timotheecour added a commit to timotheecour/Nim that referenced this issue Oct 13, 2018

@Araq Araq closed this in #8786 Oct 13, 2018

Araq added a commit that referenced this issue Oct 13, 2018

fixes #8671; show helpful msg (lookup symbol, eg iterator) on 'attemp…
…ting to call undeclared routine' error (#8786)

krux02 added a commit to krux02/Nim that referenced this issue Oct 15, 2018

narimiran added a commit to narimiran/Nim that referenced this issue Oct 31, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.