From 3c00ffabf46f55c823d49bcff5384ed28373af10 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 11 Sep 2024 15:15:44 +0200 Subject: [PATCH 1/4] ptr::add/sub: these are *not* equivalent to offset(count as isize) --- core/src/intrinsics.rs | 3 +-- core/src/ptr/const_ptr.rs | 16 +++++++++------- core/src/ptr/mut_ptr.rs | 16 +++++++++------- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/core/src/intrinsics.rs b/core/src/intrinsics.rs index 7870a62ea81cd..22fc9f72ec414 100644 --- a/core/src/intrinsics.rs +++ b/core/src/intrinsics.rs @@ -1425,8 +1425,7 @@ extern "rust-intrinsic" { /// /// If the computed offset is non-zero, then both the starting and resulting pointer must be /// either in bounds or at the end of an allocated object. If either pointer is out - /// of bounds or arithmetic overflow occurs then any further use of the returned value will - /// result in undefined behavior. + /// of bounds or arithmetic overflow occurs then this operation is undefined behavior. /// /// The stabilized version of this intrinsic is [`pointer::offset`]. #[must_use = "returns a new pointer rather than modifying its argument"] diff --git a/core/src/ptr/const_ptr.rs b/core/src/ptr/const_ptr.rs index 3b45d46b31d5e..3df24e0d512e1 100644 --- a/core/src/ptr/const_ptr.rs +++ b/core/src/ptr/const_ptr.rs @@ -346,7 +346,7 @@ impl *const T { if self.is_null() { None } else { Some(unsafe { &*(self as *const MaybeUninit) }) } } - /// Adds an offset to a pointer. + /// Adds a signed offset to a pointer. /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer /// offset of `3 * size_of::()` bytes. @@ -355,7 +355,8 @@ impl *const T { /// /// If any of the following conditions are violated, the result is Undefined Behavior: /// - /// * The computed offset, `count * size_of::()` bytes, must not overflow `isize`. + /// * The computed offset, `count * size_of::()` bytes (using unbounded arithmetic), + /// must fit in an `isize`. /// /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some /// [allocated object], and the entire memory range between `self` and the result must be in @@ -807,7 +808,7 @@ impl *const T { } } - /// Adds an offset to a pointer (convenience for `.offset(count as isize)`). + /// Adds an offset to a pointer. /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer /// offset of `3 * size_of::()` bytes. @@ -816,7 +817,8 @@ impl *const T { /// /// If any of the following conditions are violated, the result is Undefined Behavior: /// - /// * The computed offset, `count * size_of::()` bytes, must not overflow `isize`. + /// * The computed offset, `count * size_of::()` bytes (using unbounded arithmetic), + /// must fit in an `isize`. /// /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some /// [allocated object], and the entire memory range between `self` and the result must be in @@ -880,8 +882,7 @@ impl *const T { unsafe { self.cast::().add(count).with_metadata_of(self) } } - /// Subtracts an offset from a pointer (convenience for - /// `.offset((count as isize).wrapping_neg())`). + /// Subtracts an offset from a pointer. /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer /// offset of `3 * size_of::()` bytes. @@ -890,7 +891,8 @@ impl *const T { /// /// If any of the following conditions are violated, the result is Undefined Behavior: /// - /// * The computed offset, `count * size_of::()` bytes, must not overflow `isize`. + /// * The computed offset, `count * size_of::()` bytes (using unbounded arithmetic), + /// must fit in an `isize`. /// /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some /// [allocated object], and the entire memory range between `self` and the result must be in diff --git a/core/src/ptr/mut_ptr.rs b/core/src/ptr/mut_ptr.rs index ddb9195d2e7c7..630983c8355f3 100644 --- a/core/src/ptr/mut_ptr.rs +++ b/core/src/ptr/mut_ptr.rs @@ -344,7 +344,7 @@ impl *mut T { if self.is_null() { None } else { Some(unsafe { &*(self as *const MaybeUninit) }) } } - /// Adds an offset to a pointer. + /// Adds a signed offset to a pointer. /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer /// offset of `3 * size_of::()` bytes. @@ -353,7 +353,8 @@ impl *mut T { /// /// If any of the following conditions are violated, the result is Undefined Behavior: /// - /// * The computed offset, `count * size_of::()` bytes, must not overflow `isize`. + /// * The computed offset, `count * size_of::()` bytes (using unbounded arithmetic), + /// must fit in an `isize`. /// /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some /// [allocated object], and the entire memory range between `self` and the result must be in @@ -888,7 +889,7 @@ impl *mut T { unsafe { (self as *const T).sub_ptr(origin) } } - /// Adds an offset to a pointer (convenience for `.offset(count as isize)`). + /// Adds an offset to a pointer. /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer /// offset of `3 * size_of::()` bytes. @@ -897,7 +898,8 @@ impl *mut T { /// /// If any of the following conditions are violated, the result is Undefined Behavior: /// - /// * The computed offset, `count * size_of::()` bytes, must not overflow `isize`. + /// * The computed offset, `count * size_of::()` bytes (using unbounded arithmetic), + /// must fit in an `isize`. /// /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some /// [allocated object], and the entire memory range between `self` and the result must be in @@ -961,8 +963,7 @@ impl *mut T { unsafe { self.cast::().add(count).with_metadata_of(self) } } - /// Subtracts an offset from a pointer (convenience for - /// `.offset((count as isize).wrapping_neg())`). + /// Subtracts an offset from a pointer. /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer /// offset of `3 * size_of::()` bytes. @@ -971,7 +972,8 @@ impl *mut T { /// /// If any of the following conditions are violated, the result is Undefined Behavior: /// - /// * The computed offset, `count * size_of::()` bytes, must not overflow `isize`. + /// * The computed offset, `count * size_of::()` bytes (using unbounded arithmetic), + /// must fit in an `isize`. /// /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some /// [allocated object], and the entire memory range between `self` and the result must be in From acd25269596649e44218ffc2dd0c8b8469448512 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 11 Sep 2024 20:57:05 +0200 Subject: [PATCH 2/4] various updates based on review --- core/src/ptr/const_ptr.rs | 31 +++++++++++++++++++------------ core/src/ptr/mut_ptr.rs | 31 +++++++++++++++++++------------ 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/core/src/ptr/const_ptr.rs b/core/src/ptr/const_ptr.rs index 3df24e0d512e1..afec6f8795645 100644 --- a/core/src/ptr/const_ptr.rs +++ b/core/src/ptr/const_ptr.rs @@ -355,8 +355,8 @@ impl *const T { /// /// If any of the following conditions are violated, the result is Undefined Behavior: /// - /// * The computed offset, `count * size_of::()` bytes (using unbounded arithmetic), - /// must fit in an `isize`. + /// * The offset in bytes, `count * size_of::()`, computed on mathematical integers (without + /// "wrapping around"), must fit in an `isize`. /// /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some /// [allocated object], and the entire memory range between `self` and the result must be in @@ -399,7 +399,7 @@ impl *const T { unsafe { intrinsics::offset(self, count) } } - /// Calculates the offset from a pointer in bytes. + /// Adds a signed offset in bytes to a pointer. /// /// `count` is in units of **bytes**. /// @@ -808,7 +808,11 @@ impl *const T { } } - /// Adds an offset to a pointer. + /// Adds an unsigned offset to a pointer. + /// + /// This can only move the pointer forward (or not move it). If you need to move forward or + /// backward depending on the value, then you might want [`offset`](#method.offset) instead + /// which takes a signed offset. /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer /// offset of `3 * size_of::()` bytes. @@ -817,8 +821,8 @@ impl *const T { /// /// If any of the following conditions are violated, the result is Undefined Behavior: /// - /// * The computed offset, `count * size_of::()` bytes (using unbounded arithmetic), - /// must fit in an `isize`. + /// * The offset in bytes, `count * size_of::()`, computed on mathematical integers (without + /// "wrapping around"), must fit in an `isize`. /// /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some /// [allocated object], and the entire memory range between `self` and the result must be in @@ -861,7 +865,7 @@ impl *const T { unsafe { intrinsics::offset(self, count) } } - /// Calculates the offset from a pointer in bytes (convenience for `.byte_offset(count as isize)`). + /// Adds an unsigned offset in bytes to a pointer. /// /// `count` is in units of bytes. /// @@ -882,7 +886,11 @@ impl *const T { unsafe { self.cast::().add(count).with_metadata_of(self) } } - /// Subtracts an offset from a pointer. + /// Subtracts an unsigned offset from a pointer. + /// + /// This can only move the pointer backward (or not move it). If you need to move forward or + /// backward depending on the value, then you might want [`offset`](#method.offset) instead + /// which takes a signed offset. /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer /// offset of `3 * size_of::()` bytes. @@ -891,8 +899,8 @@ impl *const T { /// /// If any of the following conditions are violated, the result is Undefined Behavior: /// - /// * The computed offset, `count * size_of::()` bytes (using unbounded arithmetic), - /// must fit in an `isize`. + /// * The offset in bytes, `count * size_of::()`, computed on mathematical integers (without + /// "wrapping around"), must fit in an `isize`. /// /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some /// [allocated object], and the entire memory range between `self` and the result must be in @@ -943,8 +951,7 @@ impl *const T { } } - /// Calculates the offset from a pointer in bytes (convenience for - /// `.byte_offset((count as isize).wrapping_neg())`). + /// Subtracts an unsigned offset in bytes from a pointer. /// /// `count` is in units of bytes. /// diff --git a/core/src/ptr/mut_ptr.rs b/core/src/ptr/mut_ptr.rs index 630983c8355f3..11fb45b1e09d9 100644 --- a/core/src/ptr/mut_ptr.rs +++ b/core/src/ptr/mut_ptr.rs @@ -353,8 +353,8 @@ impl *mut T { /// /// If any of the following conditions are violated, the result is Undefined Behavior: /// - /// * The computed offset, `count * size_of::()` bytes (using unbounded arithmetic), - /// must fit in an `isize`. + /// * The offset in bytes, `count * size_of::()`, computed on mathematical integers (without + /// "wrapping around"), must fit in an `isize`. /// /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some /// [allocated object], and the entire memory range between `self` and the result must be in @@ -399,7 +399,7 @@ impl *mut T { unsafe { intrinsics::offset(self, count) } } - /// Calculates the offset from a pointer in bytes. + /// Adds a signed offset in bytes to a pointer. /// /// `count` is in units of **bytes**. /// @@ -889,7 +889,11 @@ impl *mut T { unsafe { (self as *const T).sub_ptr(origin) } } - /// Adds an offset to a pointer. + /// Adds an unsigned offset to a pointer. + /// + /// This can only move the pointer forward (or not move it). If you need to move forward or + /// backward depending on the value, then you might want [`offset`](#method.offset) instead + /// which takes a signed offset. /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer /// offset of `3 * size_of::()` bytes. @@ -898,8 +902,8 @@ impl *mut T { /// /// If any of the following conditions are violated, the result is Undefined Behavior: /// - /// * The computed offset, `count * size_of::()` bytes (using unbounded arithmetic), - /// must fit in an `isize`. + /// * The offset in bytes, `count * size_of::()`, computed on mathematical integers (without + /// "wrapping around"), must fit in an `isize`. /// /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some /// [allocated object], and the entire memory range between `self` and the result must be in @@ -942,7 +946,7 @@ impl *mut T { unsafe { intrinsics::offset(self, count) } } - /// Calculates the offset from a pointer in bytes (convenience for `.byte_offset(count as isize)`). + /// Adds an unsigned offset in bytes to a pointer. /// /// `count` is in units of bytes. /// @@ -963,7 +967,11 @@ impl *mut T { unsafe { self.cast::().add(count).with_metadata_of(self) } } - /// Subtracts an offset from a pointer. + /// Subtracts an unsigned offset from a pointer. + /// + /// This can only move the pointer backward (or not move it). If you need to move forward or + /// backward depending on the value, then you might want [`offset`](#method.offset) instead + /// which takes a signed offset. /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer /// offset of `3 * size_of::()` bytes. @@ -972,8 +980,8 @@ impl *mut T { /// /// If any of the following conditions are violated, the result is Undefined Behavior: /// - /// * The computed offset, `count * size_of::()` bytes (using unbounded arithmetic), - /// must fit in an `isize`. + /// * The offset in bytes, `count * size_of::()`, computed on mathematical integers (without + /// "wrapping around"), must fit in an `isize`. /// /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some /// [allocated object], and the entire memory range between `self` and the result must be in @@ -1024,8 +1032,7 @@ impl *mut T { } } - /// Calculates the offset from a pointer in bytes (convenience for - /// `.byte_offset((count as isize).wrapping_neg())`). + /// Subtracts an unsigned offset in bytes from a pointer. /// /// `count` is in units of bytes. /// From 553ca3f0edaed1b9c1b508462c908b1f5e5ff606 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 12 Sep 2024 16:25:09 +0200 Subject: [PATCH 3/4] also update the wrapping_ docs to use similar wording --- core/src/ptr/const_ptr.rs | 16 ++++++---------- core/src/ptr/mut_ptr.rs | 17 +++++++---------- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/core/src/ptr/const_ptr.rs b/core/src/ptr/const_ptr.rs index afec6f8795645..57307c149a46e 100644 --- a/core/src/ptr/const_ptr.rs +++ b/core/src/ptr/const_ptr.rs @@ -420,7 +420,7 @@ impl *const T { unsafe { self.cast::().offset(count).with_metadata_of(self) } } - /// Calculates the offset from a pointer using wrapping arithmetic. + /// Adds a signed offset to a pointer using wrapping arithmetic. /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer /// offset of `3 * size_of::()` bytes. @@ -482,7 +482,7 @@ impl *const T { unsafe { intrinsics::arith_offset(self, count) } } - /// Calculates the offset from a pointer in bytes using wrapping arithmetic. + /// Adds a signed offset in bytes to a pointer using wrapping arithmetic. /// /// `count` is in units of **bytes**. /// @@ -972,8 +972,7 @@ impl *const T { unsafe { self.cast::().sub(count).with_metadata_of(self) } } - /// Calculates the offset from a pointer using wrapping arithmetic. - /// (convenience for `.wrapping_offset(count as isize)`) + /// Adds an unsigned offset to a pointer using wrapping arithmetic. /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer /// offset of `3 * size_of::()` bytes. @@ -1034,8 +1033,7 @@ impl *const T { self.wrapping_offset(count as isize) } - /// Calculates the offset from a pointer in bytes using wrapping arithmetic. - /// (convenience for `.wrapping_byte_offset(count as isize)`) + /// Adds an unsigned offset in bytes to a pointer using wrapping arithmetic. /// /// `count` is in units of bytes. /// @@ -1053,8 +1051,7 @@ impl *const T { self.cast::().wrapping_add(count).with_metadata_of(self) } - /// Calculates the offset from a pointer using wrapping arithmetic. - /// (convenience for `.wrapping_offset((count as isize).wrapping_neg())`) + /// Subtracts an unsigned offset from a pointer using wrapping arithmetic. /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer /// offset of `3 * size_of::()` bytes. @@ -1115,8 +1112,7 @@ impl *const T { self.wrapping_offset((count as isize).wrapping_neg()) } - /// Calculates the offset from a pointer in bytes using wrapping arithmetic. - /// (convenience for `.wrapping_offset((count as isize).wrapping_neg())`) + /// Subtracts an unsigned offset in bytes from a pointer using wrapping arithmetic. /// /// `count` is in units of bytes. /// diff --git a/core/src/ptr/mut_ptr.rs b/core/src/ptr/mut_ptr.rs index 11fb45b1e09d9..e09419ff1a72b 100644 --- a/core/src/ptr/mut_ptr.rs +++ b/core/src/ptr/mut_ptr.rs @@ -420,7 +420,8 @@ impl *mut T { unsafe { self.cast::().offset(count).with_metadata_of(self) } } - /// Calculates the offset from a pointer using wrapping arithmetic. + /// Adds a signed offset to a pointer using wrapping arithmetic. + /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer /// offset of `3 * size_of::()` bytes. /// @@ -479,7 +480,7 @@ impl *mut T { unsafe { intrinsics::arith_offset(self, count) as *mut T } } - /// Calculates the offset from a pointer in bytes using wrapping arithmetic. + /// Adds a signed offset in bytes to a pointer using wrapping arithmetic. /// /// `count` is in units of **bytes**. /// @@ -1053,8 +1054,7 @@ impl *mut T { unsafe { self.cast::().sub(count).with_metadata_of(self) } } - /// Calculates the offset from a pointer using wrapping arithmetic. - /// (convenience for `.wrapping_offset(count as isize)`) + /// Adds an unsigned offset to a pointer using wrapping arithmetic. /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer /// offset of `3 * size_of::()` bytes. @@ -1113,8 +1113,7 @@ impl *mut T { self.wrapping_offset(count as isize) } - /// Calculates the offset from a pointer in bytes using wrapping arithmetic. - /// (convenience for `.wrapping_byte_offset(count as isize)`) + /// Adds an unsigned offset in bytes to a pointer using wrapping arithmetic. /// /// `count` is in units of bytes. /// @@ -1132,8 +1131,7 @@ impl *mut T { self.cast::().wrapping_add(count).with_metadata_of(self) } - /// Calculates the offset from a pointer using wrapping arithmetic. - /// (convenience for `.wrapping_offset((count as isize).wrapping_neg())`) + /// Subtracts an unsigned offset from a pointer using wrapping arithmetic. /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer /// offset of `3 * size_of::()` bytes. @@ -1192,8 +1190,7 @@ impl *mut T { self.wrapping_offset((count as isize).wrapping_neg()) } - /// Calculates the offset from a pointer in bytes using wrapping arithmetic. - /// (convenience for `.wrapping_offset((count as isize).wrapping_neg())`) + /// Subtracts an unsigned offset in bytes from a pointer using wrapping arithmetic. /// /// `count` is in units of bytes. /// From 288b9ca02b0d6b26c08f7f9f9ed70b41eb016e49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Bj=C3=B8rnager=20Jensen?= Date: Sat, 28 Sep 2024 08:31:51 +0200 Subject: [PATCH 4/4] Update Unicode escapes; --- core/src/char/methods.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/src/char/methods.rs b/core/src/char/methods.rs index 3dcaab6a12beb..3f11e4fe21cc9 100644 --- a/core/src/char/methods.rs +++ b/core/src/char/methods.rs @@ -69,7 +69,7 @@ impl char { /// assert_eq!(char::from_u32(value_at_max + 1), None); /// ``` #[stable(feature = "assoc_char_consts", since = "1.52.0")] - pub const MAX: char = '\u{10ffff}'; + pub const MAX: char = '\u{10FFFF}'; /// `U+FFFD REPLACEMENT CHARACTER` (�) is used in Unicode to represent a /// decoding error. @@ -1837,7 +1837,6 @@ pub const fn encode_utf16_raw(mut code: u32, dst: &mut [u16]) -> &mut [u16] { } (2, [a, b, ..]) => { code -= 0x1_0000; - *a = (code >> 10) as u16 | 0xD800; *b = (code & 0x3FF) as u16 | 0xDC00; }