1313//! the [`Unsafe`] wrapper type. An `Unsafe` is intended to be used to for
1414//! struct, enum, or union fields which carry safety invariants. All accessors
1515//! are `unsafe`, which requires any use of an `Unsafe` field to be inside an
16- //! `unsafe` block.
16+ //! `unsafe` block. One exception is [`Unsafe::as_ref`], which is available when
17+ //! the `zerocopy_0_8` feature is enabled. See its docs for more information.
1718//!
1819//! An unsafe field has the type `Unsafe<O, F, const NAME_HASH: u128>`. `O` is
1920//! the enclosing type (struct, enum, or union), `F` is the type of the field,
2324//! the same enclosing type. Note that swapping the same field between instances
2425//! of the same type [cannot be prevented](crate#limitations).
2526//!
27+ //! [immutable]: zerocopy_0_8::Immutable
28+ //!
2629//! # Examples
2730//!
2831//! ```
170173 rustdoc:: missing_crate_level_docs,
171174 rustdoc:: private_intra_doc_links
172175) ]
176+ #![ cfg_attr( doc_cfg, feature( doc_cfg) ) ]
173177
174178use core:: marker:: PhantomData ;
175179
@@ -210,16 +214,41 @@ impl<O: ?Sized, F: Copy, const NAME_HASH: u128> Clone for Unsafe<O, F, { NAME_HA
210214impl < O : ?Sized , F : ?Sized , const NAME_HASH : u128 > Unsafe < O , F , { NAME_HASH } > {
211215 /// Gets a reference to the inner value.
212216 ///
217+ /// If [`F: Immutable`][immutable], prefer [`as_ref`], which is safe.
218+ ///
219+ /// [immutable]: zerocopy_0_8::Immutable
220+ /// [`as_ref`]: Unsafe::as_ref
221+ ///
213222 /// # Safety
214223 ///
215224 /// The caller is responsible for upholding any safety invariants associated
216225 /// with this field.
217226 #[ inline( always) ]
218- pub const unsafe fn as_ref ( & self ) -> & F {
227+ pub const unsafe fn as_ref_unchecked ( & self ) -> & F {
219228 // SAFETY: This method is unsafe to call.
220229 & self . field
221230 }
222231
232+ /// Gets a reference to the inner value safely so long as the inner value is
233+ /// immutable.
234+ ///
235+ /// If [`F: Immutable`][immutable], then `F` does not permit interior
236+ /// mutation, and so it is safe to return a reference to it.
237+ ///
238+ /// [immutable]: zerocopy_0_8::Immutable
239+ #[ inline( always) ]
240+ #[ cfg( feature = "zerocopy_0_8" ) ]
241+ #[ cfg_attr( doc_cfg, doc( cfg( feature = "zerocopy_0_8" ) ) ) ]
242+ pub const fn as_ref ( & self ) -> & F
243+ where
244+ F : zerocopy_0_8:: Immutable ,
245+ {
246+ // SAFETY: `F: Immutable` guarantees that the returned `&F` cannot be
247+ // used to mutate `self`, and so it cannot be used to violate any
248+ // invariant.
249+ unsafe { self . as_ref_unchecked ( ) }
250+ }
251+
223252 /// Gets a mutable reference to the inner value.
224253 ///
225254 /// # Safety
@@ -234,7 +263,7 @@ impl<O: ?Sized, F: ?Sized, const NAME_HASH: u128> Unsafe<O, F, { NAME_HASH }> {
234263}
235264
236265impl < O : ?Sized , F , const NAME_HASH : u128 > Unsafe < O , F , { NAME_HASH } > {
237- /// Constructs a new `Unsafe<O, F, NAME_HASH> `.
266+ /// Constructs a new `Unsafe`.
238267 ///
239268 /// # Safety
240269 ///
@@ -247,13 +276,8 @@ impl<O: ?Sized, F, const NAME_HASH: u128> Unsafe<O, F, { NAME_HASH }> {
247276 }
248277
249278 /// Extracts the inner `F` from `self`.
250- ///
251- /// # Safety
252- ///
253- /// The caller is responsible for upholding any safety invariants associated
254- /// with this field.
255279 #[ inline( always) ]
256- pub const unsafe fn into ( self ) -> F {
280+ pub const fn into ( self ) -> F {
257281 use core:: mem:: ManuallyDrop ;
258282 let slf = ManuallyDrop :: new ( self ) ;
259283
@@ -280,8 +304,6 @@ impl<O: ?Sized, F, const NAME_HASH: u128> Unsafe<O, F, { NAME_HASH }> {
280304 // validity as `T`
281305 let dst = unsafe { Transmute { src : slf } . dst } ;
282306
283- // SAFETY (satisfaction of `Unsafe`'s field invariant): This method is
284- // unsafe to call.
285307 ManuallyDrop :: into_inner ( dst)
286308 }
287309}
0 commit comments