mirror of
https://github.com/nim-lang/Nim.git
synced 2026-05-24 21:59:52 +00:00
Fixes #18583. ## Problem Several stdlib collection types compute the separator for `$` using `result.len > 1`, where `result` starts as the opening bracket (`"["` or `"{"`). This breaks when a collection element type has a `$` that returns an empty string: `result.len` stays at 1 after the first item contributes nothing, so the separator is never inserted for subsequent items. ```nim import std/deques type Test = object proc `$`(x: Test): string = "" echo [Test(), Test()].toDeque # prints [] — expected [, ] ``` ## Fix Replace the length check with an explicit `first` flag in all affected modules: `deques`, `heapqueue`, `lists`, `critbits`, and `strtabs`. ## Tests Regression tests added to `tdeques`, `theapqueue`, and `tlists` using a local type whose `$` returns `""`. All three test files pass with `nim c -r`. ## Notes I work with Claude as a co-processor. I'm 56, came to programming late, and this is genuinely how I learn and contribute. I understand what I'm submitting, but I didn't write it alone. If your project prefers human-only contributions, just say so and I'll close without friction. --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -495,13 +495,16 @@ func `$`*[T](c: CritBitTree[T]): string =
|
||||
const avgItemLen = 16
|
||||
result = newStringOfCap(c.count * avgItemLen)
|
||||
result.add("{")
|
||||
var first = true
|
||||
when T is void:
|
||||
for key in keys(c):
|
||||
if result.len > 1: result.add(", ")
|
||||
if first: first = false
|
||||
else: result.add(", ")
|
||||
result.addQuoted(key)
|
||||
else:
|
||||
for key, val in pairs(c):
|
||||
if result.len > 1: result.add(", ")
|
||||
if first: first = false
|
||||
else: result.add(", ")
|
||||
result.addQuoted(key)
|
||||
result.add(": ")
|
||||
result.addQuoted(val)
|
||||
|
||||
@@ -454,8 +454,10 @@ proc `$`*[T](deq: Deque[T]): string =
|
||||
assert $a == "[10, 20, 30]"
|
||||
|
||||
result = "["
|
||||
var first = true
|
||||
for x in deq:
|
||||
if result.len > 1: result.add(", ")
|
||||
if first: first = false
|
||||
else: result.add(", ")
|
||||
result.addQuoted(x)
|
||||
result.add("]")
|
||||
|
||||
|
||||
@@ -260,7 +260,9 @@ proc `$`*[T](heap: HeapQueue[T]): string =
|
||||
assert $heap == "[1, 2]"
|
||||
|
||||
result = "["
|
||||
var first = true
|
||||
for x in heap.data:
|
||||
if result.len > 1: result.add(", ")
|
||||
if first: first = false
|
||||
else: result.add(", ")
|
||||
result.addQuoted(x)
|
||||
result.add("]")
|
||||
|
||||
@@ -304,8 +304,10 @@ proc `$`*[T](L: SomeLinkedCollection[T]): string =
|
||||
assert $a == "[1, 2, 3, 4]"
|
||||
|
||||
result = "["
|
||||
var first = true
|
||||
for x in nodes(L):
|
||||
if result.len > 1: result.add(", ")
|
||||
if first: first = false
|
||||
else: result.add(", ")
|
||||
result.addQuoted(x.value)
|
||||
result.add("]")
|
||||
|
||||
|
||||
@@ -380,8 +380,10 @@ proc `$`*(t: StringTableRef): string {.rtlFunc, extern: "nstDollar".} =
|
||||
result = "{:}"
|
||||
else:
|
||||
result = "{"
|
||||
var first = true
|
||||
for key, val in pairs(t):
|
||||
if result.len > 1: result.add(", ")
|
||||
if first: first = false
|
||||
else: result.add(", ")
|
||||
result.add(key)
|
||||
result.add(": ")
|
||||
result.add(val)
|
||||
|
||||
@@ -241,3 +241,12 @@ proc main() =
|
||||
|
||||
static: main()
|
||||
main()
|
||||
|
||||
# https://github.com/nim-lang/Nim/issues/18583
|
||||
# $ separator must be emitted even when the item's string repr is empty
|
||||
type EmptyStr18583 = object
|
||||
proc `$`(x: EmptyStr18583): string = ""
|
||||
|
||||
block:
|
||||
var d = [EmptyStr18583(), EmptyStr18583()].toDeque
|
||||
doAssert $d == "[, ]", "got: " & $d
|
||||
|
||||
@@ -104,3 +104,15 @@ template main() =
|
||||
|
||||
static: main()
|
||||
main()
|
||||
|
||||
# https://github.com/nim-lang/Nim/issues/18583
|
||||
type EmptyStr18583HeapQ = object
|
||||
proc `$`(x: EmptyStr18583HeapQ): string = ""
|
||||
proc `<`(a, b: EmptyStr18583HeapQ): bool = false
|
||||
|
||||
block:
|
||||
var h = initHeapQueue[EmptyStr18583HeapQ]()
|
||||
push(h, EmptyStr18583HeapQ())
|
||||
push(h, EmptyStr18583HeapQ())
|
||||
let s = $h
|
||||
doAssert s == "[, ]", "got: " & s
|
||||
|
||||
@@ -287,3 +287,14 @@ template main =
|
||||
|
||||
static: main()
|
||||
main()
|
||||
|
||||
# https://github.com/nim-lang/Nim/issues/18583
|
||||
type EmptyStr18583List = object
|
||||
proc `$`(x: EmptyStr18583List): string = ""
|
||||
|
||||
block:
|
||||
var L: SinglyLinkedList[EmptyStr18583List]
|
||||
L.prepend(EmptyStr18583List())
|
||||
L.prepend(EmptyStr18583List())
|
||||
let s = $L
|
||||
doAssert s == "[, ]", "got: " & s
|
||||
|
||||
Reference in New Issue
Block a user