| 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 | |