@@ -3308,7 +3308,32 @@ impl Default for Arc<str> {
3308
3308
/// This may or may not share an allocation with other Arcs.
3309
3309
#[ inline]
3310
3310
fn default ( ) -> Self {
3311
- Arc :: from ( "" )
3311
+ let arc: Arc < [ u8 ] > = Default :: default ( ) ;
3312
+ debug_assert ! ( core:: str :: from_utf8( & * arc) . is_ok( ) ) ;
3313
+ let ( ptr, alloc) = Arc :: into_inner_with_allocator ( arc) ;
3314
+ unsafe { Arc :: from_ptr_in ( ptr. as_ptr ( ) as * mut ArcInner < str > , alloc) }
3315
+ }
3316
+ }
3317
+
3318
+ #[ cfg( not( no_global_oom_handling) ) ]
3319
+ #[ stable( feature = "more_rc_default_impls" , since = "CURRENT_RUSTC_VERSION" ) ]
3320
+ impl Default for Arc < core:: ffi:: CStr > {
3321
+ /// Creates an empty CStr inside an Arc
3322
+ ///
3323
+ /// This may or may not share an allocation with other Arcs.
3324
+ #[ inline]
3325
+ fn default ( ) -> Self {
3326
+ use core:: ffi:: CStr ;
3327
+ static STATIC_INNER_CSTR : ArcInner < [ u8 ; 1 ] > = ArcInner {
3328
+ strong : atomic:: AtomicUsize :: new ( 1 ) ,
3329
+ weak : atomic:: AtomicUsize :: new ( 1 ) ,
3330
+ data : [ 0 ] ,
3331
+ } ;
3332
+ let inner: NonNull < ArcInner < [ u8 ] > > = NonNull :: from ( & STATIC_INNER_CSTR ) ;
3333
+ let inner: NonNull < ArcInner < CStr > > = NonNull :: new ( inner. as_ptr ( ) as * mut ArcInner < CStr > ) . unwrap ( ) ;
3334
+ // `this` semantically is the Arc "owned" by the static, so make sure not to drop it.
3335
+ let this: mem:: ManuallyDrop < Arc < CStr > > = unsafe { mem:: ManuallyDrop :: new ( Arc :: from_inner ( inner) ) } ;
3336
+ ( * this) . clone ( )
3312
3337
}
3313
3338
}
3314
3339
@@ -3320,6 +3345,31 @@ impl<T> Default for Arc<[T]> {
3320
3345
/// This may or may not share an allocation with other Arcs.
3321
3346
#[ inline]
3322
3347
fn default ( ) -> Self {
3348
+ let alignment_of_t: usize = mem:: align_of :: < T > ( ) ;
3349
+ // We only make statics for the lowest five alignments.
3350
+ // Alignments greater than that will use dynamic allocation.
3351
+ macro_rules! use_static_inner_for_alignments {
3352
+ ( $( $alignment: literal) ,* ) => {
3353
+ $( if alignment_of_t == $alignment {
3354
+ // Note: this must be in a new scope because static and type names are unhygenic.
3355
+ #[ repr( align( $alignment) ) ]
3356
+ struct Aligned ;
3357
+ static ALIGNED_STATIC_INNER : ArcInner <Aligned > = ArcInner {
3358
+ strong: atomic:: AtomicUsize :: new( 1 ) ,
3359
+ weak: atomic:: AtomicUsize :: new( 1 ) ,
3360
+ data: Aligned ,
3361
+ } ;
3362
+ let inner: NonNull <ArcInner <Aligned >> = NonNull :: from( & ALIGNED_STATIC_INNER ) ;
3363
+ let inner: NonNull <ArcInner <[ T ; 0 ] >> = inner. cast( ) ;
3364
+ // `this` semantically is the Arc "owned" by the static, so make sure not to drop it.
3365
+ let this: mem:: ManuallyDrop <Arc <[ T ; 0 ] >> = unsafe { mem:: ManuallyDrop :: new( Arc :: from_inner( inner) ) } ;
3366
+ return ( * this) . clone( ) ;
3367
+ } ) *
3368
+ } ;
3369
+ }
3370
+ use_static_inner_for_alignments ! ( 1 , 2 , 4 , 8 , 16 ) ;
3371
+
3372
+ // If T's alignment is not one of the ones we have a static for, make a new unique allocation.
3323
3373
let arr: [ T ; 0 ] = [ ] ;
3324
3374
Arc :: from ( arr)
3325
3375
}
0 commit comments