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

getTypeInst for generics does not gives the full instantiation info in certain cases #7737

Closed
mratsim opened this issue Apr 30, 2018 · 3 comments · Fixed by #24028
Closed

Comments

@mratsim
Copy link
Collaborator

mratsim commented Apr 30, 2018

Another case of difficulties working with types #7719/nim-lang/RFCs#44 and subtypes #6454 in macros.

In the following case I am trying to extract a subtype of multiple containers. It works fine for the built-in seq but not for a generic type. The subtype is not available through getTypeInst.

import macros, typetraits, sequtils

type
  CustomSeq*[T] = object
    data*: seq[T]

proc getSubType*(T: NimNode): NimNode =
  echo getTypeInst(T).treerepr
  result = getTypeInst(T)[1]

macro typed_helper(x: varargs[typed]): untyped =
  let foo = getSubType(x[0])

  result = quote do: discard

macro untyped_heavylifting(x: varargs[untyped]): untyped =

  var containers = nnkArgList.newTree()

  for arg in x:
    case arg.kind:
    of nnkInfix:
      if eqIdent(arg[0], "in"):
        containers.add arg[2]
    else:
      discard

  result = quote do:
    typed_helper(`containers`)

var a, b, c: seq[int]

untyped_heavylifting z in c, x in a, y in b:
  discard

## The following gives me CustomSeq instead
## of CustomSeq[int] in getTypeInst
var u, v, w: CustomSeq[int]

untyped_heavylifting z in u, x in v, y in w:
  discard
@krux02
Copy link
Contributor

krux02 commented May 1, 2018

The example is a bit verbose, I could boil it a bit down if that helps to fix the bug. It seems like varargs is causing the problem, because without varargs, it just works.

import macros

type
  CustomSeq*[T] = object
    data*: seq[T]

# when using just one argument, `foo` and `bar` should be exactly
# identical.
macro foo(arg: typed): untyped =
  echo arg.getTypeInst.treeRepr

macro bar(args: varargs[typed]): untyped =
  for arg in args:
    echo arg.getTypeInst.treeRepr

var
  a: seq[int]
  b: Custoimport macros

type
  CustomSeq*[T] = object
    data*: seq[T]

# when using just one argument, `foo` and `bar` should be exactly
# identical.
macro foo(arg: typed): untyped =
  echo arg.getTypeInst.treeRepr

macro bar(args: varargs[typed]): untyped =
  for arg in args:
    echo arg.getTypeInst.treeRepr

var
  a: seq[int]
  b: CustomSeq[int]

# these two should print the exact same
foo(a) # prints seq[int], OK
bar(a) # prints seq[int], OK

foo(b) # prints CustomSeq[int], OK
# The following prints `CustomSeq` instead of `CustomSeq[int]`.
bar(b) # prints CustomSeq     , Wrong
mSeq[int]

# these two should print the exact same
foo(a) # prints seq[int], OK
bar(a) # prints seq[int], OK

foo(b) # prints CustomSeq[int], OK
# The following prints `CustomSeq` instead of `CustomSeq[int]`.
bar(b) # prints CustomSeq     , Wrong

@mratsim as a workaround of the broken varargs you could write lots of overloads until varargs[typed] will work again.

macro typed_helper(arg1: typed): untyped = #[ ... ]#
macro typed_helper(arg1,arg2: typed): untyped = #[ ... ]#
macro typed_helper(arg1,arg2,arg3: typed): untyped = #[ ... ]#
macro typed_helper(arg1,arg2,arg3,arg4: typed): untyped = #[ ... ]#
...

@LemonBoy
Copy link
Contributor

The problem (?) is here, I don't know much about the sigmatch internals to suggest a solution though.

@metagn
Copy link
Collaborator

metagn commented Aug 19, 2024

Seems to work in devel

metagn added a commit to metagn/Nim that referenced this issue Aug 29, 2024
@Araq Araq closed this as completed in fc853cb Aug 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants