| #![allow(unused_must_use)] | |
| use std::{assert_matches, debug_assert_matches}; | |
| #[allow(dead_code)] | |
| trait Trait { | |
| fn blah(&self); | |
| } | |
| #[allow(dead_code)] | |
| struct Struct; | |
| impl Trait for Struct { | |
| cfg_select! { | |
| feature = "blah" => { | |
| fn blah(&self) { | |
| unimplemented!(); | |
| } | |
| } | |
| _ => { | |
| fn blah(&self) { | |
| unimplemented!(); | |
| } | |
| } | |
| } | |
| } | |
| #[test] | |
| fn assert_eq_trailing_comma() { | |
| assert_eq!(1, 1,); | |
| } | |
| #[test] | |
| fn assert_escape() { | |
| assert!(r#"☃\backslash"#.contains("\\")); | |
| } | |
| #[test] | |
| fn assert_ne_trailing_comma() { | |
| assert_ne!(1, 2,); | |
| } | |
| #[rustfmt::skip] | |
| #[test] | |
| fn matches_leading_pipe() { | |
| matches!(1, | 1 | 2 | 3); | |
| } | |
| #[test] | |
| fn cfg_select_basic() { | |
| cfg_select! { | |
| target_pointer_width = "64" => { | |
| fn f0_() -> bool { | |
| true | |
| } | |
| } | |
| _ => {} | |
| } | |
| cfg_select! { | |
| unix => { | |
| fn f1_() -> bool { | |
| true | |
| } | |
| } | |
| _ => { | |
| fn f1_() -> bool { | |
| false | |
| } | |
| } | |
| } | |
| cfg_select! { | |
| target_pointer_width = "32" => { | |
| fn f2_() -> bool { | |
| false | |
| } | |
| } | |
| target_pointer_width = "64" => { | |
| fn f2_() -> bool { | |
| true | |
| } | |
| } | |
| } | |
| cfg_select! { | |
| target_pointer_width = "16" => { | |
| fn f3_() -> i32 { | |
| 1 | |
| } | |
| } | |
| _ => { | |
| fn f3_() -> i32 { | |
| 2 | |
| } | |
| } | |
| } | |
| #[cfg(target_pointer_width = "64")] | |
| assert!(f0_()); | |
| #[cfg(unix)] | |
| assert!(f1_()); | |
| #[cfg(not(unix))] | |
| assert!(!f1_()); | |
| #[cfg(target_pointer_width = "32")] | |
| assert!(!f2_()); | |
| #[cfg(target_pointer_width = "64")] | |
| assert!(f2_()); | |
| #[cfg(not(target_pointer_width = "16"))] | |
| assert_eq!(f3_(), 2); | |
| } | |
| #[test] | |
| fn cfg_select_debug_assertions() { | |
| cfg_select! { | |
| debug_assertions => { | |
| assert!(cfg!(debug_assertions)); | |
| assert_eq!(4, 2 + 2); | |
| } | |
| _ => { | |
| assert!(cfg!(not(debug_assertions))); | |
| assert_eq!(10, 5 + 5); | |
| } | |
| } | |
| } | |
| #[cfg(target_pointer_width = "64")] | |
| #[test] | |
| fn cfg_select_no_duplication_on_64() { | |
| cfg_select! { | |
| windows => { | |
| fn foo() {} | |
| } | |
| unix => { | |
| fn foo() {} | |
| } | |
| target_pointer_width = "64" => { | |
| fn foo() {} | |
| } | |
| } | |
| foo(); | |
| } | |
| #[test] | |
| fn cfg_select_options() { | |
| cfg_select! { | |
| test => { | |
| use core::option::Option as Option2; | |
| fn works1() -> Option2<u32> { | |
| Some(1) | |
| } | |
| } | |
| _ => { | |
| fn works1() -> Option<u32> { | |
| None | |
| } | |
| } | |
| } | |
| cfg_select! { | |
| feature = "foo" => { | |
| fn works2() -> bool { | |
| false | |
| } | |
| } | |
| test => { | |
| fn works2() -> bool { | |
| true | |
| } | |
| } | |
| _ => { | |
| fn works2() -> bool { | |
| false | |
| } | |
| } | |
| } | |
| cfg_select! { | |
| feature = "foo" => { | |
| fn works3() -> bool { | |
| false | |
| } | |
| } | |
| _ => { | |
| fn works3() -> bool { | |
| true | |
| } | |
| } | |
| } | |
| cfg_select! { | |
| test => { | |
| use core::option::Option as Option3; | |
| fn works4() -> Option3<u32> { | |
| Some(1) | |
| } | |
| } | |
| } | |
| cfg_select! { | |
| feature = "foo" => { | |
| fn works5() -> bool { | |
| false | |
| } | |
| } | |
| test => { | |
| fn works5() -> bool { | |
| true | |
| } | |
| } | |
| } | |
| assert!(works1().is_some()); | |
| assert!(works2()); | |
| assert!(works3()); | |
| assert!(works4().is_some()); | |
| assert!(works5()); | |
| } | |
| #[test] | |
| fn cfg_select_two_functions() { | |
| cfg_select! { | |
| target_pointer_width = "64" => { | |
| fn foo1() {} | |
| fn bar1() {} | |
| } | |
| _ => { | |
| fn foo2() {} | |
| fn bar2() {} | |
| } | |
| } | |
| #[cfg(target_pointer_width = "64")] | |
| { | |
| foo1(); | |
| bar1(); | |
| } | |
| #[cfg(not(target_pointer_width = "64"))] | |
| { | |
| foo2(); | |
| bar2(); | |
| } | |
| } | |
| fn _accepts_expressions() -> i32 { | |
| cfg_select! { | |
| unix => 1, | |
| _ => 2, | |
| } | |
| } | |
| fn _accepts_only_wildcard() -> i32 { | |
| cfg_select! { | |
| _ => 1, | |
| } | |
| } | |
| // The current implementation expands to a macro call, which allows the use of expression | |
| // statements. | |
| fn _allows_stmt_expr_attributes() { | |
| let one = 1; | |
| let two = 2; | |
| cfg_select! { | |
| unix => { | |
| one * two; | |
| } | |
| _ => { | |
| one + two; | |
| } | |
| } | |
| } | |
| fn _expression() { | |
| let _ = cfg_select!( | |
| windows => " XP", | |
| _ => "", | |
| ); | |
| } | |
| #[deny(non_exhaustive_omitted_patterns)] | |
| fn _matches_does_not_trigger_non_exhaustive_omitted_patterns_lint(o: core::sync::atomic::Ordering) { | |
| // Ordering is a #[non_exhaustive] enum from a separate crate | |
| let _m = matches!(o, core::sync::atomic::Ordering::Relaxed); | |
| } | |
| struct MutRefWithDrop<'a>(&'a mut u32); | |
| // MutRefWithDrop needs to have a non-trivial drop to encounter potential lifetime issues if the | |
| // macros don't introduce a temporary scope. | |
| impl Drop for MutRefWithDrop<'_> { | |
| fn drop(&mut self) { | |
| *self.0 = u32::MAX; | |
| } | |
| } | |
| #[test] | |
| fn temporary_scope_introduction() { | |
| // Fails to compile if the macros don't introduce a temporary scope, since `&mut val` would | |
| // create a second mutable borrow while `MutRefWithDrop` still holds a unique ref. | |
| // See https://github.com/rust-lang/rust/issues/154406 for reference. | |
| let mut val = 0; | |
| (assert_matches!(*MutRefWithDrop(&mut val).0, 0), std::mem::take(&mut val)); | |
| (assert_matches!(*MutRefWithDrop(&mut val).0, 0, "msg"), std::mem::take(&mut val)); | |
| (debug_assert_matches!(*MutRefWithDrop(&mut val).0, 0), std::mem::take(&mut val)); | |
| (debug_assert_matches!(*MutRefWithDrop(&mut val).0, 0, "msg"), std::mem::take(&mut val)); | |
| (assert_eq!(*MutRefWithDrop(&mut val).0, 0), std::mem::take(&mut val)); | |
| (assert_eq!(*MutRefWithDrop(&mut val).0, 0, "msg"), std::mem::take(&mut val)); | |
| (debug_assert_eq!(*MutRefWithDrop(&mut val).0, 0), std::mem::take(&mut val)); | |
| (debug_assert_eq!(*MutRefWithDrop(&mut val).0, 0, "msg"), std::mem::take(&mut val)); | |
| (assert_ne!(*MutRefWithDrop(&mut val).0, 1), std::mem::take(&mut val)); | |
| (assert_ne!(*MutRefWithDrop(&mut val).0, 1, "msg"), std::mem::take(&mut val)); | |
| (debug_assert_ne!(*MutRefWithDrop(&mut val).0, 1), std::mem::take(&mut val)); | |
| (debug_assert_ne!(*MutRefWithDrop(&mut val).0, 1, "msg"), std::mem::take(&mut val)); | |
| (assert!(*MutRefWithDrop(&mut val).0 == 0), std::mem::take(&mut val)); | |
| (assert!(*MutRefWithDrop(&mut val).0 == 0, "msg"), std::mem::take(&mut val)); | |
| } |