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  }