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>
* make more standard libraries work with `nimPreviewSlimSystem`
* typo
* part two
* Delete specutils.nim
* fixes more tests
* more fixes
* fixes tests
* fixes three more tests
* add formatfloat import
* fix
* last
* Update lists.nim
* Update tlists.nim
* removed check `if b.tail != nil`
The tail of the list being null it is still possible to retrieve its end by going through all nodes from the head. So checking for null from `b.tail` is unnecessary. However, setting `a.tail = b.tail` only if `a.head != nil`, so you don't break a good list with an already broken one.
* Various changes to `lists` (RFC #303)
* Removing a non-element is no-op; better tests
* Remove preserves cycles; add appendMove alias; tests.
* Return value for (singly linked) `lists.remove`
* More test for lists.remove
* Moved `lists.append` to the end of the file to see all `add` definitions
* Disable testing js for now
* Use workaround for swap js bug
* Smaller diff
* Undo "silent" deprecation of append
* Correct typo in changelog
Co-authored-by: Timothee Cour <timothee.cour2@gmail.com>
* Remove `appendMoved`
Co-authored-by: Timothee Cour <timothee.cour2@gmail.com>
* Don't remove appendMoved
Co-authored-by: Clyybber <darkmine956@gmail.com>
Co-authored-by: Timothee Cour <timothee.cour2@gmail.com>
* O(1) concatenation of singly- and doubly linked lists.
There is also new `toSinglyLinkedList` and `toDoublyLinkedList`
functions for conversion from `openArray`s, similarly
to `toHashSet` or `toTable`.
* Add `sequtils` import to runnable examples with `toSeq`.
* Added missing call to runnable examples.
* Add .since annotation, changelog, and tests.
* Rename `lists.concat` as an overload to `lists.append`.
* Renamed `append` to `add` in lists.
* Remove faulty `add` for `DoublyLinkedList`s.
* Improved tests for lists.
* `lists.add` moves the second list; added `lists.copy` for shallow copy.
* More tests for `lists.add` and `lists.copy`.
* More compact tests for lists with templates.
* List concatenation with copying (`add`) and moving (tentatively `addMove`)
* Renamed `addMove` to `addMoved`; renamed arguments according to the style guide.
* Added extended example to `lists.copy`.
* Corrected .since annotations to 1.6
* Add .since annotation, changelog, and tests.
* Rename `lists.concat` as an overload to `lists.append`.
* Renamed `append` to `add` in lists.
* Remove faulty `add` for `DoublyLinkedList`s.
* `lists.add` moves the second list; added `lists.copy` for shallow copy.
* More tests for `lists.add` and `lists.copy`.
* List concatenation with copying (`add`) and moving (tentatively `addMove`)
* Renamed `addMove` to `addMoved`; renamed arguments according to the style guide.
* Since declarations changed to (1,5,1).
* Add .since annotation, changelog, and tests.
* Rename `lists.concat` as an overload to `lists.append`.
* Renamed `append` to `add` in lists.
* Remove faulty `add` for `DoublyLinkedList`s.
* `lists.add` moves the second list; added `lists.copy` for shallow copy.
* More tests for `lists.add` and `lists.copy`.
* List concatenation with copying (`add`) and moving (tentatively `addMove`)
* Renamed `addMove` to `addMoved`; renamed arguments according to the style guide.
* Changelog update.
* Fix rebasing errors.
* Self-adding with `lists.addMove` results in a cycle now.
Added some extra tests.