]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs
Rollup merge of #58306 - GuillaumeGomez:crate-browser-history, r=QuietMisdreavus
[rust.git] / src / librustc_mir / borrow_check / nll / region_infer / dump_mir.rs
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
6 use rustc::infer::NLLRegionVariableOrigin;
7 use std::io::{self, Write};
8 use super::{OutlivesConstraint, RegionInferenceContext};
9
10 // Room for "'_#NNNNr" before things get misaligned.
11 // Easy enough to fix if this ever doesn't seem like
12 // enough.
13 const REGION_WIDTH: usize = 8;
14
15 impl<'tcx> RegionInferenceContext<'tcx> {
16     /// Write out our state into the `.mir` files.
17     pub(crate) fn dump_mir(&self, out: &mut dyn Write) -> io::Result<()> {
18         writeln!(out, "| Free Region Mapping")?;
19
20         for region in self.regions() {
21             if let NLLRegionVariableOrigin::FreeRegion = self.definitions[region].origin {
22                 let classification = self
23                     .universal_regions
24                     .region_classification(region)
25                     .unwrap();
26                 let outlived_by = self.universal_region_relations.regions_outlived_by(region);
27                 writeln!(
28                     out,
29                     "| {r:rw$?} | {c:cw$?} | {ob:?}",
30                     r = region,
31                     rw = REGION_WIDTH,
32                     c = classification,
33                     cw = 8, // "External" at most
34                     ob = outlived_by
35                 )?;
36             }
37         }
38
39         writeln!(out, "|")?;
40         writeln!(out, "| Inferred Region Values")?;
41         for region in self.regions() {
42             writeln!(
43                 out,
44                 "| {r:rw$?} | {ui:4?} | {v}",
45                 r = region,
46                 rw = REGION_WIDTH,
47                 ui = self.region_universe(region),
48                 v = self.region_value_str(region),
49             )?;
50         }
51
52         writeln!(out, "|")?;
53         writeln!(out, "| Inference Constraints")?;
54         self.for_each_constraint(&mut |msg| writeln!(out, "| {}", msg))?;
55
56         Ok(())
57     }
58
59     /// Debugging aid: Invokes the `with_msg` callback repeatedly with
60     /// our internal region constraints. These are dumped into the
61     /// -Zdump-mir file so that we can figure out why the region
62     /// inference resulted in the values that it did when debugging.
63     fn for_each_constraint(
64         &self,
65         with_msg: &mut dyn FnMut(&str) -> io::Result<()>,
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
74         let mut constraints: Vec<_> = self.constraints.iter().collect();
75         constraints.sort();
76         for constraint in &constraints {
77             let OutlivesConstraint {
78                 sup,
79                 sub,
80                 locations,
81                 category,
82             } = constraint;
83             with_msg(&format!(
84                 "{:?}: {:?} due to {:?} at {:?}",
85                 sup,
86                 sub,
87                 category,
88                 locations,
89             ))?;
90         }
91
92         Ok(())
93     }
94 }
95