@@ -1244,6 +1244,42 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1244
1244
Obligation :: new ( cause, param_env, new_trait_ref. to_predicate ( ) )
1245
1245
}
1246
1246
1247
+ /// Given a closure's `DefId`, return the given name of the closure.
1248
+ ///
1249
+ /// This doesn't account for reassignments, but it's only used for suggestions.
1250
+ fn get_closure_name (
1251
+ & self ,
1252
+ def_id : DefId ,
1253
+ err : & mut DiagnosticBuilder < ' _ > ,
1254
+ msg : & str ,
1255
+ ) -> Option < String > {
1256
+ let get_name = |err : & mut DiagnosticBuilder < ' _ > , kind : & hir:: PatKind | -> Option < String > {
1257
+ // Get the local name of this closure. This can be inaccurate because
1258
+ // of the possibility of reassignment, but this should be good enough.
1259
+ match & kind {
1260
+ hir:: PatKind :: Binding ( hir:: BindingAnnotation :: Unannotated , _, name, None ) => {
1261
+ Some ( format ! ( "{}" , name) )
1262
+ }
1263
+ _ => {
1264
+ err. note ( & msg) ;
1265
+ None
1266
+ }
1267
+ }
1268
+ } ;
1269
+
1270
+ let hir = self . tcx . hir ( ) ;
1271
+ let hir_id = hir. as_local_hir_id ( def_id) ?;
1272
+ let parent_node = hir. get_parent_node ( hir_id) ;
1273
+ match hir. find ( parent_node) {
1274
+ Some ( hir:: Node :: Stmt ( hir:: Stmt {
1275
+ kind : hir:: StmtKind :: Local ( local) , ..
1276
+ } ) ) => get_name ( err, & local. pat . kind ) ,
1277
+ // Different to previous arm because one is `&hir::Local` and the other
1278
+ // is `P<hir::Local>`.
1279
+ Some ( hir:: Node :: Local ( local) ) => get_name ( err, & local. pat . kind ) ,
1280
+ _ => return None ,
1281
+ }
1282
+ }
1247
1283
1248
1284
/// We tried to apply the bound to an `fn` or closure. Check whether calling it would
1249
1285
/// evaluate to a type that *would* satisfy the trait binding. If it would, suggest calling
@@ -1274,19 +1310,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1274
1310
obligation. param_env ,
1275
1311
) ;
1276
1312
1277
- let get_name = |err : & mut DiagnosticBuilder < ' _ > , kind : & hir:: PatKind | -> Option < String > {
1278
- // Get the local name of this closure. This can be inaccurate because
1279
- // of the possibility of reassignment, but this should be good enough.
1280
- match & kind {
1281
- hir:: PatKind :: Binding ( hir:: BindingAnnotation :: Unannotated , _, name, None ) => {
1282
- Some ( format ! ( "{}" , name) )
1283
- }
1284
- _ => {
1285
- err. note ( & msg) ;
1286
- None
1287
- }
1288
- }
1289
- } ;
1290
1313
match self . evaluate_obligation ( & obligation) {
1291
1314
Ok ( EvaluationResult :: EvaluatedToOk ) |
1292
1315
Ok ( EvaluationResult :: EvaluatedToOkModuloRegions ) |
@@ -1301,29 +1324,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1301
1324
..
1302
1325
} ) ) => {
1303
1326
err. span_label ( * span, "consider calling this closure" ) ;
1304
- let hir_id = match hir . as_local_hir_id ( def_id) {
1305
- Some ( hir_id ) => hir_id ,
1327
+ let name = match self . get_closure_name ( def_id, err , & msg ) {
1328
+ Some ( name ) => name ,
1306
1329
None => return ,
1307
1330
} ;
1308
- let parent_node = hir. get_parent_node ( hir_id) ;
1309
- let name = match hir. find ( parent_node) {
1310
- Some ( hir:: Node :: Stmt ( hir:: Stmt {
1311
- kind : hir:: StmtKind :: Local ( local) , ..
1312
- } ) ) => match get_name ( err, & local. pat . kind ) {
1313
- Some ( name) => name,
1314
- None => return ,
1315
- } ,
1316
- // Different to previous arm because one is `&hir::Local` and the other
1317
- // is `P<hir::Local>`.
1318
- Some ( hir:: Node :: Local ( local) ) => match get_name ( err, & local. pat . kind ) {
1319
- Some ( name) => name,
1320
- None => return ,
1321
- } ,
1322
- _ => return ,
1323
- } ;
1324
1331
let args = decl. inputs . iter ( )
1325
1332
. map ( |_| "_" )
1326
- . collect :: < Vec < _ > > ( ) . join ( ", " ) ;
1333
+ . collect :: < Vec < _ > > ( )
1334
+ . join ( ", " ) ;
1327
1335
format ! ( "{}({})" , name, args)
1328
1336
}
1329
1337
Some ( hir:: Node :: Item ( hir:: Item {
@@ -1336,9 +1344,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1336
1344
let args = body. params . iter ( )
1337
1345
. map ( |arg| match & arg. pat . kind {
1338
1346
hir:: PatKind :: Binding ( _, _, ident, None )
1347
+ // FIXME: provide a better suggestion when encountering `SelfLower`, it
1348
+ // should suggest a method call.
1339
1349
if ident. name != kw:: SelfLower => ident. to_string ( ) ,
1340
1350
_ => "_" . to_string ( ) ,
1341
- } ) . collect :: < Vec < _ > > ( ) . join ( ", " ) ;
1351
+ } )
1352
+ . collect :: < Vec < _ > > ( )
1353
+ . join ( ", " ) ;
1342
1354
format ! ( "{}({})" , ident, args)
1343
1355
}
1344
1356
_ => return ,
0 commit comments