Skip to content

Commit ea74e65

Browse files
committed
Auto merge of rust-lang#84956 - RalfJung:rollup-m70mx2n, r=RalfJung
Rollup of 11 pull requests Successful merges: - rust-lang#83553 (Update `ptr` docs with regards to `ptr::addr_of!`) - rust-lang#84183 (Update RELEASES.md for 1.52.0) - rust-lang#84709 (Add doc alias for `chdir` to `std::env::set_current_dir`) - rust-lang#84803 (Reduce duplication in `impl_dep_tracking_hash` macros) - rust-lang#84808 (Account for unsatisfied bounds in E0599) - rust-lang#84843 (use else if in std library ) - rust-lang#84865 (rustbuild: Pass a `threads` flag that works to windows-gnu lld) - rust-lang#84878 (Clarify documentation for `[T]::contains`) - rust-lang#84882 (platform-support: Center the contents of the `std` and `host` columns) - rust-lang#84903 (Remove `rustc_middle::mir::interpret::CheckInAllocMsg::NullPointerTest`) - rust-lang#84913 (Do not ICE on invalid const param) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents e960155 + 7b5cb2f commit ea74e65

File tree

5 files changed

+52
-47
lines changed

5 files changed

+52
-47
lines changed

core/src/ptr/mod.rs

