@@ -2456,7 +2456,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
24562456 let target_span = tables
24572457 . generator_interior_types
24582458 . iter ( )
2459- . find ( |ty:: GeneratorInteriorTypeCause { ty, .. } | {
2459+ . zip ( tables. generator_interior_exprs . iter ( ) )
2460+ . find ( |( ty:: GeneratorInteriorTypeCause { ty, .. } , _) | {
24602461 // Careful: the regions for types that appear in the
24612462 // generator interior are not generally known, so we
24622463 // want to erase them when comparing (and anyway,
@@ -2479,19 +2480,21 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
24792480 ) ;
24802481 eq
24812482 } )
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 )
24842485 } ) ;
2486+
24852487 debug ! (
24862488 "maybe_note_obligation_cause_for_async_await: target_ty={:?} \
24872489 generator_interior_types={:?} target_span={:?}",
24882490 target_ty, tables. generator_interior_types, target_span
24892491 ) ;
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 {
24912493 self . note_obligation_cause_for_async_await (
24922494 err,
24932495 * target_span,
24942496 scope_span,
2497+ * expr,
24952498 snippet,
24962499 generator_did,
24972500 last_generator,
@@ -2514,6 +2517,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
25142517 err : & mut DiagnosticBuilder < ' _ > ,
25152518 target_span : Span ,
25162519 scope_span : & Option < Span > ,
2520+ expr : Option < hir:: HirId > ,
25172521 snippet : String ,
25182522 first_generator : DefId ,
25192523 last_generator : Option < DefId > ,
@@ -2549,6 +2553,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
25492553 // not implemented.
25502554 let is_send = self . tcx . is_diagnostic_item ( sym:: send_trait, trait_ref. def_id ) ;
25512555 let is_sync = self . tcx . is_diagnostic_item ( sym:: sync_trait, trait_ref. def_id ) ;
2556+ let hir = self . tcx . hir ( ) ;
25522557 let trait_explanation = if is_send || is_sync {
25532558 let ( trait_name, trait_verb) =
25542559 if is_send { ( "`Send`" , "sent" ) } else { ( "`Sync`" , "shared" ) } ;
@@ -2564,8 +2569,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
25642569
25652570 let message = if let Some ( name) = last_generator
25662571 . 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) )
25692574 {
25702575 format ! ( "future returned by `{}` is not {}" , name, trait_name)
25712576 } else {
@@ -2588,6 +2593,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
25882593 format ! ( "{} occurs here, with `{}` maybe used later" , await_or_yield, snippet) ,
25892594 ) ;
25902595
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+
25912612 span. push_span_label ( target_span, format ! ( "has type `{}`" , target_ty) ) ;
25922613
25932614 // If available, use the scope span to annotate the drop location.
0 commit comments