@@ -38,11 +38,45 @@ impl OnceNonZeroUsize {
38
38
}
39
39
}
40
40
41
- /// Gets the underlying value.
42
- #[ inline]
43
- pub fn get ( & self ) -> Option < NonZeroUsize > {
44
- let val = self . inner . load ( Ordering :: Acquire ) ;
45
- NonZeroUsize :: new ( val)
41
+ /// Get the reference to the underlying value, without checking if the cell
42
+ /// is initialized.
43
+ ///
44
+ /// # Safety
45
+ ///
46
+ /// Caller must ensure that the cell is in initialized state, and that
47
+ /// the contents are acquired by (synchronized to) this thread.
48
+ pub unsafe fn get_unchecked ( & self ) -> NonZeroUsize {
49
+ #[ inline( always) ]
50
+ fn as_const_ptr ( r : & AtomicUsize ) -> * const usize {
51
+ use core:: mem:: align_of;
52
+
53
+ let p: * const AtomicUsize = r;
54
+ // SAFETY: "This type has the same size and bit validity as
55
+ // the underlying integer type, usize. However, the alignment of
56
+ // this type is always equal to its size, even on targets where
57
+ // usize has a lesser alignment."
58
+ const _ALIGNMENT_COMPATIBLE: ( ) =
59
+ assert ! ( align_of:: <AtomicUsize >( ) % align_of:: <usize >( ) == 0 ) ;
60
+ p. cast :: < usize > ( )
61
+ }
62
+
63
+ // TODO(MSRV-1.70): Use `AtomicUsize::as_ptr().cast_const()`
64
+ // See https://github.com/rust-lang/rust/issues/138246.
65
+ let p = as_const_ptr ( & self . inner ) ;
66
+
67
+ // SAFETY: The caller is responsible for ensuring that the value
68
+ // was initialized and that the contents have been acquired by
69
+ // this thread. Assuming that, we can assume there will be no
70
+ // conflicting writes to the value since the value will never
71
+ // change once initialized. This relies on the statement in
72
+ // https://doc.rust-lang.org/1.83.0/core/sync/atomic/ that "(A
73
+ // `compare_exchange` or `compare_exchange_weak` that does not
74
+ // succeed is not considered a write."
75
+ let val = unsafe { p. read ( ) } ;
76
+
77
+ // SAFETY: The caller is responsible for ensuring the value is
78
+ // initialized and thus not zero.
79
+ unsafe { NonZeroUsize :: new_unchecked ( val) }
46
80
}
47
81
48
82
/// Gets the contents of the cell, initializing it with `f` if the cell was
0 commit comments