Skip to content

Commit ab382b7

Browse files
committed
mark as_inner as unsafe and update comments
1 parent 2a51e57 commit ab382b7

File tree

5 files changed

+76
-50
lines changed

5 files changed

+76
-50
lines changed

library/alloc/src/collections/binary_heap.rs

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

11801180
#[inline]
1181-
fn as_inner(&mut self) -> &mut Self::Source {
1181+
unsafe fn as_inner(&mut self) -> &mut Self::Source {
11821182
self
11831183
}
11841184
}

library/alloc/src/vec.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2167,6 +2167,8 @@ where
21672167
}
21682168
}
21692169

2170+
// A helper struct for in-place iteration that drops the destination slice of iteration.
2171+
// The source slice is dropped by IntoIter
21702172
struct InPlaceDrop<T> {
21712173
inner: *mut T,
21722174
dst: *mut T,
@@ -2230,8 +2232,10 @@ where
22302232
return SpecFromNested::from_iter(iterator);
22312233
}
22322234

2233-
let src_buf = iterator.as_inner().as_into_iter().buf.as_ptr();
2234-
let src_end = iterator.as_inner().as_into_iter().end;
2235+
let (src_buf, src_end) = {
2236+
let inner = unsafe { iterator.as_inner().as_into_iter() };
2237+
(inner.buf.as_ptr(), inner.end)
2238+
};
22352239
let dst = src_buf;
22362240

22372241
let dst = if mem::needs_drop::<T>() {
@@ -2273,7 +2277,7 @@ where
22732277
.unwrap()
22742278
};
22752279

