Skip to content

Commit e869b81

Browse files
committed
address remaining remarks and add example for dropping unaligned data
1 parent 1ec66fb commit e869b81

File tree

2 files changed

+35
-7
lines changed

2 files changed

+35
-7
lines changed

src/libcore/intrinsics.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,10 +1117,10 @@ extern "rust-intrinsic" {
11171117
///
11181118
/// * `dst` must be properly aligned.
11191119
///
1120-
/// Additionally, the caller must ensure that writing `count *
1120+
/// Additionally, the caller should ensure that writing `count *
11211121
/// size_of::<T>()` bytes to the given region of memory results in a valid
1122-
/// value of `T`. Creating an invalid value of `T` can result in undefined
1123-
/// behavior.
1122+
/// value of `T`. Using a region of memory typed as a `T` that contains an
1123+
/// invalid value of `T` is undefined behavior.
11241124
///
11251125
/// Note that even if the effectively copied size (`count * size_of::<T>()`) is
11261126
/// `0`, the pointer must be non-NULL and properly aligned.

src/libcore/ptr.rs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,9 @@ pub use intrinsics::write_bytes;
106106
///
107107
/// * `to_drop` must be [valid] for reads.
108108
///
109-
/// * `to_drop` must be properly aligned.
109+
/// * `to_drop` must be properly aligned. See the example below for how to drop
110+
/// an unaligned pointer.
111+
110112
///
111113
/// Additionally, if `T` is not [`Copy`], using the pointed-to value after
112114
/// calling `drop_in_place` can cause undefined behavior. Note that `*to_drop =
@@ -137,6 +139,7 @@ pub use intrinsics::write_bytes;
137139
/// // Without a call `drop_in_place`, the last item would never be dropped,
138140
/// // and the memory it manages would be leaked.
139141
/// ptr::drop_in_place(&mut v[1]);
142+
/// // Shorten `v` to prevent the last item from being dropped.
140143
/// v.set_len(1);
141144
/// }
142145
///
@@ -145,6 +148,31 @@ pub use intrinsics::write_bytes;
145148
/// // Ensure that the last item was dropped.
146149
/// assert!(weak.upgrade().is_none());
147150
/// ```
151+
///
152+
/// Drops a potentially unaligned value by copying it to aligned memory first:
153+
/// ```
154+
/// use std::ptr;
155+
/// use std::mem;
156+
///
157+
/// unsafe fn drop_after_copy<T>(to_drop: *mut T) {
158+
/// let mut copy: T = mem::uninitialized();
159+
/// let copy = &mut copy as *mut T;
160+
/// ptr::copy(to_drop, copy, 1);
161+
/// ptr::drop_in_place(copy);
162+
/// }
163+
///
164+
/// #[repr(packed, C)]
165+
/// struct Packed {
166+
/// _padding: u8,
167+
/// unaligned: Vec<i32>,
168+
/// }
169+
///
170+
/// let mut p = Packed { _padding: 0, unaligned: vec![42] };
171+
/// unsafe {
172+
/// drop_after_copy(&mut p.unaligned as *mut _);
173+
/// mem::forget(p);
174+
/// }
175+
/// ```
148176
#[stable(feature = "drop_in_place", since = "1.8.0")]
149177
#[lang = "drop_in_place"]
150178
#[allow(unconditional_recursion)]
@@ -601,7 +629,7 @@ pub unsafe fn read_unaligned<T>(src: *const T) -> T {
601629
/// dropping the old value.
602630
///
603631
/// `write` does not drop the contents of `dst`. This is safe, but it could leak
604-
/// allocations or resources, so care must be taken not to overwrite an object
632+
/// allocations or resources, so care should be taken not to overwrite an object
605633
/// that should be dropped.
606634
///
607635
/// Additionally, it does not drop `src`. Semantically, `src` is moved into the
@@ -676,7 +704,7 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
676704
/// Unlike [`write`], the pointer may be unaligned.
677705
///
678706
/// `write_unaligned` does not drop the contents of `dst`. This is safe, but it
679-
/// could leak allocations or resources, so care must be taken not to overwrite
707+
/// could leak allocations or resources, so care should be taken not to overwrite
680708
/// an object that should be dropped.
681709
///
682710
/// Additionally, it does not drop `src`. Semantically, `src` is moved into the
@@ -820,7 +848,7 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
820848
/// [`read_volatile`].
821849
///
822850
/// `write_volatile` does not drop the contents of `dst`. This is safe, but it
823-
/// could leak allocations or resources, so care must be taken not to overwrite
851+
/// could leak allocations or resources, so care should be taken not to overwrite
824852
/// an object that should be dropped.
825853
///
826854
/// Additionally, it does not drop `src`. Semantically, `src` is moved into the

0 commit comments

Comments
 (0)