1 | #![warn (rust_2018_idioms, single_use_lifetimes)] |
2 | #![allow (dead_code)] |
3 | |
4 | // Refs: https://doc.rust-lang.org/reference/attributes.html |
5 | |
6 | #[macro_use ] |
7 | mod auxiliary; |
8 | |
9 | use std::{marker::PhantomPinned, pin::Pin}; |
10 | |
11 | use pin_project::pin_project ; |
12 | |
13 | struct Always; |
14 | |
15 | // Use this type to check that `cfg(any())` is working properly. |
16 | struct Never(PhantomPinned); |
17 | |
18 | #[test] |
19 | fn cfg() { |
20 | // structs |
21 | |
22 | #[pin_project (project_replace)] |
23 | struct SameName { |
24 | #[cfg (not(any()))] |
25 | #[pin] |
26 | inner: Always, |
27 | #[cfg (any())] |
28 | #[pin] |
29 | inner: Never, |
30 | } |
31 | |
32 | assert_unpin!(SameName); |
33 | |
34 | let _ = SameName { inner: Always }; |
35 | |
36 | #[pin_project (project_replace)] |
37 | struct DifferentName { |
38 | #[cfg (not(any()))] |
39 | #[pin] |
40 | a: Always, |
41 | #[cfg (any())] |
42 | #[pin] |
43 | n: Never, |
44 | } |
45 | |
46 | assert_unpin!(DifferentName); |
47 | |
48 | let _ = DifferentName { a: Always }; |
49 | |
50 | #[pin_project (project_replace)] |
51 | struct TupleStruct( |
52 | #[cfg (not(any()))] |
53 | #[pin] |
54 | Always, |
55 | #[cfg (any())] |
56 | #[pin] |
57 | Never, |
58 | ); |
59 | |
60 | assert_unpin!(TupleStruct); |
61 | |
62 | let _ = TupleStruct(Always); |
63 | |
64 | // enums |
65 | |
66 | #[pin_project ( |
67 | project = VariantProj, |
68 | project_ref = VariantProjRef, |
69 | project_replace = VariantProjOwn, |
70 | )] |
71 | enum Variant { |
72 | #[cfg (not(any()))] |
73 | Inner(#[pin] Always), |
74 | #[cfg (any())] |
75 | Inner(#[pin] Never), |
76 | |
77 | #[cfg (not(any()))] |
78 | A(#[pin] Always), |
79 | #[cfg (any())] |
80 | N(#[pin] Never), |
81 | } |
82 | |
83 | assert_unpin!(Variant); |
84 | |
85 | let _ = Variant::Inner(Always); |
86 | let _ = Variant::A(Always); |
87 | |
88 | #[pin_project ( |
89 | project = FieldProj, |
90 | project_ref = FieldProjRef, |
91 | project_replace = FieldProjOwn, |
92 | )] |
93 | enum Field { |
94 | SameName { |
95 | #[cfg (not(any()))] |
96 | #[pin] |
97 | inner: Always, |
98 | #[cfg (any())] |
99 | #[pin] |
100 | inner: Never, |
101 | }, |
102 | DifferentName { |
103 | #[cfg (not(any()))] |
104 | #[pin] |
105 | a: Always, |
106 | #[cfg (any())] |
107 | #[pin] |
108 | n: Never, |
109 | }, |
110 | TupleVariant( |
111 | #[cfg (not(any()))] |
112 | #[pin] |
113 | Always, |
114 | #[cfg (any())] |
115 | #[pin] |
116 | Never, |
117 | ), |
118 | } |
119 | |
120 | assert_unpin!(Field); |
121 | |
122 | let _ = Field::SameName { inner: Always }; |
123 | let _ = Field::DifferentName { a: Always }; |
124 | let _ = Field::TupleVariant(Always); |
125 | } |
126 | |
127 | #[test] |
128 | fn cfg_attr() { |
129 | #[pin_project (project_replace)] |
130 | struct SameCfg { |
131 | #[cfg (not(any()))] |
132 | #[cfg_attr (not(any()), pin)] |
133 | inner: Always, |
134 | #[cfg (any())] |
135 | #[cfg_attr (any(), pin)] |
136 | inner: Never, |
137 | } |
138 | |
139 | assert_unpin!(SameCfg); |
140 | |
141 | let mut x = SameCfg { inner: Always }; |
142 | let x = Pin::new(&mut x).project(); |
143 | let _: Pin<&mut Always> = x.inner; |
144 | |
145 | #[pin_project (project_replace)] |
146 | struct DifferentCfg { |
147 | #[cfg (not(any()))] |
148 | #[cfg_attr (any(), pin)] |
149 | inner: Always, |
150 | #[cfg (any())] |
151 | #[cfg_attr (not(any()), pin)] |
152 | inner: Never, |
153 | } |
154 | |
155 | assert_unpin!(DifferentCfg); |
156 | |
157 | let mut x = DifferentCfg { inner: Always }; |
158 | let x = Pin::new(&mut x).project(); |
159 | let _: &mut Always = x.inner; |
160 | |
161 | #[cfg_attr (not(any()), pin_project)] |
162 | struct Foo<T> { |
163 | #[cfg_attr (not(any()), pin)] |
164 | inner: T, |
165 | } |
166 | |
167 | assert_unpin!(Foo<()>); |
168 | assert_not_unpin!(Foo<PhantomPinned>); |
169 | |
170 | let mut x = Foo { inner: 0_u8 }; |
171 | let x = Pin::new(&mut x).project(); |
172 | let _: Pin<&mut u8> = x.inner; |
173 | } |
174 | |
175 | #[test] |
176 | fn cfg_attr_any_packed() { |
177 | // Since `cfg(any())` can never be true, it is okay for this to pass. |
178 | #[pin_project (project_replace)] |
179 | #[cfg_attr (any(), repr(packed))] |
180 | struct Struct { |
181 | #[pin] |
182 | f: u32, |
183 | } |
184 | } |
185 | |