Skip to content
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

Remove sized requirement from Arc::from_raw #85

Merged
merged 1 commit into from
Apr 25, 2024

Conversation

stepancheg
Copy link
Contributor

ptr.byte_sub is stable since 1.75.0.

The tricky part here is figuring out offset of ArcInner.data for DST. This PR assumes that raw pointer is coming from existing Arc so it is safe to convert to reference. I'm not 100% sure this is always correct.

Correct version would require Layout::for_value_raw (or mem::align_of_val_raw) which is not stable.

This can be used to convert Arc<String> to Arc<dyn Debug>.

src/arc.rs Outdated
@@ -39,6 +39,18 @@ pub(crate) struct ArcInner<T: ?Sized> {
unsafe impl<T: ?Sized + Sync + Send> Send for ArcInner<T> {}
unsafe impl<T: ?Sized + Sync + Send> Sync for ArcInner<T> {}

impl<T: ?Sized> ArcInner<T> {
/// Safety: value must be a valid initialized pointer.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: please document what this function does, and also document that it is a safety-usable invariant

src/arc.rs Outdated
let offset_of_data = ArcInner::<T>::offset_of_data(ptr);

let ptr = ptr.byte_sub(offset_of_data);
Arc::from_raw_inner(ptr as *mut ArcInner<T>)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: please document why this usage is safe

@stepancheg stepancheg force-pushed the arc-from-raw-unsized branch 2 times, most recently from 1799e98 to 6f0671c Compare April 18, 2024 15:41
@stepancheg
Copy link
Contributor Author

Amended the PR with more comments. Not sure I made it more helpful then before.

// to subtract the offset of the `data` field from the pointer.

// SAFETY: `ptr` comes from `Arc`, so it must be initialized.
let offset_of_data = ArcInner::<T>::offset_of_data(ptr);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'd prefer an explicit documentation of the fact that from_raw_inner wants the beginning of the allocation, and ptr points to the data.

src/arc.rs Outdated
// and resulting pointer is within the allocation.
let arc_inner_ptr = ptr.byte_sub(offset_of_data);

// SAFETY: `Arc::from_raw` contract requires that `ptr` comes from `Arc::into_raw`,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but this pointer doesn't come from into_raw? It's subtracted

@stepancheg
Copy link
Contributor Author

Rephrased. Hope it's better.

src/arc.rs Outdated
let offset_of_data = ArcInner::<T>::offset_of_data(ptr);

// SAFETY: `ptr` points to `ArcInner.data`,
// so subtraction results in the beginning of the `ArcInner`.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I still want an explicit line here saying from_raw_inner accepts a pointer to the beginning of the allocation, not the data part.

This is something that is more confusing about this code and while we haven't been great about it I really want this crate to be better on this axis.

Sorry about the repeated back and forth on this!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Published another version!

`ptr.byte_sub` is stable since 1.75.0.

The tricky part here is figuring out offset of `ArcInner.data` for
DST.  This PR assumes that raw pointer is coming from existing `Arc`
so it is safe to convert to reference. I'm not 100% sure this is
always correct.

Correct version would require `Layout::for_value_raw` (or
`mem::align_of_val_raw`) which is not stable.

This can be used to convert `Arc<String>` to `Arc<dyn Debug>`.
@Manishearth Manishearth merged commit 4a778df into Manishearth:master Apr 25, 2024
4 checks passed
@Manishearth
Copy link
Owner

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants