Nim icon indicating copy to clipboard operation
Nim copied to clipboard

getImpl for closure iterator works unreliably

Open yglukhov opened this issue 3 years ago • 3 comments

import macros

macro getClosureEnvType(iter: typed): untyped =
  # Returns type of closure iterator environment object
  # Here we expect the last argument of the iterator
  # to be the environment, which works _sometimes_
  let im = getImpl(iter)
  result = getType(im.params[^1])
  result = result[^1]

iterator foo() {.closure.} =
  # This is our iterator we want to get the type of environment of
  echo "hi"

# The following two lines look unrelated but commenting either of those
# will result in compilation failure :/
var p = foo
iterator dummy_iter() {.closure.} = discard

# The following line compiles only if both above two lines are present :/
type FooEnv = getClosureEnvType(foo)
$ nim -v
Nim Compiler Version 1.7.1 [Linux: amd64]
Compiled at 2022-05-22
Copyright (c) 2006-2022 by Andreas Rumpf

git hash: 63cca93ea9bcab3c1fea39ff3789fd3a656d2db2
active boot switches: -d:release

yglukhov avatar May 22 '22 20:05 yglukhov

getImplTransformed seems to work.

import macros

macro getClosureEnvType(iter: typed): untyped =
  # Returns type of closure iterator environment object
  # Here we expect the last argument of the iterator
  # to be the environment, which works _sometimes_
  let im = getImplTransformed(iter)

  # echo im.treeRepr
  result = getType(im.params[^1])
  result = result[^1]

iterator foo*() {.closure.} =
  # This is our iterator we want to get the type of environment of
  echo "hi"

type FooEnv = getClosureEnvType(foo)

ringabout avatar Jun 21 '22 08:06 ringabout

@xflywind indeed, thanks for the tip!

yglukhov avatar Jun 21 '22 15:06 yglukhov

However it stops working as soon as the code is wrapped into a proc :(

import macros

macro getClosureEnvType(iter: typed): untyped =
  # Returns type of closure iterator environment object
  # Here we expect the last argument of the iterator
  # to be the environment, which works _sometimes_
  let im = getImplTransformed(iter)
  result = getType(im.params[^1])
  result = result[^1]

proc test() =
  iterator foo() {.closure.} =
    # This is our iterator we want to get the type of environment of
    echo "hi"

  # The following causes compilation failure
  type FooEnv = getClosureEnvType(foo)

yglukhov avatar Aug 03 '22 16:08 yglukhov