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 8 pull requests #98292

Merged
merged 27 commits into from
Jun 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
967c0ad
Implement `IterMut::as_mut_slice`
SkiFire13 Jan 19, 2022
a23e751
Panic when advance_slices()'ing too far.
m-ou-se Mar 11, 2022
4d7daa0
Update advance and advance_slices docs.
m-ou-se Mar 11, 2022
1890372
Update tests.
m-ou-se Mar 11, 2022
1ac5440
add `{Arc, Rc}::downcast_unchecked`
ibraheemdev May 1, 2022
6d523e9
Fix the generator example for `pin!()`
mbartlett21 May 4, 2022
5ae95fa
Document Rust's stance on `/proc/self/mem`
sunfishcode Jun 7, 2022
fbb59e7
Update library/std/src/os/unix/io/mod.rs
sunfishcode Jun 7, 2022
52cb18b
Update library/std/src/os/unix/io/mod.rs
sunfishcode Jun 7, 2022
27d9ab4
Update library/std/src/os/unix/io/mod.rs
sunfishcode Jun 7, 2022
f9662f2
Update library/std/src/os/unix/io/mod.rs
sunfishcode Jun 7, 2022
7656e08
Reword a question into a statement.
sunfishcode Jun 8, 2022
e89ec68
Update library/std/src/os/unix/io/mod.rs
sunfishcode Jun 8, 2022
158ff5c
Reword the question in the section header too.
sunfishcode Jun 8, 2022
6959441
Fix trailing whitespace.
sunfishcode Jun 8, 2022
f725b97
Include ForeignItem when visiting types for WF check
PrestonFrom Jun 16, 2022
c867529
Show #![feature] in example.
m-ou-se Jun 20, 2022
8b93147
`Stdio::make_pipe`
ChrisDenton May 18, 2022
740a54c
Windows: `CommandExt::async_pipes`
ChrisDenton May 18, 2022
fd9ca0c
Rollup merge of #93080 - SkiFire13:itermut-as_mut_slice, r=m-ou-se
Dylan-DPC Jun 20, 2022
99620ad
Rollup merge of #94855 - m-ou-se:advance-slice-panic-docs, r=kennytm
Dylan-DPC Jun 20, 2022
7372bf8
Rollup merge of #96609 - ibraheemdev:arc-downcast-unchecked, r=m-ou-se
Dylan-DPC Jun 20, 2022
625c929
Rollup merge of #96719 - mbartlett21:patch-4, r=Dylan-DPC
Dylan-DPC Jun 20, 2022
85f1de2
Rollup merge of #97149 - ChrisDenton:win_async_pipes, r=m-ou-se
Dylan-DPC Jun 20, 2022
2807f28
Rollup merge of #97150 - ChrisDenton:stdio-create_pipe, r=m-ou-se
Dylan-DPC Jun 20, 2022
ce1151c
Rollup merge of #97837 - sunfishcode:sunfishcode/proc-self-mem, r=m-o…
Dylan-DPC Jun 20, 2022
7bde23b
Rollup merge of #98159 - PrestonFrom:issue_95665, r=petrochenkov
Dylan-DPC Jun 20, 2022
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
5 changes: 4 additions & 1 deletion compiler/rustc_typeck/src/hir_wf_check.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::collect::ItemCtxt;
use rustc_hir as hir;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::HirId;
use rustc_hir::{ForeignItem, ForeignItemKind, HirId};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::TraitEngine;
use rustc_infer::traits::{ObligationCause, WellFormedLoc};
Expand Down Expand Up @@ -141,6 +141,9 @@ fn diagnostic_hir_wf_check<'tcx>(
ref item => bug!("Unexpected item {:?}", item),
},
hir::Node::Field(field) => Some(field.ty),
hir::Node::ForeignItem(ForeignItem {
kind: ForeignItemKind::Static(ty, _), ..
}) => Some(*ty),
ref node => bug!("Unexpected node {:?}", node),
},
WellFormedLoc::Param { function: _, param_idx } => {
Expand Down
40 changes: 38 additions & 2 deletions library/alloc/src/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1254,8 +1254,6 @@ impl<T: Clone> Rc<T> {
}

impl Rc<dyn Any> {
#[inline]
#[stable(feature = "rc_downcast", since = "1.29.0")]
/// Attempt to downcast the `Rc<dyn Any>` to a concrete type.
///
/// # Examples
Expand All @@ -1274,6 +1272,8 @@ impl Rc<dyn Any> {
/// print_if_string(Rc::new(my_string));
/// print_if_string(Rc::new(0i8));
/// ```
#[inline]
#[stable(feature = "rc_downcast", since = "1.29.0")]
pub fn downcast<T: Any>(self) -> Result<Rc<T>, Rc<dyn Any>> {
if (*self).is::<T>() {
unsafe {
Expand All @@ -1285,6 +1285,42 @@ impl Rc<dyn Any> {
Err(self)
}
}

/// Downcasts the `Rc<dyn Any>` to a concrete type.
///
/// For a safe alternative see [`downcast`].
///
/// # Examples
///
/// ```
/// #![feature(downcast_unchecked)]
///
/// use std::any::Any;
/// use std::rc::Rc;
///
/// let x: Rc<dyn Any> = Rc::new(1_usize);
///
/// unsafe {
/// assert_eq!(*x.downcast_unchecked::<usize>(), 1);
/// }
/// ```
///
/// # Safety
///
/// The contained value must be of type `T`. Calling this method
/// with the incorrect type is *undefined behavior*.
///
///
/// [`downcast`]: Self::downcast
#[inline]
#[unstable(feature = "downcast_unchecked", issue = "90850")]
pub unsafe fn downcast_unchecked<T: Any>(self) -> Rc<T> {
unsafe {
let ptr = self.ptr.cast::<RcBox<T>>();
mem::forget(self);
Rc::from_inner(ptr)
}
}
}

impl<T: ?Sized> Rc<T> {
Expand Down
45 changes: 42 additions & 3 deletions library/alloc/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1705,8 +1705,6 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Arc<T> {
}

impl Arc<dyn Any + Send + Sync> {
#[inline]
#[stable(feature = "rc_downcast", since = "1.29.0")]
/// Attempt to downcast the `Arc<dyn Any + Send + Sync>` to a concrete type.
///
/// # Examples
Expand All @@ -1725,9 +1723,11 @@ impl Arc<dyn Any + Send + Sync> {
/// print_if_string(Arc::new(my_string));
/// print_if_string(Arc::new(0i8));
/// ```
#[inline]
#[stable(feature = "rc_downcast", since = "1.29.0")]
pub fn downcast<T>(self) -> Result<Arc<T>, Self>
where
T: Any + Send + Sync + 'static,
T: Any + Send + Sync,
{
if (*self).is::<T>() {
unsafe {
Expand All @@ -1739,6 +1739,45 @@ impl Arc<dyn Any + Send + Sync> {
Err(self)
}
}

/// Downcasts the `Arc<dyn Any + Send + Sync>` to a concrete type.
///
/// For a safe alternative see [`downcast`].
///
/// # Examples
///
/// ```
/// #![feature(downcast_unchecked)]
///
/// use std::any::Any;
/// use std::sync::Arc;
///
/// let x: Arc<dyn Any + Send + Sync> = Arc::new(1_usize);
///
/// unsafe {
/// assert_eq!(*x.downcast_unchecked::<usize>(), 1);
/// }
/// ```
///
/// # Safety
///
/// The contained value must be of type `T`. Calling this method
/// with the incorrect type is *undefined behavior*.
///
///
/// [`downcast`]: Self::downcast
#[inline]
#[unstable(feature = "downcast_unchecked", issue = "90850")]
pub unsafe fn downcast_unchecked<T>(self) -> Arc<T>
where
T: Any + Send + Sync,
{
unsafe {
let ptr = self.ptr.cast::<ArcInner<T>>();
mem::forget(self);
Arc::from_inner(ptr)
}
}
}

impl<T> Weak<T> {
Expand Down
7 changes: 4 additions & 3 deletions library/core/src/pin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1006,9 +1006,10 @@ impl<P, U> DispatchFromDyn<Pin<U>> for Pin<P> where P: DispatchFromDyn<U> {}
/// // Allow generator to be self-referential (not `Unpin`)
/// // vvvvvv so that locals can cross yield points.
/// static || {
/// let foo = String::from("foo"); // --+
/// yield 0; // | <- crosses yield point!
/// println!("{}", &foo); // <----------+
/// let foo = String::from("foo");
/// let foo_ref = &foo; // ------+
/// yield 0; // | <- crosses yield point!
/// println!("{foo_ref}"); // <--+
/// yield foo.len();
/// }
/// }
Expand Down
48 changes: 48 additions & 0 deletions library/core/src/slice/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,47 @@ impl<'a, T> IterMut<'a, T> {
pub fn as_slice(&self) -> &[T] {
self.make_slice()
}

/// Views the underlying data as a mutable subslice of the original data.
///
/// To avoid creating `&mut [T]` references that alias, the returned slice
/// borrows its lifetime from the iterator the method is applied on.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(slice_iter_mut_as_mut_slice)]
///
/// let mut slice: &mut [usize] = &mut [1, 2, 3];
///
/// // First, we get the iterator:
/// let mut iter = slice.iter_mut();
/// // Then, we get a mutable slice from it:
/// let mut_slice = iter.as_mut_slice();
/// // So if we check what the `as_mut_slice` method returned, we have "[1, 2, 3]":
/// assert_eq!(mut_slice, &mut [1, 2, 3]);
///
/// // We can use it to mutate the slice:
/// mut_slice[0] = 4;
/// mut_slice[2] = 5;
///
/// // Next, we can move to the second element of the slice, checking that
/// // it yields the value we just wrote:
/// assert_eq!(iter.next(), Some(&mut 4));
/// // Now `as_mut_slice` returns "[2, 5]":
/// assert_eq!(iter.as_mut_slice(), &mut [2, 5]);
/// ```
#[must_use]
// FIXME: Uncomment the `AsMut<[T]>` impl when this gets stabilized.
#[unstable(feature = "slice_iter_mut_as_mut_slice", issue = "93079")]
pub fn as_mut_slice(&mut self) -> &mut [T] {
// SAFETY: the iterator was created from a mutable slice with pointer
// `self.ptr` and length `len!(self)`. This guarantees that all the prerequisites
// for `from_raw_parts_mut` are fulfilled.
unsafe { from_raw_parts_mut(self.ptr.as_ptr(), len!(self)) }
}
}

#[stable(feature = "slice_iter_mut_as_slice", since = "1.53.0")]
Expand All @@ -315,6 +356,13 @@ impl<T> AsRef<[T]> for IterMut<'_, T> {
}
}

// #[stable(feature = "slice_iter_mut_as_mut_slice", since = "FIXME")]
// impl<T> AsMut<[T]> for IterMut<'_, T> {
// fn as_mut(&mut self) -> &mut [T] {
// self.as_mut_slice()
// }
// }

iterator! {struct IterMut -> *mut T, &'a mut T, mut, {mut}, {}}

/// An internal abstraction over the splitting iterators, so that
Expand Down
50 changes: 34 additions & 16 deletions library/std/src/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1084,6 +1084,10 @@ impl<'a> IoSliceMut<'a> {
/// Also see [`IoSliceMut::advance_slices`] to advance the cursors of
/// multiple buffers.
///
/// # Panics
///
/// Panics when trying to advance beyond the end of the slice.
///
/// # Examples
///
/// ```
Expand All @@ -1105,15 +1109,18 @@ impl<'a> IoSliceMut<'a> {
self.0.advance(n)
}

/// Advance the internal cursor of the slices.
/// Advance a slice of slices.
///
/// # Notes
/// Shrinks the slice to remove any `IoSliceMut`s that are fully advanced over.
/// If the cursor ends up in the middle of an `IoSliceMut`, it is modified
/// to start at that cursor.
///
/// Elements in the slice may be modified if the cursor is not advanced to
/// the end of the slice. For example if we have a slice of buffers with 2
/// `IoSliceMut`s, both of length 8, and we advance the cursor by 10 bytes
/// the first `IoSliceMut` will be untouched however the second will be
/// modified to remove the first 2 bytes (10 - 8).
/// For example, if we have a slice of two 8-byte `IoSliceMut`s, and we advance by 10 bytes,
/// the result will only include the second `IoSliceMut`, advanced by 2 bytes.
///
/// # Panics
///
/// Panics when trying to advance beyond the end of the slices.
///
/// # Examples
///
Expand Down Expand Up @@ -1154,7 +1161,9 @@ impl<'a> IoSliceMut<'a> {
}

*bufs = &mut replace(bufs, &mut [])[remove..];
if !bufs.is_empty() {
if bufs.is_empty() {
assert!(n == accumulated_len, "advancing io slices beyond their length");
} else {
bufs[0].advance(n - accumulated_len)
}
}
Expand Down Expand Up @@ -1219,6 +1228,10 @@ impl<'a> IoSlice<'a> {
/// Also see [`IoSlice::advance_slices`] to advance the cursors of multiple
/// buffers.
///
/// # Panics
///
/// Panics when trying to advance beyond the end of the slice.
///
/// # Examples
///
/// ```
Expand All @@ -1240,15 +1253,18 @@ impl<'a> IoSlice<'a> {
self.0.advance(n)
}

/// Advance the internal cursor of the slices.
/// Advance a slice of slices.
///
/// # Notes
/// Shrinks the slice to remove any `IoSlice`s that are fully advanced over.
/// If the cursor ends up in the middle of an `IoSlice`, it is modified
/// to start at that cursor.
///
/// Elements in the slice may be modified if the cursor is not advanced to
/// the end of the slice. For example if we have a slice of buffers with 2
/// `IoSlice`s, both of length 8, and we advance the cursor by 10 bytes the
/// first `IoSlice` will be untouched however the second will be modified to
/// remove the first 2 bytes (10 - 8).
/// For example, if we have a slice of two 8-byte `IoSlice`s, and we advance by 10 bytes,
/// the result will only include the second `IoSlice`, advanced by 2 bytes.
///
/// # Panics
///
/// Panics when trying to advance beyond the end of the slices.
///
/// # Examples
///
Expand Down Expand Up @@ -1288,7 +1304,9 @@ impl<'a> IoSlice<'a> {
}

*bufs = &mut replace(bufs, &mut [])[remove..];
if !bufs.is_empty() {
if bufs.is_empty() {
assert!(n == accumulated_len, "advancing io slices beyond their length");
} else {
bufs[0].advance(n - accumulated_len)
}
}
Expand Down
8 changes: 4 additions & 4 deletions library/std/src/io/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,18 +423,18 @@ fn io_slice_mut_advance_slices() {
}

#[test]
#[should_panic]
fn io_slice_mut_advance_slices_empty_slice() {
let mut empty_bufs = &mut [][..];
// Shouldn't panic.
IoSliceMut::advance_slices(&mut empty_bufs, 1);
}

#[test]
#[should_panic]
fn io_slice_mut_advance_slices_beyond_total_length() {
let mut buf1 = [1; 8];
let mut bufs = &mut [IoSliceMut::new(&mut buf1)][..];

// Going beyond the total length should be ok.
IoSliceMut::advance_slices(&mut bufs, 9);
assert!(bufs.is_empty());
}
Expand Down Expand Up @@ -463,18 +463,18 @@ fn io_slice_advance_slices() {
}

#[test]
#[should_panic]
fn io_slice_advance_slices_empty_slice() {
let mut empty_bufs = &mut [][..];
// Shouldn't panic.
IoSlice::advance_slices(&mut empty_bufs, 1);
}

#[test]
#[should_panic]
fn io_slice_advance_slices_beyond_total_length() {
let buf1 = [1; 8];
let mut bufs = &mut [IoSlice::new(&buf1)][..];

// Going beyond the total length should be ok.
IoSlice::advance_slices(&mut bufs, 9);
assert!(bufs.is_empty());
}
Expand Down
19 changes: 19 additions & 0 deletions library/std/src/os/unix/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,25 @@
//! Like boxes, `OwnedFd` values conceptually own the resource they point to,
//! and free (close) it when they are dropped.
//!
//! ## `/proc/self/mem` and similar OS features
//!
//! Some platforms have special files, such as `/proc/self/mem`, which
//! provide read and write access to the process's memory. Such reads
//! and writes happen outside the control of the Rust compiler, so they do not
//! uphold Rust's memory safety guarantees.
//!
//! This does not mean that all APIs that might allow `/proc/self/mem`
//! to be opened and read from or written must be `unsafe`. Rust's safety guarantees
//! only cover what the program itself can do, and not what entities outside
//! the program can do to it. `/proc/self/mem` is considered to be such an
//! external entity, along with debugging interfaces, and people with physical access to
//! the hardware. This is true even in cases where the program is controlling
//! the external entity.
//!
//! If you desire to comprehensively prevent programs from reaching out and
//! causing external entities to reach back in and violate memory safety, it's
//! necessary to use *sandboxing*, which is outside the scope of `std`.
//!
//! [`BorrowedFd<'a>`]: crate::os::unix::io::BorrowedFd

#![stable(feature = "rust1", since = "1.0.0")]
Expand Down
Loading