Skip to content

Commit b9d3f65

Browse files
committed
[drop tracking] Use parent expression for scope
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.
1 parent 230a8ee commit b9d3f65

File tree

3 files changed

+20
-4
lines changed

3 files changed

+20
-4
lines changed

compiler/rustc_typeck/src/check/generator_interior.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,18 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
387387
ty.needs_drop(self.fcx.tcx, self.fcx.param_env)
388388
};
389389

390+
let find_parent_expr = |mut hir_id| {
391+
let hir = self.fcx.tcx.hir();
392+
hir_id = hir.find_parent_node(hir_id)?;
393+
loop {
394+
if let hir::Node::Expr(_) = self.fcx.tcx.hir().find(hir_id)? {
395+
return Some(hir_id);
396+
} else {
397+
hir_id = hir.find_parent_node(hir_id)?;
398+
}
399+
}
400+
};
401+
390402
// Typically, the value produced by an expression is consumed by its parent in some way,
391403
// so we only have to check if the parent contains a yield (note that the parent may, for
392404
// example, store the value into a local variable, but then we already consider local
@@ -409,8 +421,9 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
409421
}) {
410422
self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id)
411423
} else {
412-
debug!("parent_node: {:?}", self.fcx.tcx.hir().find_parent_node(expr.hir_id));
413-
match self.fcx.tcx.hir().find_parent_node(expr.hir_id) {
424+
let parent_expr = find_parent_expr(expr.hir_id);
425+
debug!("parent_expr: {:?}", parent_expr);
426+
match parent_expr {
414427
Some(parent) => Some(Scope { id: parent.local_id, data: ScopeData::Node }),
415428
None => {
416429
self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id)

compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,8 @@ impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> {
159159
bk: rustc_middle::ty::BorrowKind,
160160
) {
161161
debug!(
162-
"borrow: place_with_id = {place_with_id:?}, diag_expr_id={diag_expr_id:?}, \
163-
borrow_kind={bk:?}"
162+
"borrow: place_with_id = {place_with_id:#?}, diag_expr_id={diag_expr_id:#?}, \
163+
borrow_kind={bk:#?}"
164164
);
165165

166166
self.borrow_place(place_with_id);

src/test/ui/async-await/issue-73137.rs

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
// run-pass
44
// edition:2018
5+
// revisions: normal drop-tracking
6+
// [normal]compile-flags: -Zdrop-tracking=no
7+
// [drop-tracking]compile-flags: -Zdrop-tracking
58

69
#![allow(dead_code)]
710
use std::future::Future;

0 commit comments

Comments
 (0)