From 64d98f8ee037282c35007b64c2649055c56af1db Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:03 +0200 Subject: Merging upstream version 1.68.2+dfsg1. Signed-off-by: Daniel Baumann --- .../generator_interior/drop_ranges/cfg_build.rs | 22 ++++++++++++++++++---- .../drop_ranges/cfg_visualize.rs | 13 +++++++++---- .../src/generator_interior/drop_ranges/mod.rs | 12 +++++------- .../drop_ranges/record_consumed_borrow.rs | 4 ++-- 4 files changed, 34 insertions(+), 17 deletions(-) (limited to 'compiler/rustc_hir_typeck/src/generator_interior/drop_ranges') diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs index fd8ea1ad7..b3dd3031d 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs @@ -233,6 +233,7 @@ impl<'a, 'tcx> DropRangeVisitor<'a, 'tcx> { self.tcx() .sess .delay_span_bug(expr.span, format!("could not resolve infer vars in `{ty}`")); + return; } let ty = self.tcx().erase_regions(ty); let m = self.tcx().parent_module(expr.hir_id).to_def_id(); @@ -303,8 +304,8 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> { let mut reinit = None; match expr.kind { ExprKind::Assign(lhs, rhs, _) => { - self.visit_expr(lhs); self.visit_expr(rhs); + self.visit_expr(lhs); reinit = Some(lhs); } @@ -432,7 +433,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> { self.drop_ranges.add_control_edge(self.expr_index, *target) }), - ExprKind::Break(destination, ..) => { + ExprKind::Break(destination, value) => { // destination either points to an expression or to a block. We use // find_target_expression_from_destination to use the last expression of the block // if destination points to a block. @@ -442,7 +443,11 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> { // will refer to the end of the block due to the post order traversal. self.find_target_expression_from_destination(destination).map_or((), |target| { self.drop_ranges.add_control_edge_hir_id(self.expr_index, target) - }) + }); + + if let Some(value) = value { + self.visit_expr(value); + } } ExprKind::Call(f, args) => { @@ -464,6 +469,12 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> { ExprKind::AddrOf(..) | ExprKind::Array(..) + // FIXME(eholk): We probably need special handling for AssignOps. The ScopeTree builder + // in region.rs runs both lhs then rhs and rhs then lhs and then sets all yields to be + // the latest they show up in either traversal. With the older scope-based + // approximation, this was fine, but it's probably not right now. What we probably want + // to do instead is still run both orders, but consider anything that showed up as a + // yield in either order. | ExprKind::AssignOp(..) | ExprKind::Binary(..) | ExprKind::Block(..) @@ -501,6 +512,9 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> { // Increment expr_count here to match what InteriorVisitor expects. self.expr_index = self.expr_index + 1; + + // Save a node mapping to get better CFG visualization + self.drop_ranges.add_node_mapping(pat.hir_id, self.expr_index); } } @@ -520,7 +534,7 @@ impl DropRangesBuilder { } }); } - debug!("hir_id_map: {:?}", tracked_value_map); + debug!("hir_id_map: {:#?}", tracked_value_map); let num_values = tracked_value_map.len(); Self { tracked_value_map, diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_visualize.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_visualize.rs index c0a0bfe8e..e8d31be79 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_visualize.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_visualize.rs @@ -2,6 +2,7 @@ //! flow graph when needed for debugging. use rustc_graphviz as dot; +use rustc_hir::{Expr, ExprKind, Node}; use rustc_middle::ty::TyCtxt; use super::{DropRangesBuilder, PostOrderId}; @@ -80,10 +81,14 @@ impl<'a> dot::Labeller<'a> for DropRangesGraph<'_, '_> { .post_order_map .iter() .find(|(_hir_id, &post_order_id)| post_order_id == *n) - .map_or("".into(), |(hir_id, _)| self - .tcx - .hir() - .node_to_string(*hir_id)) + .map_or("".into(), |(hir_id, _)| format!( + "{}{}", + self.tcx.hir().node_to_string(*hir_id), + match self.tcx.hir().find(*hir_id) { + Some(Node::Expr(Expr { kind: ExprKind::Yield(..), .. })) => " (yield)", + _ => "", + } + )) ) .into(), ) diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs index 2abcadcc9..f7b493bc2 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs @@ -79,7 +79,7 @@ pub fn compute_drop_ranges<'a, 'tcx>( /// result of `foo`. On the other hand, if `place` points to `x` then `f` will /// be called both on the `ExprKind::Path` node that represents the expression /// as well as the HirId of the local `x` itself. -fn for_each_consumable<'tcx>(hir: Map<'tcx>, place: TrackedValue, mut f: impl FnMut(TrackedValue)) { +fn for_each_consumable(hir: Map<'_>, place: TrackedValue, mut f: impl FnMut(TrackedValue)) { f(place); let node = hir.find(place.hir_id()); if let Some(Node::Expr(expr)) = node { @@ -96,15 +96,13 @@ fn for_each_consumable<'tcx>(hir: Map<'tcx>, place: TrackedValue, mut f: impl Fn } rustc_index::newtype_index! { - pub struct PostOrderId { - DEBUG_FORMAT = "id({})", - } + #[debug_format = "id({})"] + pub struct PostOrderId {} } rustc_index::newtype_index! { - pub struct TrackedValueIndex { - DEBUG_FORMAT = "hidx({})", - } + #[debug_format = "hidx({})"] + pub struct TrackedValueIndex {} } /// Identifies a value whose drop state we need to track. diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs index bfe95852a..ed3d89031 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs @@ -116,7 +116,7 @@ impl<'tcx> ExprUseDelegate<'tcx> { // where the `identity(...)` (the rvalue) produces a return type // of `&'rv mut A`, where `'a: 'rv`. We then assign this result to // `'y`, resulting in (transitively) `'a: 'y` (i.e., while `y` is in use, - // `a` will be considered borrowed). Other parts of the code will ensure + // `a` will be considered borrowed). Other parts of the code will ensure // that if `y` is live over a yield, `&'y mut A` appears in the generator // state. If `'y` is live, then any sound region analysis must conclude // that `'a` is also live. So if this causes a bug, blame some other @@ -140,7 +140,7 @@ impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> { diag_expr_id: HirId, ) { let hir = self.tcx.hir(); - let parent = match hir.find_parent_node(place_with_id.hir_id) { + let parent = match hir.opt_parent_id(place_with_id.hir_id) { Some(parent) => parent, None => place_with_id.hir_id, }; -- cgit v1.2.3