@@ -777,8 +777,51 @@ where
777
777
778
778
/// Convert a reference to a raw pointer.
779
779
///
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
+ /// ```
782
825
#[ inline( always) ]
783
826
#[ must_use]
784
827
#[ stable( feature = "ptr_from_ref" , since = "1.76.0" ) ]
@@ -791,8 +834,45 @@ pub const fn from_ref<T: ?Sized>(r: &T) -> *const T {
791
834
792
835
/// Convert a mutable reference to a raw pointer.
793
836
///
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
+ /// ```
796
876
#[ inline( always) ]
797
877
#[ must_use]
798
878
#[ stable( feature = "ptr_from_ref" , since = "1.76.0" ) ]
0 commit comments