fixes #25116; default(T) breaks requiresInit requirements
fixes #25116
It's really annoying for range types though, I would expect tons of misusages of ranges
let z: seq[range['a'..'z']] = @['c']
Otherwise stdlibs need a requireInit typetraits for using zeroDefault for types requiring explicit initialization
The stdlib should use more zeroDefault then, why would it need yet another trait.
proc arrayWithDefault*[T](size: static int): array[size, T] {.noinit, nodestroy, raises: [].} =
## Creates a new array filled with `default(T)`.
for i in 0..size-1:
result[i] = default(T)
proc setLen[T](s: var seq[T], newlen: Natural) {.nodestroy.} =
...
for i in oldLen..<newlen:
xu.p.data[i] = default(T)
arrayWithDefault and setLen need default to set default values for objects with default value fields or ranges types
zeroDefault
the only valid use of zeroDefault is when the location is not observable from the public api of the type - ie a table could in theory use it for its storage, for memory slots that are not yet in use - but that begs the question: if it's not observable, why would you want to zero it in the first place? it's better to leave it uninitialized in that case since zeroing costs (a lot) of CPU.
It also brings into light the bytes-to-type edge where a zeroDefault-initialized instance is in fact not a valid instance of the type and therefore should not be treated as such - in particular, it should be treated as bytes meaning that its memory should also not see destructors run on it etc - consider:
type MyType = object
v: range[2..3]
proc `=destroy`(v: var MyType) =
assert v in 2..3
This is a general problem with building collections in Nim in a world with semi-deterministic destructors - the naive approach of trying to ignore the bytes-to-type edge that was introduced in ORC has downstream effects on the soundness of other features - this is also why a correct Table implementation likely would be better of using a seq[byte] for its underlying storage - a statement that holds for any custom collection really.
It seems that It can make do by making the low bound value the default value of range types, e.g., simple range types only, like default(range[3..4])
The annoying cases are notnil and views types. Probably not touch them in this PR, e.g.
{.experimental: "views".}
proc split*(s: string, seps: set[char] = Whitespace,
maxsplit: int = -1): seq[openArray[char]] =