@@ -4,6 +4,7 @@ use bytes::{Buf, BufMut, Bytes, BytesMut};
4
4
use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
5
5
use std:: sync:: Arc ;
6
6
7
+ use std:: panic:: { self , AssertUnwindSafe } ;
7
8
use std:: usize;
8
9
9
10
const LONG : & [ u8 ] = b"mary had a little lamb, little lamb, little lamb" ;
@@ -1486,16 +1487,24 @@ fn split_to_empty_addr_mut() {
1486
1487
struct OwnedTester < const L : usize > {
1487
1488
buf : [ u8 ; L ] ,
1488
1489
drop_count : Arc < AtomicUsize > ,
1490
+ pub panic_as_ref : bool ,
1489
1491
}
1490
1492
1491
1493
impl < const L : usize > OwnedTester < L > {
1492
1494
fn new ( buf : [ u8 ; L ] , drop_count : Arc < AtomicUsize > ) -> Self {
1493
- Self { buf, drop_count }
1495
+ Self {
1496
+ buf,
1497
+ drop_count,
1498
+ panic_as_ref : false ,
1499
+ }
1494
1500
}
1495
1501
}
1496
1502
1497
1503
impl < const L : usize > AsRef < [ u8 ] > for OwnedTester < L > {
1498
1504
fn as_ref ( & self ) -> & [ u8 ] {
1505
+ if self . panic_as_ref {
1506
+ panic ! ( "test-triggered panic in `AsRef<[u8]> for OwnedTester`" ) ;
1507
+ }
1499
1508
self . buf . as_slice ( )
1500
1509
}
1501
1510
}
@@ -1570,3 +1579,18 @@ fn owned_to_vec() {
1570
1579
drop ( b1) ;
1571
1580
assert_eq ! ( drop_counter. load( Ordering :: Acquire ) , 1 ) ;
1572
1581
}
1582
+
1583
+ #[ test]
1584
+ fn owned_safe_drop_on_as_ref_panic ( ) {
1585
+ let buf: [ u8 ; 10 ] = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] ;
1586
+ let drop_counter = Arc :: new ( AtomicUsize :: new ( 0 ) ) ;
1587
+ let mut owner = OwnedTester :: new ( buf, drop_counter. clone ( ) ) ;
1588
+ owner. panic_as_ref = true ;
1589
+
1590
+ let result = panic:: catch_unwind ( AssertUnwindSafe ( || {
1591
+ let _ = Bytes :: from_owner ( owner) ;
1592
+ } ) ) ;
1593
+
1594
+ assert ! ( result. is_err( ) ) ;
1595
+ assert_eq ! ( drop_counter. load( Ordering :: Acquire ) , 1 ) ;
1596
+ }
0 commit comments