@@ -2479,19 +2479,21 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
2479
2479
) ;
2480
2480
eq
2481
2481
} )
2482
- . map ( |ty:: GeneratorInteriorTypeCause { span, scope_span, .. } | {
2483
- ( span, source_map. span_to_snippet ( * span) , scope_span)
2482
+ . map ( |ty:: GeneratorInteriorTypeCause { span, scope_span, expr , .. } | {
2483
+ ( span, source_map. span_to_snippet ( * span) , scope_span, expr )
2484
2484
} ) ;
2485
+
2485
2486
debug ! (
2486
2487
"maybe_note_obligation_cause_for_async_await: target_ty={:?} \
2487
2488
generator_interior_types={:?} target_span={:?}",
2488
2489
target_ty, tables. generator_interior_types, target_span
2489
2490
) ;
2490
- if let Some ( ( target_span, Ok ( snippet) , scope_span) ) = target_span {
2491
+ if let Some ( ( target_span, Ok ( snippet) , scope_span, expr ) ) = target_span {
2491
2492
self . note_obligation_cause_for_async_await (
2492
2493
err,
2493
2494
* target_span,
2494
2495
scope_span,
2496
+ * expr,
2495
2497
snippet,
2496
2498
generator_did,
2497
2499
last_generator,
@@ -2514,6 +2516,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
2514
2516
err : & mut DiagnosticBuilder < ' _ > ,
2515
2517
target_span : Span ,
2516
2518
scope_span : & Option < Span > ,
2519
+ expr : Option < hir:: HirId > ,
2517
2520
snippet : String ,
2518
2521
first_generator : DefId ,
2519
2522
last_generator : Option < DefId > ,
@@ -2549,6 +2552,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
2549
2552
// not implemented.
2550
2553
let is_send = self . tcx . is_diagnostic_item ( sym:: send_trait, trait_ref. def_id ) ;
2551
2554
let is_sync = self . tcx . is_diagnostic_item ( sym:: sync_trait, trait_ref. def_id ) ;
2555
+ let hir = self . tcx . hir ( ) ;
2552
2556
let trait_explanation = if is_send || is_sync {
2553
2557
let ( trait_name, trait_verb) =
2554
2558
if is_send { ( "`Send`" , "sent" ) } else { ( "`Sync`" , "shared" ) } ;
@@ -2564,8 +2568,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
2564
2568
2565
2569
let message = if let Some ( name) = last_generator
2566
2570
. and_then ( |generator_did| self . tcx . parent ( generator_did) )
2567
- . and_then ( |parent_did| self . tcx . hir ( ) . as_local_hir_id ( parent_did) )
2568
- . and_then ( |parent_hir_id| self . tcx . hir ( ) . opt_name ( parent_hir_id) )
2571
+ . and_then ( |parent_did| hir. as_local_hir_id ( parent_did) )
2572
+ . and_then ( |parent_hir_id| hir. opt_name ( parent_hir_id) )
2569
2573
{
2570
2574
format ! ( "future returned by `{}` is not {}" , name, trait_name)
2571
2575
} else {
@@ -2581,7 +2585,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
2581
2585
} ;
2582
2586
2583
2587
// Look at the last interior type to get a span for the `.await`.
2584
- let await_span = tables. generator_interior_types . iter ( ) . map ( |i| i . span ) . last ( ) . unwrap ( ) ;
2588
+ let await_span = tables. generator_interior_types . iter ( ) . map ( |t| t . span ) . last ( ) . unwrap ( ) ;
2585
2589
let mut span = MultiSpan :: from_span ( await_span) ;
2586
2590
span. push_span_label (
2587
2591
await_span,
@@ -2606,6 +2610,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
2606
2610
) ,
2607
2611
) ;
2608
2612
2613
+ if let Some ( expr_id) = expr {
2614
+ let expr = hir. expect_expr ( expr_id) ;
2615
+ let is_ref = tables. expr_adjustments ( expr) . iter ( ) . any ( |adj| adj. is_region_borrow ( ) ) ;
2616
+ let parent = hir. get_parent_node ( expr_id) ;
2617
+ if let Some ( hir:: Node :: Expr ( e) ) = hir. find ( parent) {
2618
+ let method_span = hir. span ( parent) ;
2619
+ if tables. is_method_call ( e) && is_ref {
2620
+ err. span_help (
2621
+ method_span,
2622
+ "consider moving this method call into a `let` \
2623
+ binding to create a shorter lived borrow",
2624
+ ) ;
2625
+ }
2626
+ }
2627
+ }
2628
+
2609
2629
// Add a note for the item obligation that remains - normally a note pointing to the
2610
2630
// bound that introduced the obligation (e.g. `T: Send`).
2611
2631
debug ! ( "note_obligation_cause_for_async_await: next_code={:?}" , next_code) ;
0 commit comments