Skip to content

Commit 8f49327

Browse files
author
The Miri Cronjob Bot
committed
Merge ref '1553adfe6884' from rust-lang/rust
Pull recent changes from https://github.com/rust-lang/rust via Josh. Upstream ref: 1553adf Filtered ref: e5ee70aa5f36dacdc6df9490e867c45aa4e51c18 This merge was created using https://github.com/rust-lang/josh-sync.
2 parents f8272af + aad53ec commit 8f49327

File tree

29 files changed

+1451
-1505
lines changed

29 files changed

+1451
-1505
lines changed

alloc/src/collections/btree/map.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ pub(super) const MIN_LEN: usize = node::MIN_LEN_AFTER_SPLIT;
135135
/// ]);
136136
/// ```
137137
///
138+
/// ## `Entry` API
139+
///
138140
/// `BTreeMap` implements an [`Entry API`], which allows for complex
139141
/// methods of getting, setting, updating and removing keys and their values:
140142
///

alloc/src/vec/mod.rs

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,27 @@
4949
//! v[1] = v[1] + 5;
5050
//! ```
5151
//!
52+
//! # Memory layout
53+
//!
54+
//! When the type is non-zero-sized and the capacity is nonzero, [`Vec`] uses the [`Global`]
55+
//! allocator for its allocation. It is valid to convert both ways between such a [`Vec`] and a raw
56+
//! pointer allocated with the [`Global`] allocator, provided that the [`Layout`] used with the
57+
//! allocator is correct for a sequence of `capacity` elements of the type, and the first `len`
58+
//! values pointed to by the raw pointer are valid. More precisely, a `ptr: *mut T` that has been
59+
//! allocated with the [`Global`] allocator with [`Layout::array::<T>(capacity)`][Layout::array] may
60+
//! be converted into a vec using
61+
//! [`Vec::<T>::from_raw_parts(ptr, len, capacity)`](Vec::from_raw_parts). Conversely, the memory
62+
//! backing a `value: *mut T` obtained from [`Vec::<T>::as_mut_ptr`] may be deallocated using the
63+
//! [`Global`] allocator with the same layout.
64+
//!
65+
//! For zero-sized types (ZSTs), or when the capacity is zero, the `Vec` pointer must be non-null
66+
//! and sufficiently aligned. The recommended way to build a `Vec` of ZSTs if [`vec!`] cannot be
67+
//! used is to use [`ptr::NonNull::dangling`].
68+
//!
5269
//! [`push`]: Vec::push
70+
//! [`ptr::NonNull::dangling`]: NonNull::dangling
71+
//! [`Layout`]: crate::alloc::Layout
72+
//! [Layout::array]: crate::alloc::Layout::array
5373
5474
#![stable(feature = "rust1", since = "1.0.0")]
5575

