@@ -58,24 +58,18 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CheckedConversions {
5858 }
5959 } ;
6060
61- if_chain ! {
62- if let Some ( cv) = result;
63- if let Some ( to_type) = cv. to_type;
64-
65- then {
61+ if let Some ( cv) = result {
62+ if let Some ( to_type) = cv. to_type {
6663 let mut applicability = Applicability :: MachineApplicable ;
67- let snippet = snippet_with_applicability( cx, cv. expr_to_cast. span, "_" , & mut
68- applicability) ;
64+ let snippet = snippet_with_applicability ( cx, cv. expr_to_cast . span , "_" , & mut applicability) ;
6965 span_lint_and_sugg (
7066 cx,
7167 CHECKED_CONVERSIONS ,
7268 item. span ,
7369 "Checked cast can be simplified." ,
7470 "try" ,
75- format!( "{}::try_from({}).is_ok()" ,
76- to_type,
77- snippet) ,
78- applicability
71+ format ! ( "{}::try_from({}).is_ok()" , to_type, snippet) ,
72+ applicability,
7973 ) ;
8074 }
8175 }
@@ -184,7 +178,7 @@ fn check_upper_bound<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<Conversion<'tcx>> {
184178 if_chain ! {
185179 if let ExprKind :: Binary ( ref op, ref left, ref right) = & expr. kind;
186180 if let Some ( ( candidate, check) ) = normalize_le_ge( op, left, right) ;
187- if let Some ( ( from, to) ) = get_types_from_cast( check, MAX_VALUE , INTS ) ;
181+ if let Some ( ( from, to) ) = get_types_from_cast( check, INTS , "max_value" , "MAX" ) ;
188182
189183 then {
190184 Conversion :: try_new( candidate, from, to)
@@ -224,18 +218,24 @@ fn check_lower_bound_zero<'a>(candidate: &'a Expr<'_>, check: &'a Expr<'_>) -> O
224218
225219/// Check for `expr >= (to_type::MIN as from_type)`
226220fn check_lower_bound_min < ' a > ( candidate : & ' a Expr < ' _ > , check : & ' a Expr < ' _ > ) -> Option < Conversion < ' a > > {
227- if let Some ( ( from, to) ) = get_types_from_cast ( check, MIN_VALUE , SINTS ) {
221+ if let Some ( ( from, to) ) = get_types_from_cast ( check, SINTS , "min_value" , "MIN" ) {
228222 Conversion :: try_new ( candidate, from, to)
229223 } else {
230224 None
231225 }
232226}
233227
234228/// Tries to extract the from- and to-type from a cast expression
235- fn get_types_from_cast < ' a > ( expr : & ' a Expr < ' _ > , func : & ' a str , types : & ' a [ & str ] ) -> Option < ( & ' a str , & ' a str ) > {
236- // `to_type::maxmin_value() as from_type`
229+ fn get_types_from_cast < ' a > (
230+ expr : & ' a Expr < ' _ > ,
231+ types : & ' a [ & str ] ,
232+ func : & ' a str ,
233+ assoc_const : & ' a str ,
234+ ) -> Option < ( & ' a str , & ' a str ) > {
235+ // `to_type::max_value() as from_type`
236+ // or `to_type::MAX as from_type`
237237 let call_from_cast: Option < ( & Expr < ' _ > , & str ) > = if_chain ! {
238- // to_type::maxmin_value (), from_type
238+ // to_type::max_value (), from_type
239239 if let ExprKind :: Cast ( ref limit, ref from_type) = & expr. kind;
240240 if let TyKind :: Path ( ref from_type_path) = & from_type. kind;
241241 if let Some ( from_sym) = int_ty_to_sym( from_type_path) ;
@@ -247,17 +247,17 @@ fn get_types_from_cast<'a>(expr: &'a Expr<'_>, func: &'a str, types: &'a [&str])
247247 }
248248 } ;
249249
250- // `from_type::from(to_type::maxmin_value ())`
250+ // `from_type::from(to_type::max_value ())`
251251 let limit_from: Option < ( & Expr < ' _ > , & str ) > = call_from_cast. or_else ( || {
252252 if_chain ! {
253- // `from_type::from, to_type::maxmin_value ()`
253+ // `from_type::from, to_type::max_value ()`
254254 if let ExprKind :: Call ( ref from_func, ref args) = & expr. kind;
255- // `to_type::maxmin_value ()`
255+ // `to_type::max_value ()`
256256 if args. len( ) == 1 ;
257257 if let limit = & args[ 0 ] ;
258258 // `from_type::from`
259259 if let ExprKind :: Path ( ref path) = & from_func. kind;
260- if let Some ( from_sym) = get_implementing_type( path, INTS , FROM ) ;
260+ if let Some ( from_sym) = get_implementing_type( path, INTS , "from" ) ;
261261
262262 then {
263263 Some ( ( limit, from_sym) )
@@ -268,22 +268,26 @@ fn get_types_from_cast<'a>(expr: &'a Expr<'_>, func: &'a str, types: &'a [&str])
268268 } ) ;
269269
270270 if let Some ( ( limit, from_type) ) = limit_from {
271- if_chain ! {
272- if let ExprKind :: Call ( ref fun_name, _) = & limit. kind;
273- // `to_type, maxmin_value`
274- if let ExprKind :: Path ( ref path) = & fun_name. kind;
275- // `to_type`
276- if let Some ( to_type) = get_implementing_type( path, types, func) ;
277-
278- then {
279- Some ( ( from_type, to_type) )
280- } else {
281- None
282- }
271+ match limit. kind {
272+ // `from_type::from(_)`
273+ ExprKind :: Call ( path, _) => {
274+ if let ExprKind :: Path ( ref path) = path. kind {
275+ // `to_type`
276+ if let Some ( to_type) = get_implementing_type ( path, types, func) {
277+ return Some ( ( from_type, to_type) ) ;
278+ }
279+ }
280+ } ,
281+ // `to_type::MAX`
282+ ExprKind :: Path ( ref path) => {
283+ if let Some ( to_type) = get_implementing_type ( path, types, assoc_const) {
284+ return Some ( ( from_type, to_type) ) ;
285+ }
286+ } ,
287+ _ => { } ,
283288 }
284- } else {
285- None
286- }
289+ } ;
290+ None
287291}
288292
289293/// Gets the type which implements the called function
@@ -336,10 +340,6 @@ fn normalize_le_ge<'a>(op: &BinOp, left: &'a Expr<'a>, right: &'a Expr<'a>) -> O
336340}
337341
338342// Constants
339- const FROM : & str = "from" ;
340- const MAX_VALUE : & str = "max_value" ;
341- const MIN_VALUE : & str = "min_value" ;
342-
343343const UINTS : & [ & str ] = & [ "u8" , "u16" , "u32" , "u64" , "usize" ] ;
344344const SINTS : & [ & str ] = & [ "i8" , "i16" , "i32" , "i64" , "isize" ] ;
345345const INTS : & [ & str ] = & [ "u8" , "u16" , "u32" , "u64" , "usize" , "i8" , "i16" , "i32" , "i64" , "isize" ] ;
0 commit comments