@@ -2324,6 +2324,60 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2324
2324
}
2325
2325
}
2326
2326
2327
+ /// issue #102320, for `unwrap_or` with closure as argument, suggest `unwrap_or_else`
2328
+ /// FIXME: currently not working for suggesting `map_or_else`, see #102408
2329
+ pub ( crate ) fn suggest_else_fn_with_closure (
2330
+ & self ,
2331
+ err : & mut Diagnostic ,
2332
+ expr : & hir:: Expr < ' _ > ,
2333
+ found : Ty < ' tcx > ,
2334
+ expected : Ty < ' tcx > ,
2335
+ ) -> bool {
2336
+ let Some ( ( _def_id_or_name, output, _inputs) ) = self . extract_callable_info ( expr, found)
2337
+ else { return false ; } ;
2338
+
2339
+ if !self . can_coerce ( output, expected) {
2340
+ return false ;
2341
+ }
2342
+
2343
+ let parent = self . tcx . hir ( ) . get_parent_node ( expr. hir_id ) ;
2344
+ if let Some ( Node :: Expr ( call_expr) ) = self . tcx . hir ( ) . find ( parent) &&
2345
+ let hir:: ExprKind :: MethodCall (
2346
+ hir:: PathSegment { ident : method_name, .. } ,
2347
+ self_expr,
2348
+ args,
2349
+ ..,
2350
+ ) = call_expr. kind &&
2351
+ let Some ( self_ty) = self . typeck_results . borrow ( ) . expr_ty_opt ( self_expr) {
2352
+ let new_name = Ident {
2353
+ name : Symbol :: intern ( & format ! ( "{}_else" , method_name. as_str( ) ) ) ,
2354
+ span : method_name. span ,
2355
+ } ;
2356
+ let probe = self . lookup_probe (
2357
+ expr. span ,
2358
+ new_name,
2359
+ self_ty,
2360
+ self_expr,
2361
+ ProbeScope :: TraitsInScope ,
2362
+ ) ;
2363
+
2364
+ // check the method arguments number
2365
+ if let Ok ( pick) = probe &&
2366
+ let fn_sig = self . tcx . fn_sig ( pick. item . def_id ) &&
2367
+ let fn_args = fn_sig. skip_binder ( ) . inputs ( ) &&
2368
+ fn_args. len ( ) == args. len ( ) + 1 {
2369
+ err. span_suggestion_verbose (
2370
+ method_name. span . shrink_to_hi ( ) ,
2371
+ & format ! ( "try calling `{}` instead" , new_name. name. as_str( ) ) ,
2372
+ "_else" ,
2373
+ Applicability :: MaybeIncorrect ,
2374
+ ) ;
2375
+ return true ;
2376
+ }
2377
+ }
2378
+ false
2379
+ }
2380
+
2327
2381
/// Checks whether there is a local type somewhere in the chain of
2328
2382
/// autoderefs of `rcvr_ty`.
2329
2383
fn type_derefs_to_local (
0 commit comments