Skip to content

Commit 6816900

Browse files
committed
internal: project using full slot
Instead of projecting using pointer to a field project the full slot. This further shifts the code generation from the initializer site to the struct definition site, which means less code is generated overall. It also makes the safety comment easier to justify, as now the projection is done by the `#[pin_data]` macro which has full visibility of pinnedness of fields. The field alignment could also be checked on the `#[pin_data]` side; however, since `init!()` macro works for other type of structs, we cannot remove the alignment check from `init!`/`pin_init!` side anyway, so I opted to still keep the alignment check in init.rs. Signed-off-by: Gary Guo <gary@garyguo.net>
1 parent 62045f9 commit 6816900

6 files changed

Lines changed: 51 additions & 52 deletions

File tree

internal/src/init.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -245,12 +245,11 @@ fn init_fields(
245245
let slot = if pinned {
246246
quote! {
247247
// SAFETY:
248-
// - `&raw mut (*slot).#ident` points to the `#ident` field of `slot`.
249-
// - `&raw mut (*slot).#ident` is valid.
248+
// - `slot` is valid and properly aligned.
250249
// - `make_field_check` checks that `&raw mut (*slot).#ident` is properly aligned.
251250
// - `make_field_check` prevents `#ident` from being used twice, therefore
252251
// `(*slot).#ident` is exclusively accessed and has not been initialized.
253-
(unsafe { #data.#ident(&raw mut (*#slot).#ident) })
252+
(unsafe { #data.#ident(#slot) })
254253
}
255254
} else {
256255
quote! {

internal/src/pin_data.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -377,21 +377,21 @@ fn generate_the_pin_data(
377377
quote! {
378378
/// # Safety
379379
///
380-
/// - `slot` points to a `#field_name` field of a pinned struct that this
381-
/// `__ThePinData` describes.
382-
/// - `slot` is a valid, properly aligned and points to uninitialized and
383-
/// exclusively accessed memory.
380+
/// - `slot` is valid and properly aligned.
381+
/// - `(*slot).#field_name` is properly aligned.
382+
/// - `(*slot).#field_name` points to uninitialized and exclusively accessed
383+
/// memory.
384384
#(#attrs)*
385385
#[inline(always)]
386386
#vis unsafe fn #field_name(
387387
self,
388-
slot: *mut #ty,
388+
slot: *mut #struct_name #ty_generics,
389389
) -> ::pin_init::__internal::Slot<::pin_init::__internal::#pin_marker, #ty> {
390390
// SAFETY:
391391
// - If `#pin_marker` is `Pinned`, the corresponding field is structurally
392392
// pinned.
393393
// - Other safety requirements follows the safety requirement.
394-
unsafe { ::pin_init::__internal::Slot::new(slot) }
394+
unsafe { ::pin_init::__internal::Slot::new(&raw mut (*slot).#field_name) }
395395
}
396396
}
397397
})

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -868,7 +868,7 @@ pub use pin_init_internal::init;
868868
macro_rules! assert_pinned {
869869
($ty:ty, $field:ident, $field_ty:ty, inline) => {
870870
// SAFETY: This code is unreachable.
871-
let _ = move |ptr: *mut $field_ty| unsafe {
871+
let _ = move |ptr: *mut $ty| unsafe {
872872
let data = <$ty as $crate::__internal::HasPinData>::__pin_data();
873873
_ = data
874874
.$field(ptr)

tests/ui/expand/many_generics.expanded.rs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -94,51 +94,51 @@ const _: () = {
9494
}
9595
/// # Safety
9696
///
97-
/// - `slot` points to a `#ident` field of a pinned struct that this `__ThePinData`
98-
/// describes.
99-
/// - `slot` is a valid, properly aligned and points to uninitialized and
100-
/// exclusively memory.
97+
/// - `slot` is valid and properly aligned.
98+
/// - `(*slot).#field_name` is properly aligned.
99+
/// - `(*slot).#field_name` points to uninitialized and exclusively accessed
100+
/// memory.
101101
#[inline(always)]
102102
unsafe fn array(
103103
self,
104-
slot: *mut [u8; 1024 * 1024],
104+
slot: *mut Foo<'a, 'b, T, SIZE>,
105105
) -> ::pin_init::__internal::Slot<
106106
::pin_init::__internal::Unpinned,
107107
[u8; 1024 * 1024],
108108
> {
109-
unsafe { ::pin_init::__internal::Slot::new(slot) }
109+
unsafe { ::pin_init::__internal::Slot::new(&raw mut (*slot).array) }
110110
}
111111
/// # Safety
112112
///
113-
/// - `slot` points to a `#ident` field of a pinned struct that this `__ThePinData`
114-
/// describes.
115-
/// - `slot` is a valid, properly aligned and points to uninitialized and
116-
/// exclusively memory.
113+
/// - `slot` is valid and properly aligned.
114+
/// - `(*slot).#field_name` is properly aligned.
115+
/// - `(*slot).#field_name` points to uninitialized and exclusively accessed
116+
/// memory.
117117
#[inline(always)]
118118
unsafe fn r(
119119
self,
120-
slot: *mut &'b mut [&'a mut T; SIZE],
120+
slot: *mut Foo<'a, 'b, T, SIZE>,
121121
) -> ::pin_init::__internal::Slot<
122122
::pin_init::__internal::Unpinned,
123123
&'b mut [&'a mut T; SIZE],
124124
> {
125-
unsafe { ::pin_init::__internal::Slot::new(slot) }
125+
unsafe { ::pin_init::__internal::Slot::new(&raw mut (*slot).r) }
126126
}
127127
/// # Safety
128128
///
129-
/// - `slot` points to a `#ident` field of a pinned struct that this `__ThePinData`
130-
/// describes.
131-
/// - `slot` is a valid, properly aligned and points to uninitialized and
132-
/// exclusively memory.
129+
/// - `slot` is valid and properly aligned.
130+
/// - `(*slot).#field_name` is properly aligned.
131+
/// - `(*slot).#field_name` points to uninitialized and exclusively accessed
132+
/// memory.
133133
#[inline(always)]
134134
unsafe fn _pin(
135135
self,
136-
slot: *mut PhantomPinned,
136+
slot: *mut Foo<'a, 'b, T, SIZE>,
137137
) -> ::pin_init::__internal::Slot<
138138
::pin_init::__internal::Pinned,
139139
PhantomPinned,
140140
> {
141-
unsafe { ::pin_init::__internal::Slot::new(slot) }
141+
unsafe { ::pin_init::__internal::Slot::new(&raw mut (*slot)._pin) }
142142
}
143143
}
144144
unsafe impl<

tests/ui/expand/pin-data.expanded.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -58,35 +58,35 @@ const _: () = {
5858
}
5959
/// # Safety
6060
///
61-
/// - `slot` points to a `#ident` field of a pinned struct that this `__ThePinData`
62-
/// describes.
63-
/// - `slot` is a valid, properly aligned and points to uninitialized and
64-
/// exclusively memory.
61+
/// - `slot` is valid and properly aligned.
62+
/// - `(*slot).#field_name` is properly aligned.
63+
/// - `(*slot).#field_name` points to uninitialized and exclusively accessed
64+
/// memory.
6565
#[inline(always)]
6666
unsafe fn array(
6767
self,
68-
slot: *mut [u8; 1024 * 1024],
68+
slot: *mut Foo,
6969
) -> ::pin_init::__internal::Slot<
7070
::pin_init::__internal::Unpinned,
7171
[u8; 1024 * 1024],
7272
> {
73-
unsafe { ::pin_init::__internal::Slot::new(slot) }
73+
unsafe { ::pin_init::__internal::Slot::new(&raw mut (*slot).array) }
7474
}
7575
/// # Safety
7676
///
77-
/// - `slot` points to a `#ident` field of a pinned struct that this `__ThePinData`
78-
/// describes.
79-
/// - `slot` is a valid, properly aligned and points to uninitialized and
80-
/// exclusively memory.
77+
/// - `slot` is valid and properly aligned.
78+
/// - `(*slot).#field_name` is properly aligned.
79+
/// - `(*slot).#field_name` points to uninitialized and exclusively accessed
80+
/// memory.
8181
#[inline(always)]
8282
unsafe fn _pin(
8383
self,
84-
slot: *mut PhantomPinned,
84+
slot: *mut Foo,
8585
) -> ::pin_init::__internal::Slot<
8686
::pin_init::__internal::Pinned,
8787
PhantomPinned,
8888
> {
89-
unsafe { ::pin_init::__internal::Slot::new(slot) }
89+
unsafe { ::pin_init::__internal::Slot::new(&raw mut (*slot)._pin) }
9090
}
9191
}
9292
unsafe impl ::pin_init::__internal::HasPinData for Foo {

tests/ui/expand/pinned_drop.expanded.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -58,35 +58,35 @@ const _: () = {
5858
}
5959
/// # Safety
6060
///
61-
/// - `slot` points to a `#ident` field of a pinned struct that this `__ThePinData`
62-
/// describes.
63-
/// - `slot` is a valid, properly aligned and points to uninitialized and
64-
/// exclusively memory.
61+
/// - `slot` is valid and properly aligned.
62+
/// - `(*slot).#field_name` is properly aligned.
63+
/// - `(*slot).#field_name` points to uninitialized and exclusively accessed
64+
/// memory.
6565
#[inline(always)]
6666
unsafe fn array(
6767
self,
68-
slot: *mut [u8; 1024 * 1024],
68+
slot: *mut Foo,
6969
) -> ::pin_init::__internal::Slot<
7070
::pin_init::__internal::Unpinned,
7171
[u8; 1024 * 1024],
7272
> {
73-
unsafe { ::pin_init::__internal::Slot::new(slot) }
73+
unsafe { ::pin_init::__internal::Slot::new(&raw mut (*slot).array) }
7474
}
7575
/// # Safety
7676
///
77-
/// - `slot` points to a `#ident` field of a pinned struct that this `__ThePinData`
78-
/// describes.
79-
/// - `slot` is a valid, properly aligned and points to uninitialized and
80-
/// exclusively memory.
77+
/// - `slot` is valid and properly aligned.
78+
/// - `(*slot).#field_name` is properly aligned.
79+
/// - `(*slot).#field_name` points to uninitialized and exclusively accessed
80+
/// memory.
8181
#[inline(always)]
8282
unsafe fn _pin(
8383
self,
84-
slot: *mut PhantomPinned,
84+
slot: *mut Foo,
8585
) -> ::pin_init::__internal::Slot<
8686
::pin_init::__internal::Pinned,
8787
PhantomPinned,
8888
> {
89-
unsafe { ::pin_init::__internal::Slot::new(slot) }
89+
unsafe { ::pin_init::__internal::Slot::new(&raw mut (*slot)._pin) }
9090
}
9191
}
9292
unsafe impl ::pin_init::__internal::HasPinData for Foo {

0 commit comments

Comments
 (0)