From ea1460773f1be2d0d717f6ab7609727e52ffa226 Mon Sep 17 00:00:00 2001 From: Vishnunarayan K I Date: Mon, 26 Oct 2020 19:04:29 +0530 Subject: [PATCH 1/6] make MIR graphviz generation use gsgdt gsgdt [https://crates.io/crates/gsgdt] is a crate which provides an interface for stringly typed graphs. It also provides generation of graphviz dot format from said graph. --- Cargo.lock | 12 +- compiler/rustc_mir/Cargo.toml | 1 + compiler/rustc_mir/src/util/generic_graph.rs | 70 ++++++++ compiler/rustc_mir/src/util/graphviz.rs | 168 +++---------------- compiler/rustc_mir/src/util/mod.rs | 5 +- src/tools/tidy/src/deps.rs | 1 + 6 files changed, 109 insertions(+), 148 deletions(-) create mode 100644 compiler/rustc_mir/src/util/generic_graph.rs diff --git a/Cargo.lock b/Cargo.lock index 30b7628120bdb..fb52f4201c06f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1340,6 +1340,15 @@ dependencies = [ "regex", ] +[[package]] +name = "gsgdt" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cb4a3313cdc3c65906272ddd8987c7291ff6df4b5c9997c1232b6acd1ceab24" +dependencies = [ + "serde", +] + [[package]] name = "handlebars" version = "3.4.0" @@ -3923,6 +3932,7 @@ name = "rustc_mir" version = "0.0.0" dependencies = [ "either", + "gsgdt", "itertools 0.9.0", "polonius-engine", "regex", @@ -5252,7 +5262,7 @@ dependencies = [ "chrono", "lazy_static", "matchers", - "parking_lot 0.9.0", + "parking_lot 0.11.0", "regex", "serde", "serde_json", diff --git a/compiler/rustc_mir/Cargo.toml b/compiler/rustc_mir/Cargo.toml index 487668cfa1109..28ba089d0622a 100644 --- a/compiler/rustc_mir/Cargo.toml +++ b/compiler/rustc_mir/Cargo.toml @@ -10,6 +10,7 @@ doctest = false [dependencies] either = "1.5.0" rustc_graphviz = { path = "../rustc_graphviz" } +gsgdt = "0.1.1" itertools = "0.9" tracing = "0.1" polonius-engine = "0.12.0" diff --git a/compiler/rustc_mir/src/util/generic_graph.rs b/compiler/rustc_mir/src/util/generic_graph.rs new file mode 100644 index 0000000000000..df9f94016c8ee --- /dev/null +++ b/compiler/rustc_mir/src/util/generic_graph.rs @@ -0,0 +1,70 @@ +use gsgdt::{Edge, Graph, GraphKind, Node, NodeStyle}; +use rustc_hir::def_id::DefId; +use rustc_index::vec::Idx; +use rustc_middle::mir::*; +use rustc_middle::ty::TyCtxt; + +/// Convert an MIR function into a gsgdt Graph +pub fn mir_fn_to_generic_graph<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>, subgraph: bool) -> Graph { + let def_id = body.source.def_id(); + let kind = if subgraph { GraphKind::Subgraph } else { GraphKind::Digraph }; + let def_name = graphviz_safe_def_name(def_id); + let graph_name = format!("Mir_{}", def_name); + let dark_mode = tcx.sess.opts.debugging_opts.graphviz_dark_mode; + + // Nodes + let nodes: Vec = body + .basic_blocks() + .iter_enumerated() + .map(|(block, _)| bb_to_graph_node(block, body, dark_mode)) + .collect(); + + // Edges + let mut edges = Vec::new(); + for (source, _) in body.basic_blocks().iter_enumerated() { + let def_id = body.source.def_id(); + let terminator = body[source].terminator(); + let labels = terminator.kind.fmt_successor_labels(); + + for (&target, label) in terminator.successors().zip(labels) { + let src = node(def_id, source); + let trg = node(def_id, target); + edges.push(Edge::new(src, trg, label.to_string())); + } + } + + Graph::new(graph_name, kind, nodes, edges) +} + +fn bb_to_graph_node(block: BasicBlock, body: &Body<'_>, dark_mode: bool) -> Node { + let def_id = body.source.def_id(); + let data = &body[block]; + let label = node(def_id, block); + + let (title, bgcolor) = if data.is_cleanup { + (format!("{} (cleanup)", block.index()), "lightblue") + } else { + let color = if dark_mode { "dimgray" } else { "gray" }; + (format!("{}", block.index()), color) + }; + + let style = NodeStyle { title_bg: Some(bgcolor.to_owned()), ..Default::default() }; + let mut stmts: Vec = data.statements.iter().map(|x| format!("{:?}", x)).collect(); + + // add the terminator to the stmts, gsgdt can print it out seperately + let mut terminator_head = String::new(); + data.terminator().kind.fmt_head(&mut terminator_head).unwrap(); + stmts.push(terminator_head); + + Node::new(stmts, label, title, style) +} + +// Must match `[0-9A-Za-z_]*`. This does not appear in the rendered graph, so +// it does not have to be user friendly. +pub fn graphviz_safe_def_name(def_id: DefId) -> String { + format!("{}_{}", def_id.krate.index(), def_id.index.index(),) +} + +fn node(def_id: DefId, block: BasicBlock) -> String { + format!("bb{}__{}", block.index(), graphviz_safe_def_name(def_id)) +} diff --git a/compiler/rustc_mir/src/util/graphviz.rs b/compiler/rustc_mir/src/util/graphviz.rs index 625f1a3e6844e..c83a56c22aebf 100644 --- a/compiler/rustc_mir/src/util/graphviz.rs +++ b/compiler/rustc_mir/src/util/graphviz.rs @@ -1,11 +1,12 @@ +use gsgdt::GraphvizSettings; use rustc_graphviz as dot; use rustc_hir::def_id::DefId; -use rustc_index::vec::Idx; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; use std::fmt::Debug; use std::io::{self, Write}; +use super::generic_graph::mir_fn_to_generic_graph; use super::pretty::dump_mir_def_ids; /// Write a graphviz DOT graph of a list of MIRs. @@ -32,12 +33,6 @@ where Ok(()) } -// Must match `[0-9A-Za-z_]*`. This does not appear in the rendered graph, so -// it does not have to be user friendly. -pub fn graphviz_safe_def_name(def_id: DefId) -> String { - format!("{}_{}", def_id.krate.index(), def_id.index.index(),) -} - /// Write a graphviz DOT graph of the MIR. pub fn write_mir_fn_graphviz<'tcx, W>( tcx: TyCtxt<'tcx>, @@ -48,12 +43,6 @@ pub fn write_mir_fn_graphviz<'tcx, W>( where W: Write, { - let def_id = body.source.def_id(); - let kind = if subgraph { "subgraph" } else { "digraph" }; - let cluster = if subgraph { "cluster_" } else { "" }; // Prints a border around MIR - let def_name = graphviz_safe_def_name(def_id); - writeln!(w, "{} {}Mir_{} {{", kind, cluster, def_name)?; - // Global graph properties let font = format!(r#"fontname="{}""#, tcx.sess.opts.debugging_opts.graphviz_font); let mut graph_attrs = vec![&font[..]]; @@ -67,168 +56,57 @@ where content_attrs.push(r#"fontcolor="white""#); } - writeln!(w, r#" graph [{}];"#, graph_attrs.join(" "))?; - let content_attrs_str = content_attrs.join(" "); - writeln!(w, r#" node [{}];"#, content_attrs_str)?; - writeln!(w, r#" edge [{}];"#, content_attrs_str)?; - // Graph label - write_graph_label(tcx, body, w)?; - - // Nodes - for (block, _) in body.basic_blocks().iter_enumerated() { - write_node(block, body, dark_mode, w)?; - } - - // Edges - for (source, _) in body.basic_blocks().iter_enumerated() { - write_edges(source, body, w)?; - } - writeln!(w, "}}") -} - -/// Write a graphviz HTML-styled label for the given basic block, with -/// all necessary escaping already performed. (This is suitable for -/// emitting directly, as is done in this module, or for use with the -/// LabelText::HtmlStr from librustc_graphviz.) -/// -/// `init` and `fini` are callbacks for emitting additional rows of -/// data (using HTML enclosed with `` in the emitted text). -pub fn write_node_label( - block: BasicBlock, - body: &Body<'_>, - dark_mode: bool, - w: &mut W, - num_cols: u32, - init: INIT, - fini: FINI, -) -> io::Result<()> -where - INIT: Fn(&mut W) -> io::Result<()>, - FINI: Fn(&mut W) -> io::Result<()>, -{ - let data = &body[block]; - - write!(w, r#""#)?; - - // Basic block number at the top. - let (blk, bgcolor) = if data.is_cleanup { - let color = if dark_mode { "royalblue" } else { "lightblue" }; - (format!("{} (cleanup)", block.index()), color) - } else { - let color = if dark_mode { "dimgray" } else { "gray" }; - (format!("{}", block.index()), color) + let label = get_graph_label(tcx, body); + let g = mir_fn_to_generic_graph(tcx, body, subgraph); + let settings = GraphvizSettings { + graph_attrs: Some(graph_attrs.join(" ")), + node_attrs: Some(content_attrs.join(" ")), + edge_attrs: Some(content_attrs.join(" ")), + graph_label: Some(label), }; - write!( - w, - r#""#, - attrs = r#"align="center""#, - colspan = num_cols, - blk = blk, - bgcolor = bgcolor - )?; - - init(w)?; - - // List of statements in the middle. - if !data.statements.is_empty() { - write!(w, r#"")?; - } - - // Terminator head at the bottom, not including the list of successor blocks. Those will be - // displayed as labels on the edges between blocks. - let mut terminator_head = String::new(); - data.terminator().kind.fmt_head(&mut terminator_head).unwrap(); - write!(w, r#""#, dot::escape_html(&terminator_head))?; - - fini(w)?; - - // Close the table - write!(w, "
{blk}
"#)?; - for statement in &data.statements { - write!(w, "{}
", escape(statement))?; - } - write!(w, "
{}
") -} - -/// Write a graphviz DOT node for the given basic block. -fn write_node( - block: BasicBlock, - body: &Body<'_>, - dark_mode: bool, - w: &mut W, -) -> io::Result<()> { - let def_id = body.source.def_id(); - // Start a new node with the label to follow, in one of DOT's pseudo-HTML tables. - write!(w, r#" {} [shape="none", label=<"#, node(def_id, block))?; - write_node_label(block, body, dark_mode, w, 1, |_| Ok(()), |_| Ok(()))?; - // Close the node label and the node itself. - writeln!(w, ">];") -} - -/// Write graphviz DOT edges with labels between the given basic block and all of its successors. -fn write_edges(source: BasicBlock, body: &Body<'_>, w: &mut W) -> io::Result<()> { - let def_id = body.source.def_id(); - let terminator = body[source].terminator(); - let labels = terminator.kind.fmt_successor_labels(); - - for (&target, label) in terminator.successors().zip(labels) { - let src = node(def_id, source); - let trg = node(def_id, target); - writeln!(w, r#" {} -> {} [label="{}"];"#, src, trg, label)?; - } - - Ok(()) + g.to_dot(w, &settings) } /// Write the graphviz DOT label for the overall graph. This is essentially a block of text that /// will appear below the graph, showing the type of the `fn` this MIR represents and the types of /// all the variables and temporaries. -fn write_graph_label<'tcx, W: Write>( - tcx: TyCtxt<'tcx>, - body: &Body<'_>, - w: &mut W, -) -> io::Result<()> { +fn get_graph_label<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> String { let def_id = body.source.def_id(); + let mut label: Vec = Vec::new(); - write!(w, " label= 0 { - write!(w, ", ")?; + label.push(", ".to_owned()); } - write!(w, "{:?}: {}", Place::from(arg), escape(&body.local_decls[arg].ty))?; + label.push(format!("{:?}: {}", Place::from(arg), escape(&body.local_decls[arg].ty))); } - write!(w, ") -> {}", escape(&body.return_ty()))?; - write!(w, r#"
"#)?; + label.push(format!(") -> {}", escape(&body.return_ty()))); + label.push(r#"
"#.to_owned()); for local in body.vars_and_temps_iter() { let decl = &body.local_decls[local]; - write!(w, "let ")?; + label.push("let ".to_owned()); if decl.mutability == Mutability::Mut { - write!(w, "mut ")?; + label.push("mut ".to_owned()); } - write!(w, r#"{:?}: {};
"#, Place::from(local), escape(&decl.ty))?; + label.push(format!(r#"{:?}: {};
"#, Place::from(local), escape(&decl.ty))); } for var_debug_info in &body.var_debug_info { - write!( - w, + label.push(format!( r#"debug {} => {};
"#, var_debug_info.name, escape(&var_debug_info.place) - )?; + )); } - - writeln!(w, ">;") -} - -fn node(def_id: DefId, block: BasicBlock) -> String { - format!("bb{}__{}", block.index(), graphviz_safe_def_name(def_id)) + label.join("") } fn escape(t: &T) -> String { diff --git a/compiler/rustc_mir/src/util/mod.rs b/compiler/rustc_mir/src/util/mod.rs index aaee0bc526db5..58e0f908108e4 100644 --- a/compiler/rustc_mir/src/util/mod.rs +++ b/compiler/rustc_mir/src/util/mod.rs @@ -8,6 +8,7 @@ mod alignment; pub mod collect_writes; mod find_self_call; pub(crate) mod generic_graphviz; +mod generic_graph; mod graphviz; pub(crate) mod pretty; pub(crate) mod spanview; @@ -15,6 +16,6 @@ pub(crate) mod spanview; pub use self::aggregate::expand_aggregate; pub use self::alignment::is_disaligned; pub use self::find_self_call::find_self_call; -pub use self::graphviz::write_node_label as write_graphviz_node_label; -pub use self::graphviz::{graphviz_safe_def_name, write_mir_graphviz}; +pub use self::generic_graph::graphviz_safe_def_name; +pub use self::graphviz::write_mir_graphviz; pub use self::pretty::{dump_enabled, dump_mir, write_mir_pretty, PassWhere}; diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 057b0884e287a..3aeb0b8c5b351 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -104,6 +104,7 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ "getopts", "getrandom", "gimli", + "gsgdt", "hashbrown", "hermit-abi", "humantime", From 5b049e107bec04210b1ff0d48e3c66e25de1a598 Mon Sep 17 00:00:00 2001 From: Vishnunarayan K I Date: Mon, 26 Oct 2020 23:03:23 +0530 Subject: [PATCH 2/6] write to a String instead to reduce churn --- compiler/rustc_mir/src/util/graphviz.rs | 35 +++++++++++++++---------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_mir/src/util/graphviz.rs b/compiler/rustc_mir/src/util/graphviz.rs index c83a56c22aebf..8060eaab874a6 100644 --- a/compiler/rustc_mir/src/util/graphviz.rs +++ b/compiler/rustc_mir/src/util/graphviz.rs @@ -57,7 +57,9 @@ where } // Graph label - let label = get_graph_label(tcx, body); + let mut label = String::from(""); + // FIXME: remove this unwrap + write_graph_label(tcx, body, &mut label).unwrap(); let g = mir_fn_to_generic_graph(tcx, body, subgraph); let settings = GraphvizSettings { graph_attrs: Some(graph_attrs.join(" ")), @@ -71,42 +73,47 @@ where /// Write the graphviz DOT label for the overall graph. This is essentially a block of text that /// will appear below the graph, showing the type of the `fn` this MIR represents and the types of /// all the variables and temporaries. -fn get_graph_label<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> String { +fn write_graph_label<'tcx, W: std::fmt::Write>( + tcx: TyCtxt<'tcx>, + body: &Body<'_>, + w: &mut W, +) -> std::fmt::Result { let def_id = body.source.def_id(); - let mut label: Vec = Vec::new(); - label.push(format!("fn {}(", dot::escape_html(&tcx.def_path_str(def_id)))); + write!(w, "fn {}(", dot::escape_html(&tcx.def_path_str(def_id)))?; // fn argument types. for (i, arg) in body.args_iter().enumerate() { if i > 0 { - label.push(", ".to_owned()); + write!(w, ", ")?; } - label.push(format!("{:?}: {}", Place::from(arg), escape(&body.local_decls[arg].ty))); + write!(w, "{:?}: {}", Place::from(arg), escape(&body.local_decls[arg].ty))?; } - label.push(format!(") -> {}", escape(&body.return_ty()))); - label.push(r#"
"#.to_owned()); + write!(w, ") -> {}", escape(&body.return_ty()))?; + write!(w, r#"
"#)?; for local in body.vars_and_temps_iter() { let decl = &body.local_decls[local]; - label.push("let ".to_owned()); + write!(w, "let ")?; if decl.mutability == Mutability::Mut { - label.push("mut ".to_owned()); + write!(w, "mut ")?; } - label.push(format!(r#"{:?}: {};
"#, Place::from(local), escape(&decl.ty))); + write!(w, r#"{:?}: {};
"#, Place::from(local), escape(&decl.ty))?; } for var_debug_info in &body.var_debug_info { - label.push(format!( + write!( + w, r#"debug {} => {};
"#, var_debug_info.name, escape(&var_debug_info.place) - )); + )?; } - label.join("") + + Ok(()) } fn escape(t: &T) -> String { From a4e94ec9b81c4d4c4c30103952804538e2a96acc Mon Sep 17 00:00:00 2001 From: Vishnunarayan K I Date: Tue, 27 Oct 2020 20:14:38 +0530 Subject: [PATCH 3/6] update gsgdt --- Cargo.lock | 4 ++-- compiler/rustc_mir/Cargo.toml | 2 +- compiler/rustc_mir/src/util/generic_graph.rs | 7 +++---- compiler/rustc_mir/src/util/graphviz.rs | 4 ++-- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fb52f4201c06f..e4b566e6690bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1342,9 +1342,9 @@ dependencies = [ [[package]] name = "gsgdt" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cb4a3313cdc3c65906272ddd8987c7291ff6df4b5c9997c1232b6acd1ceab24" +checksum = "a0d876ce7262df96262a2a19531da6ff9a86048224d49580a585fc5c04617825" dependencies = [ "serde", ] diff --git a/compiler/rustc_mir/Cargo.toml b/compiler/rustc_mir/Cargo.toml index 28ba089d0622a..b2af26575f1e6 100644 --- a/compiler/rustc_mir/Cargo.toml +++ b/compiler/rustc_mir/Cargo.toml @@ -10,7 +10,7 @@ doctest = false [dependencies] either = "1.5.0" rustc_graphviz = { path = "../rustc_graphviz" } -gsgdt = "0.1.1" +gsgdt = "0.1.2" itertools = "0.9" tracing = "0.1" polonius-engine = "0.12.0" diff --git a/compiler/rustc_mir/src/util/generic_graph.rs b/compiler/rustc_mir/src/util/generic_graph.rs index df9f94016c8ee..acaca435aa1d9 100644 --- a/compiler/rustc_mir/src/util/generic_graph.rs +++ b/compiler/rustc_mir/src/util/generic_graph.rs @@ -1,13 +1,12 @@ -use gsgdt::{Edge, Graph, GraphKind, Node, NodeStyle}; +use gsgdt::{Edge, Graph, Node, NodeStyle}; use rustc_hir::def_id::DefId; use rustc_index::vec::Idx; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; /// Convert an MIR function into a gsgdt Graph -pub fn mir_fn_to_generic_graph<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>, subgraph: bool) -> Graph { +pub fn mir_fn_to_generic_graph<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Graph { let def_id = body.source.def_id(); - let kind = if subgraph { GraphKind::Subgraph } else { GraphKind::Digraph }; let def_name = graphviz_safe_def_name(def_id); let graph_name = format!("Mir_{}", def_name); let dark_mode = tcx.sess.opts.debugging_opts.graphviz_dark_mode; @@ -33,7 +32,7 @@ pub fn mir_fn_to_generic_graph<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>, subgrap } } - Graph::new(graph_name, kind, nodes, edges) + Graph::new(graph_name, nodes, edges) } fn bb_to_graph_node(block: BasicBlock, body: &Body<'_>, dark_mode: bool) -> Node { diff --git a/compiler/rustc_mir/src/util/graphviz.rs b/compiler/rustc_mir/src/util/graphviz.rs index 8060eaab874a6..d81759267b259 100644 --- a/compiler/rustc_mir/src/util/graphviz.rs +++ b/compiler/rustc_mir/src/util/graphviz.rs @@ -60,14 +60,14 @@ where let mut label = String::from(""); // FIXME: remove this unwrap write_graph_label(tcx, body, &mut label).unwrap(); - let g = mir_fn_to_generic_graph(tcx, body, subgraph); + let g = mir_fn_to_generic_graph(tcx, body); let settings = GraphvizSettings { graph_attrs: Some(graph_attrs.join(" ")), node_attrs: Some(content_attrs.join(" ")), edge_attrs: Some(content_attrs.join(" ")), graph_label: Some(label), }; - g.to_dot(w, &settings) + g.to_dot(w, &settings, subgraph) } /// Write the graphviz DOT label for the overall graph. This is essentially a block of text that From 86a7831f0b522e624574b440bc09b40a713dacbb Mon Sep 17 00:00:00 2001 From: Vishnunarayan K I Date: Mon, 9 Nov 2020 23:32:08 +0530 Subject: [PATCH 4/6] formatting --- Cargo.lock | 2 +- compiler/rustc_mir/src/util/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e4b566e6690bf..4c4931676aadd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5262,7 +5262,7 @@ dependencies = [ "chrono", "lazy_static", "matchers", - "parking_lot 0.11.0", + "parking_lot 0.9.0", "regex", "serde", "serde_json", diff --git a/compiler/rustc_mir/src/util/mod.rs b/compiler/rustc_mir/src/util/mod.rs index 58e0f908108e4..b7b702431bc2a 100644 --- a/compiler/rustc_mir/src/util/mod.rs +++ b/compiler/rustc_mir/src/util/mod.rs @@ -7,8 +7,8 @@ pub mod storage; mod alignment; pub mod collect_writes; mod find_self_call; -pub(crate) mod generic_graphviz; mod generic_graph; +pub(crate) mod generic_graphviz; mod graphviz; pub(crate) mod pretty; pub(crate) mod spanview; From 51ecb96252bbce159e70617da611017afb30eba8 Mon Sep 17 00:00:00 2001 From: Vishnunarayan K I Date: Thu, 12 Nov 2020 13:17:43 +0530 Subject: [PATCH 5/6] add different color for cleanup nodes in dark mode --- compiler/rustc_mir/src/util/generic_graph.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_mir/src/util/generic_graph.rs b/compiler/rustc_mir/src/util/generic_graph.rs index acaca435aa1d9..6ce305a482114 100644 --- a/compiler/rustc_mir/src/util/generic_graph.rs +++ b/compiler/rustc_mir/src/util/generic_graph.rs @@ -41,7 +41,8 @@ fn bb_to_graph_node(block: BasicBlock, body: &Body<'_>, dark_mode: bool) -> Node let label = node(def_id, block); let (title, bgcolor) = if data.is_cleanup { - (format!("{} (cleanup)", block.index()), "lightblue") + let color = if dark_mode { "royalblue" } else { "lightblue" }; + (format!("{} (cleanup)", block.index()), color) } else { let color = if dark_mode { "dimgray" } else { "gray" }; (format!("{}", block.index()), color) From 6fe31e76fb7c3a1d6346977e8edfd06c8f2c405e Mon Sep 17 00:00:00 2001 From: Vishnunarayan K I Date: Sat, 5 Dec 2020 20:21:21 +0530 Subject: [PATCH 6/6] fix clippy test --- .../clippy/tests/ui/crashes/used_underscore_binding_macro.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/tools/clippy/tests/ui/crashes/used_underscore_binding_macro.rs b/src/tools/clippy/tests/ui/crashes/used_underscore_binding_macro.rs index 6d2124c12fe98..c57a45dc7aab9 100644 --- a/src/tools/clippy/tests/ui/crashes/used_underscore_binding_macro.rs +++ b/src/tools/clippy/tests/ui/crashes/used_underscore_binding_macro.rs @@ -1,7 +1,6 @@ -#![allow(clippy::useless_attribute)] //issue #2910 +// edition:2018 -#[macro_use] -extern crate serde_derive; +use serde::Deserialize; /// Tests that we do not lint for unused underscores in a `MacroAttribute` /// expansion