1| |// This demonstrated Issue #84561: function-like macros produce unintuitive coverage results. 2| | 3| |// expect-exit-status-101 4| 21|#[derive(PartialEq, Eq)] 5| |struct Foo(u32); 6| 1|fn test3() { 7| 1| let is_true = std::env::args().len() == 1; 8| 1| let bar = Foo(1); 9| 1| assert_eq!(bar, Foo(1)); 10| 1| let baz = Foo(0); 11| 1| assert_ne!(baz, Foo(1)); 12| 1| println!("{:?}", Foo(1)); 13| 1| println!("{:?}", bar); 14| 1| println!("{:?}", baz); 15| 1| 16| 1| assert_eq!(Foo(1), Foo(1)); 17| 1| assert_ne!(Foo(0), Foo(1)); 18| 1| assert_eq!(Foo(2), Foo(2)); 19| 1| let bar = Foo(0); 20| 1| assert_ne!(bar, Foo(3)); 21| 1| assert_ne!(Foo(0), Foo(4)); 22| 1| assert_eq!(Foo(3), Foo(3), "with a message"); ^0 23| 1| println!("{:?}", bar); 24| 1| println!("{:?}", Foo(1)); 25| 1| 26| 1| assert_ne!(Foo(0), Foo(5), "{}", if is_true { "true message" } else { "false message" }); ^0 ^0 ^0 27| 1| assert_ne!( 28| | Foo(0) 29| | , 30| | Foo(5) 31| | , 32| 0| "{}" 33| 0| , 34| 0| if 35| 0| is_true 36| | { 37| 0| "true message" 38| | } else { 39| 0| "false message" 40| | } 41| | ); 42| | 43| 1| let is_true = std::env::args().len() == 1; 44| 1| 45| 1| assert_eq!( 46| 1| Foo(1), 47| 1| Foo(1) 48| 1| ); 49| 1| assert_ne!( 50| 1| Foo(0), 51| 1| Foo(1) 52| 1| ); 53| 1| assert_eq!( 54| 1| Foo(2), 55| 1| Foo(2) 56| 1| ); 57| 1| let bar = Foo(1); 58| 1| assert_ne!( 59| 1| bar, 60| 1| Foo(3) 61| 1| ); 62| 1| if is_true { 63| 1| assert_ne!( 64| 1| Foo(0), 65| 1| Foo(4) 66| 1| ); 67| | } else { 68| 0| assert_eq!( 69| 0| Foo(3), 70| 0| Foo(3) 71| 0| ); 72| | } 73| 1| if is_true { 74| 1| assert_ne!( 75| | Foo(0), 76| | Foo(4), 77| 0| "with a message" 78| | ); 79| | } else { 80| 0| assert_eq!( 81| | Foo(3), 82| | Foo(3), 83| 0| "with a message" 84| | ); 85| | } 86| 1| assert_ne!( 87| 1| if is_true { 88| 1| Foo(0) 89| | } else { 90| 0| Foo(1) 91| | }, 92| | Foo(5) 93| | ); 94| 1| assert_ne!( 95| 1| Foo(5), 96| 1| if is_true { 97| 1| Foo(0) 98| | } else { 99| 0| Foo(1) 100| | } 101| | ); 102| 1| assert_ne!( 103| 1| if is_true { 104| 1| assert_eq!( 105| 1| Foo(3), 106| 1| Foo(3) 107| 1| ); 108| 1| Foo(0) 109| | } else { 110| 0| assert_ne!( 111| 0| if is_true { 112| 0| Foo(0) 113| | } else { 114| 0| Foo(1) 115| | }, 116| | Foo(5) 117| | ); 118| 0| Foo(1) 119| | }, 120| | Foo(5), 121| 0| "with a message" 122| | ); 123| 1| assert_eq!( 124| | Foo(1), 125| | Foo(3), 126| 1| "this assert should fail" 127| | ); 128| 0| assert_eq!( 129| | Foo(3), 130| | Foo(3), 131| 0| "this assert should not be reached" 132| | ); 133| 0|} 134| | 135| |impl std::fmt::Debug for Foo { 136| | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 137| 7| write!(f, "try and succeed")?; ^0 138| 7| Ok(()) 139| 7| } 140| |} 141| | 142| |static mut DEBUG_LEVEL_ENABLED: bool = false; 143| | 144| |macro_rules! debug { 145| | ($($arg:tt)+) => ( 146| | if unsafe { DEBUG_LEVEL_ENABLED } { 147| | println!($($arg)+); 148| | } 149| | ); 150| |} 151| | 152| 1|fn test1() { 153| 1| debug!("debug is enabled"); ^0 154| 1| debug!("debug is enabled"); ^0 155| 1| let _ = 0; 156| 1| debug!("debug is enabled"); ^0 157| 1| unsafe { 158| 1| DEBUG_LEVEL_ENABLED = true; 159| 1| } 160| 1| debug!("debug is enabled"); 161| 1|} 162| | 163| |macro_rules! call_debug { 164| | ($($arg:tt)+) => ( 165| 1| fn call_print(s: &str) { 166| 1| print!("{}", s); 167| 1| } 168| | 169| | call_print("called from call_debug: "); 170| | debug!($($arg)+); 171| | ); 172| |} 173| | 174| 1|fn test2() { 175| 1| call_debug!("debug is enabled"); 176| 1|} 177| | 178| 1|fn main() { 179| 1| test1(); 180| 1| test2(); 181| 1| test3(); 182| 1|}