[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.
This commit is contained in:
parent
230a8ee364
commit
b9d3f65412
@ -387,6 +387,18 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
|
||||
ty.needs_drop(self.fcx.tcx, self.fcx.param_env)
|
||||
};
|
||||
|
||||
let find_parent_expr = |mut hir_id| {
|
||||
let hir = self.fcx.tcx.hir();
|
||||
hir_id = hir.find_parent_node(hir_id)?;
|
||||
loop {
|
||||
if let hir::Node::Expr(_) = self.fcx.tcx.hir().find(hir_id)? {
|
||||
return Some(hir_id);
|
||||
} else {
|
||||
hir_id = hir.find_parent_node(hir_id)?;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Typically, the value produced by an expression is consumed by its parent in some way,
|
||||
// so we only have to check if the parent contains a yield (note that the parent may, for
|
||||
// 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> {
|
||||
}) {
|
||||
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 = find_parent_expr(expr.hir_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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user