@@ -781,13 +781,46 @@ where
781
781
/// never silently change type or mutability, in particular if the code is refactored.
782
782
///
783
783
/// 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 .
785
785
///
786
786
/// The caller must also ensure that the memory the pointer (non-transitively) points to is never
787
787
/// written to (except inside an `UnsafeCell`) using this pointer or any pointer derived from it. If
788
788
/// you need to mutate the pointee, use [`from_mut`]`. Specifically, to turn a mutable reference `m:
789
789
/// &mut T` into `*const T`, prefer `from_mut(m).cast_const()` to obtain a pointer that can later be
790
790
/// 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
+ /// ```
791
824
#[ inline( always) ]
792
825
#[ must_use]
793
826
#[ stable( feature = "ptr_from_ref" , since = "1.76.0" ) ]
@@ -801,10 +834,43 @@ pub const fn from_ref<T: ?Sized>(r: &T) -> *const T {
801
834
/// Convert a mutable reference to a raw pointer.
802
835
///
803
836
/// 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 .
805
838
///
806
839
/// For `r: &mut T`, `from_mut(r)` is equivalent to `r as *mut T`, but is a bit safer since it will
807
840
/// 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
+ /// ```
808
874
#[ inline( always) ]
809
875
#[ must_use]
810
876
#[ stable( feature = "ptr_from_ref" , since = "1.76.0" ) ]
0 commit comments