summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs')
-rw-r--r--compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs63
1 files changed, 41 insertions, 22 deletions
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 122ad7009..fd8ea1ad7 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
@@ -9,9 +9,10 @@ use hir::{
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir as hir;
use rustc_index::vec::IndexVec;
+use rustc_infer::infer::InferCtxt;
use rustc_middle::{
hir::map::Map,
- ty::{TyCtxt, TypeckResults},
+ ty::{ParamEnv, TyCtxt, TypeVisitable, TypeckResults},
};
use std::mem::swap;
@@ -21,20 +22,29 @@ use std::mem::swap;
/// The resulting structure still needs to be iterated to a fixed point, which
/// can be done with propagate_to_fixpoint in cfg_propagate.
pub(super) fn build_control_flow_graph<'tcx>(
- hir: Map<'tcx>,
- tcx: TyCtxt<'tcx>,
+ infcx: &InferCtxt<'tcx>,
typeck_results: &TypeckResults<'tcx>,
+ param_env: ParamEnv<'tcx>,
consumed_borrowed_places: ConsumedAndBorrowedPlaces,
body: &'tcx Body<'tcx>,
num_exprs: usize,
) -> (DropRangesBuilder, FxHashSet<HirId>) {
- let mut drop_range_visitor =
- DropRangeVisitor::new(hir, tcx, typeck_results, consumed_borrowed_places, num_exprs);
+ let mut drop_range_visitor = DropRangeVisitor::new(
+ infcx,
+ typeck_results,
+ param_env,
+ consumed_borrowed_places,
+ num_exprs,
+ );
intravisit::walk_body(&mut drop_range_visitor, body);
drop_range_visitor.drop_ranges.process_deferred_edges();
- if let Some(filename) = &tcx.sess.opts.unstable_opts.dump_drop_tracking_cfg {
- super::cfg_visualize::write_graph_to_file(&drop_range_visitor.drop_ranges, filename, tcx);
+ if let Some(filename) = &infcx.tcx.sess.opts.unstable_opts.dump_drop_tracking_cfg {
+ super::cfg_visualize::write_graph_to_file(
+ &drop_range_visitor.drop_ranges,
+ filename,
+ infcx.tcx,
+ );
}
(drop_range_visitor.drop_ranges, drop_range_visitor.places.borrowed_temporaries)
@@ -82,40 +92,44 @@ pub(super) fn build_control_flow_graph<'tcx>(
/// ```
struct DropRangeVisitor<'a, 'tcx> {
- hir: Map<'tcx>,
+ typeck_results: &'a TypeckResults<'tcx>,
+ infcx: &'a InferCtxt<'tcx>,
+ param_env: ParamEnv<'tcx>,
places: ConsumedAndBorrowedPlaces,
drop_ranges: DropRangesBuilder,
expr_index: PostOrderId,
- tcx: TyCtxt<'tcx>,
- typeck_results: &'a TypeckResults<'tcx>,
label_stack: Vec<(Option<rustc_ast::Label>, PostOrderId)>,
}
impl<'a, 'tcx> DropRangeVisitor<'a, 'tcx> {
fn new(
- hir: Map<'tcx>,
- tcx: TyCtxt<'tcx>,
+ infcx: &'a InferCtxt<'tcx>,
typeck_results: &'a TypeckResults<'tcx>,
+ param_env: ParamEnv<'tcx>,
places: ConsumedAndBorrowedPlaces,
num_exprs: usize,
) -> Self {
debug!("consumed_places: {:?}", places.consumed);
let drop_ranges = DropRangesBuilder::new(
places.consumed.iter().flat_map(|(_, places)| places.iter().cloned()),
- hir,
+ infcx.tcx.hir(),
num_exprs,
);
Self {
- hir,
+ infcx,
+ typeck_results,
+ param_env,
places,
drop_ranges,
expr_index: PostOrderId::from_u32(0),
- typeck_results,
- tcx,
label_stack: vec![],
}
}
+ fn tcx(&self) -> TyCtxt<'tcx> {
+ self.infcx.tcx
+ }
+
fn record_drop(&mut self, value: TrackedValue) {
if self.places.borrowed.contains(&value) {
debug!("not marking {:?} as dropped because it is borrowed at some point", value);
@@ -137,7 +151,7 @@ impl<'a, 'tcx> DropRangeVisitor<'a, 'tcx> {
.map_or(vec![], |places| places.iter().cloned().collect());
for place in places {
trace!(?place, "consuming place");
- for_each_consumable(self.hir, place, |value| self.record_drop(value));
+ for_each_consumable(self.tcx().hir(), place, |value| self.record_drop(value));
}
}
@@ -214,10 +228,15 @@ impl<'a, 'tcx> DropRangeVisitor<'a, 'tcx> {
/// return.
fn handle_uninhabited_return(&mut self, expr: &Expr<'tcx>) {
let ty = self.typeck_results.expr_ty(expr);
- let ty = self.tcx.erase_regions(ty);
- let m = self.tcx.parent_module(expr.hir_id).to_def_id();
- let param_env = self.tcx.param_env(m.expect_local());
- if self.tcx.is_ty_uninhabited_from(m, ty, param_env) {
+ let ty = self.infcx.resolve_vars_if_possible(ty);
+ if ty.has_non_region_infer() {
+ self.tcx()
+ .sess
+ .delay_span_bug(expr.span, format!("could not resolve infer vars in `{ty}`"));
+ }
+ let ty = self.tcx().erase_regions(ty);
+ let m = self.tcx().parent_module(expr.hir_id).to_def_id();
+ if !ty.is_inhabited_from(self.tcx(), m, self.param_env) {
// This function will not return. We model this fact as an infinite loop.
self.drop_ranges.add_control_edge(self.expr_index + 1, self.expr_index + 1);
}
@@ -238,7 +257,7 @@ impl<'a, 'tcx> DropRangeVisitor<'a, 'tcx> {
destination: hir::Destination,
) -> Result<HirId, LoopIdError> {
destination.target_id.map(|target| {
- let node = self.hir.get(target);
+ let node = self.tcx().hir().get(target);
match node {
hir::Node::Expr(_) => target,
hir::Node::Block(b) => find_last_block_expression(b),