Nim icon indicating copy to clipboard operation
Nim copied to clipboard

modifying typed params in macros (even after copyNimTree) gives SIGSEGV (a`typ`is nil)

Open timotheecour opened this issue 4 years ago • 2 comments

Example

when true:
  import macros
  macro bar(n: typed): untyped =
    var n = n.copyNimTree # without this, you get: Error: typechecked nodes may not be modified
    let tmp = genSym(nskLet, "tmp")
    let j = n[1][0][0]
    n[1][0][0] = tmp
    result = quote do:
      let `tmp` = `j`
      let lhs = `n`
    echo result.repr
  type
    A = object
      x: int
    PA = ref A
  proc fn(c: int): int = c
  let a = PA()
  bar(fn(a[].x))

Current Output

# result of result.repr:
let tmp_805306395 = a
let lhs`gensym0 = fn(tmp_805306395[].x)

SIGSEGV

Expected Output

works

note 1

with bar(a[].x.fn) instead of bar(fn(a[].x)), removing var n = n.copyNimTree doesn't give Error: typechecked nodes may not be modified, but this still crashes with SIGSEGV

note that the treeRepr of the input n is:

Call
  Sym "fn"
  DotExpr
    DerefExpr
      Sym "a"
    Sym "x";

note 2

here's a stacktrace with a debug version of nim: https://gist.github.com/timotheecour/23520a5e868d674c23ffd7d9148f304d it crashes because typ was nil:

proc mapType(conf: ConfigRef; typ: PType; kind: TSymKind): TCTypeKind =
  ## Maps a Nim type to a C type
  case typ.kind

note 3

instrumenting code with astalgo.debug on the result of bar gives: without n[1][0][0] = tmp: no crash, produces this: https://gist.github.com/timotheecour/280550dad2b2656f579f7baf12b27a8e with n[1][0][0] = tmp: crash with SIGSEGV, produces this: https://gist.github.com/timotheecour/cf626ba2eb2b51279167fc1adba2f26b

the relevant difference between those 2 is that the node with kind nkDerefExpr has ((near line 43):

"typ": "tyRef",
vs
"typ": "nil",

note 4

adding calls to copyNimTree does not help, nor does doing it manually via:

  proc copy2(a: NimNode): NimNode =
    result = a.copyNimNode
    for i in 0..<a.len: result.add copy2(a[i])

Additional Information

1.5.1 0c4582c66524d58a3c72827d9546a5c5f1c40286 this impacts macros operating on types inputs, and I'm encountering this in std/wrapnils when trying to improve the ?. macro, specifically such that the sub-expression inside a function call (fn in this case) isn't re-computed.

timotheecour avatar Jul 23 '21 03:07 timotheecour