add isNamedTuple; make $(1, 2) be (1, 2) instead of (Field0: 1, Field1: 2) which leaked implementation detail (#10070)

* add `isNamedTuple`; make $(1, 2) be (1, 2) instead of leaking implementation detail (Field0: 1, Field1: 2)
  fixes this: #8670 (comment) /cc @alehander42 @Vindaar @mratsim

* Note: isNamedTuple is useful in other places, eg #10010 (comment)

* move isNamedTuple to helpers.nim to avoid exposing new symbol to system.nim

* remove workaround in tests/vm/tissues.nim failing test now that #10218 was makes it work
This commit is contained in:
Timothee Cour 2019-01-08 18:37:25 -08:00 • committed by GitHub
commit 6ce3949c8a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 113 additions and 23 deletions

View file

@ -2669,19 +2669,28 @@ proc compiles*(x: untyped): bool {.magic: "Compiles", noSideEffect, compileTime.
## echo "'+' for integers is available"
discard
include "system/helpers" # for `lineInfoToString`, `isNamedTuple`
proc `$`*[T: tuple|object](x: T): string =
## generic ``$`` operator for tuples that is lifted from the components
## of `x`. Example:
##
## .. code-block:: nim
## $(23, 45) == "(Field0: 23, Field1: 45)"
## $(23, 45) == "(23, 45)"
## $(a: 23, b: 45) == "(a: 23, b: 45)"
## $() == "()"
result = "("
var firstElement = true
const isNamed = T is object or isNamedTuple(T)
when not isNamed:
var count = 0
for name, value in fieldPairs(x):
if not firstElement: result.add(", ")
result.add(name)
result.add(": ")
when isNamed:
result.add(name)
result.add(": ")
else:
count.inc
when compiles($value):
when value isnot string and value isnot seq and compiles(value.isNil):
if value.isNil: result.add "nil"
@ -2691,6 +2700,10 @@ proc `$`*[T: tuple|object](x: T): string =
firstElement = false
else:
result.add("...")
when not isNamed:
if count == 1:
result.add(",") # $(1,) should print as the semantically legal (1,)
result.add(")")
proc collectionToString[T](x: T, prefix, separator, suffix: string): string =
@ -3958,8 +3971,6 @@ proc failedAssertImpl*(msg: string) {.raises: [], tags: [].} =
tags: [].}
Hide(raiseAssert)(msg)
include "system/helpers" # for `lineInfoToString`
template assertImpl(cond: bool, msg: string, expr: string, enabled: static[bool]) =
const loc = $instantiationInfo(-1, true)
bind instantiationInfo