Skip to content

Commit 246be7e

Browse files
committed
Auto merge of rust-lang#65826 - JohnTitor:rollup-mr6crka, r=JohnTitor
Rollup of 6 pull requests Successful merges: - rust-lang#65705 (Add {String,Vec}::into_raw_parts) - rust-lang#65749 (Insurance policy in case `iter.size_hint()` lies.) - rust-lang#65799 (Fill tracking issue number for `array_value_iter`) - rust-lang#65800 (self-profiling: Update measureme to 0.4.0 and remove non-RAII methods from profiler.) - rust-lang#65806 (Add [T]::as_ptr_range() and [T]::as_mut_ptr_range().) - rust-lang#65810 (SGX: Clear additional flag on enclave entry) Failed merges: r? @ghost
2 parents 23f890f + d40c6af commit 246be7e

File tree

12 files changed

+225
-130
lines changed

12 files changed

+225
-130
lines changed

Cargo.lock

+2-2
Original file line numberDiff line numberDiff line change
@@ -1966,9 +1966,9 @@ dependencies = [
19661966

19671967
[[package]]
19681968
name = "measureme"
1969-
version = "0.3.0"
1969+
version = "0.4.0"
19701970
source = "registry+https://github.com/rust-lang/crates.io-index"
1971-
checksum = "d09de7dafa3aa334bc806447c7e4de69419723312f4b88b80b561dea66601ce8"
1971+
checksum = "cd21b0e6e1af976b269ce062038fe5e1b9ca2f817ab7a3af09ec4210aebf0d30"
19721972
dependencies = [
19731973
"byteorder",
19741974
"memmap",

src/liballoc/string.rs

+44-9
Original file line numberDiff line numberDiff line change
@@ -196,20 +196,21 @@ use crate::vec::Vec;
196196
///
197197
/// let story = String::from("Once upon a time...");
198198
///
199-
/// let ptr = story.as_ptr();
199+
// FIXME Update this when vec_into_raw_parts is stabilized
200+
/// // Prevent automatically dropping the String's data
201+
/// let mut story = mem::ManuallyDrop::new(story);
202+
///
203+
/// let ptr = story.as_mut_ptr();
200204
/// let len = story.len();
201205
/// let capacity = story.capacity();
202206
///
203207
/// // story has nineteen bytes
204208
/// assert_eq!(19, len);
205209
///
206-
/// // Now that we have our parts, we throw the story away.
207-
/// mem::forget(story);
208-
///
209210
/// // We can re-build a String out of ptr, len, and capacity. This is all
210211
/// // unsafe because we are responsible for making sure the components are
211212
/// // valid:
212-
/// let s = unsafe { String::from_raw_parts(ptr as *mut _, len, capacity) } ;
213+
/// let s = unsafe { String::from_raw_parts(ptr, len, capacity) } ;
213214
///
214215
/// assert_eq!(String::from("Once upon a time..."), s);
215216
/// ```
@@ -647,6 +648,37 @@ impl String {
647648
decode_utf16(v.iter().cloned()).map(|r| r.unwrap_or(REPLACEMENT_CHARACTER)).collect()
648649
}
649650

651+
/// Decomposes a `String` into its raw components.
652+
///
653+
/// Returns the raw pointer to the underlying data, the length of
654+
/// the string (in bytes), and the allocated capacity of the data
655+
/// (in bytes). These are the same arguments in the same order as
656+
/// the arguments to [`from_raw_parts`].
657+
///
658+
/// After calling this function, the caller is responsible for the
659+
/// memory previously managed by the `String`. The only way to do
660+
/// this is to convert the raw pointer, length, and capacity back
661+
/// into a `String` with the [`from_raw_parts`] function, allowing
662+
/// the destructor to perform the cleanup.
663+
///
664+
/// [`from_raw_parts`]: #method.from_raw_parts
665+
///
666+
/// # Examples
667+
///
668+
/// ```
669+
/// #![feature(vec_into_raw_parts)]
670+
/// let s = String::from("hello");
671+
///
672+
/// let (ptr, len, cap) = s.into_raw_parts();
673+
///
674+
/// let rebuilt = unsafe { String::from_raw_parts(ptr, len, cap) };
675+
/// assert_eq!(rebuilt, "hello");
676+
/// ```
677+
#[unstable(feature = "vec_into_raw_parts", reason = "new API", issue = "65816")]
678+
pub fn into_raw_parts(self) -> (*mut u8, usize, usize) {
679+
self.vec.into_raw_parts()
680+
}
681+
650682
/// Creates a new `String` from a length, capacity, and pointer.
651683
///
652684
/// # Safety
@@ -677,13 +709,16 @@ impl String {
677709
///
678710
/// unsafe {
679711
/// let s = String::from("hello");
680-
/// let ptr = s.as_ptr();
712+
///
713+
// FIXME Update this when vec_into_raw_parts is stabilized
714+
/// // Prevent automatically dropping the String's data
715+
/// let mut s = mem::ManuallyDrop::new(s);
716+
///
717+
/// let ptr = s.as_mut_ptr();
681718
/// let len = s.len();
682719
/// let capacity = s.capacity();
683720
///
684-
/// mem::forget(s);
685-
///
686-
/// let s = String::from_raw_parts(ptr as *mut _, len, capacity);
721+
/// let s = String::from_raw_parts(ptr, len, capacity);
687722
///
688723
/// assert_eq!(String::from("hello"), s);
689724
/// }

src/liballoc/vec.rs

+44-5
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,44 @@ impl<T> Vec<T> {
358358
}
359359
}
360360

361+
/// Decomposes a `Vec<T>` into its raw components.
362+
///
363+
/// Returns the raw pointer to the underlying data, the length of
364+
/// the vector (in elements), and the allocated capacity of the
365+
/// data (in elements). These are the same arguments in the same
366+
/// order as the arguments to [`from_raw_parts`].
367+
///
368+
/// After calling this function, the caller is responsible for the
369+
/// memory previously managed by the `Vec`. The only way to do
370+
/// this is to convert the raw pointer, length, and capacity back
371+
/// into a `Vec` with the [`from_raw_parts`] function, allowing
372+
/// the destructor to perform the cleanup.
373+
///
374+
/// [`from_raw_parts`]: #method.from_raw_parts
375+
///
376+
/// # Examples
377+
///
378+
/// ```
379+
/// #![feature(vec_into_raw_parts)]
380+
/// let v: Vec<i32> = vec![-1, 0, 1];
381+
///
382+
/// let (ptr, len, cap) = v.into_raw_parts();
383+
///
384+
/// let rebuilt = unsafe {
385+
/// // We can now make changes to the components, such as
386+
/// // transmuting the raw pointer to a compatible type.
387+
/// let ptr = ptr as *mut u32;
388+
///
389+
/// Vec::from_raw_parts(ptr, len, cap)
390+
/// };
391+
/// assert_eq!(rebuilt, [4294967295, 0, 1]);
392+
/// ```
393+
#[unstable(feature = "vec_into_raw_parts", reason = "new API", issue = "65816")]
394+
pub fn into_raw_parts(self) -> (*mut T, usize, usize) {
395+
let mut me = mem::ManuallyDrop::new(self);
396+
(me.as_mut_ptr(), me.len(), me.capacity())
397+
}
398+
361399
/// Creates a `Vec<T>` directly from the raw components of another vector.
362400
///
363401
/// # Safety
@@ -389,18 +427,19 @@ impl<T> Vec<T> {
389427
/// use std::ptr;
390428
/// use std::mem;
391429
///
392-
/// let mut v = vec![1, 2, 3];
430+
/// let v = vec![1, 2, 3];
431+
///
432+
// FIXME Update this when vec_into_raw_parts is stabilized
433+
/// // Prevent running `v`'s destructor so we are in complete control
434+
/// // of the allocation.
435+
/// let mut v = mem::ManuallyDrop::new(v);
393436
///
394437
/// // Pull out the various important pieces of information about `v`
395438
/// let p = v.as_mut_ptr();
396439
/// let len = v.len();
397440
/// let cap = v.capacity();
398441
///
399442
/// unsafe {
400-
/// // Cast `v` into the void: no destructor run, so we are in
401-
/// // complete control of the allocation to which `p` points.
402-
/// mem::forget(v);
403-
///
404443
/// // Overwrite memory with 4, 5, 6
405444
/// for i in 0..len as isize {
406445
/// ptr::write(p.offset(i), 4 + i);

src/libcore/array/iter.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use super::LengthAtMost32;
1313
/// A by-value [array] iterator.
1414
///
1515
/// [array]: ../../std/primitive.array.html
16-
#[unstable(feature = "array_value_iter", issue = "0")]
16+
#[unstable(feature = "array_value_iter", issue = "65798")]
1717
pub struct IntoIter<T, const N: usize>
1818
where
1919
[T; N]: LengthAtMost32,
@@ -49,7 +49,7 @@ where
4949
/// *Note*: this method might never get stabilized and/or removed in the
5050
/// future as there will likely be another, preferred way of obtaining this
5151
/// iterator (either via `IntoIterator` for arrays or via another way).
52-
#[unstable(feature = "array_value_iter", issue = "0")]
52+
#[unstable(feature = "array_value_iter", issue = "65798")]
5353
pub fn new(array: [T; N]) -> Self {
5454
// The transmute here is actually safe. The docs of `MaybeUninit`
5555
// promise:
@@ -95,7 +95,7 @@ where
9595
}
9696

9797

98-
#[stable(feature = "array_value_iter_impls", since = "1.38.0")]
98+
#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
9999
impl<T, const N: usize> Iterator for IntoIter<T, {N}>
100100
where
101101
[T; N]: LengthAtMost32,
@@ -141,7 +141,7 @@ where
141141
}
142142
}
143143

144-
#[stable(feature = "array_value_iter_impls", since = "1.38.0")]
144+
#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
145145
impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, {N}>
146146
where
147147
[T; N]: LengthAtMost32,
@@ -176,7 +176,7 @@ where
176176
}
177177
}
178178

