blob: 4d58d68f29439c14c8defc84dfed4bed083d3743 [file] [log] [blame]
// 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)]
use pin_project::pin_project;
struct Struct<T, U> {
// #[pin]
pinned: T,
unpinned: U,
}
#[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`.
#[allow(dead_code)] // This lint warns unused fields/variants.
struct __StructProjection<'pin, T, U> {
pinned: ::core::pin::Pin<&'pin mut (T)>,
unpinned: &'pin mut (U),
}
#[allow(dead_code)] // This lint warns unused fields/variants.
struct __StructProjectionRef<'pin, T, U> {
pinned: ::core::pin::Pin<&'pin (T)>,
unpinned: &'pin (U),
}
impl<T, U> Struct<T, U> {
fn project<'pin>(self: ::core::pin::Pin<&'pin mut Self>) -> __StructProjection<'pin, T, U> {
unsafe {
let Struct { pinned, unpinned } = self.get_unchecked_mut();
__StructProjection { pinned: ::core::pin::Pin::new_unchecked(pinned), unpinned }
}
}
fn project_ref<'pin>(self: ::core::pin::Pin<&'pin Self>) -> __StructProjectionRef<'pin, T, U> {
unsafe {
let Struct { pinned, unpinned } = self.get_ref();
__StructProjectionRef { pinned: ::core::pin::Pin::new_unchecked(pinned), 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 delcared within
// a function, which makes it impossible to be named by user code.
// This guarnatees 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', satisfiying 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.
#[allow(non_snake_case)]
fn __unpin_scope_Struct() {
struct __Struct<'pin, T, U> {
__pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<'pin, (T, U)>,
__field0: T,
}
impl<'pin, T, U> ::core::marker::Unpin for Struct<T, U> where
__Struct<'pin, T, U>: ::core::marker::Unpin
{
}
}
// Ensure that struct does not implement `Drop`.
//
// There are two possible cases:
// 1. The user type does not implement Drop. In this case,
// the first blanked impl will not apply to it. This code
// will compile, as there is only one impl of MustNotImplDrop for the user type
// 2. The user type does impl Drop. This will make the blanket impl applicable,
// which will then comflict with the explicit MustNotImplDrop impl below.
// This will result in a compilation error, which is exactly what we want.
trait StructMustNotImplDrop {}
#[allow(clippy::drop_bounds)]
impl<T: ::core::ops::Drop> StructMustNotImplDrop for T {}
#[allow(single_use_lifetimes)]
impl<T, U> StructMustNotImplDrop for Struct<T, U> {}
// Ensure that it's impossible to use pin projections on a #[repr(packed)] struct.
//
// Taking a reference to a packed field is unsafe, amd appplying
// #[deny(safe_packed_borrows)] makes sure that doing this without
// an 'unsafe' block (which we deliberately do not generate)
// 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.
#[allow(single_use_lifetimes)]
#[allow(non_snake_case)]
#[deny(safe_packed_borrows)]
fn __pin_project_assert_not_repr_packed_Struct<T, U>(val: &Struct<T, U>) {
&val.pinned;
&val.unpinned;
}
fn main() {}