@@ -258,6 +258,7 @@ use core::ops::Deref;
258
258
use core:: ops:: CoerceUnsized ;
259
259
use core:: ptr:: { self , NonNull } ;
260
260
use core:: convert:: From ;
261
+ use core:: usize;
261
262
262
263
use alloc:: { Global , Alloc , Layout , box_free, handle_alloc_error} ;
263
264
use string:: String ;
@@ -449,6 +450,8 @@ impl<T: ?Sized> Rc<T> {
449
450
#[ stable( feature = "rc_weak" , since = "1.4.0" ) ]
450
451
pub fn downgrade ( this : & Self ) -> Weak < T > {
451
452
this. inc_weak ( ) ;
453
+ // Make sure we do not create a dangling Weak
454
+ debug_assert ! ( !is_dangling( this. ptr) ) ;
452
455
Weak { ptr : this. ptr }
453
456
}
454
457
@@ -1154,8 +1157,9 @@ impl<T> From<Vec<T>> for Rc<[T]> {
1154
1157
pub struct Weak < T : ?Sized > {
1155
1158
// This is a `NonNull` to allow optimizing the size of this type in enums,
1156
1159
// but it is not necessarily a valid pointer.
1157
- // `Weak::new` sets this to a dangling pointer so that it doesn’t need
1158
- // to allocate space on the heap.
1160
+ // `Weak::new` sets this to `usize::MAX` so that it doesn’t need
1161
+ // to allocate space on the heap. That's not a value a real pointer
1162
+ // will ever have because RcBox has alignment at least 2.
1159
1163
ptr : NonNull < RcBox < T > > ,
1160
1164
}
1161
1165
@@ -1185,15 +1189,14 @@ impl<T> Weak<T> {
1185
1189
#[ stable( feature = "downgraded_weak" , since = "1.10.0" ) ]
1186
1190
pub fn new ( ) -> Weak < T > {
1187
1191
Weak {
1188
- ptr : NonNull :: dangling ( ) ,
1192
+ ptr : NonNull :: new ( usize :: MAX as * mut RcBox < T > ) . expect ( "MAX is not 0" ) ,
1189
1193
}
1190
1194
}
1191
1195
}
1192
1196
1193
1197
pub ( crate ) fn is_dangling < T : ?Sized > ( ptr : NonNull < T > ) -> bool {
1194
1198
let address = ptr. as_ptr ( ) as * mut ( ) as usize ;
1195
- let align = align_of_val ( unsafe { ptr. as_ref ( ) } ) ;
1196
- address == align
1199
+ address == usize:: MAX
1197
1200
}
1198
1201
1199
1202
impl < T : ?Sized > Weak < T > {
0 commit comments