Skip to content

Commit ee2330e

Browse files
committed
mark as_inner as unsafe and update comments
1 parent 1114f83 commit ee2330e

File tree

4 files changed

+48
-35
lines changed

4 files changed

+48
-35
lines changed

src/liballoc/collections/binary_heap.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1150,7 +1150,7 @@ unsafe impl<T> SourceIter for IntoIter<T> {
11501150
type Source = IntoIter<T>;
11511151

11521152
#[inline]
1153-
fn as_inner(&mut self) -> &mut Self::Source {
1153+
unsafe fn as_inner(&mut self) -> &mut Self::Source {
11541154
self
11551155
}
11561156
}

src/liballoc/vec.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2061,6 +2061,8 @@ where
20612061
}
20622062
}
20632063

2064+
// A helper struct for in-place iteration that drops the destination slice of iteration.
2065+
// The source slice is dropped by IntoIter
20642066
struct InPlaceDrop<T> {
20652067
inner: *mut T,
20662068
dst: *mut T,
@@ -2125,8 +2127,10 @@ where
21252127
return SpecFromNested::from_iter(iterator);
21262128
}
21272129

2128-
let src_buf = iterator.as_inner().as_into_iter().buf.as_ptr();
2129-
let src_end = iterator.as_inner().as_into_iter().end;
2130+
let (src_buf, src_end) = {
2131+
let inner = unsafe { iterator.as_inner().as_into_iter() };
2132+
(inner.buf.as_ptr(), inner.end)
2133+
};
21302134
let dst = src_buf;
21312135

21322136
let dst = if mem::needs_drop::<T>() {
@@ -2168,7 +2172,7 @@ where
21682172
.unwrap()
21692173
};
21702174

