less garbage, more examples · model-checking/verify-rust-std@dbbb4ab (original) (raw)
`@@ -777,17 +777,51 @@ where
`
777
777
``
778
778
`/// Convert a reference to a raw pointer.
`
779
779
`///
`
780
``
`` -
/// For r: &T
, from_ref(r)
is equivalent to r as *const T
, but is a bit safer since it will
``
781
``
`-
/// never silently change 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.
`
782
783
`///
`
783
784
`/// The caller must ensure that the pointee outlives the pointer this function returns, or else it
`
784
``
`-
/// will end up pointing to garbage.
`
``
785
`+
/// will end up dangling.
`
785
786
`///
`
786
787
`/// The caller must also ensure that the memory the pointer (non-transitively) points to is never
`
787
788
`` /// written to (except inside an UnsafeCell
) using this pointer or any pointer derived from it. If
``
788
789
`` /// you need to mutate the pointee, use [from_mut
]. Specifically, to turn a mutable reference
m:
``
789
790
`` /// &mut Tinto
*const T, prefer
from_mut(m).cast_const()` to obtain a pointer that can later be
``
790
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
/// ```
791
825
`#[inline(always)]
`
792
826
`#[must_use]
`
793
827
`#[stable(feature = "ptr_from_ref", since = "1.76.0")]
`
`@@ -800,11 +834,45 @@ pub const fn from_ref<T: ?Sized>(r: &T) -> *const T {
`
800
834
``
801
835
`/// Convert a mutable reference to a raw pointer.
`
802
836
`///
`
``
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
`+
///
`
803
841
`/// The caller must ensure that the pointee outlives the pointer this function returns, or else it
`
804
``
`-
/// will end up pointing to garbage.
`
``
842
`+
/// will end up dangling.
`
``
843
`+
///
`
``
844
`+
/// ## Interaction with lifetime extension
`
805
845
`///
`
806
``
`` -
/// For r: &mut T
, from_mut(r)
is equivalent to r as *mut T
, but is a bit safer since it will
``
807
``
`-
/// never silently change type or mutability, in particular if the code is refactored.
`
``
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
/// ```
808
876
`#[inline(always)]
`
809
877
`#[must_use]
`
810
878
`#[stable(feature = "ptr_from_ref", since = "1.76.0")]
`