@@ -25,14 +25,15 @@ use rustc_span::source_map::Span;
25
25
use rustc_span:: symbol:: { sym, SymbolStr } ;
26
26
27
27
use crate :: consts:: { constant, Constant } ;
28
+ use crate :: utils:: eager_or_lazy:: is_lazyness_candidate;
28
29
use crate :: utils:: usage:: mutated_variables;
29
30
use crate :: utils:: {
30
31
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 ,
36
37
} ;
37
38
38
39
declare_clippy_lint ! {
@@ -1454,18 +1455,21 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
1454
1455
[ "unwrap_or" , "map" ] => option_map_unwrap_or:: lint ( cx, expr, arg_lists[ 1 ] , arg_lists[ 0 ] , method_spans[ 1 ] ) ,
1455
1456
[ "unwrap_or_else" , "map" ] => {
1456
1457
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" ) ;
1458
1459
}
1459
1460
} ,
1460
1461
[ "map_or" , ..] => lint_map_or_none ( cx, expr, arg_lists[ 0 ] ) ,
1461
1462
[ "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
+ }
1465
1468
} ,
1466
1469
[ "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
+ }
1469
1473
} ,
1470
1474
[ "next" , "filter" ] => lint_filter_next ( cx, expr, arg_lists[ 1 ] ) ,
1471
1475
[ "next" , "skip_while" ] => lint_skip_while_next ( cx, expr, arg_lists[ 1 ] ) ,
@@ -1508,9 +1512,9 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
1508
1512
[ "is_file" , ..] => lint_filetype_is_file ( cx, expr, arg_lists[ 0 ] ) ,
1509
1513
[ "map" , "as_ref" ] => lint_option_as_ref_deref ( cx, expr, arg_lists[ 1 ] , arg_lists[ 0 ] , false ) ,
1510
1514
[ "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" ) ,
1514
1518
_ => { } ,
1515
1519
}
1516
1520
@@ -1714,37 +1718,6 @@ fn lint_or_fun_call<'tcx>(
1714
1718
name : & str ,
1715
1719
args : & ' tcx [ hir:: Expr < ' _ > ] ,
1716
1720
) {
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
-
1748
1721
/// Checks for `unwrap_or(T::new())` or `unwrap_or(T::default())`.
1749
1722
fn check_unwrap_or_default (
1750
1723
cx : & LateContext < ' _ > ,
@@ -1825,8 +1798,7 @@ fn lint_or_fun_call<'tcx>(
1825
1798
if_chain ! {
1826
1799
if know_types. iter( ) . any( |k| k. 2 . contains( & name) ) ;
1827
1800
1828
- let mut finder = FunCallFinder { cx: & cx, found: false } ;
1829
- if { finder. visit_expr( & arg) ; finder. found } ;
1801
+ if is_lazyness_candidate( cx, arg) ;
1830
1802
if !contains_return( & arg) ;
1831
1803
1832
1804
let self_ty = cx. typeck_results( ) . expr_ty( self_expr) ;
0 commit comments