@@ -77,11 +77,12 @@ use core::atomic;
77
77
use core:: atomic:: Ordering :: { Relaxed , Release , Acquire , SeqCst } ;
78
78
use core:: fmt;
79
79
use core:: cmp:: Ordering ;
80
- use core:: mem:: { min_align_of, size_of} ;
80
+ use core:: mem:: { min_align_of_val, size_of_val} ;
81
+ use core:: intrinsics:: drop_in_place;
81
82
use core:: mem;
82
83
use core:: nonzero:: NonZero ;
83
- use core:: ops:: Deref ;
84
- use core:: ptr ;
84
+ use core:: ops:: { Deref , CoerceUnsized } ;
85
+ use core:: marker :: Unsize ;
85
86
use core:: hash:: { Hash , Hasher } ;
86
87
use heap:: deallocate;
87
88
@@ -118,15 +119,16 @@ use heap::deallocate;
118
119
/// ```
119
120
#[ unsafe_no_drop_flag]
120
121
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
121
- pub struct Arc < T > {
122
+ pub struct Arc < T : ? Sized > {
122
123
// FIXME #12808: strange name to try to avoid interfering with
123
124
// field accesses of the contained type via Deref
124
125
_ptr : NonZero < * mut ArcInner < T > > ,
125
126
}
126
127
127
- unsafe impl < T : Sync + Send > Send for Arc < T > { }
128
- unsafe impl < T : Sync + Send > Sync for Arc < T > { }
128
+ unsafe impl < T : ? Sized + Sync + Send > Send for Arc < T > { }
129
+ unsafe impl < T : ? Sized + Sync + Send > Sync for Arc < T > { }
129
130
131
+ impl < T : ?Sized + Unsize < U > , U : ?Sized > CoerceUnsized < Arc < U > > for Arc < T > { }
130
132
131
133
/// A weak pointer to an `Arc`.
132
134
///
@@ -135,30 +137,30 @@ unsafe impl<T: Sync + Send> Sync for Arc<T> { }
135
137
#[ unsafe_no_drop_flag]
136
138
#[ unstable( feature = "alloc" ,
137
139
reason = "Weak pointers may not belong in this module." ) ]
138
- pub struct Weak < T > {
140
+ pub struct Weak < T : ? Sized > {
139
141
// FIXME #12808: strange name to try to avoid interfering with
140
142
// field accesses of the contained type via Deref
141
143
_ptr : NonZero < * mut ArcInner < T > > ,
142
144
}
143
145
144
- unsafe impl < T : Sync + Send > Send for Weak < T > { }
145
- unsafe impl < T : Sync + Send > Sync for Weak < T > { }
146
+ unsafe impl < T : ? Sized + Sync + Send > Send for Weak < T > { }
147
+ unsafe impl < T : ? Sized + Sync + Send > Sync for Weak < T > { }
146
148
147
149
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
148
- impl < T : fmt:: Debug > fmt:: Debug for Weak < T > {
150
+ impl < T : ? Sized + fmt:: Debug > fmt:: Debug for Weak < T > {
149
151
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
150
152
write ! ( f, "(Weak)" )
151
153
}
152
154
}
153
155
154
- struct ArcInner < T > {
156
+ struct ArcInner < T : ? Sized > {
155
157
strong : atomic:: AtomicUsize ,
156
158
weak : atomic:: AtomicUsize ,
157
159
data : T ,
158
160
}
159
161
160
- unsafe impl < T : Sync + Send > Send for ArcInner < T > { }
161
- unsafe impl < T : Sync + Send > Sync for ArcInner < T > { }
162
+ unsafe impl < T : ? Sized + Sync + Send > Send for ArcInner < T > { }
163
+ unsafe impl < T : ? Sized + Sync + Send > Sync for ArcInner < T > { }
162
164
163
165
impl < T > Arc < T > {
164
166
/// Constructs a new `Arc<T>`.
@@ -182,7 +184,9 @@ impl<T> Arc<T> {
182
184
} ;
183
185
Arc { _ptr : unsafe { NonZero :: new ( mem:: transmute ( x) ) } }
184
186
}
187
+ }
185
188
189
+ impl < T : ?Sized > Arc < T > {
186
190
/// Downgrades the `Arc<T>` to a `Weak<T>` reference.
187
191
///
188
192
/// # Examples
@@ -204,7 +208,7 @@ impl<T> Arc<T> {
204
208
}
205
209
}
206
210
207
- impl < T > Arc < T > {
211
+ impl < T : ? Sized > Arc < T > {
208
212
#[ inline]
209
213
fn inner ( & self ) -> & ArcInner < T > {
210
214
// This unsafety is ok because while this arc is alive we're guaranteed
@@ -222,24 +226,24 @@ impl<T> Arc<T> {
222
226
223
227
// Destroy the data at this time, even though we may not free the box
224
228
// allocation itself (there may still be weak pointers lying around).
225
- drop ( ptr :: read ( & self . inner ( ) . data ) ) ;
229
+ drop_in_place ( & mut ( * ptr ) . data ) ;
226
230
227
231
if self . inner ( ) . weak . fetch_sub ( 1 , Release ) == 1 {
228
232
atomic:: fence ( Acquire ) ;
229
- deallocate ( ptr as * mut u8 , size_of :: < ArcInner < T > > ( ) , min_align_of :: < ArcInner < T > > ( ) )
233
+ deallocate ( ptr as * mut u8 , size_of_val ( & * ptr ) , min_align_of_val ( & * ptr ) )
230
234
}
231
235
}
232
236
}
233
237
234
238
/// Get the number of weak references to this value.
235
239
#[ inline]
236
240
#[ unstable( feature = "alloc" ) ]
237
- pub fn weak_count < T > ( this : & Arc < T > ) -> usize { this. inner ( ) . weak . load ( SeqCst ) - 1 }
241
+ pub fn weak_count < T : ? Sized > ( this : & Arc < T > ) -> usize { this. inner ( ) . weak . load ( SeqCst ) - 1 }
238
242
239
243
/// Get the number of strong references to this value.
240
244
#[ inline]
241
245
#[ unstable( feature = "alloc" ) ]
242
- pub fn strong_count < T > ( this : & Arc < T > ) -> usize { this. inner ( ) . strong . load ( SeqCst ) }
246
+ pub fn strong_count < T : ? Sized > ( this : & Arc < T > ) -> usize { this. inner ( ) . strong . load ( SeqCst ) }
243
247
244
248
245
249
/// Returns a mutable reference to the contained value if the `Arc<T>` is unique.
@@ -264,7 +268,7 @@ pub fn strong_count<T>(this: &Arc<T>) -> usize { this.inner().strong.load(SeqCst
264
268
/// ```
265
269
#[ inline]
266
270
#[ unstable( feature = "alloc" ) ]
267
- pub fn get_mut < T > ( this : & mut Arc < T > ) -> Option < & mut T > {
271
+ pub fn get_mut < T : ? Sized > ( this : & mut Arc < T > ) -> Option < & mut T > {
268
272
if strong_count ( this) == 1 && weak_count ( this) == 0 {
269
273
// This unsafety is ok because we're guaranteed that the pointer
270
274
// returned is the *only* pointer that will ever be returned to T. Our
@@ -279,7 +283,7 @@ pub fn get_mut<T>(this: &mut Arc<T>) -> Option<&mut T> {
279
283
}
280
284
281
285
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
282
- impl < T > Clone for Arc < T > {
286
+ impl < T : ? Sized > Clone for Arc < T > {
283
287
/// Makes a clone of the `Arc<T>`.
284
288
///
285
289
/// This increases the strong reference count.
@@ -313,7 +317,7 @@ impl<T> Clone for Arc<T> {
313
317
}
314
318
315
319
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
316
- impl < T > Deref for Arc < T > {
320
+ impl < T : ? Sized > Deref for Arc < T > {
317
321
type Target = T ;
318
322
319
323
#[ inline]
@@ -356,7 +360,7 @@ impl<T: Clone> Arc<T> {
356
360
}
357
361
358
362
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
359
- impl < T > Drop for Arc < T > {
363
+ impl < T : ? Sized > Drop for Arc < T > {
360
364
/// Drops the `Arc<T>`.
361
365
///
362
366
/// This will decrement the strong reference count. If the strong reference
@@ -390,7 +394,7 @@ impl<T> Drop for Arc<T> {
390
394
// it's run more than once)
391
395
let ptr = * self . _ptr ;
392
396
// if ptr.is_null() { return }
393
- if ptr. is_null ( ) || ptr as usize == mem:: POST_DROP_USIZE { return }
397
+ if ptr as usize == 0 || ptr as usize == mem:: POST_DROP_USIZE { return }
394
398
395
399
// Because `fetch_sub` is already atomic, we do not need to synchronize
396
400
// with other threads unless we are going to delete the object. This
@@ -424,7 +428,7 @@ impl<T> Drop for Arc<T> {
424
428
425
429
#[ unstable( feature = "alloc" ,
426
430
reason = "Weak pointers may not belong in this module." ) ]
427
- impl < T > Weak < T > {
431
+ impl < T : ? Sized > Weak < T > {
428
432
/// Upgrades a weak reference to a strong reference.
429
433
///
430
434
/// Upgrades the `Weak<T>` reference to an `Arc<T>`, if possible.
@@ -465,7 +469,7 @@ impl<T> Weak<T> {
465
469
466
470
#[ unstable( feature = "alloc" ,
467
471
reason = "Weak pointers may not belong in this module." ) ]
468
- impl < T > Clone for Weak < T > {
472
+ impl < T : ? Sized > Clone for Weak < T > {
469
473
/// Makes a clone of the `Weak<T>`.
470
474
///
471
475
/// This increases the weak reference count.
@@ -489,7 +493,7 @@ impl<T> Clone for Weak<T> {
489
493
}
490
494
491
495
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
492
- impl < T > Drop for Weak < T > {
496
+ impl < T : ? Sized > Drop for Weak < T > {
493
497
/// Drops the `Weak<T>`.
494
498
///
495
499
/// This will decrement the weak reference count.
@@ -520,21 +524,22 @@ impl<T> Drop for Weak<T> {
520
524
let ptr = * self . _ptr ;
521
525
522
526
// see comments above for why this check is here
523
- if ptr. is_null ( ) || ptr as usize == mem:: POST_DROP_USIZE { return }
527
+ if ptr as usize == 0 || ptr as usize == mem:: POST_DROP_USIZE { return }
524
528
525
529
// If we find out that we were the last weak pointer, then its time to
526
530
// deallocate the data entirely. See the discussion in Arc::drop() about
527
531
// the memory orderings
528
532
if self . inner ( ) . weak . fetch_sub ( 1 , Release ) == 1 {
529
533
atomic:: fence ( Acquire ) ;
530
- unsafe { deallocate ( ptr as * mut u8 , size_of :: < ArcInner < T > > ( ) ,
531
- min_align_of :: < ArcInner < T > > ( ) ) }
534
+ unsafe { deallocate ( ptr as * mut u8 ,
535
+ size_of_val ( & * ptr) ,
536
+ min_align_of_val ( & * ptr) ) }
532
537
}
533
538
}
534
539
}
535
540
536
541
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
537
- impl < T : PartialEq > PartialEq for Arc < T > {
542
+ impl < T : ? Sized + PartialEq > PartialEq for Arc < T > {
538
543
/// Equality for two `Arc<T>`s.
539
544
///
540
545
/// Two `Arc<T>`s are equal if their inner value are equal.
@@ -566,7 +571,7 @@ impl<T: PartialEq> PartialEq for Arc<T> {
566
571
fn ne ( & self , other : & Arc < T > ) -> bool { * ( * self ) != * ( * other) }
567
572
}
568
573
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
569
- impl < T : PartialOrd > PartialOrd for Arc < T > {
574
+ impl < T : ? Sized + PartialOrd > PartialOrd for Arc < T > {
570
575
/// Partial comparison for two `Arc<T>`s.
571
576
///
572
577
/// The two are compared by calling `partial_cmp()` on their inner values.
@@ -645,21 +650,21 @@ impl<T: PartialOrd> PartialOrd for Arc<T> {
645
650
fn ge ( & self , other : & Arc < T > ) -> bool { * ( * self ) >= * ( * other) }
646
651
}
647
652
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
648
- impl < T : Ord > Ord for Arc < T > {
653
+ impl < T : ? Sized + Ord > Ord for Arc < T > {
649
654
fn cmp ( & self , other : & Arc < T > ) -> Ordering { ( * * self ) . cmp ( & * * other) }
650
655
}
651
656
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
652
- impl < T : Eq > Eq for Arc < T > { }
657
+ impl < T : ? Sized + Eq > Eq for Arc < T > { }
653
658
654
659
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
655
- impl < T : fmt:: Display > fmt:: Display for Arc < T > {
660
+ impl < T : ? Sized + fmt:: Display > fmt:: Display for Arc < T > {
656
661
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
657
662
fmt:: Display :: fmt ( & * * self , f)
658
663
}
659
664
}
660
665
661
666
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
662
- impl < T : fmt:: Debug > fmt:: Debug for Arc < T > {
667
+ impl < T : ? Sized + fmt:: Debug > fmt:: Debug for Arc < T > {
663
668
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
664
669
fmt:: Debug :: fmt ( & * * self , f)
665
670
}
@@ -679,7 +684,7 @@ impl<T: Default> Default for Arc<T> {
679
684
}
680
685
681
686
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
682
- impl < T : Hash > Hash for Arc < T > {
687
+ impl < T : ? Sized + Hash > Hash for Arc < T > {
683
688
fn hash < H : Hasher > ( & self , state : & mut H ) {
684
689
( * * self ) . hash ( state)
685
690
}
@@ -906,4 +911,13 @@ mod tests {
906
911
// Make sure deriving works with Arc<T>
907
912
#[ derive( Eq , Ord , PartialEq , PartialOrd , Clone , Debug , Default ) ]
908
913
struct Foo { inner : Arc < i32 > }
914
+
915
+ #[ test]
916
+ fn test_unsized ( ) {
917
+ let x: Arc < [ i32 ] > = Arc :: new ( [ 1 , 2 , 3 ] ) ;
918
+ assert_eq ! ( format!( "{:?}" , x) , "[1, 2, 3]" ) ;
919
+ let y = x. clone ( ) . downgrade ( ) ;
920
+ drop ( x) ;
921
+ assert ! ( y. upgrade( ) . is_none( ) ) ;
922
+ }
909
923
}
0 commit comments