@@ -1230,6 +1230,24 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1230
1230
}
1231
1231
}
1232
1232
1233
+ fn mk_obligation_for_def_id (
1234
+ & self ,
1235
+ def_id : DefId ,
1236
+ output_ty : Ty < ' tcx > ,
1237
+ cause : ObligationCause < ' tcx > ,
1238
+ param_env : ty:: ParamEnv < ' tcx > ,
1239
+ ) -> PredicateObligation < ' tcx > {
1240
+ let new_trait_ref = ty:: TraitRef {
1241
+ def_id,
1242
+ substs : self . tcx . mk_substs_trait ( output_ty, & [ ] ) ,
1243
+ } ;
1244
+ Obligation :: new ( cause, param_env, new_trait_ref. to_predicate ( ) )
1245
+ }
1246
+
1247
+
1248
+ /// We tried to apply the bound to an `fn` or closure. Check whether calling it would
1249
+ /// evaluate to a type that *would* satisfy the trait binding. If it would, suggest calling
1250
+ /// it: `bar(foo)` → `bar(foo())`. This case is *very* likely to be hit if `foo` is `async`.
1233
1251
fn suggest_fn_call (
1234
1252
& self ,
1235
1253
obligation : & PredicateObligation < ' tcx > ,
@@ -1248,19 +1266,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1248
1266
_ => return ,
1249
1267
} ;
1250
1268
let msg = format ! ( "use parentheses to call the {}" , callable) ;
1251
- // We tried to apply the bound to an `fn` or closure. Check whether calling it would
1252
- // evaluate to a type that *would* satisfy the trait binding. If it would, suggest calling
1253
- // it: `bar(foo)` → `bar(foo())`. This case is *very* likely to be hit if `foo` is `async`.
1254
1269
1255
- let new_trait_ref = ty:: TraitRef {
1256
- def_id : trait_ref. def_id ( ) ,
1257
- substs : self . tcx . mk_substs_trait ( output_ty. skip_binder ( ) , & [ ] ) ,
1258
- } ;
1259
- let obligation = Obligation :: new (
1270
+ let obligation = self . mk_obligation_for_def_id (
1271
+ trait_ref. def_id ( ) ,
1272
+ output_ty. skip_binder ( ) ,
1260
1273
obligation. cause . clone ( ) ,
1261
1274
obligation. param_env ,
1262
- new_trait_ref. to_predicate ( ) ,
1263
1275
) ;
1276
+
1264
1277
let get_name = |err : & mut DiagnosticBuilder < ' _ > , kind : & hir:: PatKind | -> Option < String > {
1265
1278
// Get the local name of this closure. This can be inaccurate because
1266
1279
// of the possibility of reassignment, but this should be good enough.
@@ -1277,73 +1290,72 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1277
1290
match self . evaluate_obligation ( & obligation) {
1278
1291
Ok ( EvaluationResult :: EvaluatedToOk ) |
1279
1292
Ok ( EvaluationResult :: EvaluatedToOkModuloRegions ) |
1280
- Ok ( EvaluationResult :: EvaluatedToAmbig ) => {
1281
- let hir = self . tcx . hir ( ) ;
1282
- // Get the name of the callable and the arguments to be used in the suggestion.
1283
- let snippet = match hir. get_if_local ( def_id) {
1284
- Some ( hir:: Node :: Expr ( hir:: Expr {
1285
- kind : hir:: ExprKind :: Closure ( _, decl, _, span, ..) ,
1286
- ..
1287
- } ) ) => {
1288
- err. span_label ( * span, "consider calling this closure" ) ;
1289
- let hir_id = match hir. as_local_hir_id ( def_id) {
1290
- Some ( hir_id) => hir_id,
1291
- None => return ,
1292
- } ;
1293
- let parent_node = hir. get_parent_node ( hir_id) ;
1294
- let name = match hir. find ( parent_node) {
1295
- Some ( hir:: Node :: Stmt ( hir:: Stmt {
1296
- kind : hir:: StmtKind :: Local ( local) , ..
1297
- } ) ) => match get_name ( err, & local. pat . kind ) {
1298
- Some ( name) => name,
1299
- None => return ,
1300
- } ,
1301
- // Different to previous arm because one is `&hir::Local` and the other
1302
- // is `P<hir::Local>`.
1303
- Some ( hir:: Node :: Local ( local) ) => match get_name ( err, & local. pat . kind ) {
1304
- Some ( name) => name,
1305
- None => return ,
1306
- } ,
1307
- _ => return ,
1308
- } ;
1309
- let args = decl. inputs . iter ( )
1310
- . map ( |_| "_" )
1311
- . collect :: < Vec < _ > > ( ) . join ( ", " ) ;
1312
- format ! ( "{}({})" , name, args)
1313
- }
1314
- Some ( hir:: Node :: Item ( hir:: Item {
1315
- ident,
1316
- kind : hir:: ItemKind :: Fn ( .., body_id) ,
1317
- ..
1318
- } ) ) => {
1319
- err. span_label ( ident. span , "consider calling this function" ) ;
1320
- let body = hir. body ( * body_id) ;
1321
- let args = body. params . iter ( )
1322
- . map ( |arg| match & arg. pat . kind {
1323
- hir:: PatKind :: Binding ( _, _, ident, None )
1324
- if ident. name != kw:: SelfLower => ident. to_string ( ) ,
1325
- _ => "_" . to_string ( ) ,
1326
- } ) . collect :: < Vec < _ > > ( ) . join ( ", " ) ;
1327
- format ! ( "{}({})" , ident, args)
1328
- }
1293
+ Ok ( EvaluationResult :: EvaluatedToAmbig ) => { }
1294
+ _ => return ,
1295
+ }
1296
+ let hir = self . tcx . hir ( ) ;
1297
+ // Get the name of the callable and the arguments to be used in the suggestion.
1298
+ let snippet = match hir. get_if_local ( def_id) {
1299
+ Some ( hir:: Node :: Expr ( hir:: Expr {
1300
+ kind : hir:: ExprKind :: Closure ( _, decl, _, span, ..) ,
1301
+ ..
1302
+ } ) ) => {
1303
+ 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,
1306
+ None => return ,
1307
+ } ;
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
+ } ,
1329
1322
_ => return ,
1330
1323
} ;
1331
- if points_at_arg {
1332
- // When the obligation error has been ensured to have been caused by
1333
- // an argument, the `obligation.cause.span` points at the expression
1334
- // of the argument, so we can provide a suggestion. This is signaled
1335
- // by `points_at_arg`. Otherwise, we give a more general note.
1336
- err. span_suggestion (
1337
- obligation. cause . span ,
1338
- & msg,
1339
- snippet,
1340
- Applicability :: HasPlaceholders ,
1341
- ) ;
1342
- } else {
1343
- err. help ( & format ! ( "{}: `{}`" , msg, snippet) ) ;
1344
- }
1324
+ let args = decl. inputs . iter ( )
1325
+ . map ( |_| "_" )
1326
+ . collect :: < Vec < _ > > ( ) . join ( ", " ) ;
1327
+ format ! ( "{}({})" , name, args)
1328
+ }
1329
+ Some ( hir:: Node :: Item ( hir:: Item {
1330
+ ident,
1331
+ kind : hir:: ItemKind :: Fn ( .., body_id) ,
1332
+ ..
1333
+ } ) ) => {
1334
+ err. span_label ( ident. span , "consider calling this function" ) ;
1335
+ let body = hir. body ( * body_id) ;
1336
+ let args = body. params . iter ( )
1337
+ . map ( |arg| match & arg. pat . kind {
1338
+ hir:: PatKind :: Binding ( _, _, ident, None )
1339
+ if ident. name != kw:: SelfLower => ident. to_string ( ) ,
1340
+ _ => "_" . to_string ( ) ,
1341
+ } ) . collect :: < Vec < _ > > ( ) . join ( ", " ) ;
1342
+ format ! ( "{}({})" , ident, args)
1345
1343
}
1346
- _ => { }
1344
+ _ => return ,
1345
+ } ;
1346
+ if points_at_arg {
1347
+ // When the obligation error has been ensured to have been caused by
1348
+ // an argument, the `obligation.cause.span` points at the expression
1349
+ // of the argument, so we can provide a suggestion. This is signaled
1350
+ // by `points_at_arg`. Otherwise, we give a more general note.
1351
+ err. span_suggestion (
1352
+ obligation. cause . span ,
1353
+ & msg,
1354
+ snippet,
1355
+ Applicability :: HasPlaceholders ,
1356
+ ) ;
1357
+ } else {
1358
+ err. help ( & format ! ( "{}: `{}`" , msg, snippet) ) ;
1347
1359
}
1348
1360
}
1349
1361
@@ -1377,12 +1389,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1377
1389
if let ty:: Ref ( _, t_type, _) = trait_type. kind {
1378
1390
trait_type = t_type;
1379
1391
1380
- let substs = self . tcx . mk_substs_trait ( trait_type , & [ ] ) ;
1381
- let new_trait_ref = ty :: TraitRef :: new ( trait_ref. def_id , substs ) ;
1382
- let new_obligation = Obligation :: new (
1392
+ let new_obligation = self . mk_obligation_for_def_id (
1393
+ trait_ref. def_id ,
1394
+ trait_type ,
1383
1395
ObligationCause :: dummy ( ) ,
1384
1396
obligation. param_env ,
1385
- new_trait_ref. to_predicate ( ) ,
1386
1397
) ;
1387
1398
1388
1399
if self . predicate_may_hold ( & new_obligation) {
@@ -1440,12 +1451,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1440
1451
hir:: Mutability :: Immutable => self . tcx . mk_mut_ref ( region, t_type) ,
1441
1452
} ;
1442
1453
1443
- let substs = self . tcx . mk_substs_trait ( & trait_type , & [ ] ) ;
1444
- let new_trait_ref = ty :: TraitRef :: new ( trait_ref. skip_binder ( ) . def_id , substs ) ;
1445
- let new_obligation = Obligation :: new (
1454
+ let new_obligation = self . mk_obligation_for_def_id (
1455
+ trait_ref. skip_binder ( ) . def_id ,
1456
+ trait_type ,
1446
1457
ObligationCause :: dummy ( ) ,
1447
1458
obligation. param_env ,
1448
- new_trait_ref. to_predicate ( ) ,
1449
1459
) ;
1450
1460
1451
1461
if self . evaluate_obligation_no_overflow (
0 commit comments