Skip to content

Commit be81876

Browse files
committed
add ?Sized bounds to traits in #[pin_data] macro
`#[pin_data]` uses some auxiliary traits to ensure that a user does not implement `Drop` for the annotated struct, as that is unsound and can lead to UB. However, if the struct that is annotated is `!Sized`, the current bounds do not work, because `Sized` is an implicit bound for generics. This is *not* a soundness hole of pin-init, as it currently is impossible to construct an unsized value using pin-init. Signed-off-by: Benno Lossin <[email protected]>
1 parent 8079c35 commit be81876

File tree

3 files changed

+9
-8
lines changed

3 files changed

+9
-8
lines changed

internal/src/syn_pin_data.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ fn drop_impl(
313313
// if it also implements `Drop`
314314
trait MustNotImplDrop {}
315315
#[expect(drop_bounds)]
316-
impl<T: ::core::ops::Drop> MustNotImplDrop for T {}
316+
impl<T: ::core::ops::Drop + ?::core::marker::Sized> MustNotImplDrop for T {}
317317
impl #impl_generics MustNotImplDrop for #ident #ty_generics
318318
#whr
319319
{}
@@ -322,8 +322,8 @@ fn drop_impl(
322322
// `PinnedDrop` as the parameter to `#[pin_data]`.
323323
#[expect(non_camel_case_types)]
324324
trait UselessPinnedDropImpl_you_need_to_specify_PinnedDrop {}
325-
impl<T: ::pin_init::PinnedDrop> UselessPinnedDropImpl_you_need_to_specify_PinnedDrop
326-
for T {}
325+
impl<T: ::pin_init::PinnedDrop + ?::core::marker::Sized>
326+
UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for T {}
327327
impl #impl_generics
328328
UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for #ident #ty_generics
329329
#whr

src/macros.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -931,15 +931,15 @@ macro_rules! __pin_data {
931931
// if it also implements `Drop`
932932
trait MustNotImplDrop {}
933933
#[expect(drop_bounds)]
934-
impl<T: ::core::ops::Drop> MustNotImplDrop for T {}
934+
impl<T: ::core::ops::Drop + ?::core::marker::Sized> MustNotImplDrop for T {}
935935
impl<$($impl_generics)*> MustNotImplDrop for $name<$($ty_generics)*>
936936
where $($whr)* {}
937937
// We also take care to prevent users from writing a useless `PinnedDrop` implementation.
938938
// They might implement `PinnedDrop` correctly for the struct, but forget to give
939939
// `PinnedDrop` as the parameter to `#[pin_data]`.
940940
#[expect(non_camel_case_types)]
941941
trait UselessPinnedDropImpl_you_need_to_specify_PinnedDrop {}
942-
impl<T: $crate::PinnedDrop>
942+
impl<T: $crate::PinnedDrop + ?::core::marker::Sized>
943943
UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for T {}
944944
impl<$($impl_generics)*>
945945
UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for $name<$($ty_generics)*>

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,12 @@ const _: () = {
5656
{}
5757
trait MustNotImplDrop {}
5858
#[expect(drop_bounds)]
59-
impl<T: ::core::ops::Drop> MustNotImplDrop for T {}
59+
impl<T: ::core::ops::Drop + ?::core::marker::Sized> MustNotImplDrop for T {}
6060
impl MustNotImplDrop for Foo {}
6161
#[expect(non_camel_case_types)]
6262
trait UselessPinnedDropImpl_you_need_to_specify_PinnedDrop {}
63-
impl<T: ::pin_init::PinnedDrop> UselessPinnedDropImpl_you_need_to_specify_PinnedDrop
64-
for T {}
63+
impl<
64+
T: ::pin_init::PinnedDrop + ?::core::marker::Sized,
65+
> UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for T {}
6566
impl UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for Foo {}
6667
};

0 commit comments

Comments
 (0)