@@ -3308,7 +3308,32 @@ impl Default for Arc<str> {
33083308 /// This may or may not share an allocation with other Arcs.
33093309 #[ inline]
33103310 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 ( )
33123337 }
33133338}
33143339
@@ -3320,6 +3345,31 @@ impl<T> Default for Arc<[T]> {
33203345 /// This may or may not share an allocation with other Arcs.
33213346 #[ inline]
33223347 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.
33233373 let arr: [ T ; 0 ] = [ ] ;
33243374 Arc :: from ( arr)
33253375 }
0 commit comments