@@ -777,8 +777,51 @@ where
777777
778778/// Convert a reference to a raw pointer. 
779779/// 
780- /// This is equivalent to `r as *const T`, but is a bit safer since it will never silently change 
781- /// type or mutability, in particular if the code is refactored. 
780+ /// For `r: &T`, `from_ref(r)` is equivalent to `r as *const T` (except for the caveat noted below), 
781+ /// but is a bit safer since it will never silently change type or mutability, in particular if the 
782+ /// code is refactored. 
783+ /// 
784+ /// The caller must ensure that the pointee outlives the pointer this function returns, or else it 
785+ /// will end up dangling. 
786+ /// 
787+ /// The caller must also ensure that the memory the pointer (non-transitively) points to is never 
788+ /// written to (except inside an `UnsafeCell`) using this pointer or any pointer derived from it. If 
789+ /// you need to mutate the pointee, use [`from_mut`]`. Specifically, to turn a mutable reference `m: 
790+ /// &mut T` into `*const T`, prefer `from_mut(m).cast_const()` to obtain a pointer that can later be 
791+ /// used for mutation. 
792+ /// 
793+ /// ## Interaction with lifetime extension 
794+ /// 
795+ /// Note that this has subtle interactions with the rules for lifetime extension of temporaries in 
796+ /// tail expressions. This code is valid, albeit in a non-obvious way: 
797+ /// ```rust 
798+ /// # type T = i32; 
799+ /// # fn foo() -> T { 42 } 
800+ /// // The temporary holding the return value of `foo` has its lifetime extended, 
801+ /// // because the surrounding expression involves no function call. 
802+ /// let p = &foo() as *const T; 
803+ /// unsafe { p.read() }; 
804+ /// ``` 
805+ /// Naively replacing the cast with `from_ref` is not valid: 
806+ /// ```rust,no_run 
807+ /// # use std::ptr; 
808+ /// # type T = i32; 
809+ /// # fn foo() -> T { 42 } 
810+ /// // The temporary holding the return value of `foo` does *not* have its lifetime extended, 
811+ /// // because the surrounding expression involves no function call. 
812+ /// let p = ptr::from_ref(&foo()); 
813+ /// unsafe { p.read() }; // UB! Reading from a dangling pointer ⚠️ 
814+ /// ``` 
815+ /// The recommended way to write this code is to avoid relying on lifetime extension 
816+ /// when raw pointers are involved: 
817+ /// ```rust 
818+ /// # use std::ptr; 
819+ /// # type T = i32; 
820+ /// # fn foo() -> T { 42 } 
821+ /// let x = foo(); 
822+ /// let p = ptr::from_ref(&x); 
823+ /// unsafe { p.read() }; 
824+ /// ``` 
782825#[ inline( always) ]  
783826#[ must_use]  
784827#[ stable( feature = "ptr_from_ref" ,  since = "1.76.0" ) ]  
@@ -791,8 +834,45 @@ pub const fn from_ref<T: ?Sized>(r: &T) -> *const T {
791834
792835/// Convert a mutable reference to a raw pointer. 
793836/// 
794- /// This is equivalent to `r as *mut T`, but is a bit safer since it will never silently change 
795- /// type or mutability, in particular if the code is refactored. 
837+ /// For `r: &mut T`, `from_mut(r)` is equivalent to `r as *mut T` (except for the caveat noted 
838+ /// below), but is a bit safer since it will never silently change type or mutability, in particular 
839+ /// if the code is refactored. 
840+ /// 
841+ /// The caller must ensure that the pointee outlives the pointer this function returns, or else it 
842+ /// will end up dangling. 
843+ /// 
844+ /// ## Interaction with lifetime extension 
845+ /// 
846+ /// Note that this has subtle interactions with the rules for lifetime extension of temporaries in 
847+ /// tail expressions. This code is valid, albeit in a non-obvious way: 
848+ /// ```rust 
849+ /// # type T = i32; 
850+ /// # fn foo() -> T { 42 } 
851+ /// // The temporary holding the return value of `foo` has its lifetime extended, 
852+ /// // because the surrounding expression involves no function call. 
853+ /// let p = &mut foo() as *mut T; 
854+ /// unsafe { p.write(T::default()) }; 
855+ /// ``` 
856+ /// Naively replacing the cast with `from_mut` is not valid: 
857+ /// ```rust,no_run 
858+ /// # use std::ptr; 
859+ /// # type T = i32; 
860+ /// # fn foo() -> T { 42 } 
861+ /// // The temporary holding the return value of `foo` does *not* have its lifetime extended, 
862+ /// // because the surrounding expression involves no function call. 
863+ /// let p = ptr::from_mut(&mut foo()); 
864+ /// unsafe { p.write(T::default()) }; // UB! Writing to a dangling pointer ⚠️ 
865+ /// ``` 
866+ /// The recommended way to write this code is to avoid relying on lifetime extension 
867+ /// when raw pointers are involved: 
868+ /// ```rust 
869+ /// # use std::ptr; 
870+ /// # type T = i32; 
871+ /// # fn foo() -> T { 42 } 
872+ /// let mut x = foo(); 
873+ /// let p = ptr::from_mut(&mut x); 
874+ /// unsafe { p.write(T::default()) }; 
875+ /// ``` 
796876#[ inline( always) ]  
797877#[ must_use]  
798878#[ stable( feature = "ptr_from_ref" ,  since = "1.76.0" ) ]  
0 commit comments