@@ -9,7 +9,10 @@ use syntax::codemap::Span;
99
1010use utils:: { snippet, span_lint, span_note_and_lint, match_path, match_type, method_chain_args, match_trait_method,
1111 walk_ptrs_ty_depth, walk_ptrs_ty, get_trait_def_id, implements_trait} ;
12- use utils:: { DEFAULT_TRAIT_PATH , OPTION_PATH , RESULT_PATH , STRING_PATH } ;
12+ use utils:: {
13+ BTREEMAP_ENTRY_PATH , DEFAULT_TRAIT_PATH , HASHMAP_ENTRY_PATH , OPTION_PATH ,
14+ RESULT_PATH , STRING_PATH
15+ } ;
1316use utils:: MethodArgs ;
1417use rustc:: middle:: cstore:: CrateStore ;
1518
@@ -343,19 +346,31 @@ fn lint_or_fun_call(cx: &LateContext, expr: &Expr, name: &str, args: &[P<Expr>])
343346 or_has_args : bool ,
344347 span : Span
345348 ) {
349+ // (path, fn_has_argument, methods)
350+ let know_types : & [ ( & [ _ ] , _ , & [ _ ] , _ ) ] = & [
351+ ( & BTREEMAP_ENTRY_PATH , false , & [ "or_insert" ] , "with" ) ,
352+ ( & HASHMAP_ENTRY_PATH , false , & [ "or_insert" ] , "with" ) ,
353+ ( & OPTION_PATH , false , & [ "map_or" , "ok_or" , "or" , "unwrap_or" ] , "else" ) ,
354+ ( & RESULT_PATH , true , & [ "or" , "unwrap_or" ] , "else" ) ,
355+ ] ;
356+
346357 let self_ty = cx. tcx . expr_ty ( self_expr) ;
347358
348- let is_result = if match_type ( cx, self_ty, & RESULT_PATH ) {
349- true
350- }
351- else if match_type ( cx, self_ty, & OPTION_PATH ) {
352- false
359+ let ( fn_has_arguments, poss, suffix) =
360+ if let Some ( & ( _, fn_has_arguments, poss, suffix) ) = know_types. iter ( ) . find ( |& & i| {
361+ match_type ( cx, self_ty, i. 0 )
362+ } ) {
363+ ( fn_has_arguments, poss, suffix)
364+ }
365+ else {
366+ return
367+ } ;
368+
369+ if !poss. contains ( & name) {
370+ return
353371 }
354- else {
355- return ;
356- } ;
357372
358- let sugg = match ( is_result , !or_has_args) {
373+ let sugg = match ( fn_has_arguments , !or_has_args) {
359374 ( true , _) => format ! ( "|_| {}" , snippet( cx, arg. span, ".." ) ) ,
360375 ( false , false ) => format ! ( "|| {}" , snippet( cx, arg. span, ".." ) ) ,
361376 ( false , true ) => format ! ( "{}" , snippet( cx, fun. span, ".." ) ) ,
@@ -364,13 +379,14 @@ fn lint_or_fun_call(cx: &LateContext, expr: &Expr, name: &str, args: &[P<Expr>])
364379 span_lint ( cx, OR_FUN_CALL , span,
365380 & format ! ( "use of `{}` followed by a function call" , name) )
366381 . span_suggestion ( span, "try this" ,
367- format ! ( "{}.{}_else ({})" ,
382+ format ! ( "{}.{}_{} ({})" ,
368383 snippet( cx, self_expr. span, "_" ) ,
369384 name,
385+ suffix,
370386 sugg) ) ;
371387 }
372388
373- if args. len ( ) == 2 && [ "map_or" , "ok_or" , "or" , "unwrap_or" ] . contains ( & name ) {
389+ if args. len ( ) == 2 {
374390 if let ExprCall ( ref fun, ref or_args) = args[ 1 ] . node {
375391 let or_has_args = !or_args. is_empty ( ) ;
376392 if !check_unwrap_or_default ( cx, name, fun, & args[ 0 ] , & args[ 1 ] , or_has_args, expr. span ) {
0 commit comments