]> git.proxmox.com Git - rustc.git/blame - src/librustc_mir/borrow_check/region_infer/dump_mir.rs
New upstream version 1.47.0+dfsg1
[rustc.git] / src / librustc_mir / borrow_check / region_infer / dump_mir.rs
CommitLineData
ff7c6d11
XL
1//! As part of generating the regions, if you enable `-Zdump-mir=nll`,
2//! we will generate an annotated copy of the MIR that includes the
3//! state of region inference. This code handles emitting the region
4//! context internal state.
5
dfeec247 6use super::{OutlivesConstraint, RegionInferenceContext};
f035d41b 7use crate::borrow_check::type_check::Locations;
74b04a01 8use rustc_infer::infer::NLLRegionVariableOrigin;
f035d41b 9use rustc_middle::ty::TyCtxt;
ff7c6d11 10use std::io::{self, Write};
ff7c6d11
XL
11
12// Room for "'_#NNNNr" before things get misaligned.
13// Easy enough to fix if this ever doesn't seem like
14// enough.
15const REGION_WIDTH: usize = 8;
16
17impl<'tcx> RegionInferenceContext<'tcx> {
18 /// Write out our state into the `.mir` files.
f035d41b 19 pub(crate) fn dump_mir(&self, tcx: TyCtxt<'tcx>, out: &mut dyn Write) -> io::Result<()> {
ff7c6d11
XL
20 writeln!(out, "| Free Region Mapping")?;
21
22 for region in self.regions() {
8faf50e0 23 if let NLLRegionVariableOrigin::FreeRegion = self.definitions[region].origin {
dfeec247 24 let classification = self.universal_regions.region_classification(region).unwrap();
8faf50e0 25 let outlived_by = self.universal_region_relations.regions_outlived_by(region);
ff7c6d11
XL
26 writeln!(
27 out,
0bf4aa26
XL
28 "| {r:rw$?} | {c:cw$?} | {ob:?}",
29 r = region,
ff7c6d11 30 rw = REGION_WIDTH,
0bf4aa26 31 c = classification,
ff7c6d11 32 cw = 8, // "External" at most
0bf4aa26 33 ob = outlived_by
ff7c6d11
XL
34 )?;
35 }
36 }
37
38 writeln!(out, "|")?;
39 writeln!(out, "| Inferred Region Values")?;
40 for region in self.regions() {
41 writeln!(
42 out,
0bf4aa26
XL
43 "| {r:rw$?} | {ui:4?} | {v}",
44 r = region,
ff7c6d11 45 rw = REGION_WIDTH,
8faf50e0 46 ui = self.region_universe(region),
ff7c6d11
XL
47 v = self.region_value_str(region),
48 )?;
49 }
50
51 writeln!(out, "|")?;
52 writeln!(out, "| Inference Constraints")?;
f035d41b 53 self.for_each_constraint(tcx, &mut |msg| writeln!(out, "| {}", msg))?;
ff7c6d11
XL
54
55 Ok(())
56 }
57
58 /// Debugging aid: Invokes the `with_msg` callback repeatedly with
9fa01778 59 /// our internal region constraints. These are dumped into the
ff7c6d11
XL
60 /// -Zdump-mir file so that we can figure out why the region
61 /// inference resulted in the values that it did when debugging.
62 fn for_each_constraint(
63 &self,
f035d41b 64 tcx: TyCtxt<'tcx>,
0531ce1d 65 with_msg: &mut dyn FnMut(&str) -> io::Result<()>,
ff7c6d11
XL
66 ) -> io::Result<()> {
67 for region in self.definitions.indices() {
68 let value = self.liveness_constraints.region_value_str(region);
69 if value != "{}" {
70 with_msg(&format!("{:?} live at {}", region, value))?;
71 }
72 }
73
dc9dc135 74 let mut constraints: Vec<_> = self.constraints.outlives().iter().collect();
ff7c6d11
XL
75 constraints.sort();
76 for constraint in &constraints {
dfeec247 77 let OutlivesConstraint { sup, sub, locations, category } = constraint;
f035d41b
XL
78 let (name, arg) = match locations {
79 Locations::All(span) => ("All", tcx.sess.source_map().span_to_string(*span)),
80 Locations::Single(loc) => ("Single", format!("{:?}", loc)),
81 };
82 with_msg(&format!("{:?}: {:?} due to {:?} at {}({})", sup, sub, category, name, arg))?;
ff7c6d11
XL
83 }
84
85 Ok(())
86 }
87}