@@ -348,6 +348,17 @@ impl<T: ?Sized> Rc<T> {
348
348
unsafe fn from_ptr ( ptr : * mut RcBox < T > ) -> Self {
349
349
unsafe { Self :: from_inner ( NonNull :: new_unchecked ( ptr) ) }
350
350
}
351
+
352
+ // Non-inlined part of `drop`.
353
+ #[ inline( never) ]
354
+ unsafe fn drop_slow ( & mut self ) {
355
+ // Destroy the data at this time, even though we must not free the box
356
+ // allocation itself (there might still be weak pointers lying around).
357
+ unsafe { ptr:: drop_in_place ( Self :: get_mut_unchecked ( self ) ) } ;
358
+
359
+ // Drop the weak ref collectively held by all strong references.
360
+ drop ( Weak { ptr : self . ptr } ) ;
361
+ }
351
362
}
352
363
353
364
impl < T > Rc < T > {
@@ -1516,20 +1527,19 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Rc<T> {
1516
1527
/// drop(foo); // Doesn't print anything
1517
1528
/// drop(foo2); // Prints "dropped!"
1518
1529
/// ```
1530
+ #[ inline]
1519
1531
fn drop ( & mut self ) {
1520
1532
unsafe {
1521
1533
self . inner ( ) . dec_strong ( ) ;
1522
- if self . inner ( ) . strong ( ) == 0 {
1523
- // destroy the contained object
1524
- ptr:: drop_in_place ( Self :: get_mut_unchecked ( self ) ) ;
1525
-
1526
- // remove the implicit "strong weak" pointer now that we've
1527
- // destroyed the contents.
1528
- self . inner ( ) . dec_weak ( ) ;
1534
+ if self . inner ( ) . strong ( ) != 0 {
1535
+ return ;
1536
+ }
1529
1537
1530
- if self . inner ( ) . weak ( ) == 0 {
1531
- Global . deallocate ( self . ptr . cast ( ) , Layout :: for_value ( self . ptr . as_ref ( ) ) ) ;
1532
- }
1538
+ if mem:: needs_drop :: < T > ( ) {
1539
+ self . drop_slow ( ) ;
1540
+ } else {
1541
+ // Drop the weak ref collectively held by all strong references.
1542
+ drop ( Weak { ptr : self . ptr } ) ;
1533
1543
}
1534
1544
}
1535
1545
}
@@ -2457,6 +2467,7 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Weak<T> {
2457
2467
///
2458
2468
/// assert!(other_weak_foo.upgrade().is_none());
2459
2469
/// ```
2470
+ #[ inline]
2460
2471
fn drop ( & mut self ) {
2461
2472
let inner = if let Some ( inner) = self . inner ( ) { inner } else { return } ;
2462
2473
0 commit comments