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")]

`