lib.rs
1 #![cfg_attr( 2 // The "test" feature is currently unrecognized by the `cfg_rust_features` crate, and so this 3 // demonstrates and exercises the design pattern of using `cfg` with such in anticipation of 4 // the possibility of it becoming both recognized and stable. This design pattern is 5 // intentionally supported by the `cfg_rust_features` crate. 6 all(not(rust_lib_feature = "test"), rust_comp_feature = "unstable_features"), 7 // A nightly (or dev) compiler is being used and the feature is still unstable. 8 feature(test) 9 )] 10 #![cfg_attr( 11 special_dev_test = "enable-unstable-features", 12 // For development testing, pretend that the recognized features have become stable. 13 feature( 14 arbitrary_self_types, 15 cfg_version, 16 destructuring_assignment, 17 error_in_core, 18 inner_deref, 19 iter_zip, 20 never_type, 21 question_mark, 22 step_trait, 23 unwrap_infallible, 24 ) 25 )] 26 27 // Similar to above, this uses a currently-unrecognized feature. 28 #[cfg(any(rust_lib_feature = "test", rust_comp_feature = "unstable_features"))] 29 // Either: the feature has become stable, or a nightly (or dev) compiler is being used. 30 extern crate test; 31 32 #[cfg(test)] 33 mod tests 34 { 35 #[allow(dead_code)] 36 mod never_type_hack 37 { 38 pub type Never = <F as HasOutput>::Output; 39 40 pub trait HasOutput 41 { 42 type Output; 43 } 44 45 impl<O> HasOutput for fn() -> O 46 { 47 type Output = O; 48 } 49 50 pub type F = fn() -> !; 51 } 52 53 #[cfg(rust_lang_feature = "arbitrary_self_types")] 54 #[test] 55 fn arbitrary_self_types() 56 { 57 struct Wrap<T>(T); 58 59 impl<T> core::ops::Deref for Wrap<T> 60 { 61 type Target = T; 62 63 fn deref(&self) -> &Self::Target 64 { 65 &self.0 66 } 67 } 68 69 trait Trait 70 { 71 fn trait_method(self: Wrap<&Self>) -> &Self 72 { 73 &self.0 74 } 75 } 76 77 struct Thing<T>(T); 78 79 impl<T> Trait for Thing<T> {} 80 81 impl<T: Copy> Thing<T> 82 { 83 fn inherent_method(self: &Wrap<Self>) -> T 84 { 85 (self.0).0 86 } 87 } 88 89 assert!(Wrap(&Thing(true)).trait_method().0); 90 assert!(Wrap(Thing(true)).inherent_method()); 91 } 92 93 #[cfg(rust_lang_feature = "cfg_version")] 94 #[test] 95 fn cfg_version() 96 { 97 // Prevent old Rust versions from erroring on the attribute syntax. 98 macro_rules! shield { 99 () => { 100 #[cfg(version("1.0.0"))] 101 struct S; 102 let _ = S; 103 }; 104 } 105 shield!(); 106 } 107 108 #[cfg(rust_lang_feature = "destructuring_assignment")] 109 #[test] 110 fn destructuring_assignment() 111 { 112 let (a, b); 113 (a, b) = (true, false); 114 assert_ne!(a, b); 115 } 116 117 #[cfg(rust_lib_feature = "error_in_core")] 118 #[test] 119 fn error_in_core() 120 { 121 let e: &core::error::Error = &std::fmt::Error; 122 assert!(e.is::<std::fmt::Error>()); 123 } 124 125 #[cfg(rust_lib_feature = "inner_deref")] 126 #[test] 127 fn inner_deref() 128 { 129 assert_eq!(Ok(&1), Ok::<_, ()>(Box::new(1)).as_deref()); 130 } 131 132 #[cfg(rust_lib_feature = "iter_zip")] 133 #[test] 134 fn iter_zip() 135 { 136 assert_eq!(vec![(1, 2)], std::iter::zip([1], [2]).collect::<Vec<_>>()); 137 } 138 139 #[cfg(rust_lang_feature = "never_type")] 140 #[test] 141 fn never_type() 142 { 143 // Prevent old Rust versions from erroring on the `!` syntax. 144 macro_rules! shield { 145 () => { 146 let _: [!; 0] = []; 147 }; 148 } 149 shield!(); 150 } 151 152 #[cfg(rust_lang_feature = "question_mark")] 153 #[test] 154 fn question_mark() 155 { 156 // Prevent old Rust versions from erroring on the `?` syntax. 157 macro_rules! shield { 158 () => { 159 Err(())? 160 }; 161 } 162 fn f() -> Result<(), ()> 163 { 164 shield!() 165 } 166 assert_eq!(Err(()), f()); 167 } 168 169 #[cfg(rust_comp_feature = "rust1")] 170 #[test] 171 fn rust1_comp() {} 172 173 #[cfg(rust_lang_feature = "rust1")] 174 #[test] 175 fn rust1_lang() {} 176 177 #[cfg(rust_lib_feature = "rust1")] 178 #[test] 179 fn rust1_lib() {} 180 181 #[cfg(rust_lib_feature = "step_trait")] 182 #[test] 183 fn step_trait() 184 { 185 use std::iter::Step; 186 fn f<T: Step>(x: T) -> Option<T> 187 { 188 Step::forward_checked(x, 1) 189 } 190 assert_eq!(Some(2), f(1)) 191 } 192 193 // Similar to above, this exercises using a `cfg` option that is currently unsupported by the 194 // `cfg_rust_features` crate but that possibly could be supported in the future. 195 #[cfg(rust_lib_feature = "test")] 196 #[bench] 197 fn test(_bencher: &mut test::Bencher) {} 198 199 #[cfg(rust_comp_feature = "unstable_features")] 200 #[test] 201 fn unstable_features() 202 { 203 #![allow(dead_code)] 204 } 205 206 #[cfg(rust_lib_feature = "unwrap_infallible")] 207 #[test] 208 fn unwrap_infallible() 209 { 210 assert_eq!(1, Ok::<_, never_type_hack::Never>(1).into_ok()); 211 } 212 213 // This exercises using a non-existent feature that both Rust and the `cfg_rust_features` 214 // crate and will never support, and so this item should never be compiled. 215 #[cfg(rust_comp_feature = "SubGenius_Bogusness")] 216 #[test] 217 fn SubGenius_Bogusness() 218 { 219 assert!(false); 220 } 221 }