Skip to content

Commit c19b237

Browse files
committed
Add -Zgraphviz_dark_mode
Many developers use a dark theme with editors and IDEs, but this typically doesn't extend to graphviz output. When I bring up a MIR graphviz document, the white background is strikingly bright. This new option changes the colors used for graphviz output to work better in dark-themed UIs.
1 parent 5099914 commit c19b237

File tree

4 files changed

+46
-11
lines changed

4 files changed

+46
-11
lines changed

compiler/rustc_graphviz/src/lib.rs

+17-3
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,7 @@ pub enum RenderOption {
599599
NoNodeStyles,
600600

601601
Monospace,
602+
DarkTheme,
602603
}
603604

604605
/// Returns vec holding all the default render options.
@@ -630,10 +631,23 @@ where
630631
writeln!(w, "digraph {} {{", g.graph_id().as_slice())?;
631632

632633
// Global graph properties
634+
let mut graph_attrs = Vec::new();
635+
let mut content_attrs = Vec::new();
633636
if options.contains(&RenderOption::Monospace) {
634-
writeln!(w, r#" graph[fontname="monospace"];"#)?;
635-
writeln!(w, r#" node[fontname="monospace"];"#)?;
636-
writeln!(w, r#" edge[fontname="monospace"];"#)?;
637+
let font = r#"fontname="monospace""#;
638+
graph_attrs.push(font);
639+
content_attrs.push(font);
640+
};
641+
if options.contains(&RenderOption::DarkTheme) {
642+
graph_attrs.push(r#"bgcolor="black""#);
643+
content_attrs.push(r#"color="white""#);
644+
content_attrs.push(r#"fontcolor="white""#);
645+
}
646+
if !(graph_attrs.is_empty() && content_attrs.is_empty()) {
647+
writeln!(w, r#" graph[{}];"#, graph_attrs.join(" "))?;
648+
let content_attrs_str = content_attrs.join(" ");
649+
writeln!(w, r#" node[{}];"#, content_attrs_str)?;
650+
writeln!(w, r#" edge[{}];"#, content_attrs_str)?;
637651
}
638652

639653
for n in g.nodes().iter() {

compiler/rustc_mir/src/dataflow/framework/engine.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,11 @@ where
306306
let mut buf = Vec::new();
307307

308308
let graphviz = graphviz::Formatter::new(body, def_id, results, style);
309-
dot::render_opts(&graphviz, &mut buf, &[dot::RenderOption::Monospace])?;
309+
let mut render_opts = vec![dot::RenderOption::Monospace];
310+
if tcx.sess.opts.debugging_opts.graphviz_dark_mode {
311+
render_opts.push(dot::RenderOption::DarkTheme);
312+
}
313+
dot::render_opts(&graphviz, &mut buf, &render_opts)?;
310314

311315
if let Some(parent) = path.parent() {
312316
fs::create_dir_all(parent)?;

compiler/rustc_mir/src/util/graphviz.rs

+22-7
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,28 @@ where
5555
writeln!(w, "{} {}Mir_{} {{", kind, cluster, def_name)?;
5656

5757
// Global graph properties
58-
writeln!(w, r#" graph [fontname="monospace"];"#)?;
59-
writeln!(w, r#" node [fontname="monospace"];"#)?;
60-
writeln!(w, r#" edge [fontname="monospace"];"#)?;
58+
let font = r#"fontname="monospace""#;
59+
let mut graph_attrs = vec![font];
60+
let mut content_attrs = vec![font];
61+
62+
let dark_mode = tcx.sess.opts.debugging_opts.graphviz_dark_mode;
63+
if dark_mode {
64+
graph_attrs.push(r#"bgcolor="black""#);
65+
content_attrs.push(r#"color="white""#);
66+
content_attrs.push(r#"fontcolor="white""#);
67+
}
68+
69+
writeln!(w, r#" graph [{}];"#, graph_attrs.join(" "))?;
70+
let content_attrs_str = content_attrs.join(" ");
71+
writeln!(w, r#" node [{}];"#, content_attrs_str)?;
72+
writeln!(w, r#" edge [{}];"#, content_attrs_str)?;
6173

6274
// Graph label
6375
write_graph_label(tcx, def_id, body, w)?;
6476

6577
// Nodes
6678
for (block, _) in body.basic_blocks().iter_enumerated() {
67-
write_node(def_id, block, body, w)?;
79+
write_node(def_id, block, body, dark_mode, w)?;
6880
}
6981

7082
// Edges
@@ -84,6 +96,7 @@ where
8496
pub fn write_node_label<W: Write, INIT, FINI>(
8597
block: BasicBlock,
8698
body: &Body<'_>,
99+
dark_mode: bool,
87100
w: &mut W,
88101
num_cols: u32,
89102
init: INIT,
@@ -100,8 +113,9 @@ where
100113
// Basic block number at the top.
101114
write!(
102115
w,
103-
r#"<tr><td {attrs} colspan="{colspan}">{blk}</td></tr>"#,
104-
attrs = r#"bgcolor="gray" align="center""#,
116+
r#"<tr><td bgcolor="{bgcolor}" {attrs} colspan="{colspan}">{blk}</td></tr>"#,
117+
bgcolor = if dark_mode { "dimgray" } else { "gray" },
118+
attrs = r#"align="center""#,
105119
colspan = num_cols,
106120
blk = block.index()
107121
)?;
@@ -134,11 +148,12 @@ fn write_node<W: Write>(
134148
def_id: DefId,
135149
block: BasicBlock,
136150
body: &Body<'_>,
151+
dark_mode: bool,
137152
w: &mut W,
138153
) -> io::Result<()> {
139154
// Start a new node with the label to follow, in one of DOT's pseudo-HTML tables.
140155
write!(w, r#" {} [shape="none", label=<"#, node(def_id, block))?;
141-
write_node_label(block, body, w, 1, |_| Ok(()), |_| Ok(()))?;
156+
write_node_label(block, body, dark_mode, w, 1, |_| Ok(()), |_| Ok(()))?;
142157
// Close the node label and the node itself.
143158
writeln!(w, ">];")
144159
}

compiler/rustc_session/src/options.rs

+2
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
907907
"force all crates to be `rustc_private` unstable (default: no)"),
908908
fuel: Option<(String, u64)> = (None, parse_optimization_fuel, [TRACKED],
909909
"set the optimization fuel quota for a crate"),
910+
graphviz_dark_mode: bool = (false, parse_bool, [UNTRACKED],
911+
"use dark-themed colors in graphviz output (default: no)"),
910912
hir_stats: bool = (false, parse_bool, [UNTRACKED],
911913
"print some statistics about AST and HIR (default: no)"),
912914
human_readable_cgu_names: bool = (false, parse_bool, [TRACKED],

0 commit comments

Comments
 (0)