1// run-rustfix 2// aux-build:macro_rules.rs 3 4#![deny(clippy::try_err)] 5#![allow(clippy::unnecessary_wraps, clippy::needless_question_mark)] 6 7#[macro_use] 8extern crate macro_rules; 9 10use std::io; 11use std::task::Poll; 12 13// Tests that a simple case works 14// Should flag `Err(err)?` 15pub fn basic_test() -> Result<i32, i32> { 16 let err: i32 = 1; 17 // To avoid warnings during rustfix 18 if true { 19 return Err(err); 20 } 21 Ok(0) 22} 23 24// Tests that `.into()` is added when appropriate 25pub fn into_test() -> Result<i32, i32> { 26 let err: u8 = 1; 27 // To avoid warnings during rustfix 28 if true { 29 return Err(err.into()); 30 } 31 Ok(0) 32} 33 34// Tests that tries in general don't trigger the error 35pub fn negative_test() -> Result<i32, i32> { 36 Ok(nested_error()? + 1) 37} 38 39// Tests that `.into()` isn't added when the error type 40// matches the surrounding closure's return type, even 41// when it doesn't match the surrounding function's. 42pub fn closure_matches_test() -> Result<i32, i32> { 43 let res: Result<i32, i8> = Some(1) 44 .into_iter() 45 .map(|i| { 46 let err: i8 = 1; 47 // To avoid warnings during rustfix 48 if true { 49 return Err(err); 50 } 51 Ok(i) 52 }) 53 .next() 54 .unwrap(); 55 56 Ok(res?) 57} 58 59// Tests that `.into()` isn't added when the error type 60// doesn't match the surrounding closure's return type. 61pub fn closure_into_test() -> Result<i32, i32> { 62 let res: Result<i32, i16> = Some(1) 63 .into_iter() 64 .map(|i| { 65 let err: i8 = 1; 66 // To avoid warnings during rustfix 67 if true { 68 return Err(err.into()); 69 } 70 Ok(i) 71 }) 72 .next() 73 .unwrap(); 74 75 Ok(res?) 76} 77 78fn nested_error() -> Result<i32, i32> { 79 Ok(1) 80} 81 82// Bad suggestion when in macro (see #6242) 83macro_rules! try_validation { 84 ($e: expr) => {{ 85 match $e { 86 Ok(_) => 0, 87 Err(_) => return Err(1), 88 } 89 }}; 90} 91 92macro_rules! ret_one { 93 () => { 94 1 95 }; 96} 97 98macro_rules! try_validation_in_macro { 99 ($e: expr) => {{ 100 match $e { 101 Ok(_) => 0, 102 Err(_) => return Err(ret_one!()), 103 } 104 }}; 105} 106 107fn calling_macro() -> Result<i32, i32> { 108 // macro 109 try_validation!(Ok::<_, i32>(5)); 110 // `Err` arg is another macro 111 try_validation_in_macro!(Ok::<_, i32>(5)); 112 Ok(5) 113} 114 115fn main() { 116 basic_test().unwrap(); 117 into_test().unwrap(); 118 negative_test().unwrap(); 119 closure_matches_test().unwrap(); 120 closure_into_test().unwrap(); 121 calling_macro().unwrap(); 122 123 // We don't want to lint in external macros 124 try_err!(); 125} 126 127macro_rules! bar { 128 () => { 129 String::from("aasdfasdfasdfa") 130 }; 131} 132 133macro_rules! foo { 134 () => { 135 bar!() 136 }; 137} 138 139pub fn macro_inside(fail: bool) -> Result<i32, String> { 140 if fail { 141 return Err(foo!()); 142 } 143 Ok(0) 144} 145 146pub fn poll_write(n: usize) -> Poll<io::Result<usize>> { 147 if n == 0 { 148 return Poll::Ready(Err(io::ErrorKind::WriteZero.into())) 149 } else if n == 1 { 150 return Poll::Ready(Err(io::Error::new(io::ErrorKind::InvalidInput, "error"))) 151 }; 152 153 Poll::Ready(Ok(n)) 154} 155 156pub fn poll_next(ready: bool) -> Poll<Option<io::Result<()>>> { 157 if !ready { 158 return Poll::Ready(Some(Err(io::ErrorKind::NotFound.into()))) 159 } 160 161 Poll::Ready(None) 162} 163 164// Tests that `return` is not duplicated 165pub fn try_return(x: bool) -> Result<i32, i32> { 166 if x { 167 return Err(42); 168 } 169 Ok(0) 170} 171