@@ -28,6 +28,7 @@ mod iterator_step_by_zero;
28
28
mod manual_saturating_arithmetic;
29
29
mod map_collect_result_unit;
30
30
mod map_flatten;
31
+ mod map_unwrap_or;
31
32
mod ok_expect;
32
33
mod option_as_ref_deref;
33
34
mod option_map_or_none;
@@ -66,11 +67,10 @@ use rustc_span::symbol::{sym, SymbolStr};
66
67
use rustc_typeck:: hir_ty_to_ty;
67
68
68
69
use crate :: utils:: eager_or_lazy:: is_lazyness_candidate;
69
- use crate :: utils:: usage:: mutated_variables;
70
70
use crate :: utils:: {
71
71
contains_return, contains_ty, get_trait_def_id, implements_trait, in_macro, is_copy, is_expn_of,
72
- is_type_diagnostic_item, iter_input_pats, last_path_segment, match_def_path, match_qpath, match_type, meets_msrv ,
73
- method_calls , method_chain_args, paths, return_ty, single_segment_path, snippet, snippet_with_applicability,
72
+ is_type_diagnostic_item, iter_input_pats, last_path_segment, match_def_path, match_qpath, match_type, method_calls ,
73
+ method_chain_args, paths, return_ty, single_segment_path, snippet, snippet_with_applicability,
74
74
snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, SpanlessEq ,
75
75
} ;
76
76
@@ -1689,7 +1689,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
1689
1689
[ "expect" , ..] => expect_used:: check ( cx, expr, arg_lists[ 0 ] ) ,
1690
1690
[ "unwrap_or" , "map" ] => option_map_unwrap_or:: check ( cx, expr, arg_lists[ 1 ] , arg_lists[ 0 ] , method_spans[ 1 ] ) ,
1691
1691
[ "unwrap_or_else" , "map" ] => {
1692
- if !lint_map_unwrap_or_else ( cx, expr, arg_lists[ 1 ] , arg_lists[ 0 ] , self . msrv . as_ref ( ) ) {
1692
+ if !map_unwrap_or :: check ( cx, expr, arg_lists[ 1 ] , arg_lists[ 0 ] , self . msrv . as_ref ( ) ) {
1693
1693
unnecessary_lazy_eval:: check ( cx, expr, arg_lists[ 0 ] , "unwrap_or" ) ;
1694
1694
}
1695
1695
} ,
@@ -2365,73 +2365,6 @@ fn derefs_to_slice<'tcx>(
2365
2365
}
2366
2366
}
2367
2367
2368
- const MAP_UNWRAP_OR_MSRV : RustcVersion = RustcVersion :: new ( 1 , 41 , 0 ) ;
2369
-
2370
- /// lint use of `map().unwrap_or_else()` for `Option`s and `Result`s
2371
- /// Return true if lint triggered
2372
- fn lint_map_unwrap_or_else < ' tcx > (
2373
- cx : & LateContext < ' tcx > ,
2374
- expr : & ' tcx hir:: Expr < ' _ > ,
2375
- map_args : & ' tcx [ hir:: Expr < ' _ > ] ,
2376
- unwrap_args : & ' tcx [ hir:: Expr < ' _ > ] ,
2377
- msrv : Option < & RustcVersion > ,
2378
- ) -> bool {
2379
- if !meets_msrv ( msrv, & MAP_UNWRAP_OR_MSRV ) {
2380
- return false ;
2381
- }
2382
- // lint if the caller of `map()` is an `Option`
2383
- let is_option = is_type_diagnostic_item ( cx, cx. typeck_results ( ) . expr_ty ( & map_args[ 0 ] ) , sym:: option_type) ;
2384
- let is_result = is_type_diagnostic_item ( cx, cx. typeck_results ( ) . expr_ty ( & map_args[ 0 ] ) , sym:: result_type) ;
2385
-
2386
- if is_option || is_result {
2387
- // Don't make a suggestion that may fail to compile due to mutably borrowing
2388
- // the same variable twice.
2389
- let map_mutated_vars = mutated_variables ( & map_args[ 0 ] , cx) ;
2390
- let unwrap_mutated_vars = mutated_variables ( & unwrap_args[ 1 ] , cx) ;
2391
- if let ( Some ( map_mutated_vars) , Some ( unwrap_mutated_vars) ) = ( map_mutated_vars, unwrap_mutated_vars) {
2392
- if map_mutated_vars. intersection ( & unwrap_mutated_vars) . next ( ) . is_some ( ) {
2393
- return false ;
2394
- }
2395
- } else {
2396
- return false ;
2397
- }
2398
-
2399
- // lint message
2400
- let msg = if is_option {
2401
- "called `map(<f>).unwrap_or_else(<g>)` on an `Option` value. This can be done more directly by calling \
2402
- `map_or_else(<g>, <f>)` instead"
2403
- } else {
2404
- "called `map(<f>).unwrap_or_else(<g>)` on a `Result` value. This can be done more directly by calling \
2405
- `.map_or_else(<g>, <f>)` instead"
2406
- } ;
2407
- // get snippets for args to map() and unwrap_or_else()
2408
- let map_snippet = snippet ( cx, map_args[ 1 ] . span , ".." ) ;
2409
- let unwrap_snippet = snippet ( cx, unwrap_args[ 1 ] . span , ".." ) ;
2410
- // lint, with note if neither arg is > 1 line and both map() and
2411
- // unwrap_or_else() have the same span
2412
- let multiline = map_snippet. lines ( ) . count ( ) > 1 || unwrap_snippet. lines ( ) . count ( ) > 1 ;
2413
- let same_span = map_args[ 1 ] . span . ctxt ( ) == unwrap_args[ 1 ] . span . ctxt ( ) ;
2414
- if same_span && !multiline {
2415
- let var_snippet = snippet ( cx, map_args[ 0 ] . span , ".." ) ;
2416
- span_lint_and_sugg (
2417
- cx,
2418
- MAP_UNWRAP_OR ,
2419
- expr. span ,
2420
- msg,
2421
- "try this" ,
2422
- format ! ( "{}.map_or_else({}, {})" , var_snippet, unwrap_snippet, map_snippet) ,
2423
- Applicability :: MachineApplicable ,
2424
- ) ;
2425
- return true ;
2426
- } else if same_span && multiline {
2427
- span_lint ( cx, MAP_UNWRAP_OR , expr. span , msg) ;
2428
- return true ;
2429
- }
2430
- }
2431
-
2432
- false
2433
- }
2434
-
2435
2368
/// Used for `lint_binary_expr_with_method_call`.
2436
2369
#[ derive( Copy , Clone ) ]
2437
2370
struct BinaryExprInfo < ' a > {
0 commit comments