Skip to content

Commit d7eb6ec

Browse files
committed
less garbage, more examples
1 parent 64e7337 commit d7eb6ec

File tree

3 files changed

+72
-6
lines changed

3 files changed

+72
-6
lines changed

library/alloc/src/vec/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1276,7 +1276,7 @@ impl<T, A: Allocator> Vec<T, A> {
12761276
/// valid for zero sized reads if the vector didn't allocate.
12771277
///
12781278
/// The caller must ensure that the vector outlives the pointer this
1279-
/// function returns, or else it will end up pointing to garbage.
1279+
/// function returns, or else it will end up dangling.
12801280
/// Modifying the vector may cause its buffer to be reallocated,
12811281
/// which would also make any pointers to it invalid.
12821282
///
@@ -1336,7 +1336,7 @@ impl<T, A: Allocator> Vec<T, A> {
13361336
/// raw pointer valid for zero sized reads if the vector didn't allocate.
13371337
///
13381338
/// The caller must ensure that the vector outlives the pointer this
1339-
/// function returns, or else it will end up pointing to garbage.
1339+
/// function returns, or else it will end up dangling.
13401340
/// Modifying the vector may cause its buffer to be reallocated,
13411341
/// which would also make any pointers to it invalid.
13421342
///

library/core/src/ptr/mod.rs

+68-2
Original file line numberDiff line numberDiff line change
@@ -781,13 +781,46 @@ where
781781
/// never silently change type or mutability, in particular if the code is refactored.
782782
///
783783
/// The caller must ensure that the pointee outlives the pointer this function returns, or else it
784-
/// will end up pointing to garbage.
784+
/// will end up dangling.
785785
///
786786
/// The caller must also ensure that the memory the pointer (non-transitively) points to is never
787787
/// written to (except inside an `UnsafeCell`) using this pointer or any pointer derived from it. If
788788
/// you need to mutate the pointee, use [`from_mut`]`. Specifically, to turn a mutable reference `m:
789789
/// &mut T` into `*const T`, prefer `from_mut(m).cast_const()` to obtain a pointer that can later be
790790
/// used for mutation.
791+
///
792+
/// ## Interaction with lifetime extension
793+
///
794+
/// Note that this has subtle interactions with the rules for lifetime extension of temporaries in
795+
/// tail expressions. This code is valid, albeit in a non-obvious way:
796+
/// ```rust
797+
/// # type T = i32;
798+
/// # fn foo() -> T { 42 }
799+
/// // The temporary holding the return value of `foo` has its lifetime extended,
800+
/// // because the surrounding expression involves no function call.
801+
/// let p = &foo() as *const T;
802+
/// unsafe { p.read() };
803+
/// ```
804+
/// This code is not valid:
805+
/// ```rust,no_run
806+
/// # use std::ptr;
807+
/// # type T = i32;
808+
/// # fn foo() -> T { 42 }
809+
/// // The temporary holding the return value of `foo` does *not* have its lifetime extended,
810+
/// // because the surrounding expression involves no function call.
811+
/// let p = ptr::from_ref(&foo());
812+
/// unsafe { p.read() }; // UB! Reading from a dangling pointer ⚠️
813+
/// ```
814+
/// The recommended way to write this code is to avoid relying on lifetime extension
815+
/// when raw pointers are involved:
816+
/// ```rust
817+
/// # use std::ptr;
818+
/// # type T = i32;
819+
/// # fn foo() -> T { 42 }
820+
/// let x = foo();
821+
/// let p = ptr::from_ref(&x);
822+
/// unsafe { p.read() };
823+
/// ```
791824
#[inline(always)]
792825
#[must_use]
793826
#[stable(feature = "ptr_from_ref", since = "1.76.0")]
@@ -801,10 +834,43 @@ pub const fn from_ref<T: ?Sized>(r: &T) -> *const T {
801834
/// Convert a mutable reference to a raw pointer.
802835
///
803836
/// The caller must ensure that the pointee outlives the pointer this function returns, or else it
804-
/// will end up pointing to garbage.
837+
/// will end up dangling.
805838
///
806839
/// For `r: &mut T`, `from_mut(r)` is equivalent to `r as *mut T`, but is a bit safer since it will
807840
/// never silently change type or mutability, in particular if the code is refactored.
841+
///
842+
/// ## Interaction with lifetime extension
843+
///
844+
/// Note that this has subtle interactions with the rules for lifetime extension of temporaries in
845+
/// tail expressions. This code is valid, albeit in a non-obvious way:
846+
/// ```rust
847+
/// # type T = i32;
848+
/// # fn foo() -> T { 42 }
849+
/// // The temporary holding the return value of `foo` has its lifetime extended,
850+
/// // because the surrounding expression involves no function call.
851+
/// let p = &mut foo() as *mut T;
852+
/// unsafe { p.write(0) };
853+
/// ```
854+
/// This code is not valid:
855+
/// ```rust,no_run
856+
/// # use std::ptr;
857+
/// # type T = i32;
858+
/// # fn foo() -> T { 42 }
859+
/// // The temporary holding the return value of `foo` does *not* have its lifetime extended,
860+
/// // because the surrounding expression involves no function call.
861+
/// let p = ptr::from_mut(&mut foo());
862+
/// unsafe { p.write(0) }; // UB! Dereferencing a dangling pointer ⚠️
863+
/// ```
864+
/// The recommended way to write this code is to avoid relying on lifetime extension
865+
/// when raw pointers are involved:
866+
/// ```rust
867+
/// # use std::ptr;
868+
/// # type T = i32;
869+
/// # fn foo() -> T { 42 }
870+
/// let mut x = foo();
871+
/// let p = ptr::from_mut(&mut x);
872+
/// unsafe { p.write(0) };
873+
/// ```
808874
#[inline(always)]
809875
#[must_use]
810876
#[stable(feature = "ptr_from_ref", since = "1.76.0")]

library/core/src/slice/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,7 @@ impl<T> [T] {
731731
/// Returns a raw pointer to the slice's buffer.
732732
///
733733
/// The caller must ensure that the slice outlives the pointer this
734-
/// function returns, or else it will end up pointing to garbage.
734+
/// function returns, or else it will end up dangling.
735735
///
736736
/// The caller must also ensure that the memory the pointer (non-transitively) points to
737737
/// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer
@@ -766,7 +766,7 @@ impl<T> [T] {
766766
/// Returns an unsafe mutable pointer to the slice's buffer.
767767
///
768768
/// The caller must ensure that the slice outlives the pointer this
769-
/// function returns, or else it will end up pointing to garbage.
769+
/// function returns, or else it will end up dangling.
770770
///
771771
/// Modifying the container referenced by this slice may cause its buffer
772772
/// to be reallocated, which would also make any pointers to it invalid.

0 commit comments

Comments
 (0)