diff options
| author | bors <bors@rust-lang.org> | 2019-10-25 20:41:28 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-10-25 20:41:28 +0000 |
| commit | 246be7e1a557b8ac8287c6842379a0db67770be6 (patch) | |
| tree | 6359f78c7c2bbf20c7e999fa95ddab93ba1a0ea7 /src/libcore | |
| parent | 23f890f10202a71168c6424da0cdf94135d3c40c (diff) | |
| parent | d40c6afba04c906907cb57157c0aec7e12519c94 (diff) | |
| download | rust-246be7e1a557b8ac8287c6842379a0db67770be6.tar.gz rust-246be7e1a557b8ac8287c6842379a0db67770be6.zip | |
Auto merge of #65826 - JohnTitor:rollup-mr6crka, r=JohnTitor
Rollup of 6 pull requests
Successful merges:
- #65705 (Add {String,Vec}::into_raw_parts)
- #65749 (Insurance policy in case `iter.size_hint()` lies.)
- #65799 (Fill tracking issue number for `array_value_iter`)
- #65800 (self-profiling: Update measureme to 0.4.0 and remove non-RAII methods from profiler.)
- #65806 (Add [T]::as_ptr_range() and [T]::as_mut_ptr_range().)
- #65810 (SGX: Clear additional flag on enclave entry)
Failed merges:
r? @ghost
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/array/iter.rs | 20 | ||||
| -rw-r--r-- | src/libcore/array/mod.rs | 2 | ||||
| -rw-r--r-- | src/libcore/intrinsics.rs | 1 | ||||
| -rw-r--r-- | src/libcore/slice/mod.rs | 82 |
4 files changed, 93 insertions, 12 deletions
diff --git a/src/libcore/array/iter.rs b/src/libcore/array/iter.rs index 850a599c659..11803238407 100644 --- a/src/libcore/array/iter.rs +++ b/src/libcore/array/iter.rs @@ -13,7 +13,7 @@ use super::LengthAtMost32; /// A by-value [array] iterator. /// /// [array]: ../../std/primitive.array.html -#[unstable(feature = "array_value_iter", issue = "0")] +#[unstable(feature = "array_value_iter", issue = "65798")] pub struct IntoIter<T, const N: usize> where [T; N]: LengthAtMost32, @@ -49,7 +49,7 @@ where /// *Note*: this method might never get stabilized and/or removed in the /// future as there will likely be another, preferred way of obtaining this /// iterator (either via `IntoIterator` for arrays or via another way). - #[unstable(feature = "array_value_iter", issue = "0")] + #[unstable(feature = "array_value_iter", issue = "65798")] pub fn new(array: [T; N]) -> Self { // The transmute here is actually safe. The docs of `MaybeUninit` // promise: @@ -95,7 +95,7 @@ where } -#[stable(feature = "array_value_iter_impls", since = "1.38.0")] +#[stable(feature = "array_value_iter_impls", since = "1.40.0")] impl<T, const N: usize> Iterator for IntoIter<T, {N}> where [T; N]: LengthAtMost32, @@ -141,7 +141,7 @@ where } } -#[stable(feature = "array_value_iter_impls", since = "1.38.0")] +#[stable(feature = "array_value_iter_impls", since = "1.40.0")] impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, {N}> where [T; N]: LengthAtMost32, @@ -176,7 +176,7 @@ where } } -#[stable(feature = "array_value_iter_impls", since = "1.38.0")] +#[stable(feature = "array_value_iter_impls", since = "1.40.0")] impl<T, const N: usize> Drop for IntoIter<T, {N}> where [T; N]: LengthAtMost32, @@ -189,7 +189,7 @@ where } } -#[stable(feature = "array_value_iter_impls", since = "1.38.0")] +#[stable(feature = "array_value_iter_impls", since = "1.40.0")] impl<T, const N: usize> ExactSizeIterator for IntoIter<T, {N}> where [T; N]: LengthAtMost32, @@ -204,7 +204,7 @@ where } } -#[stable(feature = "array_value_iter_impls", since = "1.38.0")] +#[stable(feature = "array_value_iter_impls", since = "1.40.0")] impl<T, const N: usize> FusedIterator for IntoIter<T, {N}> where [T; N]: LengthAtMost32, @@ -214,13 +214,13 @@ where // elements (that will still be yielded) is the length of the range `alive`. // This range is decremented in length in either `next` or `next_back`. It is // always decremented by 1 in those methods, but only if `Some(_)` is returned. -#[stable(feature = "array_value_iter_impls", since = "1.38.0")] +#[stable(feature = "array_value_iter_impls", since = "1.40.0")] unsafe impl<T, const N: usize> TrustedLen for IntoIter<T, {N}> where [T; N]: LengthAtMost32, {} -#[stable(feature = "array_value_iter_impls", since = "1.38.0")] +#[stable(feature = "array_value_iter_impls", since = "1.40.0")] impl<T: Clone, const N: usize> Clone for IntoIter<T, {N}> where [T; N]: LengthAtMost32, @@ -251,7 +251,7 @@ where } } -#[stable(feature = "array_value_iter_impls", since = "1.38.0")] +#[stable(feature = "array_value_iter_impls", since = "1.40.0")] impl<T: fmt::Debug, const N: usize> fmt::Debug for IntoIter<T, {N}> where [T; N]: LengthAtMost32, diff --git a/src/libcore/array/mod.rs b/src/libcore/array/mod.rs index 120658e9a43..e1ec8b795d0 100644 --- a/src/libcore/array/mod.rs +++ b/src/libcore/array/mod.rs @@ -18,7 +18,7 @@ use crate::slice::{Iter, IterMut}; mod iter; #[cfg(not(bootstrap))] -#[unstable(feature = "array_value_iter", issue = "0")] +#[unstable(feature = "array_value_iter", issue = "65798")] pub use iter::IntoIter; /// Utility trait implemented only on arrays of fixed size diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index b240d059114..4655d39fb8f 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -874,6 +874,7 @@ extern "rust-intrinsic" { /// // the original inner type (`&i32`) to the converted inner type /// // (`Option<&i32>`), so read the nomicon pages linked above. /// let v_from_raw = unsafe { + // FIXME Update this when vec_into_raw_parts is stabilized /// // Ensure the original vector is not dropped. /// let mut v_clone = std::mem::ManuallyDrop::new(v_clone); /// Vec::from_raw_parts(v_clone.as_mut_ptr() as *mut Option<&i32>, diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 4e79ea81204..cdada1252d2 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -28,7 +28,7 @@ use crate::fmt; use crate::intrinsics::{assume, exact_div, unchecked_sub, is_aligned_and_not_null}; use crate::isize; use crate::iter::*; -use crate::ops::{FnMut, self}; +use crate::ops::{FnMut, Range, self}; use crate::option::Option; use crate::option::Option::{None, Some}; use crate::result::Result; @@ -407,6 +407,86 @@ impl<T> [T] { self as *mut [T] as *mut T } + /// Returns the two raw pointers spanning the slice. + /// + /// The returned range is half-open, which means that the end pointer + /// points *one past* the last element of the slice. This way, an empty + /// slice is represented by two equal pointers, and the difference between + /// the two pointers represents the size of the size. + /// + /// See [`as_ptr`] for warnings on using these pointers. The end pointer + /// requires extra caution, as it does not point to a valid element in the + /// slice. + /// + /// This function is useful for interacting with foreign interfaces which + /// use two pointers to refer to a range of elements in memory, as is + /// common in C++. + /// + /// It can also be useful to check if a pointer to an element refers to an + /// element of this slice: + /// + /// ``` + /// #![feature(slice_ptr_range)] + /// + /// let a = [1, 2, 3]; + /// let x = &a[1] as *const _; + /// let y = &5 as *const _; + /// + /// assert!(a.as_ptr_range().contains(&x)); + /// assert!(!a.as_ptr_range().contains(&y)); + /// ``` + /// + /// [`as_ptr`]: #method.as_ptr + #[unstable(feature = "slice_ptr_range", issue = "65807")] + #[inline] + pub fn as_ptr_range(&self) -> Range<*const T> { + // The `add` here is safe, because: + // + // - Both pointers are part of the same object, as pointing directly + // past the object also counts. + // + // - The size of the slice is never larger than isize::MAX bytes, as + // noted here: + // - https://github.com/rust-lang/unsafe-code-guidelines/issues/102#issuecomment-473340447 + // - https://doc.rust-lang.org/reference/behavior-considered-undefined.html + // - https://doc.rust-lang.org/core/slice/fn.from_raw_parts.html#safety + // (This doesn't seem normative yet, but the very same assumption is + // made in many places, including the Index implementation of slices.) + // + // - There is no wrapping around involved, as slices do not wrap past + // the end of the address space. + // + // See the documentation of pointer::add. + let start = self.as_ptr(); + let end = unsafe { start.add(self.len()) }; + start..end + } + + /// Returns the two unsafe mutable pointers spanning the slice. + /// + /// The returned range is half-open, which means that the end pointer + /// points *one past* the last element of the slice. This way, an empty + /// slice is represented by two equal pointers, and the difference between + /// the two pointers represents the size of the size. + /// + /// See [`as_mut_ptr`] for warnings on using these pointers. The end + /// pointer requires extra caution, as it does not point to a valid element + /// in the slice. + /// + /// This function is useful for interacting with foreign interfaces which + /// use two pointers to refer to a range of elements in memory, as is + /// common in C++. + /// + /// [`as_mut_ptr`]: #method.as_mut_ptr + #[unstable(feature = "slice_ptr_range", issue = "65807")] + #[inline] + pub fn as_mut_ptr_range(&mut self) -> Range<*mut T> { + // See as_ptr_range() above for why `add` here is safe. + let start = self.as_mut_ptr(); + let end = unsafe { start.add(self.len()) }; + start..end + } + /// Swaps two elements in the slice. /// /// # Arguments |