179-
#[stable(feature = "array_value_iter_impls", since = "1.38.0")]
179+
#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
180180
impl<T, const N: usize> Drop for IntoIter<T, {N}>
181181
where
182182
[T; N]: LengthAtMost32,
@@ -189,7 +189,7 @@ where
189189
}
190190
}
191191

192-
#[stable(feature = "array_value_iter_impls", since = "1.38.0")]
192+
#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
193193
impl<T, const N: usize> ExactSizeIterator for IntoIter<T, {N}>
194194
where
195195
[T; N]: LengthAtMost32,
@@ -204,7 +204,7 @@ where
204204
}
205205
}
206206

207-
#[stable(feature = "array_value_iter_impls", since = "1.38.0")]
207+
#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
208208
impl<T, const N: usize> FusedIterator for IntoIter<T, {N}>
209209
where
210210
[T; N]: LengthAtMost32,
@@ -214,13 +214,13 @@ where
214214
// elements (that will still be yielded) is the length of the range `alive`.
215215
// This range is decremented in length in either `next` or `next_back`. It is
216216
// always decremented by 1 in those methods, but only if `Some(_)` is returned.
217-
#[stable(feature = "array_value_iter_impls", since = "1.38.0")]
217+
#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
218218
unsafe impl<T, const N: usize> TrustedLen for IntoIter<T, {N}>
219219
where
220220
[T; N]: LengthAtMost32,
221221
{}
222222

