aboutsummaryrefslogtreecommitdiff
path: root/tests/pin_project.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/pin_project.rs')
-rw-r--r--tests/pin_project.rs214
1 files changed, 142 insertions, 72 deletions
diff --git a/tests/pin_project.rs b/tests/pin_project.rs
index 72bcd15..766887f 100644
--- a/tests/pin_project.rs
+++ b/tests/pin_project.rs
@@ -1,16 +1,15 @@
#![warn(rust_2018_idioms, single_use_lifetimes)]
#![allow(dead_code)]
-use core::{
+use pin_project::{pin_project, pinned_drop, UnsafeUnpin};
+use std::{
marker::{PhantomData, PhantomPinned},
pin::Pin,
};
-use pin_project::{pin_project, pinned_drop, UnsafeUnpin};
#[test]
fn projection() {
#[pin_project(
- Replace,
project = StructProj,
project_ref = StructProjRef,
project_replace = StructProjOwn,
@@ -53,7 +52,7 @@ fn projection() {
assert_eq!(s.field1, 3);
assert_eq!(s.field2, 4);
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
struct TupleStruct<T, U>(#[pin] T, U);
let mut s = TupleStruct(1, 2);
@@ -65,7 +64,7 @@ fn projection() {
let y: &mut i32 = s.1;
assert_eq!(*y, 2);
- #[pin_project(Replace, project = EnumProj)]
+ #[pin_project(project_replace, project = EnumProj)]
#[derive(Eq, PartialEq, Debug)]
enum Enum<A, B, C, D> {
Variant1(#[pin] A, B),
@@ -127,7 +126,7 @@ fn projection() {
#[test]
fn enum_project_set() {
- #[pin_project(Replace, project = EnumProj)]
+ #[pin_project(project_replace, project = EnumProj)]
#[derive(Eq, PartialEq, Debug)]
enum Enum {
Variant1(#[pin] u8),
@@ -175,7 +174,7 @@ fn where_clause() {
#[test]
fn where_clause_and_associated_type_field() {
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
struct Struct1<I>
where
I: Iterator,
@@ -185,7 +184,7 @@ fn where_clause_and_associated_type_field() {
field2: I::Item,
}
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
struct Struct2<I, J>
where
I: Iterator<Item = J>,
@@ -195,7 +194,7 @@ fn where_clause_and_associated_type_field() {
field2: J,
}
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
struct Struct3<T>
where
T: 'static,
@@ -207,12 +206,12 @@ fn where_clause_and_associated_type_field() {
impl<T> Static for Struct3<T> {}
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
struct TupleStruct<I>(#[pin] I, I::Item)
where
I: Iterator;
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
enum Enum<I>
where
I: Iterator,
@@ -224,7 +223,7 @@ fn where_clause_and_associated_type_field() {
#[test]
fn derive_copy() {
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
#[derive(Clone, Copy)]
struct Struct<T> {
val: T,
@@ -239,7 +238,7 @@ fn derive_copy() {
fn move_out() {
struct NotCopy;
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
struct Struct {
val: NotCopy,
}
@@ -247,7 +246,7 @@ fn move_out() {
let x = Struct { val: NotCopy };
let _val: NotCopy = x.val;
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
enum Enum {
Variant(NotCopy),
}
@@ -261,39 +260,39 @@ fn move_out() {
#[test]
fn trait_bounds_on_type_generics() {
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
pub struct Struct1<'a, T: ?Sized> {
field: &'a mut T,
}
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
pub struct Struct2<'a, T: ::core::fmt::Debug> {
field: &'a mut T,
}
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
pub struct Struct3<'a, T: core::fmt::Debug> {
field: &'a mut T,
}
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
pub struct Struct4<'a, T: core::fmt::Debug + core::fmt::Display> {
field: &'a mut T,
}
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
pub struct Struct5<'a, T: core::fmt::Debug + ?Sized> {
field: &'a mut T,
}
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
pub struct Struct6<'a, T: core::fmt::Debug = [u8; 16]> {
field: &'a mut T,
}
let _: Struct6<'_> = Struct6 { field: &mut [0u8; 16] };
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
pub struct Struct7<T: 'static> {
field: T,
}
@@ -302,16 +301,16 @@ fn trait_bounds_on_type_generics() {
impl<T> Static for Struct7<T> {}
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
pub struct Struct8<'a, 'b: 'a> {
field1: &'a u8,
field2: &'b u8,
}
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
pub struct TupleStruct<'a, T: ?Sized>(&'a mut T);
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
enum Enum<'a, T: ?Sized> {
Variant(&'a mut T),
}
@@ -319,13 +318,13 @@ fn trait_bounds_on_type_generics() {
#[test]
fn overlapping_lifetime_names() {
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
pub struct Struct1<'pin, T> {
#[pin]
field: &'pin mut T,
}
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
pub struct Struct2<'pin, 'pin_, 'pin__> {
#[pin]
field: &'pin &'pin_ &'pin__ (),
@@ -334,7 +333,7 @@ fn overlapping_lifetime_names() {
pub trait A<'a> {}
#[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
pub struct HRTB<'pin___, T>
where
for<'pin> &'pin T: Unpin,
@@ -349,39 +348,39 @@ fn overlapping_lifetime_names() {
#[test]
fn combine() {
#[pin_project(PinnedDrop, UnsafeUnpin)]
- pub struct Struct1<T> {
+ pub struct PinnedDropWithUnsafeUnpin<T> {
#[pin]
field: T,
}
#[pinned_drop]
- impl<T> PinnedDrop for Struct1<T> {
+ impl<T> PinnedDrop for PinnedDropWithUnsafeUnpin<T> {
fn drop(self: Pin<&mut Self>) {}
}
- unsafe impl<T: Unpin> UnsafeUnpin for Struct1<T> {}
+ unsafe impl<T: Unpin> UnsafeUnpin for PinnedDropWithUnsafeUnpin<T> {}
- #[pin_project(UnsafeUnpin, Replace)]
- pub struct Struct2<T> {
+ #[pin_project(PinnedDrop, !Unpin)]
+ pub struct PinnedDropWithNotUnpin<T> {
#[pin]
field: T,
}
- unsafe impl<T: Unpin> UnsafeUnpin for Struct2<T> {}
+ #[pinned_drop]
+ impl<T> PinnedDrop for PinnedDropWithNotUnpin<T> {
+ fn drop(self: Pin<&mut Self>) {}
+ }
- #[pin_project(PinnedDrop, !Unpin)]
- pub struct Struct3<T> {
+ #[pin_project(UnsafeUnpin, project_replace)]
+ pub struct UnsafeUnpinWithReplace<T> {
#[pin]
field: T,
}
- #[pinned_drop]
- impl<T> PinnedDrop for Struct3<T> {
- fn drop(self: Pin<&mut Self>) {}
- }
+ unsafe impl<T: Unpin> UnsafeUnpin for UnsafeUnpinWithReplace<T> {}
- #[pin_project(!Unpin, Replace)]
- pub struct Struct4<T> {
+ #[pin_project(!Unpin, project_replace)]
+ pub struct NotUnpinWithReplace<T> {
#[pin]
field: T,
}
@@ -389,7 +388,7 @@ fn combine() {
#[test]
fn private_type_in_public_type() {
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
pub struct PublicStruct<T> {
#[pin]
inner: PrivateStruct<T>,
@@ -400,21 +399,21 @@ fn private_type_in_public_type() {
#[test]
fn lifetime_project() {
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
struct Struct1<T, U> {
#[pin]
pinned: T,
unpinned: U,
}
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
struct Struct2<'a, T, U> {
#[pin]
pinned: &'a mut T,
unpinned: U,
}
- #[pin_project(Replace, project = EnumProj, project_ref = EnumProjRef)]
+ #[pin_project(project_replace, project = EnumProj, project_ref = EnumProjRef)]
enum Enum<T, U> {
Variant {
#[pin]
@@ -458,21 +457,21 @@ fn lifetime_project() {
#[rustversion::since(1.36)] // https://github.com/rust-lang/rust/pull/61207
#[test]
fn lifetime_project_elided() {
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
struct Struct1<T, U> {
#[pin]
pinned: T,
unpinned: U,
}
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
struct Struct2<'a, T, U> {
#[pin]
pinned: &'a mut T,
unpinned: U,
}
- #[pin_project(Replace, project = EnumProj, project_ref = EnumProjRef)]
+ #[pin_project(project_replace, project = EnumProj, project_ref = EnumProjRef)]
enum Enum<T, U> {
Variant {
#[pin]
@@ -516,7 +515,7 @@ fn lifetime_project_elided() {
mod visibility {
use pin_project::pin_project;
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
pub(crate) struct A {
pub b: u8,
}
@@ -534,7 +533,7 @@ fn visibility() {
#[test]
fn trivial_bounds() {
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
pub struct NoGenerics {
#[pin]
field: PhantomPinned,
@@ -709,34 +708,102 @@ fn dyn_type() {
}
#[test]
-fn self_in_where_clause() {
- pub trait Trait1 {}
+fn parse_self() {
+ macro_rules! mac {
+ ($($tt:tt)*) => {
+ $($tt)*
+ };
+ }
+
+ pub trait Trait {
+ type Assoc;
+ }
- #[pin_project(Replace)]
- pub struct Struct1<T>
+ #[pin_project(project_replace)]
+ pub struct Generics<T: Trait<Assoc = Self>>
where
- Self: Trait1,
+ Self: Trait<Assoc = Self>,
+ <Self as Trait>::Assoc: Sized,
+ mac!(Self): Trait<Assoc = mac!(Self)>,
{
- x: T,
+ _f: T,
}
- impl<T> Trait1 for Struct1<T> {}
+ impl<T: Trait<Assoc = Self>> Trait for Generics<T> {
+ type Assoc = Self;
+ }
- pub trait Trait2 {
- type Assoc;
+ #[pin_project(project_replace)]
+ pub struct Struct {
+ _f1: Box<Self>,
+ _f2: Box<<Self as Trait>::Assoc>,
+ _f3: Box<mac!(Self)>,
+ _f4: [(); Self::ASSOC],
+ _f5: [(); Self::assoc()],
+ _f6: [(); mac!(Self::assoc())],
}
- #[pin_project(Replace)]
- pub struct Struct2<T>
- where
- Self: Trait2<Assoc = Struct1<T>>,
- <Self as Trait2>::Assoc: Trait1,
- {
- x: T,
+ impl Struct {
+ const ASSOC: usize = 1;
+ const fn assoc() -> usize {
+ 0
+ }
+ }
+
+ impl Trait for Struct {
+ type Assoc = Self;
+ }
+
+ #[pin_project(project_replace)]
+ struct Tuple(
+ Box<Self>,
+ Box<<Self as Trait>::Assoc>,
+ Box<mac!(Self)>,
+ [(); Self::ASSOC],
+ [(); Self::assoc()],
+ [(); mac!(Self::assoc())],
+ );
+
+ impl Tuple {
+ const ASSOC: usize = 1;
+ const fn assoc() -> usize {
+ 0
+ }
+ }
+
+ impl Trait for Tuple {
+ type Assoc = Self;
+ }
+
+ #[pin_project(project_replace)]
+ enum Enum {
+ Struct {
+ _f1: Box<Self>,
+ _f2: Box<<Self as Trait>::Assoc>,
+ _f3: Box<mac!(Self)>,
+ _f4: [(); Self::ASSOC],
+ _f5: [(); Self::assoc()],
+ _f6: [(); mac!(Self::assoc())],
+ },
+ Tuple(
+ Box<Self>,
+ Box<<Self as Trait>::Assoc>,
+ Box<mac!(Self)>,
+ [(); Self::ASSOC],
+ [(); Self::assoc()],
+ [(); mac!(Self::assoc())],
+ ),
+ }
+
+ impl Enum {
+ const ASSOC: usize = 1;
+ const fn assoc() -> usize {
+ 0
+ }
}
- impl<T> Trait2 for Struct2<T> {
- type Assoc = Struct1<T>;
+ impl Trait for Enum {
+ type Assoc = Self;
}
}
@@ -752,7 +819,7 @@ fn no_infer_outlives() {
type Y = Option<T>;
}
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
struct Foo<A, B> {
_x: <Example<A> as Bar<B>>::Y,
}
@@ -760,11 +827,12 @@ fn no_infer_outlives() {
// https://github.com/rust-lang/rust/issues/47949
// https://github.com/taiki-e/pin-project/pull/194#discussion_r419098111
+#[allow(clippy::many_single_char_names)]
#[test]
fn project_replace_panic() {
use std::panic;
- #[pin_project(Replace)]
+ #[pin_project(project_replace)]
struct S<T, U> {
#[pin]
pinned: T,
@@ -786,7 +854,8 @@ fn project_replace_panic() {
let mut x = S { pinned: D(&mut a, true), unpinned: D(&mut b, false) };
let _y = Pin::new(&mut x)
.project_replace(S { pinned: D(&mut c, false), unpinned: D(&mut d, false) });
- // Previous `x.pinned` was dropped and panicked when `project_replace` is called, so this is unreachable.
+ // Previous `x.pinned` was dropped and panicked when `project_replace` is
+ // called, so this is unreachable.
unreachable!();
}));
assert!(res.is_err());
@@ -801,7 +870,8 @@ fn project_replace_panic() {
{
let _y = Pin::new(&mut x)
.project_replace(S { pinned: D(&mut c, false), unpinned: D(&mut d, false) });
- // `_y` (previous `x.unpinned`) live to the end of this scope, so this is not unreachable,
+ // `_y` (previous `x.unpinned`) live to the end of this scope, so
+ // this is not unreachable.
// unreachable!();
}
unreachable!();