Skip to content

macros.newLit now preserves named vs unnamed tuples #14720

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

Merged
merged 2 commits into from
Jun 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
- new proc `heapqueue.find[T](heap: HeapQueue[T], x: T): int` to get index of element ``x``.
- Add `rstgen.rstToLatex` convenience proc for `renderRstToOut` and `initRstGenerator` with `outLatex` output.
- Add `os.normalizeExe`, eg: `koch` => `./koch`.
- `macros.newLit` now preserves named vs unnamed tuples; use `-d:nimHasWorkaround14720` to keep old behavior


## Language changes
Expand Down
19 changes: 14 additions & 5 deletions lib/core/macros.nim
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@ proc newLit*(arg: enum): NimNode {.compileTime.} =
proc newLit*[N,T](arg: array[N,T]): NimNode {.compileTime.}
proc newLit*[T](arg: seq[T]): NimNode {.compileTime.}
proc newLit*[T](s: set[T]): NimNode {.compileTime.}
proc newLit*(arg: tuple): NimNode {.compileTime.}
proc newLit*[T: tuple](arg: T): NimNode {.compileTime.}

proc newLit*(arg: object): NimNode {.compileTime.} =
result = nnkObjConstr.newTree(arg.type.getTypeInst[1])
Expand Down Expand Up @@ -800,10 +800,19 @@ proc newLit*[T](s: set[T]): NimNode {.compileTime.} =
var typ = getTypeInst(typeof(s))[1]
result = newCall(typ,result)

proc newLit*(arg: tuple): NimNode {.compileTime.} =
result = nnkPar.newTree
for a,b in arg.fieldPairs:
result.add nnkExprColonExpr.newTree(newIdentNode(a), newLit(b))
proc isNamedTuple(T: typedesc): bool {.magic: "TypeTrait".}
## See `typetraits.isNamedTuple`

proc newLit*[T: tuple](arg: T): NimNode {.compileTime.} =
## use -d:nimHasWorkaround14720 to restore behavior prior to PR, forcing
## a named tuple even when `arg` is unnamed.
result = nnkTupleConstr.newTree
when defined(nimHasWorkaround14720) or isNamedTuple(T):
Copy link
Member

@zah zah Jun 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sometimes, I've thought that it would be nice if the compiler has a generic way to check for the presence of a bug fix (a bit like the generic since mechanism).

Right how, when I encounter an issue, I often leave a TODO comment in the code with a link to the filed issue. If each release of the compiler was storing internally an integer set of all the fixed issues, it would have been possible to write the following code:

when not hasFix(12231):
  # some work-around here
else:
  {.fatal: "The work-around can be removed now".}

Copy link
Member Author

@timotheecour timotheecour Jun 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zah

  • this would not have helped here, where a bugfix causes some code relying on the bug to fail (see ggplotnim)
  • nim already has a mechanism for that using nimHasFoo (see condsyms.nim), and it's strictly more flexible than an issue number, because it gives you freedom to specify what was fixed; eg if:
    bug 1234 contains 2 sub issues foo and bar, you can have a nim commit with: nimHasFix1234Foo(ornimHasFixFoo`)

see timotheecour#317 for the detailed proposal

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is such a library in rust: you can do it as a macro

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't find it :( but it checks the issue tracker on compile time e.g. in CI iirc. it's cool

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, it seems its blocked!

for a, b in arg.fieldPairs:
result.add nnkExprColonExpr.newTree(newIdentNode(a), newLit(b))
else:
for b in arg.fields:
result.add newLit(b)

proc nestList*(op: NimNode; pack: NimNode): NimNode {.compileTime.} =
## Nests the list `pack` into a tree of call expressions:
Expand Down
2 changes: 1 addition & 1 deletion testament/important_packages.nim
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pkg1 "elvis"
# Error: cannot open 'tests/runNative.nim'
pkg1 "fragments", false, "nim c -r fragments/dsl.nim"
pkg1 "gara"
pkg1 "ggplotnim", true, "nim c -d:noCairo -r -d:nimWorkaround14447 tests/tests.nim"
pkg1 "ggplotnim", true, "nim c -d:noCairo -r -d:nimWorkaround14447 -d:nimHasWorkaround14720 tests/tests.nim"
# pkg1 "gittyup", true, "nimble test", "https://github.com/disruptek/gittyup"
pkg1 "glob"
pkg1 "gnuplot"
Expand Down
8 changes: 8 additions & 0 deletions tests/macros/tmacros_various.nim
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,11 @@ static:
doAssert(v == a)

echo "macrocache ok"

block tupleNewLitTests:
macro t(): untyped =
result = newLit (1, "foo", (), (1,), (a1: 'x', a2: @["ba"]))
doAssert $t() == """(1, "foo", (), (1,), (a1: 'x', a2: @["ba"]))"""
# this `$` test is needed because tuple equality doesn't distinguish
# between named vs unnamed tuples
doAssert t() == (1, "foo", (), (1, ), (a1: 'x', a2: @["ba"]))