@@ -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" ) ]
0 commit comments