@@ -2456,7 +2456,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
2456
2456
let target_span = tables
2457
2457
. generator_interior_types
2458
2458
. iter ( )
2459
- . find ( |ty:: GeneratorInteriorTypeCause { ty, .. } | {
2459
+ . zip ( tables. generator_interior_exprs . iter ( ) )
2460
+ . find ( |( ty:: GeneratorInteriorTypeCause { ty, .. } , _) | {
2460
2461
// Careful: the regions for types that appear in the
2461
2462
// generator interior are not generally known, so we
2462
2463
// want to erase them when comparing (and anyway,
@@ -2479,19 +2480,21 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
2479
2480
) ;
2480
2481
eq
2481
2482
} )
2482
- . map ( |ty:: GeneratorInteriorTypeCause { span, scope_span, .. } | {
2483
- ( span, source_map. span_to_snippet ( * span) , scope_span)
2483
+ . map ( |( ty:: GeneratorInteriorTypeCause { span, scope_span, .. } , expr ) | {
2484
+ ( span, source_map. span_to_snippet ( * span) , scope_span, expr )
2484
2485
} ) ;
2486
+
2485
2487
debug ! (
2486
2488
"maybe_note_obligation_cause_for_async_await: target_ty={:?} \
2487
2489
generator_interior_types={:?} target_span={:?}",
2488
2490
target_ty, tables. generator_interior_types, target_span
2489
2491
) ;
2490
- if let Some ( ( target_span, Ok ( snippet) , scope_span) ) = target_span {
2492
+ if let Some ( ( target_span, Ok ( snippet) , scope_span, expr ) ) = target_span {
2491
2493
self . note_obligation_cause_for_async_await (
2492
2494
err,
2493
2495
* target_span,
2494
2496
scope_span,
2497
+ * expr,
2495
2498
snippet,
2496
2499
generator_did,
2497
2500
last_generator,
@@ -2514,6 +2517,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
2514
2517
err : & mut DiagnosticBuilder < ' _ > ,
2515
2518
target_span : Span ,
2516
2519
scope_span : & Option < Span > ,
2520
+ expr : Option < hir:: HirId > ,
2517
2521
snippet : String ,
2518
2522
first_generator : DefId ,
2519
2523
last_generator : Option < DefId > ,
@@ -2549,6 +2553,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
2549
2553
// not implemented.
2550
2554
let is_send = self . tcx . is_diagnostic_item ( sym:: send_trait, trait_ref. def_id ) ;
2551
2555
let is_sync = self . tcx . is_diagnostic_item ( sym:: sync_trait, trait_ref. def_id ) ;
2556
+ let hir = self . tcx . hir ( ) ;
2552
2557
let trait_explanation = if is_send || is_sync {
2553
2558
let ( trait_name, trait_verb) =
2554
2559
if is_send { ( "`Send`" , "sent" ) } else { ( "`Sync`" , "shared" ) } ;
@@ -2564,8 +2569,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
2564
2569
2565
2570
let message = if let Some ( name) = last_generator
2566
2571
. 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) )
2572
+ . and_then ( |parent_did| hir. as_local_hir_id ( parent_did) )
2573
+ . and_then ( |parent_hir_id| hir. opt_name ( parent_hir_id) )
2569
2574
{
2570
2575
format ! ( "future returned by `{}` is not {}" , name, trait_name)
2571
2576
} else {
@@ -2588,6 +2593,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
2588
2593
format ! ( "{} occurs here, with `{}` maybe used later" , await_or_yield, snippet) ,
2589
2594
) ;
2590
2595
2596
+ if let Some ( expr_id) = expr {
2597
+ let expr = hir. expect_expr ( expr_id) ;
2598
+ let is_ref = tables. expr_adjustments ( expr) . iter ( ) . any ( |adj| adj. is_region_borrow ( ) ) ;
2599
+ let parent = hir. get_parent_node ( expr_id) ;
2600
+ if let Some ( hir:: Node :: Expr ( e) ) = hir. find ( parent) {
2601
+ let method_span = hir. span ( parent) ;
2602
+ if tables. is_method_call ( e) && is_ref {
2603
+ err. span_help (
2604
+ method_span,
2605
+ "consider moving this method call into a `let` \
2606
+ binding to create a shorter lived borrow"
2607
+ ) ;
2608
+ }
2609
+ }
2610
+ }
2611
+
2591
2612
span. push_span_label ( target_span, format ! ( "has type `{}`" , target_ty) ) ;
2592
2613
2593
2614
// If available, use the scope span to annotate the drop location.
0 commit comments