@@ -523,18 +543,23 @@ impl<T> Vec<T> {
523543
/// This is highly unsafe, due to the number of invariants that aren't
524544
/// checked:
525545
///
526-
/// * `ptr` must have been allocated using the global allocator, such as via
527-
/// the [`alloc::alloc`] function.
528-
/// * `T` needs to have the same alignment as what `ptr` was allocated with.
546+
/// * If `T` is not a zero-sized type and the capacity is nonzero, `ptr` must have
547+
/// been allocated using the global allocator, such as via the [`alloc::alloc`]
548+
/// function. If `T` is a zero-sized type or the capacity is zero, `ptr` need
549+
/// only be non-null and aligned.
550+
/// * `T` needs to have the same alignment as what `ptr` was allocated with,
551+
/// if the pointer is required to be allocated.
529552
/// (`T` having a less strict alignment is not sufficient, the alignment really
530553
/// needs to be equal to satisfy the [`dealloc`] requirement that memory must be
531554
/// allocated and deallocated with the same layout.)
532-
/// * The size of `T` times the `capacity` (ie. the allocated size in bytes) needs
533-
/// to be the same size as the pointer was allocated with. (Because similar to
534-
/// alignment, [`dealloc`] must be called with the same layout `size`.)
555+
/// * The size of `T` times the `capacity` (ie. the allocated size in bytes), if
556+
/// nonzero, needs to be the same size as the pointer was allocated with.
557+
/// (Because similar to alignment, [`dealloc`] must be called with the same
558+
/// layout `size`.)
535559
/// * `length` needs to be less than or equal to `capacity`.
536560
/// * The first `length` values must be properly initialized values of type `T`.
537-
/// * `capacity` needs to be the capacity that the pointer was allocated with.
561+
/// * `capacity` needs to be the capacity that the pointer was allocated with,
562+
/// if the pointer is required to be allocated.
538563
/// * The allocated size in bytes must be no larger than `isize::MAX`.
539564
/// See the safety documentation of [`pointer::offset`].
540565
///
@@ -770,12 +795,16 @@ impl<T> Vec<T> {
770795
/// order as the arguments to [`from_raw_parts`].
771796
///
772797
/// After calling this function, the caller is responsible for the
773-
/// memory previously managed by the `Vec`. The only way to do
774-
/// this is to convert the raw pointer, length, and capacity back
775-
/// into a `Vec` with the [`from_raw_parts`] function, allowing
776-
/// the destructor to perform the cleanup.
798+
/// memory previously managed by the `Vec`. Most often, one does
799+
/// this by converting the raw pointer, length, and capacity back
800+
/// into a `Vec` with the [`from_raw_parts`] function; more generally,
801+
/// if `T` is non-zero-sized and the capacity is nonzero, one may use
802+
/// any method that calls [`dealloc`] with a layout of
803+
/// `Layout::array::<T>(capacity)`; if `T` is zero-sized or the
804+
/// capacity is zero, nothing needs to be done.
777805
///
778806
/// [`from_raw_parts`]: Vec::from_raw_parts
807+
/// [`dealloc`]: crate::alloc::GlobalAlloc::dealloc
779808
///
780809
/// # Examples
781810
///
@@ -1755,6 +1784,12 @@ impl<T, A: Allocator> Vec<T, A> {
17551784
/// may still invalidate this pointer.
17561785
/// See the second example below for how this guarantee can be used.
17571786
///
1787+
/// The method also guarantees that, as long as `T` is not zero-sized and the capacity is
1788+
/// nonzero, the pointer may be passed into [`dealloc`] with a layout of
1789+
/// `Layout::array::<T>(capacity)` in order to deallocate the backing memory. If this is done,
1790+
/// be careful not to run the destructor of the `Vec`, as dropping it will result in
1791+
/// double-frees. Wrapping the `Vec` in a [`ManuallyDrop`] is the typical way to achieve this.
1792+
///
17581793
/// # Examples
17591794
///
17601795
/// ```
@@ -1787,9 +1822,24 @@ impl<T, A: Allocator> Vec<T, A> {
17871822
/// }
17881823
/// ```
17891824
///
1825+
/// Deallocating a vector using [`Box`] (which uses [`dealloc`] internally):
1826+
///
1827+
/// ```
1828+
/// use std::mem::{ManuallyDrop, MaybeUninit};
1829+
///
1830+
/// let mut v = ManuallyDrop::new(vec![0, 1, 2]);
1831+
/// let ptr = v.as_mut_ptr();
1832+
/// let capacity = v.capacity();
1833+
/// let slice_ptr: *mut [MaybeUninit<i32>] =
1834+
/// std::ptr::slice_from_raw_parts_mut(ptr.cast(), capacity);
1835+
/// drop(unsafe { Box::from_raw(slice_ptr) });
1836+
/// ```
1837+
///
17901838
/// [`as_mut_ptr`]: Vec::as_mut_ptr
17911839
/// [`as_ptr`]: Vec::as_ptr
17921840
/// [`as_non_null`]: Vec::as_non_null
1841+
/// [`dealloc`]: crate::alloc::GlobalAlloc::dealloc
1842+
/// [`ManuallyDrop`]: core::mem::ManuallyDrop
17931843
#[stable(feature = "vec_as_ptr", since = "1.37.0")]
17941844
#[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
17951845
#[rustc_never_returns_null_ptr]

core/src/char/methods.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -920,7 +920,11 @@ impl char {
920920
#[stable(feature = "rust1", since = "1.0.0")]
921921
#[inline]
922922
pub fn is_alphanumeric(self) -> bool {
923-
self.is_alphabetic() || self.is_numeric()
923+
if self.is_ascii() {
924+
self.is_ascii_alphanumeric()
925+
} else {
926+
unicode::Alphabetic(self) || unicode::N(self)
927+
}
924928
}
925929

926930
/// Returns `true` if this `char` has the general category for control codes.

core/src/clone.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,34 @@ mod uninit;
139139
/// // Note: With the manual implementations the above line will compile.
140140
/// ```
141141
///
142+
/// ## `Clone` and `PartialEq`/`Eq`
143+
/// `Clone` is intended for the duplication of objects. Consequently, when implementing
144+
/// both `Clone` and [`PartialEq`], the following property is expected to hold:
145+
/// ```text
146+
/// x == x -> x.clone() == x
147+
/// ```
148+
/// In other words, if an object compares equal to itself,
149+
/// its clone must also compare equal to the original.
150+
///
151+
/// For types that also implement [`Eq`] – for which `x == x` always holds –
152+
/// this implies that `x.clone() == x` must always be true.
153+
/// Standard library collections such as
154+
/// [`HashMap`], [`HashSet`], [`BTreeMap`], [`BTreeSet`] and [`BinaryHeap`]
155+
/// rely on their keys respecting this property for correct behavior.
156+
/// Furthermore, these collections require that cloning a key preserves the outcome of the
157+
/// [`Hash`] and [`Ord`] methods. Thankfully, this follows automatically from `x.clone() == x`
158+
/// if `Hash` and `Ord` are correctly implemented according to their own requirements.
159+
///
160+
/// When deriving both `Clone` and [`PartialEq`] using `#[derive(Clone, PartialEq)]`
161+
/// or when additionally deriving [`Eq`] using `#[derive(Clone, PartialEq, Eq)]`,
162+
/// then this property is automatically upheld – provided that it is satisfied by
163+
/// the underlying types.
164+
///
165+
/// Violating this property is a logic error. The behavior resulting from a logic error is not
166+
/// specified, but users of the trait must ensure that such logic errors do *not* result in
167+
/// undefined behavior. This means that `unsafe` code **must not** rely on this property
168+
/// being satisfied.
169+
///
142170
/// ## Additional implementors
143171
///
144172
/// In addition to the [implementors listed below][impls],
@@ -152,6 +180,11 @@ mod uninit;
152180
/// (even if the referent doesn't),
153181
/// while variables captured by mutable reference never implement `Clone`.
154182
///
183+
/// [`HashMap`]: ../../std/collections/struct.HashMap.html
184+
/// [`HashSet`]: ../../std/collections/struct.HashSet.html
185+
/// [`BTreeMap`]: ../../std/collections/struct.BTreeMap.html
186+
/// [`BTreeSet`]: ../../std/collections/struct.BTreeSet.html
187+
/// [`BinaryHeap`]: ../../std/collections/struct.BinaryHeap.html
155188
/// [impls]: #implementors
156189
#[stable(feature = "rust1", since = "1.0.0")]
157190
#[lang = "clone"]

core/src/internal_macros.rs

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
11
// implements the unary operator "op &T"
22
// based on "op T" where T is expected to be `Copy`able
33
macro_rules! forward_ref_unop {
4-
(impl $imp:ident, $method:ident for $t:ty) => {
5-
forward_ref_unop!(impl $imp, $method for $t,
6-
#[stable(feature = "rust1", since = "1.0.0")]);
7-
};
8-
(impl $imp:ident, $method:ident for $t:ty, #[$attr:meta]) => {
9-
#[$attr]
10-
impl $imp for &$t {
4+
(impl $imp:ident, $method:ident for $t:ty, $(#[$attr:meta])+) => {
5+
$(#[$attr])+
6+
impl const $imp for &$t {
117
type Output = <$t as $imp>::Output;
128

139
#[inline]
@@ -21,13 +17,9 @@ macro_rules! forward_ref_unop {
2117
// implements binary operators "&T op U", "T op &U", "&T op &U"
2218
// based on "T op U" where T and U are expected to be `Copy`able
2319
macro_rules! forward_ref_binop {
24-
(impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
25-
forward_ref_binop!(impl $imp, $method for $t, $u,
26-
#[stable(feature = "rust1", since = "1.0.0")]);
27-
};
28-
(impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => {
29-
#[$attr]
30-
impl<'a> $imp<$u> for &'a $t {
20+
(impl $imp:ident, $method:ident for $t:ty, $u:ty, $(#[$attr:meta])+) => {
21+
$(#[$attr])+
22+
impl const $imp<$u> for &$t {
3123
type Output = <$t as $imp<$u>>::Output;
3224

3325
#[inline]
@@ -37,8 +29,8 @@ macro_rules! forward_ref_binop {
3729
}
3830
}
3931

40-
#[$attr]
41-
impl $imp<&$u> for $t {
32+
$(#[$attr])+
33+
impl const $imp<&$u> for $t {
4234
type Output = <$t as $imp<$u>>::Output;
4335

4436
#[inline]
@@ -48,8 +40,8 @@ macro_rules! forward_ref_binop {
4840
}
4941
}
5042

51-
#[$attr]
52-
impl $imp<&$u> for &$t {
43+
$(#[$attr])+
44+
impl const $imp<&$u> for &$t {
5345
type Output = <$t as $imp<$u>>::Output;
5446

5547
#[inline]
@@ -64,13 +56,9 @@ macro_rules! forward_ref_binop {
6456
// implements "T op= &U", based on "T op= U"
6557
// where U is expected to be `Copy`able
6658
macro_rules! forward_ref_op_assign {
67-
(impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
68-
forward_ref_op_assign!(impl $imp, $method for $t, $u,
69-
#[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]);
70-
};
71-
(impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => {
72-
#[$attr]
73-
impl $imp<&$u> for $t {
59+
(impl $imp:ident, $method:ident for $t:ty, $u:ty, $(#[$attr:meta])+) => {
60+
$(#[$attr])+
61+
impl const $imp<&$u> for $t {
7462
#[inline]
7563
#[track_caller]
7664
fn $method(&mut self, other: &$u) {

0 commit comments

Comments
 (0)