@@ -25,14 +25,15 @@ use rustc_span::source_map::Span;
2525use rustc_span:: symbol:: { sym, SymbolStr } ;
2626
2727use crate :: consts:: { constant, Constant } ;
28+ use crate :: utils:: eager_or_lazy:: is_lazyness_candidate;
2829use crate :: utils:: usage:: mutated_variables;
2930use crate :: utils:: {
3031 contains_ty, get_arg_name, get_parent_expr, get_trait_def_id, has_iter_method, higher, implements_trait, in_macro,
31- is_copy, is_ctor_or_promotable_const_function , is_expn_of, is_type_diagnostic_item, iter_input_pats,
32- last_path_segment , match_def_path , match_qpath , match_trait_method , match_type , match_var , method_calls ,
33- method_chain_args , paths , remove_blocks , return_ty , single_segment_path , snippet , snippet_with_applicability ,
34- snippet_with_macro_callsite , span_lint , span_lint_and_help , span_lint_and_note , span_lint_and_sugg ,
35- span_lint_and_then , sugg , walk_ptrs_ty , walk_ptrs_ty_depth, SpanlessEq ,
32+ is_copy, is_expn_of, is_type_diagnostic_item, iter_input_pats, last_path_segment , match_def_path , match_qpath ,
33+ match_trait_method , match_type , match_var , method_calls , method_chain_args , paths , remove_blocks , return_ty ,
34+ single_segment_path , snippet , snippet_with_applicability , snippet_with_macro_callsite , span_lint ,
35+ span_lint_and_help , span_lint_and_note , span_lint_and_sugg , span_lint_and_then , sugg , walk_ptrs_ty ,
36+ walk_ptrs_ty_depth, SpanlessEq ,
3637} ;
3738
3839declare_clippy_lint ! {
@@ -1454,18 +1455,21 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
14541455 [ "unwrap_or" , "map" ] => option_map_unwrap_or:: lint ( cx, expr, arg_lists[ 1 ] , arg_lists[ 0 ] , method_spans[ 1 ] ) ,
14551456 [ "unwrap_or_else" , "map" ] => {
14561457 if !lint_map_unwrap_or_else ( cx, expr, arg_lists[ 1 ] , arg_lists[ 0 ] ) {
1457- unnecessary_lazy_eval:: lint ( cx, expr, arg_lists[ 0 ] , true , "unwrap_or" ) ;
1458+ unnecessary_lazy_eval:: lint ( cx, expr, arg_lists[ 0 ] , "unwrap_or" ) ;
14581459 }
14591460 } ,
14601461 [ "map_or" , ..] => lint_map_or_none ( cx, expr, arg_lists[ 0 ] ) ,
14611462 [ "and_then" , ..] => {
1462- unnecessary_lazy_eval:: lint ( cx, expr, arg_lists[ 0 ] , false , "and" ) ;
1463- bind_instead_of_map:: OptionAndThenSome :: lint ( cx, expr, arg_lists[ 0 ] ) ;
1464- bind_instead_of_map:: ResultAndThenOk :: lint ( cx, expr, arg_lists[ 0 ] ) ;
1463+ let biom_option_linted = bind_instead_of_map:: OptionAndThenSome :: lint ( cx, expr, arg_lists[ 0 ] ) ;
1464+ let biom_result_linted = bind_instead_of_map:: ResultAndThenOk :: lint ( cx, expr, arg_lists[ 0 ] ) ;
1465+ if !biom_option_linted && !biom_result_linted {
1466+ unnecessary_lazy_eval:: lint ( cx, expr, arg_lists[ 0 ] , "and" ) ;
1467+ }
14651468 } ,
14661469 [ "or_else" , ..] => {
1467- unnecessary_lazy_eval:: lint ( cx, expr, arg_lists[ 0 ] , false , "or" ) ;
1468- bind_instead_of_map:: ResultOrElseErrInfo :: lint ( cx, expr, arg_lists[ 0 ] ) ;
1470+ if !bind_instead_of_map:: ResultOrElseErrInfo :: lint ( cx, expr, arg_lists[ 0 ] ) {
1471+ unnecessary_lazy_eval:: lint ( cx, expr, arg_lists[ 0 ] , "or" ) ;
1472+ }
14691473 } ,
14701474 [ "next" , "filter" ] => lint_filter_next ( cx, expr, arg_lists[ 1 ] ) ,
14711475 [ "next" , "skip_while" ] => lint_skip_while_next ( cx, expr, arg_lists[ 1 ] ) ,
@@ -1508,9 +1512,9 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
15081512 [ "is_file" , ..] => lint_filetype_is_file ( cx, expr, arg_lists[ 0 ] ) ,
15091513 [ "map" , "as_ref" ] => lint_option_as_ref_deref ( cx, expr, arg_lists[ 1 ] , arg_lists[ 0 ] , false ) ,
15101514 [ "map" , "as_mut" ] => lint_option_as_ref_deref ( cx, expr, arg_lists[ 1 ] , arg_lists[ 0 ] , true ) ,
1511- [ "unwrap_or_else" , ..] => unnecessary_lazy_eval:: lint ( cx, expr, arg_lists[ 0 ] , true , "unwrap_or" ) ,
1512- [ "get_or_insert_with" , ..] => unnecessary_lazy_eval:: lint ( cx, expr, arg_lists[ 0 ] , true , "get_or_insert" ) ,
1513- [ "ok_or_else" , ..] => unnecessary_lazy_eval:: lint ( cx, expr, arg_lists[ 0 ] , true , "ok_or" ) ,
1515+ [ "unwrap_or_else" , ..] => unnecessary_lazy_eval:: lint ( cx, expr, arg_lists[ 0 ] , "unwrap_or" ) ,
1516+ [ "get_or_insert_with" , ..] => unnecessary_lazy_eval:: lint ( cx, expr, arg_lists[ 0 ] , "get_or_insert" ) ,
1517+ [ "ok_or_else" , ..] => unnecessary_lazy_eval:: lint ( cx, expr, arg_lists[ 0 ] , "ok_or" ) ,
15141518 _ => { } ,
15151519 }
15161520
@@ -1714,37 +1718,6 @@ fn lint_or_fun_call<'tcx>(
17141718 name : & str ,
17151719 args : & ' tcx [ hir:: Expr < ' _ > ] ,
17161720) {
1717- // Searches an expression for method calls or function calls that aren't ctors
1718- struct FunCallFinder < ' a , ' tcx > {
1719- cx : & ' a LateContext < ' tcx > ,
1720- found : bool ,
1721- }
1722-
1723- impl < ' a , ' tcx > intravisit:: Visitor < ' tcx > for FunCallFinder < ' a , ' tcx > {
1724- type Map = Map < ' tcx > ;
1725-
1726- fn visit_expr ( & mut self , expr : & ' tcx hir:: Expr < ' _ > ) {
1727- let call_found = match & expr. kind {
1728- // ignore enum and struct constructors
1729- hir:: ExprKind :: Call ( ..) => !is_ctor_or_promotable_const_function ( self . cx , expr) ,
1730- hir:: ExprKind :: MethodCall ( ..) => true ,
1731- _ => false ,
1732- } ;
1733-
1734- if call_found {
1735- self . found |= true ;
1736- }
1737-
1738- if !self . found {
1739- intravisit:: walk_expr ( self , expr) ;
1740- }
1741- }
1742-
1743- fn nested_visit_map ( & mut self ) -> intravisit:: NestedVisitorMap < Self :: Map > {
1744- intravisit:: NestedVisitorMap :: None
1745- }
1746- }
1747-
17481721 /// Checks for `unwrap_or(T::new())` or `unwrap_or(T::default())`.
17491722 fn check_unwrap_or_default (
17501723 cx : & LateContext < ' _ > ,
@@ -1825,8 +1798,7 @@ fn lint_or_fun_call<'tcx>(
18251798 if_chain ! {
18261799 if know_types. iter( ) . any( |k| k. 2 . contains( & name) ) ;
18271800
1828- let mut finder = FunCallFinder { cx: & cx, found: false } ;
1829- if { finder. visit_expr( & arg) ; finder. found } ;
1801+ if is_lazyness_candidate( cx, arg) ;
18301802 if !contains_return( & arg) ;
18311803
18321804 let self_ty = cx. typeck_results( ) . expr_ty( self_expr) ;
0 commit comments