Skip to content

Commit dc45151

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 <benno.lossin@proton.me>
1 parent 51b1934 commit dc45151

3 files changed

Lines changed: 9 additions & 8 deletions

File tree

internal/src/syn_pin_data.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ fn drop_impl(
337337
// if it also implements `Drop`
338338
trait MustNotImplDrop {}
339339
#[expect(drop_bounds)]
340-
impl<T: ::core::ops::Drop> MustNotImplDrop for T {}
340+
impl<T: ::core::ops::Drop + ?::core::marker::Sized> MustNotImplDrop for T {}
341341
impl #impl_generics MustNotImplDrop for #ident #ty_generics
342342
#whr
343343
{}
@@ -346,8 +346,8 @@ fn drop_impl(
346346
// `PinnedDrop` as the parameter to `#[pin_data]`.
347347
#[expect(non_camel_case_types)]
348348
trait UselessPinnedDropImpl_you_need_to_specify_PinnedDrop {}
349-
impl<T: ::pin_init::PinnedDrop> UselessPinnedDropImpl_you_need_to_specify_PinnedDrop
350-
for T {}
349+
impl<T: ::pin_init::PinnedDrop + ?::core::marker::Sized>
350+
UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for T {}
351351
impl #impl_generics
352352
UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for #ident #ty_generics
353353
#whr

src/macros.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -942,15 +942,15 @@ macro_rules! __pin_data {
942942
// if it also implements `Drop`
943943
trait MustNotImplDrop {}
944944
#[expect(drop_bounds)]
945-
impl<T: ::core::ops::Drop> MustNotImplDrop for T {}
945+
impl<T: ::core::ops::Drop + ?::core::marker::Sized> MustNotImplDrop for T {}
946946
impl<$($impl_generics)*> MustNotImplDrop for $name<$($ty_generics)*>
947947
where $($whr)* {}
948948
// We also take care to prevent users from writing a useless `PinnedDrop` implementation.
949949
// They might implement `PinnedDrop` correctly for the struct, but forget to give
950950
// `PinnedDrop` as the parameter to `#[pin_data]`.
951951
#[expect(non_camel_case_types)]
952952
trait UselessPinnedDropImpl_you_need_to_specify_PinnedDrop {}
953-
impl<T: $crate::PinnedDrop>
953+
impl<T: $crate::PinnedDrop + ?::core::marker::Sized>
954954
UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for T {}
955955
impl<$($impl_generics)*>
956956
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
@@ -68,11 +68,12 @@ const _: () = {
6868
{}
6969
trait MustNotImplDrop {}
7070
#[expect(drop_bounds)]
71-
impl<T: ::core::ops::Drop> MustNotImplDrop for T {}
71+
impl<T: ::core::ops::Drop + ?::core::marker::Sized> MustNotImplDrop for T {}
7272
impl MustNotImplDrop for Foo {}
7373
#[expect(non_camel_case_types)]
7474
trait UselessPinnedDropImpl_you_need_to_specify_PinnedDrop {}
75-
impl<T: ::pin_init::PinnedDrop> UselessPinnedDropImpl_you_need_to_specify_PinnedDrop
76-
for T {}
75+
impl<
76+
T: ::pin_init::PinnedDrop + ?::core::marker::Sized,
77+
> UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for T {}
7778
impl UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for Foo {}
7879
};

0 commit comments

Comments
 (0)