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.
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.
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.
16 use rustc::infer::NLLRegionVariableOrigin;
17 use std::io::{self, Write};
18 use super::{OutlivesConstraint, RegionInferenceContext};
20 // Room for "'_#NNNNr" before things get misaligned.
21 // Easy enough to fix if this ever doesn't seem like
23 const REGION_WIDTH: usize = 8;
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")?;
30 for region in self.regions() {
31 if let NLLRegionVariableOrigin::FreeRegion = self.definitions[region].origin {
32 let classification = self
34 .region_classification(region)
36 let outlived_by = self.universal_region_relations.regions_outlived_by(region);
39 "| {r:rw$?} | {c:cw$?} | {ob:?}",
43 cw = 8, // "External" at most
50 writeln!(out, "| Inferred Region Values")?;
51 for region in self.regions() {
54 "| {r:rw$?} | {ui:4?} | {v}",
57 ui = self.region_universe(region),
58 v = self.region_value_str(region),
63 writeln!(out, "| Inference Constraints")?;
64 self.for_each_constraint(&mut |msg| writeln!(out, "| {}", msg))?;
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(
75 with_msg: &mut dyn FnMut(&str) -> io::Result<()>,
77 for region in self.definitions.indices() {
78 let value = self.liveness_constraints.region_value_str(region);
80 with_msg(&format!("{:?} live at {}", region, value))?;
84 let mut constraints: Vec<_> = self.constraints.iter().collect();
86 for constraint in &constraints {
87 let OutlivesConstraint {
94 "{:?}: {:?} due to {:?} at {:?}",