]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs
Auto merge of #55162 - nikomatsakis:issue-54902-underscore-bound, r=tmandry
[rust.git] / src / librustc_mir / borrow_check / nll / region_infer / dump_mir.rs
1 // Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! As part of generating the regions, if you enable `-Zdump-mir=nll`,
12 //! we will generate an annotated copy of the MIR that includes the
13 //! state of region inference. This code handles emitting the region
14 //! context internal state.
15
16 use rustc::infer::NLLRegionVariableOrigin;
17 use std::io::{self, Write};
18 use super::{OutlivesConstraint, RegionInferenceContext};
19
20 // Room for "'_#NNNNr" before things get misaligned.
21 // Easy enough to fix if this ever doesn't seem like
22 // enough.
23 const REGION_WIDTH: usize = 8;
24
25 impl<'tcx> RegionInferenceContext<'tcx> {
26     /// Write out our state into the `.mir` files.
27     pub(crate) fn dump_mir(&self, out: &mut dyn Write) -> io::Result<()> {
28         writeln!(out, "| Free Region Mapping")?;
29
30         for region in self.regions() {
31             if let NLLRegionVariableOrigin::FreeRegion = self.definitions[region].origin {
32                 let classification = self
33                     .universal_regions
34                     .region_classification(region)
35                     .unwrap();
36                 let outlived_by = self.universal_region_relations.regions_outlived_by(region);
37                 writeln!(
38                     out,
39                     "| {r:rw$?} | {c:cw$?} | {ob:?}",
40                     r = region,
41                     rw = REGION_WIDTH,
42                     c = classification,
43                     cw = 8, // "External" at most
44                     ob = outlived_by
45                 )?;
46             }
47         }
48
49         writeln!(out, "|")?;
50         writeln!(out, "| Inferred Region Values")?;
51         for region in self.regions() {
52             writeln!(
53                 out,
54                 "| {r:rw$?} | {ui:4?} | {v}",
55                 r = region,
56                 rw = REGION_WIDTH,
57                 ui = self.region_universe(region),
58                 v = self.region_value_str(region),
59             )?;
60         }
61
62         writeln!(out, "|")?;
63         writeln!(out, "| Inference Constraints")?;
64         self.for_each_constraint(&mut |msg| writeln!(out, "| {}", msg))?;
65
66         Ok(())
67     }
68
69     /// Debugging aid: Invokes the `with_msg` callback repeatedly with
70     /// our internal region constraints.  These are dumped into the
71     /// -Zdump-mir file so that we can figure out why the region
72     /// inference resulted in the values that it did when debugging.
73     fn for_each_constraint(
74         &self,
75         with_msg: &mut dyn FnMut(&str) -> io::Result<()>,
76     ) -> io::Result<()> {
77         for region in self.definitions.indices() {
78             let value = self.liveness_constraints.region_value_str(region);
79             if value != "{}" {
80                 with_msg(&format!("{:?} live at {}", region, value))?;
81             }
82         }
83
84         let mut constraints: Vec<_> = self.constraints.iter().collect();
85         constraints.sort();
86         for constraint in &constraints {
87             let OutlivesConstraint {
88                 sup,
89                 sub,
90                 locations,
91                 category,
92             } = constraint;
93             with_msg(&format!(
94                 "{:?}: {:?} due to {:?} at {:?}",
95                 sup,
96                 sub,
97                 category,
98                 locations,
99             ))?;
100         }
101
102         Ok(())
103     }
104 }
105