223-
#[stable(feature = "array_value_iter_impls", since = "1.38.0")]
223+
#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
224224
impl<T: Clone, const N: usize> Clone for IntoIter<T, {N}>
225225
where
226226
[T; N]: LengthAtMost32,
@@ -251,7 +251,7 @@ where
251251
}
252252
}
253253

254-
#[stable(feature = "array_value_iter_impls", since = "1.38.0")]
254+
#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
255255
impl<T: fmt::Debug, const N: usize> fmt::Debug for IntoIter<T, {N}>
256256
where
257257
[T; N]: LengthAtMost32,

src/libcore/array/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::slice::{Iter, IterMut};
1818
mod iter;
1919

2020
#[cfg(not(bootstrap))]
21-
#[unstable(feature = "array_value_iter", issue = "0")]
21+
#[unstable(feature = "array_value_iter", issue = "65798")]
2222
pub use iter::IntoIter;
2323

2424
/// Utility trait implemented only on arrays of fixed size

src/libcore/intrinsics.rs

+1
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,7 @@ extern "rust-intrinsic" {
874874
/// // the original inner type (`&i32`) to the converted inner type
875875
/// // (`Option<&i32>`), so read the nomicon pages linked above.
876876
/// let v_from_raw = unsafe {
877+
// FIXME Update this when vec_into_raw_parts is stabilized
877878
/// // Ensure the original vector is not dropped.
878879
/// let mut v_clone = std::mem::ManuallyDrop::new(v_clone);
879880
/// Vec::from_raw_parts(v_clone.as_mut_ptr() as *mut Option<&i32>,

src/libcore/slice/mod.rs

+81-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use crate::fmt;
2828
use crate::intrinsics::{assume, exact_div, unchecked_sub, is_aligned_and_not_null};
2929
use crate::isize;
3030
use crate::iter::*;
31-
use crate::ops::{FnMut, self};
31+
use crate::ops::{FnMut, Range, self};
3232
use crate::option::Option;
3333
use crate::option::Option::{None, Some};
3434
use crate::result::Result;
@@ -407,6 +407,86 @@ impl<T> [T] {
407407
self as *mut [T] as *mut T
408408
}
409409

410+
/// Returns the two raw pointers spanning the slice.
411+
///
412+
/// The returned range is half-open, which means that the end pointer
413+
/// points *one past* the last element of the slice. This way, an empty
414+
/// slice is represented by two equal pointers, and the difference between
415+
/// the two pointers represents the size of the size.
416+
///
417+
/// See [`as_ptr`] for warnings on using these pointers. The end pointer
418+
/// requires extra caution, as it does not point to a valid element in the
419+
/// slice.
420+
///
421+
/// This function is useful for interacting with foreign interfaces which
422+
/// use two pointers to refer to a range of elements in memory, as is
423+
/// common in C++.
424+
///
425+
/// It can also be useful to check if a pointer to an element refers to an
426+
/// element of this slice:
427+
///
428+
/// ```
429+
/// #![feature(slice_ptr_range)]
430+
///
431+
/// let a = [1, 2, 3];
432+
/// let x = &a[1] as *const _;
433+
/// let y = &5 as *const _;
434+
///
435+
/// assert!(a.as_ptr_range().contains(&x));
436+
/// assert!(!a.as_ptr_range().contains(&y));
437+
/// ```
438+
///
439+
/// [`as_ptr`]: #method.as_ptr
440+
#[unstable(feature = "slice_ptr_range", issue = "65807")]
441+
#[inline]
442+
pub fn as_ptr_range(&self) -> Range<*const T> {
443+
// The `add` here is safe, because:
444+
//
445+
// - Both pointers are part of the same object, as pointing directly
446+
// past the object also counts.
447+
//
448+
// - The size of the slice is never larger than isize::MAX bytes, as
449+
// noted here:
450+
// - https://github.com/rust-lang/unsafe-code-guidelines/issues/102#issuecomment-473340447
451+
// - https://doc.rust-lang.org/reference/behavior-considered-undefined.html
452+
// - https://doc.rust-lang.org/core/slice/fn.from_raw_parts.html#safety
453+
// (This doesn't seem normative yet, but the very same assumption is
454+
// made in many places, including the Index implementation of slices.)
455+
//
456+
// - There is no wrapping around involved, as slices do not wrap past
457+
// the end of the address space.
458+
//
459+
// See the documentation of pointer::add.
460+
let start = self.as_ptr();
461+
let end = unsafe { start.add(self.len()) };
462+
start..end
463+
}
464+
465+
/// Returns the two unsafe mutable pointers spanning the slice.
466+
///
467+
/// The returned range is half-open, which means that the end pointer
468+
/// points *one past* the last element of the slice. This way, an empty
469+
/// slice is represented by two equal pointers, and the difference between
470+
/// the two pointers represents the size of the size.
471+
///
472+
/// See [`as_mut_ptr`] for warnings on using these pointers. The end
473+
/// pointer requires extra caution, as it does not point to a valid element
474+
/// in the slice.
475+
///
476+
/// This function is useful for interacting with foreign interfaces which
477+
/// use two pointers to refer to a range of elements in memory, as is
478+
/// common in C++.
479+
///
480+
/// [`as_mut_ptr`]: #method.as_mut_ptr
481+
#[unstable(feature = "slice_ptr_range", issue = "65807")]
482+
#[inline]
483+
pub fn as_mut_ptr_range(&mut self) -> Range<*mut T> {
484+
// See as_ptr_range() above for why `add` here is safe.
485+
let start = self.as_mut_ptr();
486+
let end = unsafe { start.add(self.len()) };
487+
start..end
488+
}
489+
410490
/// Swaps two elements in the slice.
411491
///
412492
/// # Arguments

src/librustc/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,4 @@ byteorder = { version = "1.3" }
3737
chalk-engine = { version = "0.9.0", default-features=false }
3838
rustc_fs_util = { path = "../librustc_fs_util" }
3939
smallvec = { version = "0.6.8", features = ["union", "may_dangle"] }
40-
measureme = "0.3"
40+
measureme = "0.4"

src/librustc/ty/context.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -2930,14 +2930,18 @@ impl<T, R, E> InternIteratorElement<T, R> for Result<T, E> {
29302930
// lower bounds from `size_hint` agree they are correct.
29312931
Ok(match iter.size_hint() {
29322932
(1, Some(1)) => {
2933-
f(&[iter.next().unwrap()?])
2933+
let t0 = iter.next().unwrap()?;
2934+
assert!(iter.next().is_none());
2935+
f(&[t0])
29342936
}
29352937
(2, Some(2)) => {
29362938
let t0 = iter.next().unwrap()?;
29372939
let t1 = iter.next().unwrap()?;
2940+
assert!(iter.next().is_none());
29382941
f(&[t0, t1])
29392942
}
29402943
(0, Some(0)) => {
2944+
assert!(iter.next().is_none());
29412945
f(&[])
29422946
}
29432947
_ => {

0 commit comments

Comments
 (0)