Skip to content

Macro generated generic proc doesnt work #11877

@SolitudeSF

Description

@SolitudeSF

I have following macro that generates the procedure out of existing procedure. It essentially just strips a return value and adds var to a first argument. I also had to move some generic related fields, because getImpl for some reason provides illformed AST.

Example

import macros

macro genMutating*(p: typed, name: untyped) =
  result = p.getImpl

  var call = nnkCall.newTree(result[0].strVal.ident)
  for i in 1..<result[3].len:
    for c in result[3][i]:
      if c.kind == nnkIdent: call.add c

  result[0] = nnkPostfix.newTree(ident "*", ident name.strVal)
  result[2] = result[5][1]
  result[3][0] = newEmptyNode()
  result[3][1][1] = nnkVarTy.newTree(result[3][1][1])
  result[5] = newEmptyNode()
  result[6] = nnkStmtList.newTree(nnkAsgn.newTree(result[3][1][0], call))

type
  Color* = array[3, int] | array[4, int]
  Image*[T: Color] = seq[T]

func test*[T: Color](img: Image[T]): Image[T] = discard

test.genMutating res
# func res[T](img: var Image[T]) =
#   img = test(img)

var i = Image[array[3, int]](@[[1, 2, 3]])
i.res

Current Output

Compilation fails with

test.nim(29, 2) template/generic instantiation of `res` from here
test.nim(22, 12) Error: cannot instantiate: 'T'

But if i use --expandMacro or repr result and place the output into the code instead of macro the program compiles and runs fine.

Expected Output

Should compile and run successfully.

Tested on 0.20.2 and latest devel.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions