Impl FromIterator for Rc<[T]>?


#1

This is just braindump note to hear people’s opinions. I’ll write Pre-RFC about it soon.

Currently only way to create Rc<[T]> from Iterator<Item=T> is:

let rc: Rc<[T]> = iter.collect::<Vec<T>>().into();

But this code copies entire contents of vector to rc’s buffer, as Rc<[T]>'s heap layout is not compatible with Vec<T>.

Implementing it as title says can be a bit trickier as RcBox is not designed to be grow. Hopefully we can borrow most logic for it from RawVec.

Maybe we can name this feature as shared_from_iterator. It should also cover iterator of char/&str and Arc as well.

Reference: shared-from-slice RFC


#2

A few quick notes:

  • This would be a nice addition if it’s possible to do well.
  • You probably don’t need an RFC for this, you can just make a PR against rust-lang/rust.
  • Try to optimize this for TrustedLen + ExactSizeIterator with specialization as the allocation can then be done in a single go with no reallocation.
  • You could probably delay setting the strong and weak counts until the end, i.e: after the last reallocation has been done. This refers to:
            ptr::write(&mut (*inner).strong, Cell::new(1));
            ptr::write(&mut (*inner).weak, Cell::new(1));

#3

As you would probably need a growable vector in the implementation anyway, would a Box<[T]> -> Rc<[T]> conversion be enough? Then you could collect into a Vec and do v.into_boxed_slice().into().

Optimality here also presumes that collecting into Vec for an exactly sized iterator doesn’t overallocate.