From cce258b2b2e5f96367044fb85c04e35dda449dbe Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Wed, 6 Jan 2021 19:04:45 -0800 Subject: [PATCH 01/13] Make NonNull::as_ref (and friends) return refs with unbound lifetimes --- library/core/src/ptr/non_null.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index d849008b88030..ec444ab54ac75 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -103,7 +103,7 @@ impl NonNull { /// [the module documentation]: crate::ptr#safety #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] - pub unsafe fn as_uninit_ref(&self) -> &MaybeUninit { + pub unsafe fn as_uninit_ref<'a>(&self) -> &'a MaybeUninit { // SAFETY: the caller must guarantee that `self` meets all the // requirements for a reference. unsafe { &*self.cast().as_ptr() } @@ -135,7 +135,7 @@ impl NonNull { /// [the module documentation]: crate::ptr#safety #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] - pub unsafe fn as_uninit_mut(&mut self) -> &mut MaybeUninit { + pub unsafe fn as_uninit_mut<'a>(&mut self) -> &'a mut MaybeUninit { // SAFETY: the caller must guarantee that `self` meets all the // requirements for a reference. unsafe { &mut *self.cast().as_ptr() } @@ -206,7 +206,7 @@ impl NonNull { /// [the module documentation]: crate::ptr#safety #[stable(feature = "nonnull", since = "1.25.0")] #[inline] - pub unsafe fn as_ref(&self) -> &T { + pub unsafe fn as_ref<'a>(&self) -> &'a T { // SAFETY: the caller must guarantee that `self` meets all the // requirements for a reference. unsafe { &*self.as_ptr() } @@ -242,7 +242,7 @@ impl NonNull { /// [the module documentation]: crate::ptr#safety #[stable(feature = "nonnull", since = "1.25.0")] #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { + pub unsafe fn as_mut<'a>(&mut self) -> &'a mut T { // SAFETY: the caller must guarantee that `self` meets all the // requirements for a mutable reference. unsafe { &mut *self.as_ptr() } @@ -390,7 +390,7 @@ impl NonNull<[T]> { /// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] - pub unsafe fn as_uninit_slice(&self) -> &[MaybeUninit] { + pub unsafe fn as_uninit_slice<'a>(&self) -> &'a [MaybeUninit] { // SAFETY: the caller must uphold the safety contract for `as_uninit_slice`. unsafe { slice::from_raw_parts(self.cast().as_ptr(), self.len()) } } @@ -452,7 +452,7 @@ impl NonNull<[T]> { /// ``` #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] - pub unsafe fn as_uninit_slice_mut(&self) -> &mut [MaybeUninit] { + pub unsafe fn as_uninit_slice_mut<'a>(&self) -> &'a mut [MaybeUninit] { // SAFETY: the caller must uphold the safety contract for `as_uninit_slice_mut`. unsafe { slice::from_raw_parts_mut(self.cast().as_ptr(), self.len()) } } From c89e64363ba25a4bf487d71a4ad6e9a8cbe40384 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Fri, 26 Feb 2021 15:44:35 +0100 Subject: [PATCH 02/13] Fix invalid slice access in String::retain --- library/alloc/src/string.rs | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 6fb3fcbb63be2..e8d83d3f18dad 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -1233,37 +1233,44 @@ impl String { where F: FnMut(char) -> bool, { - let len = self.len(); - let mut del_bytes = 0; - let mut idx = 0; + struct SetLenOnDrop<'a> { + s: &'a mut String, + idx: usize, + del_bytes: usize, + } - unsafe { - self.vec.set_len(0); + impl<'a> Drop for SetLenOnDrop<'a> { + fn drop(&mut self) { + let new_len = self.idx - self.del_bytes; + debug_assert!(new_len <= self.s.len()); + unsafe { self.s.vec.set_len(new_len) }; + } } - while idx < len { - let ch = unsafe { self.get_unchecked(idx..len).chars().next().unwrap() }; + let len = self.len(); + let mut guard = SetLenOnDrop { s: self, idx: 0, del_bytes: 0 }; + + while guard.idx < len { + let ch = unsafe { guard.s.get_unchecked(guard.idx..len).chars().next().unwrap() }; let ch_len = ch.len_utf8(); if !f(ch) { - del_bytes += ch_len; - } else if del_bytes > 0 { + guard.del_bytes += ch_len; + } else if guard.del_bytes > 0 { unsafe { ptr::copy( - self.vec.as_ptr().add(idx), - self.vec.as_mut_ptr().add(idx - del_bytes), + guard.s.vec.as_ptr().add(guard.idx), + guard.s.vec.as_mut_ptr().add(guard.idx - guard.del_bytes), ch_len, ); } } // Point idx to the next char - idx += ch_len; + guard.idx += ch_len; } - unsafe { - self.vec.set_len(len - del_bytes); - } + drop(guard); } /// Inserts a character into this `String` at a byte position. From 7539626c4aea0ff036a8d200c587f8ae2743d9bc Mon Sep 17 00:00:00 2001 From: Christiaan Dirkx Date: Tue, 2 Mar 2021 00:00:04 +0100 Subject: [PATCH 03/13] Move `std::sys::unix::platform` to `std::sys::unix::ext` --- library/std/src/sys/mod.rs | 2 -- library/std/src/sys/unix/ext/fs.rs | 2 +- library/std/src/sys/unix/ext/mod.rs | 36 +++++++++++++++++++++++++++++ library/std/src/sys/unix/ext/raw.rs | 6 ++--- library/std/src/sys/unix/mod.rs | 32 ------------------------- 5 files changed, 40 insertions(+), 38 deletions(-) diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs index d3f53801d2d0f..b0b17f2cee993 100644 --- a/library/std/src/sys/mod.rs +++ b/library/std/src/sys/mod.rs @@ -70,8 +70,6 @@ cfg_if::cfg_if! { #[allow(missing_docs)] pub mod unix_ext {} } else { - // On other platforms like Windows document the bare bones of unix - use crate::os::linux as platform; #[path = "unix/ext/mod.rs"] pub mod unix_ext; } diff --git a/library/std/src/sys/unix/ext/fs.rs b/library/std/src/sys/unix/ext/fs.rs index ba75b9bac8035..21bdfe29578bf 100644 --- a/library/std/src/sys/unix/ext/fs.rs +++ b/library/std/src/sys/unix/ext/fs.rs @@ -2,11 +2,11 @@ #![stable(feature = "rust1", since = "1.0.0")] +use super::platform::fs::MetadataExt as _; use crate::fs::{self, OpenOptions, Permissions}; use crate::io; use crate::path::Path; use crate::sys; -use crate::sys::platform::fs::MetadataExt as UnixMetadataExt; use crate::sys_common::{AsInner, AsInnerMut, FromInner}; // Used for `File::read` on intra-doc links #[allow(unused_imports)] diff --git a/library/std/src/sys/unix/ext/mod.rs b/library/std/src/sys/unix/ext/mod.rs index f43546880983a..e5048f7e545e0 100644 --- a/library/std/src/sys/unix/ext/mod.rs +++ b/library/std/src/sys/unix/ext/mod.rs @@ -29,6 +29,42 @@ #![doc(cfg(unix))] #![allow(missing_docs)] +cfg_if::cfg_if! { + if #[cfg(doc)] { + // Use linux as the default platform when documenting on other platforms like Windows + use crate::os::linux as platform; + } else { + #[cfg(target_os = "android")] + use crate::os::android as platform; + #[cfg(target_os = "dragonfly")] + use crate::os::dragonfly as platform; + #[cfg(target_os = "emscripten")] + use crate::os::emscripten as platform; + #[cfg(target_os = "freebsd")] + use crate::os::freebsd as platform; + #[cfg(target_os = "fuchsia")] + use crate::os::fuchsia as platform; + #[cfg(target_os = "haiku")] + use crate::os::haiku as platform; + #[cfg(target_os = "illumos")] + use crate::os::illumos as platform; + #[cfg(target_os = "ios")] + use crate::os::ios as platform; + #[cfg(any(target_os = "linux", target_os = "l4re"))] + use crate::os::linux as platform; + #[cfg(target_os = "macos")] + use crate::os::macos as platform; + #[cfg(target_os = "netbsd")] + use crate::os::netbsd as platform; + #[cfg(target_os = "openbsd")] + use crate::os::openbsd as platform; + #[cfg(target_os = "redox")] + use crate::os::redox as platform; + #[cfg(target_os = "solaris")] + use crate::os::solaris as platform; + } +} + pub mod ffi; pub mod fs; pub mod io; diff --git a/library/std/src/sys/unix/ext/raw.rs b/library/std/src/sys/unix/ext/raw.rs index 3199a0bff0bcc..c292955cb4eea 100644 --- a/library/std/src/sys/unix/ext/raw.rs +++ b/library/std/src/sys/unix/ext/raw.rs @@ -24,10 +24,10 @@ pub type pid_t = i32; #[doc(inline)] #[stable(feature = "pthread_t", since = "1.8.0")] -pub use crate::sys::platform::raw::pthread_t; +pub use super::platform::raw::pthread_t; #[doc(inline)] #[stable(feature = "raw_ext", since = "1.1.0")] -pub use crate::sys::platform::raw::{blkcnt_t, time_t}; +pub use super::platform::raw::{blkcnt_t, time_t}; #[doc(inline)] #[stable(feature = "raw_ext", since = "1.1.0")] -pub use crate::sys::platform::raw::{blksize_t, dev_t, ino_t, mode_t, nlink_t, off_t}; +pub use super::platform::raw::{blksize_t, dev_t, ino_t, mode_t, nlink_t, off_t}; diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs index f8a5ee8996911..44328ffc22e5b 100644 --- a/library/std/src/sys/unix/mod.rs +++ b/library/std/src/sys/unix/mod.rs @@ -2,38 +2,6 @@ use crate::io::ErrorKind; -#[cfg(any(doc, target_os = "linux"))] -pub use crate::os::linux as platform; - -#[cfg(all(not(doc), target_os = "android"))] -pub use crate::os::android as platform; -#[cfg(all(not(doc), target_os = "dragonfly"))] -pub use crate::os::dragonfly as platform; -#[cfg(all(not(doc), target_os = "emscripten"))] -pub use crate::os::emscripten as platform; -#[cfg(all(not(doc), target_os = "freebsd"))] -pub use crate::os::freebsd as platform; -#[cfg(all(not(doc), target_os = "fuchsia"))] -pub use crate::os::fuchsia as platform; -#[cfg(all(not(doc), target_os = "haiku"))] -pub use crate::os::haiku as platform; -#[cfg(all(not(doc), target_os = "illumos"))] -pub use crate::os::illumos as platform; -#[cfg(all(not(doc), target_os = "ios"))] -pub use crate::os::ios as platform; -#[cfg(all(not(doc), target_os = "l4re"))] -pub use crate::os::linux as platform; -#[cfg(all(not(doc), target_os = "macos"))] -pub use crate::os::macos as platform; -#[cfg(all(not(doc), target_os = "netbsd"))] -pub use crate::os::netbsd as platform; -#[cfg(all(not(doc), target_os = "openbsd"))] -pub use crate::os::openbsd as platform; -#[cfg(all(not(doc), target_os = "redox"))] -pub use crate::os::redox as platform; -#[cfg(all(not(doc), target_os = "solaris"))] -pub use crate::os::solaris as platform; - pub use self::rand::hashmap_random_keys; pub use libc::strlen; From 5176f677f588740549185eb877513282512cde3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 4 Mar 2021 18:57:07 +0100 Subject: [PATCH 04/13] slice: Stabilize IterMut::as_slice. Much like #72584. As per #58957 there's no blocker for this, and I wanted to use this today :-) --- library/core/src/slice/iter.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index 796301c76b608..8f404d7153019 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -286,7 +286,6 @@ impl<'a, T> IterMut<'a, T> { /// Basic usage: /// /// ``` - /// # #![feature(slice_iter_mut_as_slice)] /// let mut slice: &mut [usize] = &mut [1, 2, 3]; /// /// // First, we get the iterator: @@ -299,12 +298,19 @@ impl<'a, T> IterMut<'a, T> { /// // Now `as_slice` returns "[2, 3]": /// assert_eq!(iter.as_slice(), &[2, 3]); /// ``` - #[unstable(feature = "slice_iter_mut_as_slice", reason = "recently added", issue = "58957")] + #[stable(feature = "slice_iter_mut_as_slice", since = "1.52.0")] pub fn as_slice(&self) -> &[T] { self.make_slice() } } +#[stable(feature = "slice_iter_mut_as_slice", since = "1.52.0")] +impl AsRef<[T]> for IterMut<'_, T> { + fn as_ref(&self) -> &[T] { + self.as_slice() + } +} + iterator! {struct IterMut -> *mut T, &'a mut T, mut, {mut}, {}} /// An internal abstraction over the splitting iterators, so that From 93fda34bdb7007a54e69ecfc2df235ac465da1e4 Mon Sep 17 00:00:00 2001 From: zseri Date: Fri, 5 Mar 2021 20:02:48 +0100 Subject: [PATCH 05/13] stabilize feature(osstring_ascii) --- library/std/src/ffi/os_str.rs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 272eccda89471..5e0ce0358f782 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -715,7 +715,6 @@ impl OsStr { /// # Examples /// /// ``` - /// #![feature(osstring_ascii)] /// use std::ffi::OsString; /// /// let mut s = OsString::from("GRÜßE, JÜRGEN ❤"); @@ -724,7 +723,7 @@ impl OsStr { /// /// assert_eq!("grÜße, jÜrgen ❤", s); /// ``` - #[unstable(feature = "osstring_ascii", issue = "70516")] + #[stable(feature = "osstring_ascii", since = "1.52.0")] #[inline] pub fn make_ascii_lowercase(&mut self) { self.inner.make_ascii_lowercase() @@ -741,7 +740,6 @@ impl OsStr { /// # Examples /// /// ``` - /// #![feature(osstring_ascii)] /// use std::ffi::OsString; /// /// let mut s = OsString::from("Grüße, Jürgen ❤"); @@ -750,7 +748,7 @@ impl OsStr { /// /// assert_eq!("GRüßE, JüRGEN ❤", s); /// ``` - #[unstable(feature = "osstring_ascii", issue = "70516")] + #[stable(feature = "osstring_ascii", since = "1.52.0")] #[inline] pub fn make_ascii_uppercase(&mut self) { self.inner.make_ascii_uppercase() @@ -767,13 +765,12 @@ impl OsStr { /// # Examples /// /// ``` - /// #![feature(osstring_ascii)] /// use std::ffi::OsString; /// let s = OsString::from("Grüße, Jürgen ❤"); /// /// assert_eq!("grüße, jürgen ❤", s.to_ascii_lowercase()); /// ``` - #[unstable(feature = "osstring_ascii", issue = "70516")] + #[stable(feature = "osstring_ascii", since = "1.52.0")] pub fn to_ascii_lowercase(&self) -> OsString { OsString::from_inner(self.inner.to_ascii_lowercase()) } @@ -789,13 +786,12 @@ impl OsStr { /// # Examples /// /// ``` - /// #![feature(osstring_ascii)] /// use std::ffi::OsString; /// let s = OsString::from("Grüße, Jürgen ❤"); /// /// assert_eq!("GRüßE, JüRGEN ❤", s.to_ascii_uppercase()); /// ``` - #[unstable(feature = "osstring_ascii", issue = "70516")] + #[stable(feature = "osstring_ascii", since = "1.52.0")] pub fn to_ascii_uppercase(&self) -> OsString { OsString::from_inner(self.inner.to_ascii_uppercase()) } @@ -805,7 +801,6 @@ impl OsStr { /// # Examples /// /// ``` - /// #![feature(osstring_ascii)] /// use std::ffi::OsString; /// /// let ascii = OsString::from("hello!\n"); @@ -814,7 +809,7 @@ impl OsStr { /// assert!(ascii.is_ascii()); /// assert!(!non_ascii.is_ascii()); /// ``` - #[unstable(feature = "osstring_ascii", issue = "70516")] + #[stable(feature = "osstring_ascii", since = "1.52.0")] #[inline] pub fn is_ascii(&self) -> bool { self.inner.is_ascii() @@ -828,14 +823,13 @@ impl OsStr { /// # Examples /// /// ``` - /// #![feature(osstring_ascii)] /// use std::ffi::OsString; /// /// assert!(OsString::from("Ferris").eq_ignore_ascii_case("FERRIS")); /// assert!(OsString::from("Ferrös").eq_ignore_ascii_case("FERRöS")); /// assert!(!OsString::from("Ferrös").eq_ignore_ascii_case("FERRÖS")); /// ``` - #[unstable(feature = "osstring_ascii", issue = "70516")] + #[stable(feature = "osstring_ascii", since = "1.52.0")] pub fn eq_ignore_ascii_case>(&self, other: S) -> bool { self.inner.eq_ignore_ascii_case(&other.as_ref().inner) } From 8dc0ae24bcafeb52259ae20fcad29185acf31fcc Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sun, 14 Mar 2021 12:54:34 +0100 Subject: [PATCH 06/13] Remove Option::{unwrap_none, expect_none}. --- library/core/src/option.rs | 94 +------------------ library/core/tests/iter/adapters/chain.rs | 12 +-- library/core/tests/lib.rs | 1 - library/test/src/lib.rs | 6 +- .../std-panic-locations.rs | 5 - 5 files changed, 10 insertions(+), 108 deletions(-) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index f1a0f455cd091..da2c0cf476d16 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -150,7 +150,7 @@ use crate::iter::{FromIterator, FusedIterator, TrustedLen}; use crate::pin::Pin; use crate::{ - fmt, hint, mem, + hint, mem, ops::{self, Deref, DerefMut}, }; @@ -1121,90 +1121,6 @@ impl Option<&mut T> { } } -impl Option { - /// Consumes `self` while expecting [`None`] and returning nothing. - /// - /// # Panics - /// - /// Panics if the value is a [`Some`], with a panic message including the - /// passed message, and the content of the [`Some`]. - /// - /// # Examples - /// - /// ``` - /// #![feature(option_expect_none)] - /// - /// use std::collections::HashMap; - /// let mut squares = HashMap::new(); - /// for i in -10..=10 { - /// // This will not panic, since all keys are unique. - /// squares.insert(i, i * i).expect_none("duplicate key"); - /// } - /// ``` - /// - /// ```should_panic - /// #![feature(option_expect_none)] - /// - /// use std::collections::HashMap; - /// let mut sqrts = HashMap::new(); - /// for i in -10..=10 { - /// // This will panic, since both negative and positive `i` will - /// // insert the same `i * i` key, returning the old `Some(i)`. - /// sqrts.insert(i * i, i).expect_none("duplicate key"); - /// } - /// ``` - #[inline] - #[track_caller] - #[unstable(feature = "option_expect_none", reason = "newly added", issue = "62633")] - pub fn expect_none(self, msg: &str) { - if let Some(val) = self { - expect_none_failed(msg, &val); - } - } - - /// Consumes `self` while expecting [`None`] and returning nothing. - /// - /// # Panics - /// - /// Panics if the value is a [`Some`], with a custom panic message provided - /// by the [`Some`]'s value. - /// - /// [`Some(v)`]: Some - /// - /// # Examples - /// - /// ``` - /// #![feature(option_unwrap_none)] - /// - /// use std::collections::HashMap; - /// let mut squares = HashMap::new(); - /// for i in -10..=10 { - /// // This will not panic, since all keys are unique. - /// squares.insert(i, i * i).unwrap_none(); - /// } - /// ``` - /// - /// ```should_panic - /// #![feature(option_unwrap_none)] - /// - /// use std::collections::HashMap; - /// let mut sqrts = HashMap::new(); - /// for i in -10..=10 { - /// // This will panic, since both negative and positive `i` will - /// // insert the same `i * i` key, returning the old `Some(i)`. - /// sqrts.insert(i * i, i).unwrap_none(); - /// } - /// ``` - #[inline] - #[track_caller] - #[unstable(feature = "option_unwrap_none", reason = "newly added", issue = "62633")] - pub fn unwrap_none(self) { - if let Some(val) = self { - expect_none_failed("called `Option::unwrap_none()` on a `Some` value", &val); - } - } -} - impl Option { /// Returns the contained [`Some`] value or a default /// @@ -1321,14 +1237,6 @@ fn expect_failed(msg: &str) -> ! { panic!("{}", msg) } -// This is a separate function to reduce the code size of .expect_none() itself. -#[inline(never)] -#[cold] -#[track_caller] -fn expect_none_failed(msg: &str, value: &dyn fmt::Debug) -> ! { - panic!("{}: {:?}", msg, value) -} - ///////////////////////////////////////////////////////////////////////////// // Trait implementations ///////////////////////////////////////////////////////////////////////////// diff --git a/library/core/tests/iter/adapters/chain.rs b/library/core/tests/iter/adapters/chain.rs index ca5ae12ae263f..4cd79687b53d4 100644 --- a/library/core/tests/iter/adapters/chain.rs +++ b/library/core/tests/iter/adapters/chain.rs @@ -174,14 +174,14 @@ fn test_iterator_chain_size_hint() { fn test_iterator_chain_unfused() { // Chain shouldn't be fused in its second iterator, depending on direction let mut iter = NonFused::new(empty()).chain(Toggle { is_empty: true }); - iter.next().unwrap_none(); - iter.next().unwrap(); - iter.next().unwrap_none(); + assert!(iter.next().is_none()); + assert!(iter.next().is_some()); + assert!(iter.next().is_none()); let mut iter = Toggle { is_empty: true }.chain(NonFused::new(empty())); - iter.next_back().unwrap_none(); - iter.next_back().unwrap(); - iter.next_back().unwrap_none(); + assert!(iter.next_back().is_none()); + assert!(iter.next_back().is_some()); + assert!(iter.next_back().is_none()); } #[test] diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index b7fcc74036381..658658d7006f7 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -68,7 +68,6 @@ #![feature(unwrap_infallible)] #![feature(option_result_unwrap_unchecked)] #![feature(result_into_ok_or_err)] -#![feature(option_unwrap_none)] #![feature(peekable_peek_mut)] #![cfg_attr(not(bootstrap), feature(ptr_metadata))] #![feature(once_cell)] diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs index 3415eaa9fb345..7683f792b8dbf 100644 --- a/library/test/src/lib.rs +++ b/library/test/src/lib.rs @@ -25,7 +25,6 @@ #![feature(nll)] #![feature(available_concurrency)] #![feature(internal_output_capture)] -#![feature(option_unwrap_none)] #![feature(panic_unwind)] #![feature(staged_api)] #![feature(termination_trait_lib)] @@ -298,8 +297,9 @@ where let test = remaining.pop().unwrap(); let event = TestEvent::TeWait(test.desc.clone()); notify_about_test_event(event)?; - run_test(opts, !opts.run_tests, test, run_strategy, tx.clone(), Concurrent::No) - .unwrap_none(); + let join_handle = + run_test(opts, !opts.run_tests, test, run_strategy, tx.clone(), Concurrent::No); + assert!(join_handle.is_none()); let completed_test = rx.recv().unwrap(); let event = TestEvent::TeResult(completed_test); diff --git a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs index 84b7c6701e5e1..f0850d5c1f1e9 100644 --- a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs +++ b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs @@ -3,7 +3,6 @@ // revisions: default mir-opt //[mir-opt] compile-flags: -Zmir-opt-level=4 -#![feature(option_expect_none, option_unwrap_none)] #![allow(unconditional_panic)] //! Test that panic locations for `#[track_caller]` functions in std have the correct @@ -32,10 +31,6 @@ fn main() { assert_panicked(|| nope.unwrap()); assert_panicked(|| nope.expect("")); - let yep: Option<()> = Some(()); - assert_panicked(|| yep.unwrap_none()); - assert_panicked(|| yep.expect_none("")); - let oops: Result<(), ()> = Err(()); assert_panicked(|| oops.unwrap()); assert_panicked(|| oops.expect("")); From 4002171315bb294d9c518dd1f053072ced66e282 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 21 Mar 2021 12:10:34 -0400 Subject: [PATCH 07/13] Download a more recent LLVM version if `src/version` is modified When bumping the bootstrap version, the name of the generated LLVM shared object file is changed, even though it's the same contents as before. If bootstrap tries to use an older version, it will get linking errors: ``` Building rustdoc for stage1 (x86_64-unknown-linux-gnu) Compiling rustdoc-tool v0.0.0 (/home/joshua/rustc/src/tools/rustdoc) error: linking with `cc` failed: exit code: 1 | = note: "cc" "-Wl,--as-needed" ... lots of args ... = note: /usr/bin/ld: cannot find -lLLVM-12-rust-1.53.0-nightly clang: error: linker command failed with exit code 1 (use -v to see invocation) error: could not compile `rustdoc-tool` ``` --- src/bootstrap/bootstrap.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 3e7d1d54f1284..075756b73ba82 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -463,6 +463,8 @@ def download_stage0(self): "--", "{}/src/llvm-project".format(top_level), "{}/src/bootstrap/download-ci-llvm-stamp".format(top_level), + # the LLVM shared object file is named `LLVM-12-rust-{version}-nightly` + "{}/src/version".format(top_level) ]).decode(sys.getdefaultencoding()).strip() llvm_assertions = self.get_toml('assertions', 'llvm') == 'true' llvm_root = self.llvm_root() From 0acdada18b38f0f0e45836cbc20663e32216f211 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sun, 21 Mar 2021 17:49:14 +0100 Subject: [PATCH 08/13] Bump osstring_ascii stabilization version to 1.53.0. --- library/std/src/ffi/os_str.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 5e0ce0358f782..b407714c380a9 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -723,7 +723,7 @@ impl OsStr { /// /// assert_eq!("grÜße, jÜrgen ❤", s); /// ``` - #[stable(feature = "osstring_ascii", since = "1.52.0")] + #[stable(feature = "osstring_ascii", since = "1.53.0")] #[inline] pub fn make_ascii_lowercase(&mut self) { self.inner.make_ascii_lowercase() @@ -748,7 +748,7 @@ impl OsStr { /// /// assert_eq!("GRüßE, JüRGEN ❤", s); /// ``` - #[stable(feature = "osstring_ascii", since = "1.52.0")] + #[stable(feature = "osstring_ascii", since = "1.53.0")] #[inline] pub fn make_ascii_uppercase(&mut self) { self.inner.make_ascii_uppercase() @@ -770,7 +770,7 @@ impl OsStr { /// /// assert_eq!("grüße, jürgen ❤", s.to_ascii_lowercase()); /// ``` - #[stable(feature = "osstring_ascii", since = "1.52.0")] + #[stable(feature = "osstring_ascii", since = "1.53.0")] pub fn to_ascii_lowercase(&self) -> OsString { OsString::from_inner(self.inner.to_ascii_lowercase()) } @@ -791,7 +791,7 @@ impl OsStr { /// /// assert_eq!("GRüßE, JüRGEN ❤", s.to_ascii_uppercase()); /// ``` - #[stable(feature = "osstring_ascii", since = "1.52.0")] + #[stable(feature = "osstring_ascii", since = "1.53.0")] pub fn to_ascii_uppercase(&self) -> OsString { OsString::from_inner(self.inner.to_ascii_uppercase()) } @@ -809,7 +809,7 @@ impl OsStr { /// assert!(ascii.is_ascii()); /// assert!(!non_ascii.is_ascii()); /// ``` - #[stable(feature = "osstring_ascii", since = "1.52.0")] + #[stable(feature = "osstring_ascii", since = "1.53.0")] #[inline] pub fn is_ascii(&self) -> bool { self.inner.is_ascii() @@ -829,7 +829,7 @@ impl OsStr { /// assert!(OsString::from("Ferrös").eq_ignore_ascii_case("FERRöS")); /// assert!(!OsString::from("Ferrös").eq_ignore_ascii_case("FERRÖS")); /// ``` - #[stable(feature = "osstring_ascii", since = "1.52.0")] + #[stable(feature = "osstring_ascii", since = "1.53.0")] pub fn eq_ignore_ascii_case>(&self, other: S) -> bool { self.inner.eq_ignore_ascii_case(&other.as_ref().inner) } From 236c0cf103aa485db1748587ad87213943bcfb33 Mon Sep 17 00:00:00 2001 From: The8472 Date: Sun, 31 Jan 2021 21:12:43 +0100 Subject: [PATCH 09/13] implement TrustedLen and TrustedRandomAccess for VecDeque iterators --- .../src/collections/vec_deque/into_iter.rs | 32 ++++++++++++++++++- .../alloc/src/collections/vec_deque/iter.rs | 24 +++++++++++++- .../src/collections/vec_deque/iter_mut.rs | 24 +++++++++++++- 3 files changed, 77 insertions(+), 3 deletions(-) diff --git a/library/alloc/src/collections/vec_deque/into_iter.rs b/library/alloc/src/collections/vec_deque/into_iter.rs index 465b058cd98e9..1c635dd4f27fa 100644 --- a/library/alloc/src/collections/vec_deque/into_iter.rs +++ b/library/alloc/src/collections/vec_deque/into_iter.rs @@ -1,5 +1,5 @@ use core::fmt; -use core::iter::FusedIterator; +use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess}; use super::VecDeque; @@ -36,6 +36,22 @@ impl Iterator for IntoIter { let len = self.inner.len(); (len, Some(len)) } + + #[inline] + unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item + where + Self: TrustedRandomAccess, + { + // Safety: The TrustedRandomAccess contract requires that callers only pass an index + // that is in bounds. + // Additionally Self: TrustedRandomAccess is only implemented for T: Copy which means even + // multiple repeated reads of the same index would be safe and the + // values are !Drop, thus won't suffer from double drops. + unsafe { + let idx = self.inner.wrap_add(self.inner.tail, idx); + self.inner.buffer_read(idx) + } + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -55,3 +71,17 @@ impl ExactSizeIterator for IntoIter { #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for IntoIter {} + +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl TrustedLen for IntoIter {} + +#[doc(hidden)] +#[unstable(feature = "trusted_random_access", issue = "none")] +// T: Copy as approximation for !Drop since get_unchecked does not update the pointers +// and thus we can't implement drop-handling +unsafe impl TrustedRandomAccess for IntoIter +where + T: Copy, +{ + const MAY_HAVE_SIDE_EFFECT: bool = false; +} diff --git a/library/alloc/src/collections/vec_deque/iter.rs b/library/alloc/src/collections/vec_deque/iter.rs index ad31b991cb6c3..e4cfb3acdfd5c 100644 --- a/library/alloc/src/collections/vec_deque/iter.rs +++ b/library/alloc/src/collections/vec_deque/iter.rs @@ -1,5 +1,5 @@ use core::fmt; -use core::iter::FusedIterator; +use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess}; use core::ops::Try; use super::{count, wrap_index, RingSlices}; @@ -101,6 +101,19 @@ impl<'a, T> Iterator for Iter<'a, T> { fn last(mut self) -> Option<&'a T> { self.next_back() } + + #[inline] + unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item + where + Self: TrustedRandomAccess, + { + // Safety: The TrustedRandomAccess contract requires that callers only pass an index + // that is in bounds. + unsafe { + let idx = wrap_index(self.tail.wrapping_add(idx), self.ring.len()); + self.ring.get_unchecked(idx) + } + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -157,3 +170,12 @@ impl ExactSizeIterator for Iter<'_, T> { #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for Iter<'_, T> {} + +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl TrustedLen for Iter<'_, T> {} + +#[doc(hidden)] +#[unstable(feature = "trusted_random_access", issue = "none")] +unsafe impl TrustedRandomAccess for Iter<'_, T> { + const MAY_HAVE_SIDE_EFFECT: bool = false; +} diff --git a/library/alloc/src/collections/vec_deque/iter_mut.rs b/library/alloc/src/collections/vec_deque/iter_mut.rs index 3d0c3094e26cd..9493676e66bc8 100644 --- a/library/alloc/src/collections/vec_deque/iter_mut.rs +++ b/library/alloc/src/collections/vec_deque/iter_mut.rs @@ -1,5 +1,5 @@ use core::fmt; -use core::iter::FusedIterator; +use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess}; use core::marker::PhantomData; use super::{count, wrap_index, RingSlices}; @@ -87,6 +87,19 @@ impl<'a, T> Iterator for IterMut<'a, T> { fn last(mut self) -> Option<&'a mut T> { self.next_back() } + + #[inline] + unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item + where + Self: TrustedRandomAccess, + { + // Safety: The TrustedRandomAccess contract requires that callers only pass an index + // that is in bounds. + unsafe { + let idx = wrap_index(self.tail.wrapping_add(idx), self.ring.len()); + &mut *self.ring.get_unchecked_mut(idx) + } + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -126,3 +139,12 @@ impl ExactSizeIterator for IterMut<'_, T> { #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for IterMut<'_, T> {} + +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl TrustedLen for IterMut<'_, T> {} + +#[doc(hidden)] +#[unstable(feature = "trusted_random_access", issue = "none")] +unsafe impl TrustedRandomAccess for IterMut<'_, T> { + const MAY_HAVE_SIDE_EFFECT: bool = false; +} From 1438207c3d150ce42804e857537b12082c68c79b Mon Sep 17 00:00:00 2001 From: The8472 Date: Sun, 31 Jan 2021 21:13:04 +0100 Subject: [PATCH 10/13] use BITS constant --- library/alloc/src/collections/vec_deque/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 7a0de74eb239d..d3e70991ad518 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -58,7 +58,7 @@ mod tests; const INITIAL_CAPACITY: usize = 7; // 2^3 - 1 const MINIMUM_CAPACITY: usize = 1; // 2 - 1 -const MAXIMUM_ZST_CAPACITY: usize = 1 << (core::mem::size_of::() * 8 - 1); // Largest possible power of two +const MAXIMUM_ZST_CAPACITY: usize = 1 << (usize::BITS - 1); // Largest possible power of two /// A double-ended queue implemented with a growable ring buffer. /// From 895d7a9a096aab4690a032cee28f57f4b8a0e9ac Mon Sep 17 00:00:00 2001 From: The8472 Date: Sun, 31 Jan 2021 21:15:18 +0100 Subject: [PATCH 11/13] implement TrustedRandomAccess for Ranges over int types --- library/core/src/iter/range.rs | 43 +++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs index cc80e06decd48..4b293c596e7af 100644 --- a/library/core/src/iter/range.rs +++ b/library/core/src/iter/range.rs @@ -3,7 +3,7 @@ use crate::convert::TryFrom; use crate::mem; use crate::ops::{self, Try}; -use super::{FusedIterator, TrustedLen}; +use super::{FusedIterator, TrustedLen, TrustedRandomAccess}; /// Objects that have a notion of *successor* and *predecessor* operations. /// @@ -493,6 +493,18 @@ macro_rules! range_exact_iter_impl { )*) } +/// Safety: This macro must only be used on types that are `Copy` and result in ranges +/// which have an exact `size_hint()` where the upper bound must not be `None`. +macro_rules! unsafe_range_trusted_random_access_impl { + ($($t:ty)*) => ($( + #[doc(hidden)] + #[unstable(feature = "trusted_random_access", issue = "none")] + unsafe impl TrustedRandomAccess for ops::Range<$t> { + const MAY_HAVE_SIDE_EFFECT: bool = false; + } + )*) +} + macro_rules! range_incl_exact_iter_impl { ($($t:ty)*) => ($( #[stable(feature = "inclusive_range", since = "1.26.0")] @@ -553,6 +565,18 @@ impl Iterator for ops::Range { fn max(mut self) -> Option { self.next_back() } + + #[inline] + unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item + where + Self: TrustedRandomAccess, + { + // SAFETY: The TrustedRandomAccess contract requires that callers only pass an index + // that is in bounds. + // Additionally Self: TrustedRandomAccess is only implemented for Copy types + // which means even repeated reads of the same index would be safe. + unsafe { Step::forward_unchecked(self.start.clone(), idx) } + } } // These macros generate `ExactSizeIterator` impls for various range types. @@ -574,6 +598,23 @@ range_exact_iter_impl! { u32 i32 } + +unsafe_range_trusted_random_access_impl! { + usize u8 u16 + isize i8 i16 +} + +#[cfg(target_pointer_width = "32")] +unsafe_range_trusted_random_access_impl! { + u32 i32 +} + +#[cfg(target_pointer_width = "64")] +unsafe_range_trusted_random_access_impl! { + u32 i32 + u64 i64 +} + range_incl_exact_iter_impl! { u8 i8 From 08a1dd287d371b8df7fbef610e66bc925b3eea0b Mon Sep 17 00:00:00 2001 From: The8472 Date: Sun, 31 Jan 2021 21:16:08 +0100 Subject: [PATCH 12/13] implement TrustedRandomAccess for array::IntoIter --- library/core/src/array/iter.rs | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/library/core/src/array/iter.rs b/library/core/src/array/iter.rs index 4472fba26b99b..f82454addd09a 100644 --- a/library/core/src/array/iter.rs +++ b/library/core/src/array/iter.rs @@ -2,7 +2,7 @@ use crate::{ fmt, - iter::{ExactSizeIterator, FusedIterator, TrustedLen}, + iter::{ExactSizeIterator, FusedIterator, TrustedLen, TrustedRandomAccess}, mem::{self, MaybeUninit}, ops::Range, ptr, @@ -130,6 +130,18 @@ impl Iterator for IntoIter { fn last(mut self) -> Option { self.next_back() } + + #[inline] + unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item + where + Self: TrustedRandomAccess, + { + // SAFETY: Callers are only allowed to pass an index that is in bounds + // Additionally Self: TrustedRandomAccess is only implemented for T: Copy which means even + // multiple repeated reads of the same index would be safe and the + // values aree !Drop, thus won't suffer from double drops. + unsafe { self.data.get_unchecked(self.alive.start + idx).assume_init_read() } + } } #[stable(feature = "array_value_iter_impls", since = "1.40.0")] @@ -184,6 +196,17 @@ impl FusedIterator for IntoIter {} #[stable(feature = "array_value_iter_impls", since = "1.40.0")] unsafe impl TrustedLen for IntoIter {} +#[doc(hidden)] +#[unstable(feature = "trusted_random_access", issue = "none")] +// T: Copy as approximation for !Drop since get_unchecked does not update the pointers +// and thus we can't implement drop-handling +unsafe impl TrustedRandomAccess for IntoIter +where + T: Copy, +{ + const MAY_HAVE_SIDE_EFFECT: bool = false; +} + #[stable(feature = "array_value_iter_impls", since = "1.40.0")] impl Clone for IntoIter { fn clone(&self) -> Self { From 2bd7c1b5de8bdbc7cafa2ee496ef9d80381fb0dd Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sun, 21 Mar 2021 23:01:28 +0100 Subject: [PATCH 13/13] Bump slice_iter_mut_as_slice stable version. --- library/core/src/slice/iter.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index 8f404d7153019..25cd8e6e29d3c 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -298,13 +298,13 @@ impl<'a, T> IterMut<'a, T> { /// // Now `as_slice` returns "[2, 3]": /// assert_eq!(iter.as_slice(), &[2, 3]); /// ``` - #[stable(feature = "slice_iter_mut_as_slice", since = "1.52.0")] + #[stable(feature = "slice_iter_mut_as_slice", since = "1.53.0")] pub fn as_slice(&self) -> &[T] { self.make_slice() } } -#[stable(feature = "slice_iter_mut_as_slice", since = "1.52.0")] +#[stable(feature = "slice_iter_mut_as_slice", since = "1.53.0")] impl AsRef<[T]> for IterMut<'_, T> { fn as_ref(&self) -> &[T] { self.as_slice()