@@ -7,8 +7,8 @@ pub struct Slot<T> {
77}
88
99impl < T > SwapSlot < T > for Slot < T > {
10- fn store ( & self , item : T ) {
11- * self . lock . write ( ) . unwrap ( ) = Some ( Arc :: new ( item) ) ;
10+ fn store ( & self , item : impl Into < Arc < T > > ) {
11+ * self . lock . write ( ) . unwrap ( ) = Some ( item. into ( ) ) ;
1212 }
1313
1414 fn load ( & self ) -> Option < Arc < T > > {
@@ -69,3 +69,46 @@ mod test {
6969 assert_eq ! ( Arc :: strong_count( & arc. unwrap( ) ) , 2 )
7070 }
7171}
72+
73+ #[ cfg( test) ]
74+ mod allocation_tests {
75+ use crate :: flavors:: allocation_tests:: { allocs_current_thread, reset_allocs_current_thread} ;
76+
77+ use super :: * ;
78+
79+ #[ test]
80+ fn store_with_arc_does_not_allocate_new_arc ( ) {
81+ let slot = Slot :: < u32 > :: none ( ) ;
82+ let arc = Arc :: new ( 123u32 ) ;
83+
84+ // Ignore allocations from constructing `slot` and `arc`.
85+ reset_allocs_current_thread ( ) ;
86+
87+ // This should only move / clone the Arc; no new heap allocation for T.
88+ slot. store ( arc. clone ( ) ) ;
89+
90+ // Might still be 0 or some tiny number depending on RwLock internals,
91+ // but definitely shouldn't be "one Arc allocation vs another" difference.
92+ let after = allocs_current_thread ( ) ;
93+ assert_eq ! (
94+ after, 0 ,
95+ "expected no additional allocations when storing an Arc"
96+ ) ;
97+ }
98+
99+ #[ test]
100+ fn store_with_value_allocates_arc ( ) {
101+ let slot = Slot :: < u32 > :: none ( ) ;
102+
103+ reset_allocs_current_thread ( ) ;
104+
105+ // This goes through `impl From<T> for Arc<T>` and must allocate.
106+ slot. store ( 5u32 ) ;
107+
108+ let after = allocs_current_thread ( ) ;
109+ assert ! (
110+ after == 1 ,
111+ "expected at least one allocation when storing a bare value T"
112+ ) ;
113+ }
114+ }
0 commit comments