@@ -1244,6 +1244,42 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
12441244 Obligation :: new ( cause, param_env, new_trait_ref. to_predicate ( ) )
12451245 }
12461246
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+ }
12471283
12481284 /// We tried to apply the bound to an `fn` or closure. Check whether calling it would
12491285 /// 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> {
12741310 obligation. param_env ,
12751311 ) ;
12761312
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- } ;
12901313 match self . evaluate_obligation ( & obligation) {
12911314 Ok ( EvaluationResult :: EvaluatedToOk ) |
12921315 Ok ( EvaluationResult :: EvaluatedToOkModuloRegions ) |
@@ -1301,29 +1324,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
13011324 ..
13021325 } ) ) => {
13031326 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 ,
13061329 None => return ,
13071330 } ;
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- } ;
13241331 let args = decl. inputs . iter ( )
13251332 . map ( |_| "_" )
1326- . collect :: < Vec < _ > > ( ) . join ( ", " ) ;
1333+ . collect :: < Vec < _ > > ( )
1334+ . join ( ", " ) ;
13271335 format ! ( "{}({})" , name, args)
13281336 }
13291337 Some ( hir:: Node :: Item ( hir:: Item {
@@ -1336,9 +1344,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
13361344 let args = body. params . iter ( )
13371345 . map ( |arg| match & arg. pat . kind {
13381346 hir:: PatKind :: Binding ( _, _, ident, None )
1347+ // FIXME: provide a better suggestion when encountering `SelfLower`, it
1348+ // should suggest a method call.
13391349 if ident. name != kw:: SelfLower => ident. to_string ( ) ,
13401350 _ => "_" . to_string ( ) ,
1341- } ) . collect :: < Vec < _ > > ( ) . join ( ", " ) ;
1351+ } )
1352+ . collect :: < Vec < _ > > ( )
1353+ . join ( ", " ) ;
13421354 format ! ( "{}({})" , ident, args)
13431355 }
13441356 _ => return ,
0 commit comments