diff options
Diffstat (limited to 'library')
36 files changed, 273 insertions, 273 deletions
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index ce70de6ebdd..109c3a0e683 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -14,8 +14,9 @@ mod tests; extern "Rust" { // These are the magic symbols to call the global allocator. rustc generates - // them from the `#[global_allocator]` attribute if there is one, or uses the - // default implementations in libstd (`__rdl_alloc` etc in `src/libstd/alloc.rs`) + // them to call `__rg_alloc` etc. if there is a `#[global_allocator]` attribute + // (the code expanding that attribute macro generates those functions), or to call + // the default implementations in libstd (`__rdl_alloc` etc. in `library/std/src/alloc.rs`) // otherwise. #[rustc_allocator] #[rustc_allocator_nounwind] @@ -26,8 +27,6 @@ extern "Rust" { fn __rust_realloc(ptr: *mut u8, old_size: usize, align: usize, new_size: usize) -> *mut u8; #[rustc_allocator_nounwind] fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8; - #[rustc_allocator_nounwind] - fn __rust_alloc_error_handler(size: usize, align: usize) -> !; } /// The global memory allocator. @@ -37,7 +36,7 @@ extern "Rust" { /// if there is one, or the `std` crate’s default. /// /// Note: while this type is unstable, the functionality it provides can be -/// accessed through the [free functions in `alloc`](index.html#functions). +/// accessed through the [free functions in `alloc`](self#functions). #[unstable(feature = "allocator_api", issue = "32838")] #[derive(Copy, Clone, Default, Debug)] pub struct Global; @@ -323,6 +322,16 @@ pub(crate) unsafe fn box_free<T: ?Sized>(ptr: Unique<T>) { } } +// # Allocation error handler + +extern "Rust" { + // This is the magic symbol to call the global alloc error handler. rustc generates + // it to call `__rg_oom` if there is a `#[alloc_error_handler]`, or to call the + // default implementations below (`__rdl_oom`) otherwise. + #[rustc_allocator_nounwind] + fn __rust_alloc_error_handler(size: usize, align: usize) -> !; +} + /// Abort on memory allocation error or failure. /// /// Callers of memory allocation APIs wishing to abort computation @@ -367,7 +376,7 @@ pub fn handle_alloc_error(layout: Layout) -> ! { #[doc(hidden)] #[allow(unused_attributes)] #[unstable(feature = "alloc_internals", issue = "none")] -pub mod __default_lib_allocator { +pub mod __alloc_error_handler { use crate::alloc::Layout; // called via generated `__rust_alloc_error_handler` diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 5c8c2c5a5a8..0fc81cb2193 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -815,7 +815,7 @@ impl From<Cow<'_, str>> for Box<str> { #[stable(feature = "boxed_str_conv", since = "1.19.0")] impl From<Box<str>> for Box<[u8]> { - /// Converts a `Box<str>>` into a `Box<[u8]>` + /// Converts a `Box<str>` into a `Box<[u8]>` /// /// This conversion does not allocate on the heap and happens in place. /// diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs index 880627e94c3..4fa97ff053e 100644 --- a/library/alloc/src/collections/btree/node.rs +++ b/library/alloc/src/collections/btree/node.rs @@ -170,6 +170,22 @@ impl<K, V> Root<K, V> { NodeRef { height: self.height, node: self.node.as_ptr(), _marker: PhantomData } } + /// Borrows and returns a mutable reference to the leaf node owned by the root. + /// # Safety + /// The root node is a leaf. + unsafe fn leaf_node_as_mut(&mut self) -> NodeRef<marker::Mut<'_>, K, V, marker::Leaf> { + debug_assert!(self.height == 0); + NodeRef { height: self.height, node: self.node.as_ptr(), _marker: PhantomData } + } + + /// Borrows and returns a mutable reference to the internal node owned by the root. + /// # Safety + /// The root node is not a leaf. + unsafe fn internal_node_as_mut(&mut self) -> NodeRef<marker::Mut<'_>, K, V, marker::Internal> { + debug_assert!(self.height > 0); + NodeRef { height: self.height, node: self.node.as_ptr(), _marker: PhantomData } + } + pub fn node_as_valmut(&mut self) -> NodeRef<marker::ValMut<'_>, K, V, marker::LeafOrInternal> { NodeRef { height: self.height, node: self.node.as_ptr(), _marker: PhantomData } } @@ -188,14 +204,11 @@ impl<K, V> Root<K, V> { self.node = BoxedNode::from_internal(new_node); self.height += 1; - let mut ret = - NodeRef { height: self.height, node: self.node.as_ptr(), _marker: PhantomData }; - unsafe { + let mut ret = self.internal_node_as_mut(); ret.reborrow_mut().first_edge().correct_parent_link(); + ret } - - ret } /// Removes the internal root node, using its first child as the new root node. @@ -212,11 +225,8 @@ impl<K, V> Root<K, V> { let top = self.node.ptr; - self.node = unsafe { - BoxedNode::from_ptr( - self.node_as_mut().cast_unchecked::<marker::Internal>().first_edge().descend().node, - ) - }; + let internal_node = unsafe { self.internal_node_as_mut() }; + self.node = unsafe { BoxedNode::from_ptr(internal_node.first_edge().descend().node) }; self.height -= 1; self.node_as_mut().as_leaf_mut().parent = None; @@ -443,9 +453,9 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> { } impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> { - /// Unsafely asserts to the compiler some static information about whether this - /// node is a `Leaf` or an `Internal`. - unsafe fn cast_unchecked<NewType>(self) -> NodeRef<marker::Mut<'a>, K, V, NewType> { + /// Unsafely asserts to the compiler the static information that this node is an `Internal`. + unsafe fn cast_to_internal_unchecked(self) -> NodeRef<marker::Mut<'a>, K, V, marker::Internal> { + debug_assert!(self.height > 0); NodeRef { height: self.height, node: self.node, _marker: PhantomData } } @@ -943,10 +953,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark Handle::new_edge(left.reborrow_mut(), insert_idx) }, InsertionPlace::Right(insert_idx) => unsafe { - Handle::new_edge( - right.node_as_mut().cast_unchecked::<marker::Leaf>(), - insert_idx, - ) + Handle::new_edge(right.leaf_node_as_mut(), insert_idx) }, }; let val_ptr = insertion_edge.insert_fit(key, val); @@ -1006,10 +1013,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, Handle::new_edge(left.reborrow_mut(), insert_idx) }, InsertionPlace::Right(insert_idx) => unsafe { - Handle::new_edge( - right.node_as_mut().cast_unchecked::<marker::Internal>(), - insert_idx, - ) + Handle::new_edge(right.internal_node_as_mut(), insert_idx) }, }; insertion_edge.insert_fit(key, val, edge); @@ -1205,7 +1209,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, let mut new_root = Root { node: BoxedNode::from_internal(new_node), height }; - new_root.node_as_mut().cast_unchecked().correct_childrens_parent_links(0..=new_len); + new_root.internal_node_as_mut().correct_childrens_parent_links(0..=new_len); (self.node, k, v, new_root) } @@ -1258,8 +1262,8 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, if self.node.height > 1 { // SAFETY: the height of the nodes being merged is one below the height // of the node of this edge, thus above zero, so they are internal. - let mut left_node = left_node.cast_unchecked::<marker::Internal>(); - let right_node = right_node.cast_unchecked::<marker::Internal>(); + let mut left_node = left_node.cast_to_internal_unchecked(); + let right_node = right_node.cast_to_internal_unchecked(); ptr::copy_nonoverlapping( right_node.edge_at(0), left_node.edges_mut().as_mut_ptr().add(left_len + 1), diff --git a/library/alloc/src/vec.rs b/library/alloc/src/vec.rs index e8e52299d0b..5e68f76693f 100644 --- a/library/alloc/src/vec.rs +++ b/library/alloc/src/vec.rs @@ -1476,7 +1476,8 @@ impl<T> Vec<T> { /// `'a`. If the type has only static references, or none at all, then this /// may be chosen to be `'static`. /// - /// This function is similar to the `leak` function on `Box`. + /// This function is similar to the [`leak`][Box::leak] function on [`Box`] + /// except that there is no way to recover the leaked memory. /// /// This function is mainly useful for data that lives for the remainder of /// the program's life. Dropping the returned reference will cause a memory diff --git a/library/backtrace b/library/backtrace -Subproject 4083a90168d605b682ba166a0c01f86b3384e47 +Subproject 893fbb23688e98376e54c26b59432a2966a8cc9 diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 15ec13ca65a..7140218fa91 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -226,7 +226,7 @@ use crate::ptr; /// assert_eq!(my_struct.special_field.get(), new_value); /// ``` /// -/// See the [module-level documentation](index.html) for more. +/// See the [module-level documentation](self) for more. #[stable(feature = "rust1", since = "1.0.0")] #[repr(transparent)] pub struct Cell<T: ?Sized> { @@ -566,7 +566,7 @@ impl<T> Cell<[T]> { /// A mutable memory location with dynamically checked borrow rules /// -/// See the [module-level documentation](index.html) for more. +/// See the [module-level documentation](self) for more. #[stable(feature = "rust1", since = "1.0.0")] pub struct RefCell<T: ?Sized> { borrow: Cell<BorrowFlag>, @@ -1203,7 +1203,7 @@ impl Clone for BorrowRef<'_> { /// Wraps a borrowed reference to a value in a `RefCell` box. /// A wrapper type for an immutably borrowed value from a `RefCell<T>`. /// -/// See the [module-level documentation](index.html) for more. +/// See the [module-level documentation](self) for more. #[stable(feature = "rust1", since = "1.0.0")] pub struct Ref<'b, T: ?Sized + 'b> { value: &'b T, @@ -1493,7 +1493,7 @@ impl<'b> BorrowRefMut<'b> { /// A wrapper type for a mutably borrowed value from a `RefCell<T>`. /// -/// See the [module-level documentation](index.html) for more. +/// See the [module-level documentation](self) for more. #[stable(feature = "rust1", since = "1.0.0")] pub struct RefMut<'b, T: ?Sized + 'b> { value: &'b mut T, diff --git a/library/core/src/ffi.rs b/library/core/src/ffi.rs index 4525ba78ba0..e146a97ae94 100644 --- a/library/core/src/ffi.rs +++ b/library/core/src/ffi.rs @@ -280,7 +280,7 @@ impl<'a, 'f: 'a> DerefMut for VaList<'a, 'f> { // within a private module. Once RFC 2145 has been implemented look into // improving this. mod sealed_trait { - /// Trait which permits the allowed types to be used with [VaList::arg]. + /// Trait which permits the allowed types to be used with [super::VaListImpl::arg]. #[unstable( feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ diff --git a/library/core/src/iter/sources.rs b/library/core/src/iter/sources.rs index 97562cf73b8..44da8f4715c 100644 --- a/library/core/src/iter/sources.rs +++ b/library/core/src/iter/sources.rs @@ -501,9 +501,9 @@ pub fn once_with<A, F: FnOnce() -> A>(gen: F) -> OnceWith<F> { /// /// # Examples /// -/// Let’s re-implement the counter iterator from [module-level documentation]: +/// Let’s re-implement the counter iterator from the [module-level documentation]: /// -/// [module-level documentation]: index.html +/// [module-level documentation]: super /// /// ``` /// let mut count = 0; diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index 41a503c4abb..1ae6d15c12d 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -94,7 +94,7 @@ pub trait FromIterator<A>: Sized { /// /// See the [module-level documentation] for more. /// - /// [module-level documentation]: index.html + /// [module-level documentation]: crate::iter /// /// # Examples /// @@ -120,7 +120,7 @@ pub trait FromIterator<A>: Sized { /// collection of some kind. /// /// One benefit of implementing `IntoIterator` is that your type will [work -/// with Rust's `for` loop syntax](index.html#for-loops-and-intoiterator). +/// with Rust's `for` loop syntax](crate::iter#for-loops-and-intoiterator). /// /// See also: [`FromIterator`]. /// @@ -212,7 +212,7 @@ pub trait IntoIterator { /// /// See the [module-level documentation] for more. /// - /// [module-level documentation]: index.html + /// [module-level documentation]: crate::iter /// /// # Examples /// diff --git a/library/core/src/iter/traits/exact_size.rs b/library/core/src/iter/traits/exact_size.rs index 33ace60a274..eadbdf45c7c 100644 --- a/library/core/src/iter/traits/exact_size.rs +++ b/library/core/src/iter/traits/exact_size.rs @@ -26,10 +26,10 @@ /// assert_eq!(5, five.len()); /// ``` /// -/// In the [module level docs][moddocs], we implemented an [`Iterator`], -/// `Counter`. Let's implement `ExactSizeIterator` for it as well: +/// In the [module-level docs], we implemented an [`Iterator`], `Counter`. +/// Let's implement `ExactSizeIterator` for it as well: /// -/// [moddocs]: index.html +/// [module-level docs]: crate::iter /// /// ``` /// # struct Counter { diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 960a26fd283..c9a80b5bc77 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -82,7 +82,6 @@ #![feature(const_pin)] #![feature(const_fn)] #![feature(const_fn_union)] -#![feature(const_assume)] #![cfg_attr(not(bootstrap), feature(const_impl_trait))] #![feature(const_fn_floating_point_arithmetic)] #![feature(const_fn_fn_ptr_basics)] diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 0cfb4af59b9..9cb20a0afdc 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -141,6 +141,9 @@ //! ``` //! //! [`Box<T>`]: ../../std/boxed/struct.Box.html +//! [`Box<U>`]: ../../std/boxed/struct.Box.html +//! [`num::NonZero*`]: crate::num +//! [`ptr::NonNull<U>`]: crate::ptr::NonNull #![stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 5cec183c237..b6d9f13d881 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -233,7 +233,7 @@ use crate::{convert, fmt}; /// `Result` is a type that represents either success ([`Ok`]) or failure ([`Err`]). /// -/// See the [`std::result`](index.html) module documentation for details. +/// See the [module documentation](self) for details. #[derive(Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] #[must_use = "this `Result` may be an `Err` variant, which should be handled"] #[rustc_diagnostic_item = "result_type"] diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 13d0dda19c7..349c2cde274 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -79,16 +79,6 @@ pub use index::check_range; #[lang = "slice"] #[cfg(not(test))] impl<T> [T] { - /// The maximum, inclusive, length such that the slice is no larger than `isize::MAX` bytes. - /// This constant is used in `len` below. - const MAX_LEN_BOUND: usize = { - if mem::size_of::<T>() == 0 { - usize::MAX - } else { - isize::MAX as usize / mem::size_of::<T>() - } - }; - /// Returns the number of elements in the slice. /// /// # Examples @@ -101,20 +91,11 @@ impl<T> [T] { #[rustc_const_stable(feature = "const_slice_len", since = "1.32.0")] #[inline] // SAFETY: const sound because we transmute out the length field as a usize (which it must be) - #[allow_internal_unstable(const_fn_union, const_assume)] + #[allow_internal_unstable(const_fn_union)] pub const fn len(&self) -> usize { // SAFETY: this is safe because `&[T]` and `FatPtr<T>` have the same layout. // Only `std` can make this guarantee. - let raw_len = unsafe { crate::ptr::Repr { rust: self }.raw.len }; - - // SAFETY: this assume asserts that `raw_len * size_of::<T>() <= isize::MAX`. All - // references must point to one allocation with size at most isize::MAX. Note that we the - // multiplication could appear to overflow until we have assumed the bound. This overflow - // would make additional values appear 'valid' and then `n > 1` the range of permissible - // length would no longer be the full or even a single range. - unsafe { crate::intrinsics::assume(raw_len <= Self::MAX_LEN_BOUND) }; - - raw_len + unsafe { crate::ptr::Repr { rust: self }.raw.len } } /// Returns `true` if the slice has a length of 0. @@ -2054,6 +2035,50 @@ impl<T> [T] { } /// Reorder the slice such that the element at `index` is at its final sorted position. + #[unstable(feature = "slice_partition_at_index", issue = "55300")] + #[rustc_deprecated(since = "1.49.0", reason = "use the select_nth_unstable() instead")] + #[inline] + pub fn partition_at_index(&mut self, index: usize) -> (&mut [T], &mut T, &mut [T]) + where + T: Ord, + { + self.select_nth_unstable(index) + } + + /// Reorder the slice with a comparator function such that the element at `index` is at its + /// final sorted position. + #[unstable(feature = "slice_partition_at_index", issue = "55300")] + #[rustc_deprecated(since = "1.49.0", reason = "use select_nth_unstable_by() instead")] + #[inline] + pub fn partition_at_index_by<F>( + &mut self, + index: usize, + compare: F, + ) -> (&mut [T], &mut T, &mut [T]) + where + F: FnMut(&T, &T) -> Ordering, + { + self.select_nth_unstable_by(index, compare) + } + + /// Reorder the slice with a key extraction function such that the element at `index` is at its + /// final sorted position. + #[unstable(feature = "slice_partition_at_index", issue = "55300")] + #[rustc_deprecated(since = "1.49.0", reason = "use the select_nth_unstable_by_key() instead")] + #[inline] + pub fn partition_at_index_by_key<K, F>( + &mut self, + index: usize, + f: F, + ) -> (&mut [T], &mut T, &mut [T]) + where + F: FnMut(&T) -> K, + K: Ord, + { + self.select_nth_unstable_by_key(index, f) + } + + /// Reorder the slice such that the element at `index` is at its final sorted position. /// /// This reordering has the additional property that any value at position `i < index` will be /// less than or equal to any value at a position `j > index`. Additionally, this reordering is @@ -2077,12 +2102,10 @@ impl<T> [T] { /// # Examples /// /// ``` - /// #![feature(slice_partition_at_index)] - /// /// let mut v = [-5i32, 4, 1, -3, 2]; /// /// // Find the median - /// v.partition_at_index(2); + /// v.select_nth_unstable(2); /// /// // We are only guaranteed the slice will be one of the following, based on the way we sort /// // about the specified index. @@ -2091,9 +2114,9 @@ impl<T> [T] { /// v == [-3, -5, 1, 4, 2] || /// v == [-5, -3, 1, 4, 2]); /// ``` - #[unstable(feature = "slice_partition_at_index", issue = "55300")] + #[stable(feature = "slice_select_nth_unstable", since = "1.49.0")] #[inline] - pub fn partition_at_index(&mut self, index: usize) -> (&mut [T], &mut T, &mut [T]) + pub fn select_nth_unstable(&mut self, index: usize) -> (&mut [T], &mut T, &mut [T]) where T: Ord, { @@ -2127,12 +2150,10 @@ impl<T> [T] { /// # Examples /// /// ``` - /// #![feature(slice_partition_at_index)] - /// /// let mut v = [-5i32, 4, 1, -3, 2]; /// /// // Find the median as if the slice were sorted in descending order. - /// v.partition_at_index_by(2, |a, b| b.cmp(a)); + /// v.select_nth_unstable_by(2, |a, b| b.cmp(a)); /// /// // We are only guaranteed the slice will be one of the following, based on the way we sort /// // about the specified index. @@ -2141,9 +2162,9 @@ impl<T> [T] { /// v == [4, 2, 1, -5, -3] || /// v == [4, 2, 1, -3, -5]); /// ``` - #[unstable(feature = "slice_partition_at_index", issue = "55300")] + #[stable(feature = "slice_select_nth_unstable", since = "1.49.0")] #[inline] - pub fn partition_at_index_by<F>( + pub fn select_nth_unstable_by<F>( &mut self, index: usize, mut compare: F, @@ -2181,12 +2202,10 @@ impl<T> [T] { /// # Examples /// /// ``` - /// #![feature(slice_partition_at_index)] - /// /// let mut v = [-5i32, 4, 1, -3, 2]; /// /// // Return the median as if the array were sorted according to absolute value. - /// v.partition_at_index_by_key(2, |a| a.abs()); + /// v.select_nth_unstable_by_key(2, |a| a.abs()); /// /// // We are only guaranteed the slice will be one of the following, based on the way we sort /// // about the specified index. @@ -2195,9 +2214,9 @@ impl<T> [T] { /// v == [2, 1, -3, 4, -5] || /// v == [2, 1, -3, -5, 4]); /// ``` - #[unstable(feature = "slice_partition_at_index", issue = "55300")] + #[stable(feature = "slice_select_nth_unstable", since = "1.49.0")] #[inline] - pub fn partition_at_index_by_key<K, F>( + pub fn select_nth_unstable_by_key<K, F>( &mut self, index: usize, mut f: F, diff --git a/library/core/tests/num/int_macros.rs b/library/core/tests/num/int_macros.rs index 27e6760e7cb..fcb0d6031be 100644 --- a/library/core/tests/num/int_macros.rs +++ b/library/core/tests/num/int_macros.rs @@ -204,8 +204,8 @@ macro_rules! int_module { #[test] fn test_from_str() { - fn from_str<T: ::std::str::FromStr>(t: &str) -> Option<T> { - ::std::str::FromStr::from_str(t).ok() + fn from_str<T: std::str::FromStr>(t: &str) -> Option<T> { + std::str::FromStr::from_str(t).ok() } assert_eq!(from_str::<$T>("0"), Some(0 as $T)); assert_eq!(from_str::<$T>("3"), Some(3 as $T)); diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs index 5ef30b1a889..ac5c9353ccb 100644 --- a/library/core/tests/slice.rs +++ b/library/core/tests/slice.rs @@ -1571,7 +1571,7 @@ fn sort_unstable() { #[test] #[cfg(not(target_arch = "wasm32"))] #[cfg_attr(miri, ignore)] // Miri is too slow -fn partition_at_index() { +fn select_nth_unstable() { use core::cmp::Ordering::{Equal, Greater, Less}; use rand::rngs::StdRng; use rand::seq::SliceRandom; @@ -1597,7 +1597,7 @@ fn partition_at_index() { // Sort in default order. for pivot in 0..len { let mut v = orig.clone(); - v.partition_at_index(pivot); + v.select_nth_unstable(pivot); assert_eq!(v_sorted[pivot], v[pivot]); for i in 0..pivot { @@ -1610,7 +1610,7 @@ fn partition_at_index() { // Sort in ascending order. for pivot in 0..len { let mut v = orig.clone(); - let (left, pivot, right) = v.partition_at_index_by(pivot, |a, b| a.cmp(b)); + let (left, pivot, right) = v.select_nth_unstable_by(pivot, |a, b| a.cmp(b)); assert_eq!(left.len() + right.len(), len - 1); @@ -1633,7 +1633,7 @@ fn partition_at_index() { for pivot in 0..len { let mut v = orig.clone(); - v.partition_at_index_by(pivot, sort_descending_comparator); + v.select_nth_unstable_by(pivot, sort_descending_comparator); assert_eq!(v_sorted_descending[pivot], v[pivot]); for i in 0..pivot { @@ -1654,7 +1654,7 @@ fn partition_at_index() { } for pivot in 0..v.len() { - v.partition_at_index_by(pivot, |_, _| *[Less, Equal, Greater].choose(&mut rng).unwrap()); + v.select_nth_unstable_by(pivot, |_, _| *[Less, Equal, Greater].choose(&mut rng).unwrap()); v.sort(); for i in 0..v.len() { assert_eq!(v[i], i as i32); @@ -1662,28 +1662,28 @@ fn partition_at_index() { } // Should not panic. - [(); 10].partition_at_index(0); - [(); 10].partition_at_index(5); - [(); 10].partition_at_index(9); - [(); 100].partition_at_index(0); - [(); 100].partition_at_index(50); - [(); 100].partition_at_index(99); + [(); 10].select_nth_unstable(0); + [(); 10].select_nth_unstable(5); + [(); 10].select_nth_unstable(9); + [(); 100].select_nth_unstable(0); + [(); 100].select_nth_unstable(50); + [(); 100].select_nth_unstable(99); let mut v = [0xDEADBEEFu64]; - v.partition_at_index(0); + v.select_nth_unstable(0); assert!(v == [0xDEADBEEF]); } #[test] #[should_panic(expected = "index 0 greater than length of slice")] -fn partition_at_index_zero_length() { - [0i32; 0].partition_at_index(0); +fn select_nth_unstable_zero_length() { + [0i32; 0].select_nth_unstable(0); } #[test] #[should_panic(expected = "index 20 greater than length of slice")] -fn partition_at_index_past_length() { - [0i32; 10].partition_at_index(20); +fn select_nth_unstable_past_length() { + [0i32; 10].select_nth_unstable(20); } pub mod memchr { diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 2663f682a1d..7e7a28be2b0 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -69,7 +69,7 @@ use crate::sys_common::{AsInner, FromInner, IntoInner}; /// [`&OsStr`]: OsStr /// [`&str`]: str /// [`CStr`]: crate::ffi::CStr -/// [conversions]: index.html#conversions +/// [conversions]: super#conversions #[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] pub struct OsString { @@ -88,7 +88,7 @@ pub struct OsString { /// the traits which `OsStr` implements for [conversions] from/to native representations. /// /// [`&str`]: str -/// [conversions]: index.html#conversions +/// [conversions]: super#conversions #[stable(feature = "rust1", since = "1.0.0")] // FIXME: // `OsStr::from_inner` current implementation relies diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index d4cc2cd239b..5224672adb2 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -85,7 +85,7 @@ //! # Contributing changes to the documentation //! //! Check out the rust contribution guidelines [here]( -//! https://rustc-dev-guide.rust-lang.org/getting-started.html). +//! https://rustc-dev-guide.rust-lang.org/contributing.html#writing-documentation). //! The source for this documentation can be found on //! [GitHub](https://github.com/rust-lang/rust). //! To contribute changes, make sure you read the guidelines first, then submit diff --git a/library/std/src/os/linux/fs.rs b/library/std/src/os/linux/fs.rs index ff23c3d67e3..9b7af97616c 100644 --- a/library/std/src/os/linux/fs.rs +++ b/library/std/src/os/linux/fs.rs @@ -20,7 +20,7 @@ pub trait MetadataExt { /// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the /// cross-Unix abstractions contained within the raw stat. /// - /// [`stat`]: crate::os::linux::raw::stat + /// [`stat`]: struct@crate::os::linux::raw::stat /// /// # Examples /// diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 6fa73042a30..50bd2a03b62 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -1009,7 +1009,7 @@ impl FusedIterator for Ancestors<'_> {} /// [`set_extension`]: PathBuf::set_extension /// /// More details about the overall approach can be found in -/// the [module documentation](index.html). +/// the [module documentation](self). /// /// # Examples /// @@ -1655,7 +1655,7 @@ impl AsRef<OsStr> for PathBuf { /// see [`PathBuf`]. /// /// More details about the overall approach can be found in -/// the [module documentation](index.html). +/// the [module documentation](self). /// /// # Examples /// diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs index 81bbf376378..ae678479234 100644 --- a/library/std/src/primitive_docs.rs +++ b/library/std/src/primitive_docs.rs @@ -1118,6 +1118,8 @@ mod prim_ref {} /// For more information and a list of supported ABIs, see [the nomicon's /// section on foreign calling conventions][nomicon-abi]. /// +/// [nomicon-abi]: ../nomicon/ffi.html#foreign-calling-conventions +/// /// ### Variadic functions /// /// Extern function declarations with the "C" or "cdecl" ABIs can also be *variadic*, allowing them diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index eb600d2465c..5e55f97705d 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -319,9 +319,9 @@ impl Command { let mut p = Process { pid: 0, status: None }; - struct PosixSpawnFileActions(MaybeUninit<libc::posix_spawn_file_actions_t>); + struct PosixSpawnFileActions<'a>(&'a mut MaybeUninit<libc::posix_spawn_file_actions_t>); - impl Drop for PosixSpawnFileActions { + impl Drop for PosixSpawnFileActions<'_> { fn drop(&mut self) { unsafe { libc::posix_spawn_file_actions_destroy(self.0.as_mut_ptr()); @@ -329,9 +329,9 @@ impl Command { } } - struct PosixSpawnattr(MaybeUninit<libc::posix_spawnattr_t>); + struct PosixSpawnattr<'a>(&'a mut MaybeUninit<libc::posix_spawnattr_t>); - impl Drop for PosixSpawnattr { + impl Drop for PosixSpawnattr<'_> { fn drop(&mut self) { unsafe { libc::posix_spawnattr_destroy(self.0.as_mut_ptr()); @@ -339,59 +339,65 @@ impl Command { } } + fn cvt_nz(error: libc::c_int) -> io::Result<()> { + if error == 0 { Ok(()) } else { Err(io::Error::from_raw_os_error(error)) } + } + unsafe { - let mut file_actions = PosixSpawnFileActions(MaybeUninit::uninit()); - let mut attrs = PosixSpawnattr(MaybeUninit::uninit()); + let mut attrs = MaybeUninit::uninit(); + cvt_nz(libc::posix_spawnattr_init(attrs.as_mut_ptr()))?; + let attrs = PosixSpawnattr(&mut attrs); - libc::posix_spawnattr_init(attrs.0.as_mut_ptr()); - libc::posix_spawn_file_actions_init(file_actions.0.as_mut_ptr()); + let mut file_actions = MaybeUninit::uninit(); + cvt_nz(libc::posix_spawn_file_actions_init(file_actions.as_mut_ptr()))?; + let file_actions = PosixSpawnFileActions(&mut file_actions); if let Some(fd) = stdio.stdin.fd() { - cvt(libc::posix_spawn_file_actions_adddup2( + cvt_nz(libc::posix_spawn_file_actions_adddup2( file_actions.0.as_mut_ptr(), fd, libc::STDIN_FILENO, ))?; } if let Some(fd) = stdio.stdout.fd() { - cvt(libc::posix_spawn_file_actions_adddup2( + cvt_nz(libc::posix_spawn_file_actions_adddup2( file_actions.0.as_mut_ptr(), fd, libc::STDOUT_FILENO, ))?; } if let Some(fd) = stdio.stderr.fd() { - cvt(libc::posix_spawn_file_actions_adddup2( + cvt_nz(libc::posix_spawn_file_actions_adddup2( file_actions.0.as_mut_ptr(), fd, libc::STDERR_FILENO, ))?; } if let Some((f, cwd)) = addchdir { - cvt(f(file_actions.0.as_mut_ptr(), cwd.as_ptr()))?; + cvt_nz(f(file_actions.0.as_mut_ptr(), cwd.as_ptr()))?; } let mut set = MaybeUninit::<libc::sigset_t>::uninit(); cvt(sigemptyset(set.as_mut_ptr()))?; - cvt(libc::posix_spawnattr_setsigmask(attrs.0.as_mut_ptr(), set.as_ptr()))?; + cvt_nz(libc::posix_spawnattr_setsigmask(attrs.0.as_mut_ptr(), set.as_ptr()))?; cvt(sigaddset(set.as_mut_ptr(), libc::SIGPIPE))?; - cvt(libc::posix_spawnattr_setsigdefault(attrs.0.as_mut_ptr(), set.as_ptr()))?; + cvt_nz(libc::posix_spawnattr_setsigdefault(attrs.0.as_mut_ptr(), set.as_ptr()))?; let flags = libc::POSIX_SPAWN_SETSIGDEF | libc::POSIX_SPAWN_SETSIGMASK; - cvt(libc::posix_spawnattr_setflags(attrs.0.as_mut_ptr(), flags as _))?; + cvt_nz(libc::posix_spawnattr_setflags(attrs.0.as_mut_ptr(), flags as _))?; // Make sure we synchronize access to the global `environ` resource let _env_lock = sys::os::env_lock(); let envp = envp.map(|c| c.as_ptr()).unwrap_or_else(|| *sys::os::environ() as *const _); - let ret = libc::posix_spawnp( + cvt_nz(libc::posix_spawnp( &mut p.pid, self.get_program_cstr().as_ptr(), file_actions.0.as_ptr(), attrs.0.as_ptr(), self.get_argv().as_ptr() as *const _, envp as *const _, - ); - if ret == 0 { Ok(Some(p)) } else { Err(io::Error::from_raw_os_error(ret)) } + ))?; + Ok(Some(p)) } } } diff --git a/library/std/src/sys/unix/time.rs b/library/std/src/sys/unix/time.rs index f2a9cb5a0e8..fac4b05ad0b 100644 --- a/library/std/src/sys/unix/time.rs +++ b/library/std/src/sys/unix/time.rs @@ -117,8 +117,7 @@ impl Hash for Timespec { #[cfg(any(target_os = "macos", target_os = "ios"))] mod inner { use crate::fmt; - use crate::mem; - use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst}; + use crate::sync::atomic::{AtomicU64, Ordering}; use crate::sys::cvt; use crate::sys_common::mul_div_u64; use crate::time::Duration; @@ -233,31 +232,42 @@ mod inner { } fn info() -> mach_timebase_info { - static mut INFO: mach_timebase_info = mach_timebase_info { numer: 0, denom: 0 }; - static STATE: AtomicUsize = AtomicUsize::new(0); - - unsafe { - // If a previous thread has filled in this global state, use that. - if STATE.load(SeqCst) == 2 { - return INFO; - } + // INFO_BITS conceptually is an `Option<mach_timebase_info>`. We can do + // this in 64 bits because we know 0 is never a valid value for the + // `denom` field. + // + // Encoding this as a single `AtomicU64` allows us to use `Relaxed` + // operations, as we are only interested in in the effects on a single + // memory location. + static INFO_BITS: AtomicU64 = AtomicU64::new(0); + + // If a previous thread has initialized `INFO_BITS`, use it. + let info_bits = INFO_BITS.load(Ordering::Relaxed); + if info_bits != 0 { + return info_from_bits(info_bits); + } - // ... otherwise learn for ourselves ... - let mut info = mem::zeroed(); - extern "C" { - fn mach_timebase_info(info: mach_timebase_info_t) -> kern_return_t; - } + // ... otherwise learn for ourselves ... + extern "C" { + fn mach_timebase_info(info: mach_timebase_info_t) -> kern_return_t; + } + let mut info = info_from_bits(0); + unsafe { mach_timebase_info(&mut info); - - // ... and attempt to be the one thread that stores it globally for - // all other threads - if STATE.compare_exchange(0, 1, SeqCst, SeqCst).is_ok() { - INFO = info; - STATE.store(2, SeqCst); - } - return info; } + INFO_BITS.store(info_to_bits(info), Ordering::Relaxed); + info + } + + #[inline] + fn info_to_bits(info: mach_timebase_info) -> u64 { + ((info.denom as u64) << 32) | (info.numer as u64) + } + + #[inline] + fn info_from_bits(bits: u64) -> mach_timebase_info { + mach_timebase_info { numer: bits as u32, denom: (bits >> 32) as u32 } } } diff --git a/library/std/src/sys/unsupported/common.rs b/library/std/src/sys/unsupported/common.rs index 80311d26819..2cdd9c4d19e 100644 --- a/library/std/src/sys/unsupported/common.rs +++ b/library/std/src/sys/unsupported/common.rs @@ -39,10 +39,13 @@ pub fn hashmap_random_keys() -> (u64, u64) { pub enum Void {} pub unsafe fn strlen(mut s: *const c_char) -> usize { - let mut n = 0; - while *s != 0 { - n += 1; - s = s.offset(1); + // SAFETY: The caller must guarantee `s` points to a valid 0-terminated string. + unsafe { + let mut n = 0; + while *s != 0 { + n += 1; + s = s.offset(1); + } + n } - return n; } diff --git a/library/std/src/sys/unsupported/mod.rs b/library/std/src/sys/unsupported/mod.rs index 8ba870c5dbc..d9efdec33d9 100644 --- a/library/std/src/sys/unsupported/mod.rs +++ b/library/std/src/sys/unsupported/mod.rs @@ -1,3 +1,5 @@ +#![deny(unsafe_op_in_unsafe_fn)] + pub mod alloc; pub mod args; pub mod cmath; diff --git a/library/std/src/sys/unsupported/mutex.rs b/library/std/src/sys/unsupported/mutex.rs index 06ea9a1e2c1..b3203c16c50 100644 --- a/library/std/src/sys/unsupported/mutex.rs +++ b/library/std/src/sys/unsupported/mutex.rs @@ -1,7 +1,8 @@ -use crate::cell::UnsafeCell; +use crate::cell::Cell; pub struct Mutex { - locked: UnsafeCell<bool>, + // This platform has no threads, so we can use a Cell here. + locked: Cell<bool>, } pub type MovableMutex = Mutex; @@ -10,9 +11,8 @@ unsafe impl Send for Mutex {} unsafe impl Sync for Mutex {} // no threads on this platform impl Mutex { - #[rustc_const_stable(feature = "const_sys_mutex_new", since = "1.0.0")] pub const fn new() -> Mutex { - Mutex { locked: UnsafeCell::new(false) } + Mutex { locked: Cell::new(false) } } #[inline] @@ -20,25 +20,17 @@ impl Mutex { #[inline] pub unsafe fn lock(&self) { - let locked = self.locked.get(); - assert!(!*locked, "cannot recursively acquire mutex"); - *locked = true; + assert_eq!(self.locked.replace(true), false, "cannot recursively acquire mutex"); } #[inline] pub unsafe fn unlock(&self) { - *self.locked.get() = false; + self.locked.set(false); } #[inline] pub unsafe fn try_lock(&self) -> bool { - let locked = self.locked.get(); - if *locked { - false - } else { - *locked = true; - true - } + self.locked.replace(true) == false } #[inline] diff --git a/library/std/src/sys/unsupported/rwlock.rs b/library/std/src/sys/unsupported/rwlock.rs index d37f34ac935..6982b2b155f 100644 --- a/library/std/src/sys/unsupported/rwlock.rs +++ b/library/std/src/sys/unsupported/rwlock.rs @@ -1,7 +1,8 @@ -use crate::cell::UnsafeCell; +use crate::cell::Cell; pub struct RWLock { - mode: UnsafeCell<isize>, + // This platform has no threads, so we can use a Cell here. + mode: Cell<isize>, } unsafe impl Send for RWLock {} @@ -9,14 +10,14 @@ unsafe impl Sync for RWLock {} // no threads on this platform impl RWLock { pub const fn new() -> RWLock { - RWLock { mode: UnsafeCell::new(0) } + RWLock { mode: Cell::new(0) } } #[inline] pub unsafe fn read(&self) { - let mode = self.mode.get(); - if *mode >= 0 { - *mode += 1; + let m = self.mode.get(); + if m >= 0 { + self.mode.set(m + 1); } else { rtabort!("rwlock locked for writing"); } @@ -24,9 +25,9 @@ impl RWLock { #[inline] pub unsafe fn try_read(&self) -> bool { - let mode = self.mode.get(); - if *mode >= 0 { - *mode += 1; + let m = self.mode.get(); + if m >= 0 { + self.mode.set(m + 1); true } else { false @@ -35,19 +36,15 @@ impl RWLock { #[inline] pub unsafe fn write(&self) { - let mode = self.mode.get(); - if *mode == 0 { - *mode = -1; - } else { + if self.mode.replace(-1) != 0 { rtabort!("rwlock locked for reading") } } #[inline] pub unsafe fn try_write(&self) -> bool { - let mode = self.mode.get(); - if *mode == 0 { - *mode = -1; + if self.mode.get() == 0 { + self.mode.set(-1); true } else { false @@ -56,12 +53,12 @@ impl RWLock { #[inline] pub unsafe fn read_unlock(&self) { - *self.mode.get() -= 1; + self.mode.set(self.mode.get() - 1); } #[inline] pub unsafe fn write_unlock(&self) { - *self.mode.get() += 1; + assert_eq!(self.mode.replace(0), -1); } #[inline] diff --git a/library/std/src/sys/wasi/ext/io.rs b/library/std/src/sys/wasi/ext/io.rs index 661214e8f4c..81413f39dc1 100644 --- a/library/std/src/sys/wasi/ext/io.rs +++ b/library/std/src/sys/wasi/ext/io.rs @@ -160,3 +160,21 @@ impl AsRawFd for io::Stderr { sys::stdio::Stderr.as_raw_fd() } } + +impl<'a> AsRawFd for io::StdinLock<'a> { + fn as_raw_fd(&self) -> RawFd { + sys::stdio::Stdin.as_raw_fd() + } +} + +impl<'a> AsRawFd for io::StdoutLock<'a> { + fn as_raw_fd(&self) -> RawFd { + sys::stdio::Stdout.as_raw_fd() + } +} + +impl<'a> AsRawFd for io::StderrLock<'a> { + fn as_raw_fd(&self) -> RawFd { + sys::stdio::Stderr.as_raw_fd() + } +} diff --git a/library/std/src/sys/wasi/mod.rs b/library/std/src/sys/wasi/mod.rs index a7a4407ac38..a0a37ef8316 100644 --- a/library/std/src/sys/wasi/mod.rs +++ b/library/std/src/sys/wasi/mod.rs @@ -53,6 +53,7 @@ pub mod thread_local_key; pub mod time; #[path = "../unsupported/common.rs"] +#[deny(unsafe_op_in_unsafe_fn)] #[allow(unused)] mod common; pub use common::*; diff --git a/library/std/src/sys/wasm/mod.rs b/library/std/src/sys/wasm/mod.rs index 2934ea59ab5..18295e1129a 100644 --- a/library/std/src/sys/wasm/mod.rs +++ b/library/std/src/sys/wasm/mod.rs @@ -66,5 +66,6 @@ cfg_if::cfg_if! { } #[path = "../unsupported/common.rs"] +#[deny(unsafe_op_in_unsafe_fn)] mod common; pub use common::*; diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs index 559c4dc9c7c..657421e3fa4 100644 --- a/library/std/src/sys/windows/c.rs +++ b/library/std/src/sys/windows/c.rs @@ -47,7 +47,6 @@ pub type LPWCH = *mut WCHAR; pub type LPWIN32_FIND_DATAW = *mut WIN32_FIND_DATAW; pub type LPWSADATA = *mut WSADATA; pub type LPWSAPROTOCOL_INFO = *mut WSAPROTOCOL_INFO; -pub type LPSTR = *mut CHAR; pub type LPWSTR = *mut WCHAR; pub type LPFILETIME = *mut FILETIME; pub type LPWSABUF = *mut WSABUF; @@ -876,16 +875,6 @@ extern "system" { pub fn DeleteFileW(lpPathName: LPCWSTR) -> BOOL; pub fn GetCurrentDirectoryW(nBufferLength: DWORD, lpBuffer: LPWSTR) -> DWORD; pub fn SetCurrentDirectoryW(lpPathName: LPCWSTR) -> BOOL; - pub fn WideCharToMultiByte( - CodePage: UINT, - dwFlags: DWORD, - lpWideCharStr: LPCWSTR, - cchWideChar: c_int, - lpMultiByteStr: LPSTR, - cbMultiByte: c_int, - lpDefaultChar: LPCSTR, - lpUsedDefaultChar: LPBOOL, - ) -> c_int; pub fn closesocket(socket: SOCKET) -> c_int; pub fn recv(socket: SOCKET, buf: *mut c_void, len: c_int, flags: c_int) -> c_int; diff --git a/library/std/src/sys/windows/mod.rs b/library/std/src/sys/windows/mod.rs index 8178e6806b9..8c19cc78b09 100644 --- a/library/std/src/sys/windows/mod.rs +++ b/library/std/src/sys/windows/mod.rs @@ -4,7 +4,6 @@ use crate::ffi::{OsStr, OsString}; use crate::io::ErrorKind; use crate::os::windows::ffi::{OsStrExt, OsStringExt}; use crate::path::PathBuf; -use crate::ptr; use crate::time::Duration; pub use self::rand::hashmap_random_keys; @@ -206,58 +205,6 @@ fn os2path(s: &[u16]) -> PathBuf { PathBuf::from(OsString::from_wide(s)) } -#[allow(dead_code)] // Only used in backtrace::gnu::get_executable_filename() -fn wide_char_to_multi_byte( - code_page: u32, - flags: u32, - s: &[u16], - no_default_char: bool, -) -> crate::io::Result<Vec<i8>> { - unsafe { - let mut size = c::WideCharToMultiByte( - code_page, - flags, - s.as_ptr(), - s.len() as i32, - ptr::null_mut(), - 0, - ptr::null(), - ptr::null_mut(), - ); - if size == 0 { - return Err(crate::io::Error::last_os_error()); - } - - let mut buf = Vec::with_capacity(size as usize); - buf.set_len(size as usize); - - let mut used_default_char = c::FALSE; - size = c::WideCharToMultiByte( - code_page, - flags, - s.as_ptr(), - s.len() as i32, - buf.as_mut_ptr(), - buf.len() as i32, - ptr::null(), - if no_default_char { &mut used_default_char } else { ptr::null_mut() }, - ); - if size == 0 { - return Err(crate::io::Error::last_os_error()); - } - if no_default_char && used_default_char == c::TRUE { - return Err(crate::io::Error::new( - crate::io::ErrorKind::InvalidData, - "string cannot be converted to requested code page", - )); - } - - buf.set_len(size as usize); - - Ok(buf) - } -} - pub fn truncate_utf16_at_nul(v: &[u16]) -> &[u16] { match unrolled_find_u16s(0, v) { // don't include the 0 diff --git a/library/std/src/sys/windows/time.rs b/library/std/src/sys/windows/time.rs index 900260169c7..91e4f765484 100644 --- a/library/std/src/sys/windows/time.rs +++ b/library/std/src/sys/windows/time.rs @@ -165,7 +165,7 @@ fn intervals2dur(intervals: u64) -> Duration { mod perf_counter { use super::NANOS_PER_SEC; - use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst}; + use crate::sync::atomic::{AtomicU64, Ordering}; use crate::sys::c; use crate::sys::cvt; use crate::sys_common::mul_div_u64; @@ -197,27 +197,25 @@ mod perf_counter { } fn frequency() -> c::LARGE_INTEGER { - static mut FREQUENCY: c::LARGE_INTEGER = 0; - static STATE: AtomicUsize = AtomicUsize::new(0); - + // Either the cached result of `QueryPerformanceFrequency` or `0` for + // uninitialized. Storing this as a single `AtomicU64` allows us to use + // `Relaxed` operations, as we are only interested in the effects on a + // single memory location. + static FREQUENCY: AtomicU64 = AtomicU64::new(0); + + let cached = FREQUENCY.load(Ordering::Relaxed); + // If a previous thread has filled in this global state, use that. + if cached != 0 { + return cached as c::LARGE_INTEGER; + } + // ... otherwise learn for ourselves ... + let mut frequency = 0; unsafe { - // If a previous thread has filled in this global state, use that. - if STATE.load(SeqCst) == 2 { - return FREQUENCY; - } - - // ... otherwise learn for ourselves ... - let mut frequency = 0; cvt(c::QueryPerformanceFrequency(&mut frequency)).unwrap(); - - // ... and attempt to be the one thread that stores it globally for - // all other threads - if STATE.compare_exchange(0, 1, SeqCst, SeqCst).is_ok() { - FREQUENCY = frequency; - STATE.store(2, SeqCst); - } - frequency } + + FREQUENCY.store(frequency as u64, Ordering::Relaxed); + frequency } fn query() -> c::LARGE_INTEGER { diff --git a/library/std/src/sys_common/mutex.rs b/library/std/src/sys_common/mutex.rs index a1e11d24465..91d919a3f9b 100644 --- a/library/std/src/sys_common/mutex.rs +++ b/library/std/src/sys_common/mutex.rs @@ -21,7 +21,6 @@ impl StaticMutex { /// first used with any of the functions below. /// Also, the behavior is undefined if this mutex is ever used reentrantly, /// i.e., `lock` is called by the thread currently holding the lock. - #[rustc_const_stable(feature = "const_sys_mutex_new", since = "1.0.0")] pub const fn new() -> Self { Self(imp::Mutex::new()) } diff --git a/library/test/src/formatters/json.rs b/library/test/src/formatters/json.rs index 9ebc991d638..41e7e6adcf1 100644 --- a/library/test/src/formatters/json.rs +++ b/library/test/src/formatters/json.rs @@ -182,8 +182,8 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> { /// Base code taken form `libserialize::json::escape_str` struct EscapedString<S: AsRef<str>>(S); -impl<S: AsRef<str>> ::std::fmt::Display for EscapedString<S> { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { +impl<S: AsRef<str>> std::fmt::Display for EscapedString<S> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> ::std::fmt::Result { let mut start = 0; for (i, byte) in self.0.as_ref().bytes().enumerate() { diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs index 806df572cf9..ff1d82fc990 100644 --- a/library/unwind/src/libunwind.rs +++ b/library/unwind/src/libunwind.rs @@ -89,7 +89,7 @@ extern "C" { } cfg_if::cfg_if! { -if #[cfg(all(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm"))))] { +if #[cfg(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm")))] { // Not ARM EHABI #[repr(C)] #[derive(Copy, Clone, PartialEq)] |
