Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 6 pull requests #65826

Merged
merged 22 commits into from
Oct 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
fc50036
fixed ac vulnerability
raoulstrackx Oct 21, 2019
f6aa64b
self-profiling: Remove unused methods from profiler.
michaelwoerister Oct 24, 2019
ee1173a
self-profiling: Update measureme to 0.4.0 and use new RAII-based API.
michaelwoerister Oct 24, 2019
9c08306
self-profiling: Switch query-blocking measurements to RAII-style API.
michaelwoerister Oct 24, 2019
dcf3436
Fill tracking issue number for `array_value_iter` and fix Rust version
LukasKalbertodt Oct 25, 2019
4936f96
Add [T]::as_ptr_range() and [T]::as_mut_ptr_range().
m-ou-se Oct 25, 2019
f1b69b0
Add slice_ptr_range tracking issue number.
m-ou-se Oct 25, 2019
d257c20
removed unnecessary push
raoulstrackx Oct 25, 2019
34f5d59
cleaning up code
raoulstrackx Oct 25, 2019
de9b660
Explain why pointer::add in slice::as_ptr_range is safe.
m-ou-se Oct 25, 2019
5aafa98
forgot pushfq/popqfq: fixed
raoulstrackx Oct 25, 2019
0d21d25
Remove unneeded pointer casting
shepmaster Oct 22, 2019
dce8fab
Use ManuallyDrop in examples for {Vec,String}::from_raw_parts
shepmaster Oct 22, 2019
6600cf6
Add {String,Vec}::into_raw_parts
shepmaster Oct 22, 2019
dfcfca2
Take out an insurance policy in case `iter.size_hint()`
Centril Oct 24, 2019
381c442
Fix slice::as_ptr_range doctest.
m-ou-se Oct 25, 2019
a808ba3
Rollup merge of #65705 - shepmaster:vec-into-raw, r=SimonSapin
JohnTitor Oct 25, 2019
7068c2d
Rollup merge of #65749 - Centril:insurance-policy, r=RalfJung
JohnTitor Oct 25, 2019
9192f36
Rollup merge of #65799 - LukasKalbertodt:fill-array-value-iter-tracki…
JohnTitor Oct 25, 2019
574b078
Rollup merge of #65800 - michaelwoerister:measureme-0.4.0, r=wesleywiser
JohnTitor Oct 25, 2019
f0c58e9
Rollup merge of #65806 - fusion-engineering-forks:slice-ptr-range, r=…
JohnTitor Oct 25, 2019
d40c6af
Rollup merge of #65810 - raoulstrackx:ac_mitigation, r=nagisa
JohnTitor Oct 25, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1966,9 +1966,9 @@ dependencies = [

[[package]]
name = "measureme"
version = "0.3.0"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d09de7dafa3aa334bc806447c7e4de69419723312f4b88b80b561dea66601ce8"
checksum = "cd21b0e6e1af976b269ce062038fe5e1b9ca2f817ab7a3af09ec4210aebf0d30"
dependencies = [
"byteorder",
"memmap",
Expand Down
53 changes: 44 additions & 9 deletions src/liballoc/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,20 +196,21 @@ use crate::vec::Vec;
///
/// let story = String::from("Once upon a time...");
///
/// let ptr = story.as_ptr();
// FIXME Update this when vec_into_raw_parts is stabilized
/// // Prevent automatically dropping the String's data
/// let mut story = mem::ManuallyDrop::new(story);
///
/// let ptr = story.as_mut_ptr();
/// let len = story.len();
/// let capacity = story.capacity();
///
/// // story has nineteen bytes
/// assert_eq!(19, len);
///
/// // Now that we have our parts, we throw the story away.
/// mem::forget(story);
///
/// // We can re-build a String out of ptr, len, and capacity. This is all
/// // unsafe because we are responsible for making sure the components are
/// // valid:
/// let s = unsafe { String::from_raw_parts(ptr as *mut _, len, capacity) } ;
/// let s = unsafe { String::from_raw_parts(ptr, len, capacity) } ;
///
/// assert_eq!(String::from("Once upon a time..."), s);
/// ```
Expand Down Expand Up @@ -647,6 +648,37 @@ impl String {
decode_utf16(v.iter().cloned()).map(|r| r.unwrap_or(REPLACEMENT_CHARACTER)).collect()
}

/// Decomposes a `String` into its raw components.
///
/// Returns the raw pointer to the underlying data, the length of
/// the string (in bytes), and the allocated capacity of the data
/// (in bytes). These are the same arguments in the same order as
/// the arguments to [`from_raw_parts`].
///
/// After calling this function, the caller is responsible for the
/// memory previously managed by the `String`. The only way to do
/// this is to convert the raw pointer, length, and capacity back
/// into a `String` with the [`from_raw_parts`] function, allowing
/// the destructor to perform the cleanup.
///
/// [`from_raw_parts`]: #method.from_raw_parts
///
/// # Examples
///
/// ```
/// #![feature(vec_into_raw_parts)]
/// let s = String::from("hello");
///
/// let (ptr, len, cap) = s.into_raw_parts();
///
/// let rebuilt = unsafe { String::from_raw_parts(ptr, len, cap) };
/// assert_eq!(rebuilt, "hello");
/// ```
#[unstable(feature = "vec_into_raw_parts", reason = "new API", issue = "65816")]
pub fn into_raw_parts(self) -> (*mut u8, usize, usize) {
self.vec.into_raw_parts()
}

/// Creates a new `String` from a length, capacity, and pointer.
///
/// # Safety
Expand Down Expand Up @@ -677,13 +709,16 @@ impl String {
///
/// unsafe {
/// let s = String::from("hello");
/// let ptr = s.as_ptr();
///
// FIXME Update this when vec_into_raw_parts is stabilized
/// // Prevent automatically dropping the String's data
/// let mut s = mem::ManuallyDrop::new(s);
///
/// let ptr = s.as_mut_ptr();
/// let len = s.len();
/// let capacity = s.capacity();
///
/// mem::forget(s);
///
/// let s = String::from_raw_parts(ptr as *mut _, len, capacity);
/// let s = String::from_raw_parts(ptr, len, capacity);
///
/// assert_eq!(String::from("hello"), s);
/// }
Expand Down
49 changes: 44 additions & 5 deletions src/liballoc/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,44 @@ impl<T> Vec<T> {
}
}

/// Decomposes a `Vec<T>` into its raw components.
///
/// Returns the raw pointer to the underlying data, the length of
/// the vector (in elements), and the allocated capacity of the
/// data (in elements). These are the same arguments in the same
/// order as the arguments to [`from_raw_parts`].
///
/// After calling this function, the caller is responsible for the
/// memory previously managed by the `Vec`. The only way to do
/// this is to convert the raw pointer, length, and capacity back
/// into a `Vec` with the [`from_raw_parts`] function, allowing
/// the destructor to perform the cleanup.
///
/// [`from_raw_parts`]: #method.from_raw_parts
///
/// # Examples
///
/// ```
/// #![feature(vec_into_raw_parts)]
/// let v: Vec<i32> = vec![-1, 0, 1];
///
/// let (ptr, len, cap) = v.into_raw_parts();
///
/// let rebuilt = unsafe {
/// // We can now make changes to the components, such as
/// // transmuting the raw pointer to a compatible type.
/// let ptr = ptr as *mut u32;
///
/// Vec::from_raw_parts(ptr, len, cap)
/// };
/// assert_eq!(rebuilt, [4294967295, 0, 1]);
/// ```
#[unstable(feature = "vec_into_raw_parts", reason = "new API", issue = "65816")]
pub fn into_raw_parts(self) -> (*mut T, usize, usize) {
let mut me = mem::ManuallyDrop::new(self);
(me.as_mut_ptr(), me.len(), me.capacity())
}

/// Creates a `Vec<T>` directly from the raw components of another vector.
///
/// # Safety
Expand Down Expand Up @@ -389,18 +427,19 @@ impl<T> Vec<T> {
/// use std::ptr;
/// use std::mem;
///
/// let mut v = vec![1, 2, 3];
/// let v = vec![1, 2, 3];
///
// FIXME Update this when vec_into_raw_parts is stabilized
/// // Prevent running `v`'s destructor so we are in complete control
/// // of the allocation.
/// let mut v = mem::ManuallyDrop::new(v);
///
/// // Pull out the various important pieces of information about `v`
/// let p = v.as_mut_ptr();
/// let len = v.len();
/// let cap = v.capacity();
///
/// unsafe {
/// // Cast `v` into the void: no destructor run, so we are in
/// // complete control of the allocation to which `p` points.
/// mem::forget(v);
///
/// // Overwrite memory with 4, 5, 6
/// for i in 0..len as isize {
/// ptr::write(p.offset(i), 4 + i);
Expand Down
20 changes: 10 additions & 10 deletions src/libcore/array/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions src/libcore/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
Expand Down
82 changes: 81 additions & 1 deletion src/libcore/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ byteorder = { version = "1.3" }
chalk-engine = { version = "0.9.0", default-features=false }
rustc_fs_util = { path = "../librustc_fs_util" }
smallvec = { version = "0.6.8", features = ["union", "may_dangle"] }
measureme = "0.3"
measureme = "0.4"
6 changes: 5 additions & 1 deletion src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2930,14 +2930,18 @@ impl<T, R, E> InternIteratorElement<T, R> for Result<T, E> {
// lower bounds from `size_hint` agree they are correct.
Ok(match iter.size_hint() {
(1, Some(1)) => {
f(&[iter.next().unwrap()?])
let t0 = iter.next().unwrap()?;
assert!(iter.next().is_none());
f(&[t0])
}
(2, Some(2)) => {
let t0 = iter.next().unwrap()?;
let t1 = iter.next().unwrap()?;
assert!(iter.next().is_none());
f(&[t0, t1])
}
(0, Some(0)) => {
assert!(iter.next().is_none());
f(&[])
}
_ => {
Expand Down
Loading