Slightly more readable NLL/constraint graph dumps
This commit is contained in:
parent
b14d8b2ef2
commit
800c50608c
@ -6,7 +6,38 @@ use std::borrow::Cow;
|
|||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use itertools::Itertools;
|
||||||
use rustc_graphviz as dot;
|
use rustc_graphviz as dot;
|
||||||
|
use rustc_middle::ty::UniverseIndex;
|
||||||
|
|
||||||
|
fn render_outlives_constraint(constraint: &OutlivesConstraint<'_>) -> String {
|
||||||
|
match constraint.locations {
|
||||||
|
Locations::All(_) => "All(...)".to_string(),
|
||||||
|
Locations::Single(loc) => format!("{loc:?}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_universe(u: UniverseIndex) -> String {
|
||||||
|
if u.is_root() {
|
||||||
|
return "".to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
format!("/{:?}", u)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_region_vid(rvid: RegionVid, regioncx: &RegionInferenceContext<'_>) -> String {
|
||||||
|
let universe_str = render_universe(regioncx.region_definition(rvid).universe);
|
||||||
|
|
||||||
|
let external_name_str = if let Some(external_name) =
|
||||||
|
regioncx.region_definition(rvid).external_name.and_then(|e| e.get_name())
|
||||||
|
{
|
||||||
|
format!(" ({external_name})")
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
};
|
||||||
|
|
||||||
|
format!("{:?}{universe_str}{external_name_str}", rvid)
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> RegionInferenceContext<'tcx> {
|
impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
/// Write out the region constraint graph.
|
/// Write out the region constraint graph.
|
||||||
@ -46,10 +77,10 @@ impl<'a, 'this, 'tcx> dot::Labeller<'this> for RawConstraints<'a, 'tcx> {
|
|||||||
Some(dot::LabelText::LabelStr(Cow::Borrowed("box")))
|
Some(dot::LabelText::LabelStr(Cow::Borrowed("box")))
|
||||||
}
|
}
|
||||||
fn node_label(&'this self, n: &RegionVid) -> dot::LabelText<'this> {
|
fn node_label(&'this self, n: &RegionVid) -> dot::LabelText<'this> {
|
||||||
dot::LabelText::LabelStr(format!("{n:?}").into())
|
dot::LabelText::LabelStr(render_region_vid(*n, self.regioncx).into())
|
||||||
}
|
}
|
||||||
fn edge_label(&'this self, e: &OutlivesConstraint<'tcx>) -> dot::LabelText<'this> {
|
fn edge_label(&'this self, e: &OutlivesConstraint<'tcx>) -> dot::LabelText<'this> {
|
||||||
dot::LabelText::LabelStr(format!("{:?}", e.locations).into())
|
dot::LabelText::LabelStr(render_outlives_constraint(e).into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,8 +127,9 @@ impl<'a, 'this, 'tcx> dot::Labeller<'this> for SccConstraints<'a, 'tcx> {
|
|||||||
Some(dot::LabelText::LabelStr(Cow::Borrowed("box")))
|
Some(dot::LabelText::LabelStr(Cow::Borrowed("box")))
|
||||||
}
|
}
|
||||||
fn node_label(&'this self, n: &ConstraintSccIndex) -> dot::LabelText<'this> {
|
fn node_label(&'this self, n: &ConstraintSccIndex) -> dot::LabelText<'this> {
|
||||||
let nodes = &self.nodes_per_scc[*n];
|
let nodes_str =
|
||||||
dot::LabelText::LabelStr(format!("{n:?} = {nodes:?}").into())
|
self.nodes_per_scc[*n].iter().map(|n| render_region_vid(*n, self.regioncx)).join(", ");
|
||||||
|
dot::LabelText::LabelStr(format!("SCC({n}) = {{{nodes_str}}}", n = n.as_usize()).into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1562,7 +1562,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||||||
|
|
||||||
// Because this free region must be in the ROOT universe, we
|
// Because this free region must be in the ROOT universe, we
|
||||||
// know it cannot contain any bound universes.
|
// know it cannot contain any bound universes.
|
||||||
assert!(self.scc_universes[longer_fr_scc] == ty::UniverseIndex::ROOT);
|
assert!(self.scc_universes[longer_fr_scc].is_root());
|
||||||
debug_assert!(self.scc_values.placeholders_contained_in(longer_fr_scc).next().is_none());
|
debug_assert!(self.scc_values.placeholders_contained_in(longer_fr_scc).next().is_none());
|
||||||
|
|
||||||
// Only check all of the relations for the main representative of each
|
// Only check all of the relations for the main representative of each
|
||||||
|
@ -213,7 +213,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||||||
let scc = self.constraint_sccs.scc(vid);
|
let scc = self.constraint_sccs.scc(vid);
|
||||||
|
|
||||||
// Special handling of higher-ranked regions.
|
// Special handling of higher-ranked regions.
|
||||||
if self.scc_universes[scc] != ty::UniverseIndex::ROOT {
|
if !self.scc_universes[scc].is_root() {
|
||||||
match self.scc_values.placeholders_contained_in(scc).enumerate().last() {
|
match self.scc_values.placeholders_contained_in(scc).enumerate().last() {
|
||||||
// If the region contains a single placeholder then they're equal.
|
// If the region contains a single placeholder then they're equal.
|
||||||
Some((0, placeholder)) => {
|
Some((0, placeholder)) => {
|
||||||
|
@ -346,6 +346,11 @@ impl UniverseIndex {
|
|||||||
pub fn cannot_name(self, other: UniverseIndex) -> bool {
|
pub fn cannot_name(self, other: UniverseIndex) -> bool {
|
||||||
self < other
|
self < other
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if `self` is the root universe, otherwise false.
|
||||||
|
pub fn is_root(self) -> bool {
|
||||||
|
self == Self::ROOT
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for UniverseIndex {
|
impl Default for UniverseIndex {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user