-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow Weak::as_ptr and friends for unsized T #74160
Merged
Merged
Changes from 5 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
7289383
Adjust rc::Weak::from_raw to support unsized T
CAD97 0c61ce2
?Sized bounds for rc::Weak::as_ptr and friends
CAD97 5e7406c
Adjust sync::Weak::from_raw to support unsized T
CAD97 9d9903c
Allow Weak::as_ptr and friends for unsized T
CAD97 3d07108
Add tests for weak into/from raw
CAD97 e27ef13
grammar nit
RalfJung File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1509,7 +1509,16 @@ impl<T> Weak<T> { | |
pub fn new() -> Weak<T> { | ||
Weak { ptr: NonNull::new(usize::MAX as *mut ArcInner<T>).expect("MAX is not 0") } | ||
} | ||
} | ||
|
||
/// Helper type to allow accessing the reference counts without | ||
/// making any assertions about the data field. | ||
struct WeakInner<'a> { | ||
weak: &'a atomic::AtomicUsize, | ||
strong: &'a atomic::AtomicUsize, | ||
} | ||
|
||
impl<T: ?Sized> Weak<T> { | ||
/// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`. | ||
/// | ||
/// The pointer is valid only if there are some strong references. The pointer may be dangling, | ||
|
@@ -1629,28 +1638,20 @@ impl<T> Weak<T> { | |
/// [`forget`]: std::mem::forget | ||
#[stable(feature = "weak_into_raw", since = "1.45.0")] | ||
pub unsafe fn from_raw(ptr: *const T) -> Self { | ||
if ptr.is_null() { | ||
Self::new() | ||
} else { | ||
// See Arc::from_raw for details | ||
unsafe { | ||
let offset = data_offset(ptr); | ||
let fake_ptr = ptr as *mut ArcInner<T>; | ||
let ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset)); | ||
Weak { ptr: NonNull::new(ptr).expect("Invalid pointer passed to from_raw") } | ||
} | ||
} | ||
} | ||
} | ||
// SAFETY: data_offset is safe to call, because this pointer originates from a Weak. | ||
// See Weak::as_ptr for context on how the input pointer is derived. | ||
let offset = unsafe { data_offset(ptr) }; | ||
|
||
// Reverse the offset to find the original ArcInner. | ||
// SAFETY: we use wrapping_offset here because the pointer may be dangling (iff T: Sized) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same problem with the iff.
RalfJung marked this conversation as resolved.
Show resolved
Hide resolved
|
||
let ptr = unsafe { | ||
set_data_ptr(ptr as *mut ArcInner<T>, (ptr as *mut u8).wrapping_offset(-offset)) | ||
}; | ||
|
||
/// Helper type to allow accessing the reference counts without | ||
/// making any assertions about the data field. | ||
struct WeakInner<'a> { | ||
weak: &'a atomic::AtomicUsize, | ||
strong: &'a atomic::AtomicUsize, | ||
} | ||
// SAFETY: we now have recovered the original Weak pointer, so can create the Weak. | ||
unsafe { Weak { ptr: NonNull::new_unchecked(ptr) } } | ||
} | ||
|
||
impl<T: ?Sized> Weak<T> { | ||
/// Attempts to upgrade the `Weak` pointer to an [`Arc`], delaying | ||
/// dropping of the inner value if successful. | ||
/// | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"iff" isn't right here... the pointer is not "dangling if and only if
T
is sized". That would mean thatT: Sized
implies a dangling pointer.I think a plain "if" is correct here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The actual clause is "(may be dangling) iff (T is Sized)", but just regular if is probably fine here either way. I'll change it soon.
In any case, the desired semantics is that (T is Sized) is a necessary but not sufficient precondition for (pointer is dangling). (It is, however, necessary and sufficient for (pointer may dangle).)
I'm too tired at the moment to remember precisely which english is the "correct" way to encode this, probably "only if," if "iff" is not quite right and I felt the reason to use "iff" in the first place.
Just "if" is correct informally though so I'll just change it to that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@CAD97 from what I can see, this change is still outstanding.