@@ -848,7 +848,7 @@ impl<T: ?Sized> Rc<T> {
848
848
pub fn downgrade ( this : & Self ) -> Weak < T > {
849
849
this. inner ( ) . inc_weak ( ) ;
850
850
// Make sure we do not create a dangling Weak
851
- debug_assert ! ( !is_dangling( this. ptr) ) ;
851
+ debug_assert ! ( !is_dangling( this. ptr. as_ptr ( ) ) ) ;
852
852
Weak { ptr : this. ptr }
853
853
}
854
854
@@ -1837,8 +1837,8 @@ impl<T> Weak<T> {
1837
1837
}
1838
1838
}
1839
1839
1840
- pub ( crate ) fn is_dangling < T : ?Sized > ( ptr : NonNull < T > ) -> bool {
1841
- let address = ptr. as_ptr ( ) as * mut ( ) as usize ;
1840
+ pub ( crate ) fn is_dangling < T : ?Sized > ( ptr : * mut T ) -> bool {
1841
+ let address = ptr as * mut ( ) as usize ;
1842
1842
address == usize:: MAX
1843
1843
}
1844
1844
@@ -1879,17 +1879,15 @@ impl<T: ?Sized> Weak<T> {
1879
1879
pub fn as_ptr ( & self ) -> * const T {
1880
1880
let ptr: * mut RcBox < T > = NonNull :: as_ptr ( self . ptr ) ;
1881
1881
1882
- if is_dangling ( self . ptr ) {
1883
- // If the pointer is dangling, we return a null pointer as the dangling sentinel.
1884
- // We can't return the usize::MAX sentinel, as that could valid if T is ZST.
1885
- // SAFETY: we have to return a known sentinel here that cannot be produced for
1886
- // a valid pointer, so that `from_raw` can reverse this transformation.
1887
- ( ptr as * mut T ) . set_ptr_value ( ptr:: null_mut ( ) )
1882
+ if is_dangling ( ptr) {
1883
+ // If the pointer is dangling, we return the sentinel directly. This cannot be
1884
+ // a valid payload address, as it is at least as aligned as RcBox (usize).
1885
+ ptr as * const T
1888
1886
} else {
1889
1887
// SAFETY: if is_dangling returns false, then the pointer is dereferencable.
1890
1888
// The payload may be dropped at this point, and we have to maintain provenance,
1891
1889
// so use raw pointer manipulation.
1892
- unsafe { & raw mut ( * ptr) . value }
1890
+ unsafe { & raw const ( * ptr) . value }
1893
1891
}
1894
1892
}
1895
1893
@@ -1973,10 +1971,9 @@ impl<T: ?Sized> Weak<T> {
1973
1971
pub unsafe fn from_raw ( ptr : * const T ) -> Self {
1974
1972
// See Weak::as_ptr for context on how the input pointer is derived.
1975
1973
1976
- let ptr = if ptr. is_null ( ) {
1977
- // If we get a null pointer, this is a dangling weak.
1978
- // SAFETY: this is the same sentinel as used in Weak::new and is_dangling
1979
- ( ptr as * mut RcBox < T > ) . set_ptr_value ( usize:: MAX as * mut _ )
1974
+ let ptr = if is_dangling ( ptr as * mut T ) {
1975
+ // This is a dangling Weak.
1976
+ ptr as * mut RcBox < T >
1980
1977
} else {
1981
1978
// Otherwise, we're guaranteed the pointer came from a nondangling Weak.
1982
1979
// SAFETY: data_offset is safe to call, as ptr references a real (potentially dropped) T.
@@ -2052,7 +2049,7 @@ impl<T: ?Sized> Weak<T> {
2052
2049
/// (i.e., when this `Weak` was created by `Weak::new`).
2053
2050
#[ inline]
2054
2051
fn inner ( & self ) -> Option < WeakInner < ' _ > > {
2055
- if is_dangling ( self . ptr ) {
2052
+ if is_dangling ( self . ptr . as_ptr ( ) ) {
2056
2053
None
2057
2054
} else {
2058
2055
// We are careful to *not* create a reference covering the "data" field, as
0 commit comments