From 800c50608ca992bce2b90bd7361ad908bb4045e2 Mon Sep 17 00:00:00 2001 From: Amanda Stjerna Date: Thu, 11 Apr 2024 16:56:45 +0200 Subject: [PATCH] Slightly more readable NLL/constraint graph dumps --- .../src/region_infer/graphviz.rs | 40 +++++++++++++++++-- .../rustc_borrowck/src/region_infer/mod.rs | 2 +- .../src/region_infer/opaque_types.rs | 2 +- compiler/rustc_type_ir/src/lib.rs | 5 +++ 4 files changed, 43 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/graphviz.rs b/compiler/rustc_borrowck/src/region_infer/graphviz.rs index c103ba3c40709..f145d30fe38a9 100644 --- a/compiler/rustc_borrowck/src/region_infer/graphviz.rs +++ b/compiler/rustc_borrowck/src/region_infer/graphviz.rs @@ -6,7 +6,38 @@ use std::borrow::Cow; use std::io::{self, Write}; use super::*; +use itertools::Itertools; 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> { /// 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"))) } 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> { - 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"))) } fn node_label(&'this self, n: &ConstraintSccIndex) -> dot::LabelText<'this> { - let nodes = &self.nodes_per_scc[*n]; - dot::LabelText::LabelStr(format!("{n:?} = {nodes:?}").into()) + let nodes_str = + 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()) } } diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 599f7dd18c3ea..dd75548a15df7 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -1562,7 +1562,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Because this free region must be in the ROOT universe, we // 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()); // Only check all of the relations for the main representative of each diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 9f0e54febe4cd..73ba5bee13b7f 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -213,7 +213,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let scc = self.constraint_sccs.scc(vid); // 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() { // If the region contains a single placeholder then they're equal. Some((0, placeholder)) => { diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 45e22b12a8b06..a5b33a8125d50 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -346,6 +346,11 @@ impl UniverseIndex { pub fn cannot_name(self, other: UniverseIndex) -> bool { 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 {