2276-
let src = iterator.as_inner().as_into_iter();
2280+
let src = unsafe { iterator.as_inner().as_into_iter() };
22772281
// check if SourceIter and InPlaceIterable contracts were upheld.
22782282
// caveat: if they weren't we may not even make it to this point
22792283
debug_assert_eq!(src_buf, src.buf.as_ptr());
@@ -2993,7 +2997,7 @@ unsafe impl<T> SourceIter for IntoIter<T> {
29932997
type Source = IntoIter<T>;
29942998

29952999
#[inline]
2996-
fn as_inner(&mut self) -> &mut Self::Source {
3000+
unsafe fn as_inner(&mut self) -> &mut Self::Source {
29973001
self
29983002
}
29993003
}

library/core/src/iter/adapters/fuse.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -529,9 +529,10 @@ unsafe impl<S: Iterator, I: FusedIterator> SourceIter for Fuse<I>
529529
type Source = S;
530530

531531
#[inline]
532-
fn as_inner(&mut self) -> &mut S {
532+
unsafe fn as_inner(&mut self) -> &mut S {
533533
match self.iter {
534-
Some(ref mut iter) => SourceIter::as_inner(iter),
534+
// Safety: unsafe function forwarding to unsafe function with the same requirements
535+
Some(ref mut iter) => unsafe { SourceIter::as_inner(iter) },
535536
// SAFETY: the specialized iterator never sets `None`
536537
None => unsafe { intrinsics::unreachable() },
537538
}

library/core/src/iter/adapters/mod.rs

Lines changed: 55 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use self::zip::try_get_unchecked;
2222
pub use self::zip::TrustedRandomAccess;
2323
pub use self::zip::Zip;
2424

25-
/// This trait provides transitive access to source-stages in an interator-adapter pipeline
25+
/// This trait provides transitive access to source-stage in an interator-adapter pipeline
2626
/// under the conditions that
2727
/// * the iterator source `S` itself implements `SourceIter<Source = S>`
2828
/// * there is a delegating implementation of this trait for each adapter in the pipeline between
@@ -49,40 +49,44 @@ pub use self::zip::Zip;
4949
///
5050
/// let mut iter = vec![9, 9, 9].into_iter().map(|i| i * i);
5151
/// let _ = iter.next();
52-
/// let mut remainder = std::mem::replace(iter.as_inner(), Vec::new().into_iter());
52+
/// let mut remainder = std::mem::replace(unsafe { iter.as_inner() }, Vec::new().into_iter());
5353
/// println!("n = {} elements remaining", remainder.len());
5454
/// ```
5555
///
56-
/// [`FromIterator`]: trait.FromIterator.html
57-
/// [`as_inner`]: #method.as_inner
56+
/// [`FromIterator`]: crate::iter::FromIterator
57+
/// [`as_inner`]: SourceIter::as_inner
5858
#[unstable(issue = "0", feature = "inplace_iteration")]
5959
pub unsafe trait SourceIter {
6060
/// A source stage in an iterator pipeline.
6161
type Source: Iterator;
6262

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

8892
/// A double-ended iterator with the direction inverted.
@@ -1015,8 +1019,9 @@ where
10151019
type Source = S;
10161020

10171021
#[inline]
1018-
fn as_inner(&mut self) -> &mut S {
1019-
SourceIter::as_inner(&mut self.iter)
1022+
unsafe fn as_inner(&mut self) -> &mut S {
1023+
// Safety: unsafe function forwarding to unsafe function with the same requirements
1024+
unsafe { SourceIter::as_inner(&mut self.iter) }
10201025
}
10211026
}
10221027

@@ -1162,8 +1167,9 @@ unsafe impl<S: Iterator, P, I: Iterator> SourceIter for Filter<I, P> where
11621167
type Source = S;
11631168

11641169
#[inline]
1165-
fn as_inner(&mut self) -> &mut S {
1166-
SourceIter::as_inner(&mut self.iter)
1170+
unsafe fn as_inner(&mut self) -> &mut S {
1171+
// Safety: unsafe function forwarding to unsafe function with the same requirements
1172+
unsafe { SourceIter::as_inner(&mut self.iter) }
11671173
}
11681174
}
11691175

@@ -1305,8 +1311,9 @@ unsafe impl<S: Iterator, B, I: Iterator, F> SourceIter for FilterMap<I, F> where
13051311
type Source = S;
13061312

13071313
#[inline]
1308-
fn as_inner(&mut self) -> &mut S {
1309-
SourceIter::as_inner(&mut self.iter)
1314+
unsafe fn as_inner(&mut self) -> &mut S {
1315+
// Safety: unsafe function forwarding to unsafe function with the same requirements
1316+
unsafe { SourceIter::as_inner(&mut self.iter) }
13101317
}
13111318
}
13121319

@@ -1541,8 +1548,9 @@ where
15411548
type Source = S;
15421549

15431550
#[inline]
1544-
fn as_inner(&mut self) -> &mut S {
1545-
SourceIter::as_inner(&mut self.iter)
1551+
unsafe fn as_inner(&mut self) -> &mut S {
1552+
// Safety: unsafe function forwarding to unsafe function with the same requirements
1553+
unsafe { SourceIter::as_inner(&mut self.iter) }
15461554
}
15471555
}
15481556

@@ -1838,8 +1846,9 @@ where
18381846
type Source = S;
18391847

18401848
#[inline]
1841-
fn as_inner(&mut self) -> &mut S {
1842-
SourceIter::as_inner(&mut self.iter)
1849+
unsafe fn as_inner(&mut self) -> &mut S {
1850+
// Safety: unsafe function forwarding to unsafe function with the same requirements
1851+
unsafe { SourceIter::as_inner(&mut self.iter) }
18431852
}
18441853
}
18451854

@@ -1955,8 +1964,9 @@ unsafe impl<S: Iterator, P, I: Iterator> SourceIter for SkipWhile<I, P> where
19551964
type Source = S;
19561965

19571966
#[inline]
1958-
fn as_inner(&mut self) -> &mut S {
1959-
SourceIter::as_inner(&mut self.iter)
1967+
unsafe fn as_inner(&mut self) -> &mut S {
1968+
// Safety: unsafe function forwarding to unsafe function with the same requirements
1969+
unsafe { SourceIter::as_inner(&mut self.iter) }
19601970
}
19611971
}
19621972

@@ -2163,8 +2173,9 @@ unsafe impl<S: Iterator, P, I: Iterator> SourceIter for TakeWhile<I, P> where
21632173
type Source = S;
21642174

21652175
#[inline]
2166-
fn as_inner(&mut self) -> &mut S {
2167-
SourceIter::as_inner(&mut self.iter)
2176+
unsafe fn as_inner(&mut self) -> &mut S {
2177+
// Safety: unsafe function forwarding to unsafe function with the same requirements
2178+
unsafe { SourceIter::as_inner(&mut self.iter) }
21682179
}
21692180
}
21702181

@@ -2364,8 +2375,9 @@ where
23642375
type Source = S;
23652376

23662377
#[inline]
2367-
fn as_inner(&mut self) -> &mut S {
2368-
SourceIter::as_inner(&mut self.iter)
2378+
unsafe fn as_inner(&mut self) -> &mut S {
2379+
// Safety: unsafe function forwarding to unsafe function with the same requirements
2380+
unsafe { SourceIter::as_inner(&mut self.iter) }
23692381
}
23702382
}
23712383

@@ -2487,8 +2499,9 @@ unsafe impl<S: Iterator, I: Iterator> SourceIter for Take<I> where I: SourceIter
24872499
type Source = S;
24882500

24892501
#[inline]
2490-
fn as_inner(&mut self) -> &mut S {
2491-
SourceIter::as_inner(&mut self.iter)
2502+
unsafe fn as_inner(&mut self) -> &mut S {
2503+
// Safety: unsafe function forwarding to unsafe function with the same requirements
2504+
unsafe { SourceIter::as_inner(&mut self.iter) }
24922505
}
24932506
}
24942507

@@ -2667,8 +2680,9 @@ unsafe impl<St, F, B, S: Iterator, I: Iterator> SourceIter for Scan<I, St, F>
26672680
type Source = S;
26682681

26692682
#[inline]
2670-
fn as_inner(&mut self) -> &mut S {
2671-
SourceIter::as_inner(&mut self.iter)
2683+
unsafe fn as_inner(&mut self) -> &mut S {
2684+
// Safety: unsafe function forwarding to unsafe function with the same requirements
2685+
unsafe { SourceIter::as_inner(&mut self.iter) }
26722686
}
26732687
}
26742688

@@ -2831,8 +2845,9 @@ unsafe impl<S: Iterator, I: Iterator, F> SourceIter for Inspect<I, F> where
28312845
type Source = S;
28322846

28332847
#[inline]
2834-
fn as_inner(&mut self) -> &mut S {
2835-
SourceIter::as_inner(&mut self.iter)
2848+
unsafe fn as_inner(&mut self) -> &mut S {
2849+
// Safety: unsafe function forwarding to unsafe function with the same requirements
2850+
unsafe { SourceIter::as_inner(&mut self.iter) }
28362851
}
28372852
}
28382853

library/core/src/iter/adapters/zip.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -342,13 +342,19 @@ unsafe impl<S, A, B> SourceIter for Zip<A, B>
342342
type Source = S;
343343

344344
#[inline]
345-
fn as_inner(&mut self) -> &mut S {
346-
SourceIter::as_inner(&mut self.a)
345+
unsafe fn as_inner(&mut self) -> &mut S {
346+
// Safety: unsafe function forwarding to unsafe function with the same requirements
347+
unsafe { SourceIter::as_inner(&mut self.a) }
347348
}
348349
}
349350

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

353359
#[stable(feature = "rust1", since = "1.0.0")]
354360
impl<A: Debug, B: Debug> Debug for Zip<A, B> {

0 commit comments

Comments
 (0)