nim-lang / Nim

Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula. Its design focuses on efficiency, expressiveness, and elegance (in that order of priority).
https://nim-lang.org
Other
16.62k stars 1.47k forks source link

generics execute compile time code in wrong order #11947

Open timotheecour opened 5 years ago

timotheecour commented 5 years ago

The generic prepass order seems buggy, resulting in incomprehensible semantics (eg https://github.com/nim-lang/Nim/issues/8924), see also below.

that means if you add a static: doAssert false or when false: seemsDisabledButIsNot the results are not what you'd expect and differ from what would happen inside a non-generic proc.

Example2

  import std/macros

  macro mfun7*(a: untyped): untyped =
    echo "ok7"
  macro mfun8*(a: static int): untyped =
    echo "ok8"

  template mfun5() =
    static: echo "ok5"
  template mfun2() =
    static: echo "ok2"
  template mfun4() =
    echo "ok4"

  proc fun[T]() = # no bug if non-generic
    static:
      echo "ok3"
      mfun4()
      static:
        echo "ok1"
      mfun2()
    mfun5()
    static: echo "ok6"
    mfun7(1)
    mfun8(1)

  fun[int]()

Current Output

mfun7 (with no static param) is evaluated too early

ok7
ok1
ok2
ok3
ok4
ok5
ok6
ok8

Expected Output

same as for when fun is not generic:

ok1
ok2
ok3
ok4
ok5
ok6
ok7
ok8

Additional Information

timotheecour commented 5 years ago

see https://github.com/nim-lang/Nim/pull/11950 which fixes 1st part the fact the 1st part exists only for generics is because a different code path is being used for generics vs regular procs for calling macros. The 2nd part is still there.

Araq commented 5 years ago

The "different code path" is a feature and this is your basic mistake:

Expected Output same as for when fun is not generic

It's simply not like that in Nim with its semi-checked generics.