Rollup merge of #125897 - RalfJung:from-ref, r=Amanieu · model-checking/verify-rust-std@d6f970a (original) (raw)
`@@ -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 Tinto
*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")]
`