2171-
let src = iterator.as_inner().as_into_iter();
2175+
let src = unsafe { iterator.as_inner().as_into_iter() };
21722176
// check if SourceIter and InPlaceIterable contracts were upheld.
21732177
// caveat: if they weren't we may not even make it to this point
21742178
debug_assert_eq!(src_buf, src.buf.as_ptr());
@@ -2839,7 +2843,7 @@ unsafe impl<T> SourceIter for IntoIter<T> {
28392843
type Source = IntoIter<T>;
28402844

28412845
#[inline]
2842-
fn as_inner(&mut self) -> &mut Self::Source {
2846+
unsafe fn as_inner(&mut self) -> &mut Self::Source {
28432847
self
28442848
}
28452849
}

src/libcore/iter/adapters/mod.rs

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub use self::zip::Zip;
2020
#[unstable(issue = "0", feature = "std_internals")]
2121
pub use self::zip::TrustedRandomAccess;
2222

23-
/// This trait provides transitive access to source-stages in an interator-adapter pipeline
23+
/// This trait provides transitive access to source-stage in an interator-adapter pipeline
2424
/// under the conditions that
2525
/// * the iterator source `S` itself implements `SourceIter<Source = S>`
2626
/// * there is a delegating implementation of this trait for each adapter in the pipeline between
@@ -47,7 +47,7 @@ pub use self::zip::TrustedRandomAccess;
4747
///
4848
/// let mut iter = vec![9, 9, 9].into_iter().map(|i| i * i);
4949
/// let _ = iter.next();
50-
/// let mut remainder = std::mem::replace(iter.as_inner(), Vec::new().into_iter());
50+
/// let mut remainder = std::mem::replace(unsafe { iter.as_inner() }, Vec::new().into_iter());
5151
/// println!("n = {} elements remaining", remainder.len());
5252
/// ```
5353
///
@@ -58,29 +58,33 @@ pub unsafe trait SourceIter {
5858
/// A source stage in an iterator pipeline.
5959
type Source: Iterator;
6060

61-
/// Extract the source of an iterator pipeline.
61+
/// Retrieve the source of an iterator pipeline.
6262
///
63-
/// Callers may assume that calls to [`next()`] or any method taking `&self`
64-
/// does no replace the referenced value.
65-
/// But callers may replace the referenced values as long they in turn do not
66-
/// expose it through a delegating implementation of this trait.
67-
/// Which means that while adapters may not modify the reference they cannot
68-
/// rely on it not being modified.
63+
/// # Safety
6964
///
70-
/// Adapters must not rely on exclusive ownership or immutability of the source.
71-
/// The lack of exclusive ownership also requires that adapters must uphold the source's
72-
/// public API even when they have crate- or module-internal access.
65+
/// Implementations of must return the same mutable reference for their lifetime, unless
66+
/// replaced by a caller.
67+
/// Callers may only replace the reference when they stopped iteration and drop the
68+
/// iterator pipeline after extracting the source.
69+
///
70+
/// This means iterator adapters can rely on the source not changing during
71+
/// iteration but they cannot rely on it in their Drop implementations.
72+
///
73+
/// Implementing this method means adapters relinquish private-only access to their
74+
/// source and can only rely on guarantees made based on method receiver types.
75+
/// The lack of restricted access also requires that adapters must uphold the source's
76+
/// public API even when they have access to its internals.
7377
///
7478
/// Callers in turn must expect the source to be in any state that is consistent with
7579
/// its public API since adapters sitting between it and the source have the same
7680
/// access. In particular an adapter may have consumed more elements than strictly necessary.
7781
///
78-
/// The overall goal of these requirements is to grant the consumer of a pipeline
79-
/// access to the underlying storage of an iterator while restricting any statefulness
80-
/// and side-effects of the pipeline stages from affecting or relying on that storage.
82+
/// The overall goal of these requirements is to let the consumer of a pipeline use
83+
/// * whatever remains in the source after iteration has stopped
84+
/// * the memory that has become unused by advancing a consuming iterator
8185
///
8286
/// [`next()`]: trait.Iterator.html#method.next
83-
fn as_inner(&mut self) -> &mut Self::Source;
87+
unsafe fn as_inner(&mut self) -> &mut Self::Source;
8488
}
8589

8690
/// A double-ended iterator with the direction inverted.
@@ -959,7 +963,7 @@ where
959963
type Source = S;
960964

961965
#[inline]
962-
fn as_inner(&mut self) -> &mut S {
966+
unsafe fn as_inner(&mut self) -> &mut S {
963967
SourceIter::as_inner(&mut self.iter)
964968
}
965969
}
@@ -1106,7 +1110,7 @@ unsafe impl<S: Iterator, P, I: Iterator> SourceIter for Filter<I, P> where
11061110
type Source = S;
11071111

11081112
#[inline]
1109-
fn as_inner(&mut self) -> &mut S {
1113+
unsafe fn as_inner(&mut self) -> &mut S {
11101114
SourceIter::as_inner(&mut self.iter)
11111115
}
11121116
}
@@ -1249,7 +1253,7 @@ unsafe impl<S: Iterator, B, I: Iterator, F> SourceIter for FilterMap<I, F> where
12491253
type Source = S;
12501254

12511255
#[inline]
1252-
fn as_inner(&mut self) -> &mut S {
1256+
unsafe fn as_inner(&mut self) -> &mut S {
12531257
SourceIter::as_inner(&mut self.iter)
12541258
}
12551259
}
@@ -1479,7 +1483,7 @@ where
14791483
type Source = S;
14801484

14811485
#[inline]
1482-
fn as_inner(&mut self) -> &mut S {
1486+
unsafe fn as_inner(&mut self) -> &mut S {
14831487
SourceIter::as_inner(&mut self.iter)
14841488
}
14851489
}
@@ -1709,7 +1713,7 @@ where
17091713
type Source = S;
17101714

17111715
#[inline]
1712-
fn as_inner(&mut self) -> &mut S {
1716+
unsafe fn as_inner(&mut self) -> &mut S {
17131717
SourceIter::as_inner(&mut self.iter)
17141718
}
17151719
}
@@ -1826,7 +1830,7 @@ unsafe impl<S: Iterator, P, I: Iterator> SourceIter for SkipWhile<I, P> where
18261830
type Source = S;
18271831

18281832
#[inline]
1829-
fn as_inner(&mut self) -> &mut S {
1833+
unsafe fn as_inner(&mut self) -> &mut S {
18301834
SourceIter::as_inner(&mut self.iter)
18311835
}
18321836
}
@@ -2033,7 +2037,7 @@ unsafe impl<S: Iterator, P, I: Iterator> SourceIter for TakeWhile<I, P> where
20332037
type Source = S;
20342038

20352039
#[inline]
2036-
fn as_inner(&mut self) -> &mut S {
2040+
unsafe fn as_inner(&mut self) -> &mut S {
20372041
SourceIter::as_inner(&mut self.iter)
20382042
}
20392043
}
@@ -2232,7 +2236,7 @@ where
22322236
type Source = S;
22332237

22342238
#[inline]
2235-
fn as_inner(&mut self) -> &mut S {
2239+
unsafe fn as_inner(&mut self) -> &mut S {
22362240
SourceIter::as_inner(&mut self.iter)
22372241
}
22382242
}
@@ -2341,7 +2345,7 @@ unsafe impl<S: Iterator, I: Iterator> SourceIter for Take<I> where I: SourceIter
23412345
type Source = S;
23422346

23432347
#[inline]
2344-
fn as_inner(&mut self) -> &mut S {
2348+
unsafe fn as_inner(&mut self) -> &mut S {
23452349
SourceIter::as_inner(&mut self.iter)
23462350
}
23472351
}
@@ -2489,7 +2493,7 @@ unsafe impl<St, F, B, S: Iterator, I: Iterator> SourceIter for Scan<I, St, F>
24892493
type Source = S;
24902494

24912495
#[inline]
2492-
fn as_inner(&mut self) -> &mut S {
2496+
unsafe fn as_inner(&mut self) -> &mut S {
24932497
SourceIter::as_inner(&mut self.iter)
24942498
}
24952499
}
@@ -2763,7 +2767,7 @@ where
27632767
type Source = S;
27642768

27652769
#[inline]
2766-
fn as_inner(&mut self) -> &mut S {
2770+
unsafe fn as_inner(&mut self) -> &mut S {
27672771
SourceIter::as_inner(&mut self.iter)
27682772
}
27692773
}
@@ -2925,7 +2929,7 @@ unsafe impl<S: Iterator, I: Iterator, F> SourceIter for Inspect<I, F> where
29252929
type Source = S;
29262930

29272931
#[inline]
2928-
fn as_inner(&mut self) -> &mut S {
2932+
unsafe fn as_inner(&mut self) -> &mut S {
29292933
SourceIter::as_inner(&mut self.iter)
29302934
}
29312935
}

src/libcore/iter/adapters/zip.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,13 +305,18 @@ where
305305
type Source = S;
306306

307307
#[inline]
308-
fn as_inner(&mut self) -> &mut S {
308+
unsafe fn as_inner(&mut self) -> &mut S {
309309
SourceIter::as_inner(&mut self.a)
310310
}
311311
}
312312

313313
#[unstable(issue = "0", feature = "inplace_iteration")]
314-
unsafe impl<A: InPlaceIterable, B: Iterator> InPlaceIterable for Zip<A, B> {}
314+
// Limited to Item: Copy since interaction between Zip's use of TrustedRandomAccess
315+
// and Drop implementation of the source is unclear.
316+
//
317+
// An additional method returning the number of times the source has been logically advanced
318+
// (without calling next()) would be needed to properly drop the remainder of the source.
319+
unsafe impl<A: InPlaceIterable, B: Iterator> InPlaceIterable for Zip<A, B> where A::Item: Copy {}
315320

316321
/// An iterator whose items are random-accessible efficiently
317322
///

0 commit comments

Comments
 (0)