[rust-dev] Reminder: ~[T] is not going away

Daniel Micay danielmicay at gmail.com
Wed Apr 2 18:21:56 PDT 2014

On 02/04/14 07:22 PM, Niko Matsakis wrote:
> On Wed, Apr 02, 2014 at 04:03:37PM -0400, Daniel Micay wrote:
>> I have no sane proposal to fix this beyond passing a size to free.
> I don't believe there is a problem with just not using null to
> represent such pointers (for example, 1 would suffice). This does
> impose some additional burdens on slice conversion and the like.

I used a sentinel value in my fix along with providing a guarantee that
`free` is never called on zero-size allocation. That's the end of any
no-op `Vec<T>` -> `~[T]` conversions since it will need to free a zero
size allocation. It's not far from just calling `shrink_to_fit`, and
allowing for passing a size to `free`.


I don't think there's any way around without making `~ZeroSizeType`
start allocating memory or losing the `Option<NonNullablePointer>`
optimization otherwise.

> This conversation has focused on low-level effects, which is important
> to understand, but I think the bigger question is: how do we WANT the
> language to look? Is it useful to have a distinct `Vec<T>` and `~[T]`
> or -- in our ideal world -- would they be the same? I think we can
> make the interconversion fast for the default allocator, but we should
> design for the language we want to use.

A distinct `~[T]` and `Vec<T>` will make the language more painful to
use, so the only point I'm trying to counter is the performance one
because it is *is* a valid micro-optimization in some cases.

If our default allocation scheme takes advantage of a known size, then
it will be faster. I don't think we should keep using a
malloc/realloc/free-style API under the hood in the future.

> I could go either way on this. In the kind of programs I write, at
> least, most vectors get built up to a specific length and then stop
> growing (frequently they stop changing as well, but not
> always). Sometimes they continue growing. I actually rather like the
> idea of using `Vec<T>` as a kind of builder and `~[T]` as the
> end-product. In those cases where the vector continues to grow, of
> course, I can just keep the `Vec<T>` around. Following this logic, I
> would imagine that most APIs want to consume and produce `~[T]`, since
> they consume and produce end products.

The language needs to be providing a significant safety/correctness
guarantee or performance win in exchange for the extra noise and I don't
really think it will be in general. There will be use cases for `~[T]`
but I don't think they will be common.

If an API consumes `~[T]`, it will lose track of capacity the caller may
already be able to provide. If it produces `~[T]`, it will lose track of
capacity the caller may want to use later on.

> On the other hand, I could imagine and appreciate an argument that we
> should just take and produce `Vec<T>`, which gives somewhat more
> flexibility. In general, Rust takes the philosophy that "if you own
> it, you can mutate it", so why make growing harder than it needs to
> be? Preferring Vec<T> also means fewer choices, usually a good thing.
> Perhaps the best thing is to wait a month (or two or three) until DST
> is more of a reality and then see how we feel.
> Niko

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: OpenPGP digital signature
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140402/a27558a5/attachment.sig>

More information about the Rust-dev mailing list