about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2022-09-03 10:33:06 +0530
committerGitHub <noreply@github.com>2022-09-03 10:33:06 +0530
commitdc8fe633d5812096008d94d47fa692264d327a46 (patch)
tree7c3d92ed9171f0e079166db53dbb8ba3166bcfd1
parenta0056795da7a51f0ebebf0d5ad8f0b663d089420 (diff)
parentf921f5626d1dcc08f2707ed2c22e22fd1ad678b7 (diff)
Rollup merge of #101217 - eholk:drop-tracking-73137, r=jyn514
[drop tracking] Use parent expression for scope, not parent node

Previously we were just using the parent node as the scope for a temporary value, but it turns out this is too narrow. For example, in an expression like

    Foo {
        b: &42,
        a: async { 0 }.await,
    }

the scope for the &42 was set to the ExprField node for `b: &42`, when we actually want to use the Foo struct expression.

We fix this by recursively searching through parent nodes until we find a Node::Expr. It may be that we don't find one, and if so that's okay, we will just fall back on the enclosing temporary scope which is always sufficient.

Helps with #97331

r? ``@jyn514``
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs3
-rw-r--r--compiler/rustc_typeck/src/check/generator_interior.rs11
-rw-r--r--compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs4
-rw-r--r--src/test/ui/async-await/issue-73137.rs3
4 files changed, 17 insertions, 4 deletions
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 8f787739248..6217bffb8f7 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -291,6 +291,9 @@ impl<'hir> Map<'hir> {
         Some(def_kind)
     }
 
+    /// Finds the id of the parent node to this one.
+    ///
+    /// If calling repeatedly and iterating over parents, prefer [`Map::parent_iter`].
     pub fn find_parent_node(self, id: HirId) -> Option<HirId> {
         if id.local_id == ItemLocalId::from_u32(0) {
             Some(self.tcx.hir_owner_parent(id.owner))
diff --git a/compiler/rustc_typeck/src/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs
index 2a8c460bb11..7fda6f79f23 100644
--- a/compiler/rustc_typeck/src/check/generator_interior.rs
+++ b/compiler/rustc_typeck/src/check/generator_interior.rs
@@ -408,8 +408,15 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
             }) {
             self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id)
         } else {
-            debug!("parent_node: {:?}", self.fcx.tcx.hir().find_parent_node(expr.hir_id));
-            match self.fcx.tcx.hir().find_parent_node(expr.hir_id) {
+            let parent_expr = self
+                .fcx
+                .tcx
+                .hir()
+                .parent_iter(expr.hir_id)
+                .find(|(_, node)| matches!(node, hir::Node::Expr(_)))
+                .map(|(id, _)| id);
+            debug!("parent_expr: {:?}", parent_expr);
+            match parent_expr {
                 Some(parent) => Some(Scope { id: parent.local_id, data: ScopeData::Node }),
                 None => {
                     self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id)
diff --git a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs
index ded0888c33e..e22675e9d5f 100644
--- a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs
+++ b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs
@@ -159,8 +159,8 @@ impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> {
         bk: rustc_middle::ty::BorrowKind,
     ) {
         debug!(
-            "borrow: place_with_id = {place_with_id:?}, diag_expr_id={diag_expr_id:?}, \
-            borrow_kind={bk:?}"
+            "borrow: place_with_id = {place_with_id:#?}, diag_expr_id={diag_expr_id:#?}, \
+            borrow_kind={bk:#?}"
         );
 
         self.borrow_place(place_with_id);
diff --git a/src/test/ui/async-await/issue-73137.rs b/src/test/ui/async-await/issue-73137.rs
index c43ce2cadba..dcbe7765a9e 100644
--- a/src/test/ui/async-await/issue-73137.rs
+++ b/src/test/ui/async-await/issue-73137.rs
@@ -2,6 +2,9 @@
 
 // run-pass
 // edition:2018
+// revisions: normal drop-tracking
+// [normal]compile-flags: -Zdrop-tracking=no
+// [drop-tracking]compile-flags: -Zdrop-tracking
 
 #![allow(dead_code)]
 use std::future::Future;