@@ -258,6 +258,7 @@ use core::ops::Deref;
258258use core:: ops:: CoerceUnsized ;
259259use core:: ptr:: { self , NonNull } ;
260260use core:: convert:: From ;
261+ use core:: usize;
261262
262263use alloc:: { Global , Alloc , Layout , box_free, handle_alloc_error} ;
263264use string:: String ;
@@ -449,6 +450,8 @@ impl<T: ?Sized> Rc<T> {
449450 #[ stable( feature = "rc_weak" , since = "1.4.0" ) ]
450451 pub fn downgrade ( this : & Self ) -> Weak < T > {
451452 this. inc_weak ( ) ;
453+ // Make sure we do not create a dangling Weak
454+ debug_assert ! ( !is_dangling( this. ptr) ) ;
452455 Weak { ptr : this. ptr }
453456 }
454457
@@ -1154,8 +1157,9 @@ impl<T> From<Vec<T>> for Rc<[T]> {
11541157pub struct Weak < T : ?Sized > {
11551158 // This is a `NonNull` to allow optimizing the size of this type in enums,
11561159 // 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.
11591163 ptr : NonNull < RcBox < T > > ,
11601164}
11611165
@@ -1185,15 +1189,14 @@ impl<T> Weak<T> {
11851189 #[ stable( feature = "downgraded_weak" , since = "1.10.0" ) ]
11861190 pub fn new ( ) -> Weak < T > {
11871191 Weak {
1188- ptr : NonNull :: dangling ( ) ,
1192+ ptr : NonNull :: new ( usize :: MAX as * mut RcBox < T > ) . expect ( "MAX is not 0" ) ,
11891193 }
11901194 }
11911195}
11921196
11931197pub ( crate ) fn is_dangling < T : ?Sized > ( ptr : NonNull < T > ) -> bool {
11941198 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
11971200}
11981201
11991202impl < T : ?Sized > Weak < T > {
0 commit comments