Impl FromIterator for Rc<[T]>?

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

1 Like

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));

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.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.