Nim icon indicating copy to clipboard operation
Nim copied to clipboard

non-hygenic behavior for gensymmed name in template

Open arnetheduck opened this issue 1 year ago • 7 comments
trafficstars

Description

import std/macros

macro evalOnceAs*(exp, alias: untyped): untyped =
  expectKind(alias, nnkIdent)

  let
    body = nnkStmtList.newTree()
    val =
      if exp.kind == nnkSym:
        # The symbol can be used directly
        # TODO dot expressions? etc..
        exp
      else:
        let val = genSym(ident = "evalOnce_" & $alias)
        body.add newLetStmt(val, exp)
        val
  body.add(
    newProc(
      name = genSym(nskTemplate, $alias),
      params = [getType(untyped)],
      body = val,
      procType = nnkTemplateDef,
    )
  )

  body

type ArrayBuf = object
  buf: array[32, byte]
  n: int

template data*(bParam: ArrayBuf): openArray =
  bParam.evalOnceAs(b)
  b.buf.toOpenArray(0, b.n - 1)


proc f() =
  var b: int
  var a: ArrayBuf

  echo a.data()

  echo b

var b: int

proc f2() =
  var a: ArrayBuf

  echo a.data()

  echo b

the name b is local to the template and not dirty - it should neither conflict with the other b nor leak out of the template

A variation, when b is in a different scope:


var b: int
proc f() =
  var a: ArrayBuf

  echo a.data()

  echo b

f()

Here, (buf: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], n: 0) gets printed.

Nim Version

2.0.8

Current Output

testit.nim(26, 20) Error: redefinition of 'b'; previous declaration here: /home/arnetheduck/status/nimbus-eth1/_exper/testit.nim(45, 7)

Expected Output

No response

Known Workarounds

No response

Additional Information

No response

arnetheduck avatar Oct 08 '24 08:10 arnetheduck