1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
// Original code (./struct-default.rs):
//
// ```rust
// #![allow(dead_code)]
//
// use pin_project::pin_project;
//
// #[pin_project]
// struct Struct<T, U> {
// #[pin]
// pinned: T,
// unpinned: U,
// }
//
// fn main() {}
// ```
#![allow(dead_code, unused_imports, unused_parens, unknown_lints, renamed_and_removed_lints)]
#![allow(clippy::needless_lifetimes)]
use pin_project::pin_project;
// #[pin_project]
struct Struct<T, U> {
// #[pin]
pinned: T,
unpinned: U,
}
const _: () = {
struct __StructProjection<'pin, T, U>
where
Struct<T, U>: 'pin,
{
pinned: ::pin_project::__private::Pin<&'pin mut (T)>,
unpinned: &'pin mut (U),
}
struct __StructProjectionRef<'pin, T, U>
where
Struct<T, U>: 'pin,
{
pinned: ::pin_project::__private::Pin<&'pin (T)>,
unpinned: &'pin (U),
}
impl<T, U> Struct<T, U> {
fn project<'pin>(
self: ::pin_project::__private::Pin<&'pin mut Self>,
) -> __StructProjection<'pin, T, U> {
unsafe {
let Self { pinned, unpinned } = self.get_unchecked_mut();
__StructProjection {
pinned: ::pin_project::__private::Pin::new_unchecked(pinned),
unpinned,
}
}
}
fn project_ref<'pin>(
self: ::pin_project::__private::Pin<&'pin Self>,
) -> __StructProjectionRef<'pin, T, U> {
unsafe {
let Self { pinned, unpinned } = self.get_ref();
__StructProjectionRef {
pinned: ::pin_project::__private::Pin::new_unchecked(pinned),
unpinned,
}
}
}
}
// Ensure that it's impossible to use pin projections on a #[repr(packed)]
// struct.
//
// Taking a reference to a packed field is UB, and applying
// `#[forbid(unaligned_references)]` makes sure that doing this is a hard error.
//
// If the struct ends up having #[repr(packed)] applied somehow,
// this will generate an (unfriendly) error message. Under all reasonable
// circumstances, we'll detect the #[repr(packed)] attribute, and generate
// a much nicer error above.
//
// See https://github.com/taiki-e/pin-project/pull/34 for more details.
#[forbid(unaligned_references, safe_packed_borrows)]
fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
let _ = &this.pinned;
let _ = &this.unpinned;
}
// Automatically create the appropriate conditional `Unpin` implementation.
//
// Basically this is equivalent to the following code:
//
// ```rust
// impl<T, U> Unpin for Struct<T, U> where T: Unpin {}
// ```
//
// However, if struct is public and there is a private type field,
// this would cause an E0446 (private type in public interface).
//
// When RFC 2145 is implemented (rust-lang/rust#48054),
// this will become a lint, rather then a hard error.
//
// As a workaround for this, we generate a new struct, containing all of
// the pinned fields from our #[pin_project] type. This struct is declared
// within a function, which makes it impossible to be named by user code.
// This guarantees that it will use the default auto-trait impl for Unpin -
// that is, it will implement Unpin iff all of its fields implement Unpin.
// This type can be safely declared as 'public', satisfying the privacy
// checker without actually allowing user code to access it.
//
// This allows users to apply the #[pin_project] attribute to types
// regardless of the privacy of the types of their fields.
//
// See also https://github.com/taiki-e/pin-project/pull/53.
struct __Struct<'pin, T, U> {
__pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<
'pin,
(::pin_project::__private::PhantomData<T>, ::pin_project::__private::PhantomData<U>),
>,
__field0: T,
}
impl<'pin, T, U> ::pin_project::__private::Unpin for Struct<T, U> where
__Struct<'pin, T, U>: ::pin_project::__private::Unpin
{
}
// A dummy impl of `UnsafeUnpin`, to ensure that the user cannot implement it.
//
// To ensure that users don't accidentally write a non-functional `UnsafeUnpin`
// impls, we emit one ourselves. If the user ends up writing an `UnsafeUnpin`
// impl, they'll get a "conflicting implementations of trait" error when
// coherence checks are run.
#[doc(hidden)]
unsafe impl<'pin, T, U> ::pin_project::UnsafeUnpin for Struct<T, U> where
__Struct<'pin, T, U>: ::pin_project::__private::Unpin
{
}
// Ensure that struct does not implement `Drop`.
//
// If you attempt to provide an Drop impl, the blanket impl will
// then apply to your type, causing a compile-time error due to
// the conflict with the second impl.
trait StructMustNotImplDrop {}
#[allow(clippy::drop_bounds, drop_bounds)]
impl<T: ::pin_project::__private::Drop> StructMustNotImplDrop for T {}
impl<T, U> StructMustNotImplDrop for Struct<T, U> {}
// A dummy impl of `PinnedDrop`, to ensure that users don't accidentally
// write a non-functional `PinnedDrop` impls.
#[doc(hidden)]
impl<T, U> ::pin_project::__private::PinnedDrop for Struct<T, U> {
unsafe fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
}
};
fn main() {}
|