]> git.lizzy.rs Git - rust.git/commitdiff
Documentation improvements
authorFrank Steffahn <frank.steffahn@stu.uni-kiel.de>
Thu, 1 Jul 2021 21:01:16 +0000 (23:01 +0200)
committerFrank Steffahn <frank.steffahn@stu.uni-kiel.de>
Wed, 28 Jul 2021 12:33:37 +0000 (14:33 +0200)
library/alloc/src/vec/source_iter_marker.rs
library/core/src/iter/adapters/zip.rs

index 4c06c044e1a27fdd4246b868d7f7259b3e4c2f0a..23a2e313c0189c83ead315d18382f93ea8415b2a 100644 (file)
@@ -71,6 +71,18 @@ impl<T, I> SpecFromIter<T, I> for Vec<T>
         // 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<T>(
 trait SpecInPlaceCollect<T, I>: Iterator<Item = T> {
     /// 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;
 }
 
index 0c62ee294fab535310ccfa3b74045ffa1fe795c7..c7e69e922c13792d5d02178b4a23b9591ba440ad 100644 (file)
@@ -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]