From 6d9c0a16d9398b2eb24582f60f47affc119eb0af Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Thu, 1 Jul 2021 23:01:16 +0200 Subject: [PATCH] Documentation improvements --- library/alloc/src/vec/source_iter_marker.rs | 19 +++++++++++++++++-- library/core/src/iter/adapters/zip.rs | 7 ++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/library/alloc/src/vec/source_iter_marker.rs b/library/alloc/src/vec/source_iter_marker.rs index 4c06c044e1a..23a2e313c01 100644 --- a/library/alloc/src/vec/source_iter_marker.rs +++ b/library/alloc/src/vec/source_iter_marker.rs @@ -71,6 +71,18 @@ impl SpecFromIter for Vec // drop any remaining values at the tail of the source // but prevent drop of the allocation itself once IntoIter goes out of scope // if the drop panics then we also leak any elements collected into dst_buf + // + // FIXME: Since `SpecInPlaceCollect::collect_in_place` above might use + // `__iterator_get_unchecked` internally, this call might be operating on + // a `vec::IntoIter` with incorrect internal state regarding which elements + // have already been “consumed”. However, the `TrustedRandomIteratorNoCoerce` + // implementation of `vec::IntoIter` is only present if the `Vec` elements + // don’t have a destructor, so it doesn’t matter if elements are “dropped multiple times” + // in this case. + // This argument technically currently lacks justification from the `# Safety` docs for + // `SourceIter`/`InPlaceIterable` and/or `TrustedRandomAccess`, so it might be possible that + // someone could inadvertently create new library unsoundness + // involving this `.forget_allocation_drop_remaining()` call. src.forget_allocation_drop_remaining(); let vec = unsafe { Vec::from_raw_parts(dst_buf, len, cap) }; @@ -101,8 +113,11 @@ fn write_in_place_with_drop( trait SpecInPlaceCollect: Iterator { /// Collects an iterator (`self`) into the destination buffer (`dst`) and returns the number of items /// collected. `end` is the last writable element of the allocation and used for bounds checks. - // FIXME: Clarify safety conditions. Iterator must not be coerced to a subtype - // after this call due to potential use of [`TrustedRandomAccessNoCoerce`]. + /// + /// This method is specialized and one of its implementations makes use of + /// `Iterator::__iterator_get_unchecked` calls with a `TrustedRandomAccessNoCoerce` bound + /// on `I` which means the caller of this method must take the safety conditions + /// of that trait into consideration. fn collect_in_place(&mut self, dst: *mut T, end: *const T) -> usize; } diff --git a/library/core/src/iter/adapters/zip.rs b/library/core/src/iter/adapters/zip.rs index 0c62ee294fa..c7e69e922c1 100644 --- a/library/core/src/iter/adapters/zip.rs +++ b/library/core/src/iter/adapters/zip.rs @@ -524,7 +524,12 @@ pub unsafe trait TrustedRandomAccess: TrustedRandomAccessNoCoerce {} /// Like [`TrustedRandomAccess`] but without any of the requirements / guarantees around /// coercions to subtypes after `__iterator_get_unchecked` (they aren’t allowed here!), and -/// without the requirement that subtypes / supertypes implement [`TrustedRandomAccessNoCoerce`]. +/// without the requirement that subtypes / supertypes implement `TrustedRandomAccessNoCoerce`. +/// +/// This trait was created in PR #85874 to fix soundness issue #85873 without performance regressions. +/// It is subject to change as we might want to build a more generally useful (for performance +/// optimizations) and more sophisticated trait or trait hierarchy that replaces or extends +/// [`TrustedRandomAccess`] and `TrustedRandomAccessNoCoerce`. #[doc(hidden)] #[unstable(feature = "trusted_random_access", issue = "none")] #[rustc_specialization_trait] -- 2.44.0