@@ -10,6 +10,7 @@ mod inspect_for_each;
10
10
mod iter_count;
11
11
mod manual_saturating_arithmetic;
12
12
mod ok_expect;
13
+ mod option_as_ref_deref;
13
14
mod option_map_unwrap_or;
14
15
mod skip_while_next;
15
16
mod unnecessary_filter_map;
@@ -1725,10 +1726,10 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
1725
1726
} ,
1726
1727
[ "is_file" , ..] => lint_filetype_is_file ( cx, expr, arg_lists[ 0 ] ) ,
1727
1728
[ "map" , "as_ref" ] => {
1728
- lint_option_as_ref_deref ( cx, expr, arg_lists[ 1 ] , arg_lists[ 0 ] , false , self . msrv . as_ref ( ) )
1729
+ option_as_ref_deref :: check ( cx, expr, arg_lists[ 1 ] , arg_lists[ 0 ] , false , self . msrv . as_ref ( ) )
1729
1730
} ,
1730
1731
[ "map" , "as_mut" ] => {
1731
- lint_option_as_ref_deref ( cx, expr, arg_lists[ 1 ] , arg_lists[ 0 ] , true , self . msrv . as_ref ( ) )
1732
+ option_as_ref_deref :: check ( cx, expr, arg_lists[ 1 ] , arg_lists[ 0 ] , true , self . msrv . as_ref ( ) )
1732
1733
} ,
1733
1734
[ "unwrap_or_else" , ..] => unnecessary_lazy_eval:: check ( cx, expr, arg_lists[ 0 ] , "unwrap_or" ) ,
1734
1735
[ "get_or_insert_with" , ..] => unnecessary_lazy_eval:: check ( cx, expr, arg_lists[ 0 ] , "get_or_insert" ) ,
@@ -3584,115 +3585,6 @@ fn lint_suspicious_map(cx: &LateContext<'_>, expr: &hir::Expr<'_>) {
3584
3585
) ;
3585
3586
}
3586
3587
3587
- const OPTION_AS_REF_DEREF_MSRV : RustcVersion = RustcVersion :: new ( 1 , 40 , 0 ) ;
3588
-
3589
- /// lint use of `_.as_ref().map(Deref::deref)` for `Option`s
3590
- fn lint_option_as_ref_deref < ' tcx > (
3591
- cx : & LateContext < ' tcx > ,
3592
- expr : & hir:: Expr < ' _ > ,
3593
- as_ref_args : & [ hir:: Expr < ' _ > ] ,
3594
- map_args : & [ hir:: Expr < ' _ > ] ,
3595
- is_mut : bool ,
3596
- msrv : Option < & RustcVersion > ,
3597
- ) {
3598
- if !meets_msrv ( msrv, & OPTION_AS_REF_DEREF_MSRV ) {
3599
- return ;
3600
- }
3601
-
3602
- let same_mutability = |m| ( is_mut && m == & hir:: Mutability :: Mut ) || ( !is_mut && m == & hir:: Mutability :: Not ) ;
3603
-
3604
- let option_ty = cx. typeck_results ( ) . expr_ty ( & as_ref_args[ 0 ] ) ;
3605
- if !is_type_diagnostic_item ( cx, option_ty, sym:: option_type) {
3606
- return ;
3607
- }
3608
-
3609
- let deref_aliases: [ & [ & str ] ; 9 ] = [
3610
- & paths:: DEREF_TRAIT_METHOD ,
3611
- & paths:: DEREF_MUT_TRAIT_METHOD ,
3612
- & paths:: CSTRING_AS_C_STR ,
3613
- & paths:: OS_STRING_AS_OS_STR ,
3614
- & paths:: PATH_BUF_AS_PATH ,
3615
- & paths:: STRING_AS_STR ,
3616
- & paths:: STRING_AS_MUT_STR ,
3617
- & paths:: VEC_AS_SLICE ,
3618
- & paths:: VEC_AS_MUT_SLICE ,
3619
- ] ;
3620
-
3621
- let is_deref = match map_args[ 1 ] . kind {
3622
- hir:: ExprKind :: Path ( ref expr_qpath) => cx
3623
- . qpath_res ( expr_qpath, map_args[ 1 ] . hir_id )
3624
- . opt_def_id ( )
3625
- . map_or ( false , |fun_def_id| {
3626
- deref_aliases. iter ( ) . any ( |path| match_def_path ( cx, fun_def_id, path) )
3627
- } ) ,
3628
- hir:: ExprKind :: Closure ( _, _, body_id, _, _) => {
3629
- let closure_body = cx. tcx . hir ( ) . body ( body_id) ;
3630
- let closure_expr = remove_blocks ( & closure_body. value ) ;
3631
-
3632
- match & closure_expr. kind {
3633
- hir:: ExprKind :: MethodCall ( _, _, args, _) => {
3634
- if_chain ! {
3635
- if args. len( ) == 1 ;
3636
- if path_to_local_id( & args[ 0 ] , closure_body. params[ 0 ] . pat. hir_id) ;
3637
- let adj = cx
3638
- . typeck_results( )
3639
- . expr_adjustments( & args[ 0 ] )
3640
- . iter( )
3641
- . map( |x| & x. kind)
3642
- . collect:: <Box <[ _] >>( ) ;
3643
- if let [ ty:: adjustment:: Adjust :: Deref ( None ) , ty:: adjustment:: Adjust :: Borrow ( _) ] = * adj;
3644
- then {
3645
- let method_did = cx. typeck_results( ) . type_dependent_def_id( closure_expr. hir_id) . unwrap( ) ;
3646
- deref_aliases. iter( ) . any( |path| match_def_path( cx, method_did, path) )
3647
- } else {
3648
- false
3649
- }
3650
- }
3651
- } ,
3652
- hir:: ExprKind :: AddrOf ( hir:: BorrowKind :: Ref , m, ref inner) if same_mutability ( m) => {
3653
- if_chain ! {
3654
- if let hir:: ExprKind :: Unary ( hir:: UnOp :: Deref , ref inner1) = inner. kind;
3655
- if let hir:: ExprKind :: Unary ( hir:: UnOp :: Deref , ref inner2) = inner1. kind;
3656
- then {
3657
- path_to_local_id( inner2, closure_body. params[ 0 ] . pat. hir_id)
3658
- } else {
3659
- false
3660
- }
3661
- }
3662
- } ,
3663
- _ => false ,
3664
- }
3665
- } ,
3666
- _ => false ,
3667
- } ;
3668
-
3669
- if is_deref {
3670
- let current_method = if is_mut {
3671
- format ! ( ".as_mut().map({})" , snippet( cx, map_args[ 1 ] . span, ".." ) )
3672
- } else {
3673
- format ! ( ".as_ref().map({})" , snippet( cx, map_args[ 1 ] . span, ".." ) )
3674
- } ;
3675
- let method_hint = if is_mut { "as_deref_mut" } else { "as_deref" } ;
3676
- let hint = format ! ( "{}.{}()" , snippet( cx, as_ref_args[ 0 ] . span, ".." ) , method_hint) ;
3677
- let suggestion = format ! ( "try using {} instead" , method_hint) ;
3678
-
3679
- let msg = format ! (
3680
- "called `{0}` on an Option value. This can be done more directly \
3681
- by calling `{1}` instead",
3682
- current_method, hint
3683
- ) ;
3684
- span_lint_and_sugg (
3685
- cx,
3686
- OPTION_AS_REF_DEREF ,
3687
- expr. span ,
3688
- & msg,
3689
- & suggestion,
3690
- hint,
3691
- Applicability :: MachineApplicable ,
3692
- ) ;
3693
- }
3694
- }
3695
-
3696
3588
fn lint_map_collect (
3697
3589
cx : & LateContext < ' _ > ,
3698
3590
expr : & hir:: Expr < ' _ > ,
0 commit comments