about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/traits/error_reporting.rs38
-rw-r--r--src/librustc/ty/adjustment.rs2
-rw-r--r--src/librustc/ty/context.rs9
-rw-r--r--src/librustc_typeck/check/generator_interior.rs6
-rw-r--r--src/test/ui/async-await/issue-64130-4-async-move.stderr5
5 files changed, 32 insertions, 28 deletions
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 13eb47a041f..aaad0be9a04 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -2456,7 +2456,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         let target_span = tables
             .generator_interior_types
             .iter()
-            .zip(tables.generator_interior_exprs.iter())
             .find(|(ty::GeneratorInteriorTypeCause { ty, .. }, _)| {
                 // Careful: the regions for types that appear in the
                 // generator interior are not generally known, so we
@@ -2578,7 +2577,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             };
 
             span.push_span_label(original_span, message);
-            err.set_span(span.clone());
+            err.set_span(span);
 
             format!("is not {}", trait_name)
         } else {
@@ -2586,29 +2585,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         };
 
         // Look at the last interior type to get a span for the `.await`.
-        let await_span = tables.generator_interior_types.iter().map(|i| i.span).last().unwrap();
+        let await_span =
+            tables.generator_interior_types.iter().map(|(i, _)| i.span).last().unwrap();
         let mut span = MultiSpan::from_span(await_span);
         span.push_span_label(
             await_span,
             format!("{} occurs here, with `{}` maybe used later", await_or_yield, snippet),
         );
 
-        if let Some(expr_id) = expr {
-            let expr = hir.expect_expr(expr_id);
-            let is_ref = tables.expr_adjustments(expr).iter().any(|adj| adj.is_region_borrow());
-            let parent = hir.get_parent_node(expr_id);
-            if let Some(hir::Node::Expr(e)) = hir.find(parent) {
-                let method_span = hir.span(parent);
-                if tables.is_method_call(e) && is_ref {
-                    err.span_help(
-                        method_span,
-                        "consider moving this method call into a `let` \
-                        binding to create a shorter lived borrow"
-                    );
-                }
-            }
-        }
-
         span.push_span_label(target_span, format!("has type `{}`", target_ty));
 
         // If available, use the scope span to annotate the drop location.
@@ -2627,6 +2611,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             ),
         );
 
+        if let Some(expr_id) = expr {
+            let expr = hir.expect_expr(expr_id);
+            let is_ref = tables.expr_adjustments(expr).iter().any(|adj| adj.is_region_borrow());
+            let parent = hir.get_parent_node(expr_id);
+            if let Some(hir::Node::Expr(e)) = hir.find(parent) {
+                let method_span = hir.span(parent);
+                if tables.is_method_call(e) && is_ref {
+                    err.span_help(
+                        method_span,
+                        "consider moving this method call into a `let` \
+                        binding to create a shorter lived borrow",
+                    );
+                }
+            }
+        }
+
         // Add a note for the item obligation that remains - normally a note pointing to the
         // bound that introduced the obligation (e.g. `T: Send`).
         debug!("note_obligation_cause_for_async_await: next_code={:?}", next_code);
diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs
index 6531289bd70..db034d1618c 100644
--- a/src/librustc/ty/adjustment.rs
+++ b/src/librustc/ty/adjustment.rs
@@ -85,7 +85,7 @@ impl Adjustment<'tcx> {
     pub fn is_region_borrow(&self) -> bool {
         match self.kind {
             Adjust::Borrow(AutoBorrow::Ref(..)) => true,
-            _ => false
+            _ => false,
         }
     }
 }
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 4a5fced7a89..d64e049c47b 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -436,11 +436,9 @@ pub struct TypeckTables<'tcx> {
     /// entire variable.
     pub upvar_list: ty::UpvarListMap,
 
-    /// Stores the type, span and optional scope span of all types
+    /// Stores the type, expression, span and optional scope span of all types
     /// that are live across the yield of this generator (if a generator).
-    pub generator_interior_types: Vec<GeneratorInteriorTypeCause<'tcx>>,
-
-    pub generator_interior_exprs: Vec<Option<hir::HirId>>,
+    pub generator_interior_types: Vec<(GeneratorInteriorTypeCause<'tcx>, Option<hir::HirId>)>,
 }
 
 impl<'tcx> TypeckTables<'tcx> {
@@ -467,7 +465,6 @@ impl<'tcx> TypeckTables<'tcx> {
             concrete_opaque_types: Default::default(),
             upvar_list: Default::default(),
             generator_interior_types: Default::default(),
-            generator_interior_exprs: Default::default(),
         }
     }
 
@@ -731,7 +728,6 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckTables<'tcx> {
             ref concrete_opaque_types,
             ref upvar_list,
             ref generator_interior_types,
-            ref generator_interior_exprs,
         } = *self;
 
         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
@@ -770,7 +766,6 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckTables<'tcx> {
             concrete_opaque_types.hash_stable(hcx, hasher);
             upvar_list.hash_stable(hcx, hasher);
             generator_interior_types.hash_stable(hcx, hasher);
-            generator_interior_exprs.hash_stable(hcx, hasher);
         })
     }
 }
diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs
index 9d8805f225d..7185de76fcb 100644
--- a/src/librustc_typeck/check/generator_interior.rs
+++ b/src/librustc_typeck/check/generator_interior.rs
@@ -18,6 +18,7 @@ use rustc_span::Span;
 struct InteriorVisitor<'a, 'tcx> {
     fcx: &'a FnCtxt<'a, 'tcx>,
     types: FxHashMap<ty::GeneratorInteriorTypeCause<'tcx>, usize>,
+    exprs: Vec<Option<hir::HirId>>,
     region_scope_tree: &'tcx region::ScopeTree,
     expr_count: usize,
     kind: hir::GeneratorKind,
@@ -99,6 +100,7 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
                         scope_span,
                     })
                     .or_insert(entries);
+                self.exprs.push(expr.map(|e| e.hir_id));
             }
         } else {
             debug!(
@@ -136,6 +138,7 @@ pub fn resolve_interior<'a, 'tcx>(
         expr_count: 0,
         kind,
         prev_unresolved_span: None,
+        exprs: vec![],
     };
     intravisit::walk_body(&mut visitor, body);
 
@@ -170,7 +173,8 @@ pub fn resolve_interior<'a, 'tcx>(
     });
 
     // Store the generator types and spans into the tables for this generator.
-    let interior_types = types.iter().map(|t| t.0.clone()).collect::<Vec<_>>();
+    let interior_types =
+        types.iter().zip(visitor.exprs).map(|(t, e)| (t.0.clone(), e)).collect::<Vec<_>>();
     visitor.fcx.inh.tables.borrow_mut().generator_interior_types = interior_types;
 
     // Extract type components
diff --git a/src/test/ui/async-await/issue-64130-4-async-move.stderr b/src/test/ui/async-await/issue-64130-4-async-move.stderr
index ddbb469b99c..77d0885c38d 100644
--- a/src/test/ui/async-await/issue-64130-4-async-move.stderr
+++ b/src/test/ui/async-await/issue-64130-4-async-move.stderr
@@ -16,6 +16,11 @@ LL |                 let _x = get().await;
 ...
 LL |     }
    |     - `client` is later dropped here
+help: consider moving this method call into a `let` binding to create a shorter lived borrow
+  --> $DIR/issue-64130-4-async-move.rs:19:15
+   |
+LL |         match client.status() {
+   |               ^^^^^^^^^^^^^^^
    = note: the return type of a function must have a statically known size
 
 error: aborting due to previous error