Lines changed: 23 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -720,9 +720,6 @@ pub const unsafe fn read<T>(src: *const T) -> T {
720720
///
721721
/// ## On `packed` structs
722722
///
723-
/// It is currently impossible to create raw pointers to unaligned fields
724-
/// of a packed struct.
725-
///
726723
/// Attempting to create a raw pointer to an `unaligned` struct field with
727724
/// an expression such as `&packed.unaligned as *const FieldType` creates an
728725
/// intermediate unaligned reference before converting that to a raw pointer.
@@ -731,9 +728,13 @@ pub const unsafe fn read<T>(src: *const T) -> T {
731728
/// As a result, using `&packed.unaligned as *const FieldType` causes immediate
732729
/// *undefined behavior* in your program.
733730
///
731+
/// Instead you must use the [`ptr::addr_of!`](addr_of) macro to
732+
/// create the pointer. You may use that returned pointer together with this
733+
/// function.
734+
///
734735
/// An example of what not to do and how this relates to `read_unaligned` is:
735736
///
736-
/// ```no_run
737+
/// ```
737738
/// #[repr(packed, C)]
738739
/// struct Packed {
739740
/// _padding: u8,
@@ -745,24 +746,15 @@ pub const unsafe fn read<T>(src: *const T) -> T {
745746
/// unaligned: 0x01020304,
746747
/// };
747748
///
748-
/// #[allow(unaligned_references)]
749-
/// let v = unsafe {
750-
/// // Here we attempt to take the address of a 32-bit integer which is not aligned.
751-
/// let unaligned =
752-
/// // A temporary unaligned reference is created here which results in
753-
/// // undefined behavior regardless of whether the reference is used or not.
754-
/// &packed.unaligned
755-
/// // Casting to a raw pointer doesn't help; the mistake already happened.
756-
/// as *const u32;
749+
/// // Take the address of a 32-bit integer which is not aligned.
750+
/// // In contrast to `&packed.unaligned as *const _`, this has no undefined behavior.
751+
/// let unaligned = std::ptr::addr_of!(packed.unaligned);
757752
///
758-
/// let v = std::ptr::read_unaligned(unaligned);
759-
///
760-
/// v
761-
/// };
753+
/// let v = unsafe { std::ptr::read_unaligned(unaligned) };
754+
/// assert_eq!(v, 0x01020304);
762755
/// ```
763756
///
764757
/// Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however.
765-
// FIXME: Update docs based on outcome of RFC #2582 and friends.
766758
///
767759
/// # Examples
768760
///
@@ -916,9 +908,6 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
916908
///
917909
/// ## On `packed` structs
918910
///
919-
/// It is currently impossible to create raw pointers to unaligned fields
920-
/// of a packed struct.
921-
///
922911
/// Attempting to create a raw pointer to an `unaligned` struct field with
923912
/// an expression such as `&packed.unaligned as *const FieldType` creates an
924913
/// intermediate unaligned reference before converting that to a raw pointer.
@@ -927,36 +916,32 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
927916
/// As a result, using `&packed.unaligned as *const FieldType` causes immediate
928917
/// *undefined behavior* in your program.
929918
///
930-
/// An example of what not to do and how this relates to `write_unaligned` is:
919+
/// Instead you must use the [`ptr::addr_of_mut!`](addr_of_mut)
920+
/// macro to create the pointer. You may use that returned pointer together with
921+
/// this function.
922+
///
923+
/// An example of how to do it and how this relates to `write_unaligned` is:
931924
///
932-
/// ```no_run
925+
/// ```
933926
/// #[repr(packed, C)]
934927
/// struct Packed {
935928
/// _padding: u8,
936929
/// unaligned: u32,
937930
/// }
938931
///
939-
/// let v = 0x01020304;
940932
/// let mut packed: Packed = unsafe { std::mem::zeroed() };
941933
///
942-
/// #[allow(unaligned_references)]
943-
/// let v = unsafe {
944-
/// // Here we attempt to take the address of a 32-bit integer which is not aligned.
945-
/// let unaligned =
946-
/// // A temporary unaligned reference is created here which results in
947-
/// // undefined behavior regardless of whether the reference is used or not.
948-
/// &mut packed.unaligned
949-
/// // Casting to a raw pointer doesn't help; the mistake already happened.
950-
/// as *mut u32;
934+
/// // Take the address of a 32-bit integer which is not aligned.
935+
/// // In contrast to `&packed.unaligned as *mut _`, this has no undefined behavior.
936+
/// let unaligned = std::ptr::addr_of_mut!(packed.unaligned);
951937
///
952-
/// std::ptr::write_unaligned(unaligned, v);
938+
/// unsafe { std::ptr::write_unaligned(unaligned, 42) };
953939
///
954-
/// v
955-
/// };
940+
/// assert_eq!({packed.unaligned}, 42); // `{...}` forces copying the field instead of creating a reference.
956941
/// ```
957942
///
958-
/// Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however.
959-
// FIXME: Update docs based on outcome of RFC #2582 and friends.
943+
/// Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however
944+
/// (as can be seen in the `assert_eq!` above).
960945
///
961946
/// # Examples
962947
///

core/src/slice/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1948,8 +1948,9 @@ impl<T> [T] {
19481948
/// assert!(!v.contains(&50));
19491949
/// ```
19501950
///
1951-
/// If you do not have an `&T`, but just an `&U` such that `T: Borrow<U>`
1952-
/// (e.g. `String: Borrow<str>`), you can use `iter().any`:
1951+
/// If you do not have a `&T`, but some other value that you can compare
1952+
/// with one (for example, `String` implements `PartialEq<str>`), you can
1953+
/// use `iter().any`:
19531954
///
19541955
/// ```
19551956
/// let v = [String::from("hello"), String::from("world")]; // slice of `String`

core/src/time.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -518,13 +518,11 @@ impl Duration {
518518
if let Some(mut secs) = self.secs.checked_sub(rhs.secs) {
519519
let nanos = if self.nanos >= rhs.nanos {
520520
self.nanos - rhs.nanos
521+
} else if let Some(sub_secs) = secs.checked_sub(1) {
522+
secs = sub_secs;
523+
self.nanos + NANOS_PER_SEC - rhs.nanos
521524
} else {
522-
if let Some(sub_secs) = secs.checked_sub(1) {
523-
secs = sub_secs;
524-
self.nanos + NANOS_PER_SEC - rhs.nanos
525-
} else {
526-
return None;
527-
}
525+
return None;
528526
};
529527
debug_assert!(nanos < NANOS_PER_SEC);
530528
Some(Duration { secs, nanos })

std/src/env.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ pub fn current_dir() -> io::Result<PathBuf> {
6161
/// assert!(env::set_current_dir(&root).is_ok());
6262
/// println!("Successfully changed working directory to {}!", root.display());
6363
/// ```
64+
#[doc(alias = "chdir")]
6465
#[stable(feature = "env", since = "1.0.0")]
6566
pub fn set_current_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
6667
os_imp::chdir(path.as_ref())

std/src/primitive_docs.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,27 @@ mod prim_unit {}
445445
/// Note that here the call to [`drop`] is for clarity - it indicates
446446
/// that we are done with the given value and it should be destroyed.
447447
///
448-
/// ## 3. Get it from C.
448+
/// ## 3. Create it using `ptr::addr_of!`
449+
///
450+
/// Instead of coercing a reference to a raw pointer, you can use the macros
451+
/// [`ptr::addr_of!`] (for `*const T`) and [`ptr::addr_of_mut!`] (for `*mut T`).
452+
/// These macros allow you to create raw pointers to fields to which you cannot
453+
/// create a reference (without causing undefined behaviour), such as an
454+
/// unaligned field. This might be necessary if packed structs or uninitialized
455+
/// memory is involved.
456+
///
457+
/// ```
458+
/// #[derive(Debug, Default, Copy, Clone)]
459+
/// #[repr(C, packed)]
460+
/// struct S {
461+
/// aligned: u8,
462+
/// unaligned: u32,
463+
/// }
464+
/// let s = S::default();
465+
/// let p = std::ptr::addr_of!(s.unaligned); // not allowed with coercion
466+
/// ```
467+
///
468+
/// ## 4. Get it from C.
449469
///
450470
/// ```
451471
/// # #![feature(rustc_private)]

0 commit comments

Comments
 (0)