]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_incremental/assert_dep_graph.rs
Auto merge of #67733 - pietroalbini:gha-2, r=alexcrichton
[rust.git] / src / librustc_incremental / assert_dep_graph.rs
index e3e3b0b17483ece87a87443462949e2dc2cb3679..64547845e74f1478a9235c6231fc1efddad5f30d 100644 (file)
 //! ```
 
 use graphviz as dot;
-use rustc::dep_graph::{DepGraphQuery, DepNode, DepKind};
 use rustc::dep_graph::debug::{DepNodeFilter, EdgeFilter};
-use rustc::hir::def_id::DefId;
+use rustc::dep_graph::{DepGraphQuery, DepKind, DepNode};
+use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc::ty::TyCtxt;
 use rustc_data_structures::fx::FxHashSet;
-use rustc_data_structures::graph::implementation::{
-    Direction, INCOMING, OUTGOING, NodeIndex
-};
-use rustc::hir;
-use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
+use rustc_data_structures::graph::implementation::{Direction, NodeIndex, INCOMING, OUTGOING};
+use rustc_hir as hir;
+use rustc_hir::def_id::DefId;
+use rustc_span::symbol::sym;
+use rustc_span::Span;
+use syntax::ast;
+
 use std::env;
 use std::fs::{self, File};
 use std::io::Write;
-use syntax::{ast, symbol::sym};
-use syntax_pos::Span;
 
 pub fn assert_dep_graph(tcx: TyCtxt<'_>) {
     tcx.dep_graph.with_ignore(|| {
@@ -65,19 +65,21 @@ pub fn assert_dep_graph(tcx: TyCtxt<'_>) {
 
         // Find annotations supplied by user (if any).
         let (if_this_changed, then_this_would_need) = {
-            let mut visitor = IfThisChanged { tcx,
-                                            if_this_changed: vec![],
-                                            then_this_would_need: vec![] };
+            let mut visitor =
+                IfThisChanged { tcx, if_this_changed: vec![], then_this_would_need: vec![] };
             visitor.process_attrs(hir::CRATE_HIR_ID, &tcx.hir().krate().attrs);
             tcx.hir().krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
             (visitor.if_this_changed, visitor.then_this_would_need)
         };
 
         if !if_this_changed.is_empty() || !then_this_would_need.is_empty() {
-            assert!(tcx.sess.opts.debugging_opts.query_dep_graph,
-                    "cannot use the `#[{}]` or `#[{}]` annotations \
+            assert!(
+                tcx.sess.opts.debugging_opts.query_dep_graph,
+                "cannot use the `#[{}]` or `#[{}]` annotations \
                     without supplying `-Z query-dep-graph`",
-                    sym::rustc_if_this_changed, sym::rustc_then_this_would_need);
+                sym::rustc_if_this_changed,
+                sym::rustc_then_this_would_need
+            );
         }
 
         // Check paths.
@@ -99,11 +101,12 @@ fn argument(&self, attr: &ast::Attribute) -> Option<ast::Name> {
         let mut value = None;
         for list_item in attr.meta_item_list().unwrap_or_default() {
             match list_item.ident() {
-                Some(ident) if list_item.is_word() && value.is_none() =>
-                    value = Some(ident.name),
+                Some(ident) if list_item.is_word() && value.is_none() => value = Some(ident.name),
                 _ =>
-                    // FIXME better-encapsulate meta_item (don't directly access `node`)
-                    span_bug!(list_item.span(), "unexpected meta-item {:?}", list_item),
+                // FIXME better-encapsulate meta_item (don't directly access `node`)
+                {
+                    span_bug!(list_item.span(), "unexpected meta-item {:?}", list_item)
+                }
             }
         }
         value
@@ -117,41 +120,39 @@ fn process_attrs(&mut self, hir_id: hir::HirId, attrs: &[ast::Attribute]) {
                 let dep_node_interned = self.argument(attr);
                 let dep_node = match dep_node_interned {
                     None => def_path_hash.to_dep_node(DepKind::Hir),
-                    Some(n) => {
-                        match DepNode::from_label_string(&n.as_str(), def_path_hash) {
-                            Ok(n) => n,
-                            Err(()) => {
-                                self.tcx.sess.span_fatal(
-                                    attr.span,
-                                    &format!("unrecognized DepNode variant {:?}", n));
-                            }
+                    Some(n) => match DepNode::from_label_string(&n.as_str(), def_path_hash) {
+                        Ok(n) => n,
+                        Err(()) => {
+                            self.tcx.sess.span_fatal(
+                                attr.span,
+                                &format!("unrecognized DepNode variant {:?}", n),
+                            );
                         }
-                    }
+                    },
                 };
                 self.if_this_changed.push((attr.span, def_id, dep_node));
             } else if attr.check_name(sym::rustc_then_this_would_need) {
                 let dep_node_interned = self.argument(attr);
                 let dep_node = match dep_node_interned {
-                    Some(n) => {
-                        match DepNode::from_label_string(&n.as_str(), def_path_hash) {
-                            Ok(n) => n,
-                            Err(()) => {
-                                self.tcx.sess.span_fatal(
-                                    attr.span,
-                                    &format!("unrecognized DepNode variant {:?}", n));
-                            }
+                    Some(n) => match DepNode::from_label_string(&n.as_str(), def_path_hash) {
+                        Ok(n) => n,
+                        Err(()) => {
+                            self.tcx.sess.span_fatal(
+                                attr.span,
+                                &format!("unrecognized DepNode variant {:?}", n),
+                            );
                         }
-                    }
+                    },
                     None => {
-                        self.tcx.sess.span_fatal(
-                            attr.span,
-                            "missing DepNode variant");
+                        self.tcx.sess.span_fatal(attr.span, "missing DepNode variant");
                     }
                 };
-                self.then_this_would_need.push((attr.span,
-                                                dep_node_interned.unwrap(),
-                                                hir_id,
-                                                dep_node));
+                self.then_this_would_need.push((
+                    attr.span,
+                    dep_node_interned.unwrap(),
+                    hir_id,
+                    dep_node,
+                ));
             }
         }
     }
@@ -162,22 +163,22 @@ fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
         NestedVisitorMap::OnlyBodies(&self.tcx.hir())
     }
 
-    fn visit_item(&mut self, item: &'tcx hir::Item) {
+    fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
         self.process_attrs(item.hir_id, &item.attrs);
         intravisit::walk_item(self, item);
     }
 
-    fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
+    fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
         self.process_attrs(trait_item.hir_id, &trait_item.attrs);
         intravisit::walk_trait_item(self, trait_item);
     }
 
-    fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
+    fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
         self.process_attrs(impl_item.hir_id, &impl_item.attrs);
         intravisit::walk_impl_item(self, impl_item);
     }
 
-    fn visit_struct_field(&mut self, s: &'tcx hir::StructField) {
+    fn visit_struct_field(&mut self, s: &'tcx hir::StructField<'tcx>) {
         self.process_attrs(s.hir_id, &s.attrs);
         intravisit::walk_struct_field(self, s);
     }
@@ -187,10 +188,7 @@ fn check_paths<'tcx>(tcx: TyCtxt<'tcx>, if_this_changed: &Sources, then_this_wou
     // Return early here so as not to construct the query, which is not cheap.
     if if_this_changed.is_empty() {
         for &(target_span, _, _, _) in then_this_would_need {
-            tcx.sess.span_err(
-                target_span,
-                "no `#[rustc_if_this_changed]` annotation detected");
-
+            tcx.sess.span_err(target_span, "no `#[rustc_if_this_changed]` annotation detected");
         }
         return;
     }
@@ -201,13 +199,14 @@ fn check_paths<'tcx>(tcx: TyCtxt<'tcx>, if_this_changed: &Sources, then_this_wou
             if !dependents.contains(&target_dep_node) {
                 tcx.sess.span_err(
                     target_span,
-                    &format!("no path from `{}` to `{}`",
-                             tcx.def_path_str(source_def_id),
-                             target_pass));
+                    &format!(
+                        "no path from `{}` to `{}`",
+                        tcx.def_path_str(source_def_id),
+                        target_pass
+                    ),
+                );
             } else {
-                tcx.sess.span_err(
-                    target_span,
-                    "OK");
+                tcx.sess.span_err(target_span, "OK");
             }
         }
     }
@@ -220,22 +219,18 @@ fn dump_graph(tcx: TyCtxt<'_>) {
     let nodes = match env::var("RUST_DEP_GRAPH_FILTER") {
         Ok(string) => {
             // Expect one of: "-> target", "source -> target", or "source ->".
-            let edge_filter = EdgeFilter::new(&string).unwrap_or_else(|e| {
-                bug!("invalid filter: {}", e)
-            });
+            let edge_filter =
+                EdgeFilter::new(&string).unwrap_or_else(|e| bug!("invalid filter: {}", e));
             let sources = node_set(&query, &edge_filter.source);
             let targets = node_set(&query, &edge_filter.target);
             filter_nodes(&query, &sources, &targets)
         }
-        Err(_) => {
-            query.nodes()
-                 .into_iter()
-                 .collect()
-        }
+        Err(_) => query.nodes().into_iter().collect(),
     };
     let edges = filter_edges(&query, &nodes);
 
-    { // dump a .txt file with just the edges:
+    {
+        // dump a .txt file with just the edges:
         let txt_path = format!("{}.txt", path);
         let mut file = File::create(&txt_path).unwrap();
         for &(ref source, ref target) in &edges {
@@ -243,7 +238,8 @@ fn dump_graph(tcx: TyCtxt<'_>) {
         }
     }
 
-    { // dump a .dot file in graphviz format:
+    {
+        // dump a .dot file in graphviz format:
         let dot_path = format!("{}.dot", path);
         let mut v = Vec::new();
         dot::render(&GraphvizDepGraph(nodes, edges), &mut v).unwrap();
@@ -251,8 +247,7 @@ fn dump_graph(tcx: TyCtxt<'_>) {
     }
 }
 
-pub struct GraphvizDepGraph<'q>(FxHashSet<&'q DepNode>,
-                                Vec<(&'q DepNode, &'q DepNode)>);
+pub struct GraphvizDepGraph<'q>(FxHashSet<&'q DepNode>, Vec<(&'q DepNode, &'q DepNode)>);
 
 impl<'a, 'q> dot::GraphWalk<'a> for GraphvizDepGraph<'q> {
     type Node = &'q DepNode;
@@ -279,10 +274,10 @@ fn graph_id(&self) -> dot::Id<'_> {
         dot::Id::new("DependencyGraph").unwrap()
     }
     fn node_id(&self, n: &&'q DepNode) -> dot::Id<'_> {
-        let s: String =
-            format!("{:?}", n).chars()
-                              .map(|c| if c == '_' || c.is_alphanumeric() { c } else { '_' })
-                              .collect();
+        let s: String = format!("{:?}", n)
+            .chars()
+            .map(|c| if c == '_' || c.is_alphanumeric() { c } else { '_' })
+            .collect();
         debug!("n={:?} s={:?}", n, s);
         dot::Id::new(s).unwrap()
     }
@@ -294,9 +289,10 @@ fn node_label(&self, n: &&'q DepNode) -> dot::LabelText<'_> {
 // Given an optional filter like `"x,y,z"`, returns either `None` (no
 // filter) or the set of nodes whose labels contain all of those
 // substrings.
-fn node_set<'q>(query: &'q DepGraphQuery, filter: &DepNodeFilter)
-                -> Option<FxHashSet<&'q DepNode>>
-{
+fn node_set<'q>(
+    query: &'q DepGraphQuery,
+    filter: &DepNodeFilter,
+) -> Option<FxHashSet<&'q DepNode>> {
     debug!("node_set(filter={:?})", filter);
 
     if filter.accepts_all() {
@@ -306,11 +302,11 @@ fn node_set<'q>(query: &'q DepGraphQuery, filter: &DepNodeFilter)
     Some(query.nodes().into_iter().filter(|n| filter.test(n)).collect())
 }
 
-fn filter_nodes<'q>(query: &'q DepGraphQuery,
-                    sources: &Option<FxHashSet<&'q DepNode>>,
-                    targets: &Option<FxHashSet<&'q DepNode>>)
-                    -> FxHashSet<&'q DepNode>
-{
+fn filter_nodes<'q>(
+    query: &'q DepGraphQuery,
+    sources: &Option<FxHashSet<&'q DepNode>>,
+    targets: &Option<FxHashSet<&'q DepNode>>,
+) -> FxHashSet<&'q DepNode> {
     if let &Some(ref sources) = sources {
         if let &Some(ref targets) = targets {
             walk_between(query, sources, targets)
@@ -324,11 +320,11 @@ fn filter_nodes<'q>(query: &'q DepGraphQuery,
     }
 }
 
-fn walk_nodes<'q>(query: &'q DepGraphQuery,
-                  starts: &FxHashSet<&'q DepNode>,
-                  direction: Direction)
-                  -> FxHashSet<&'q DepNode>
-{
+fn walk_nodes<'q>(
+    query: &'q DepGraphQuery,
+    starts: &FxHashSet<&'q DepNode>,
+    direction: Direction,
+) -> FxHashSet<&'q DepNode> {
     let mut set = FxHashSet::default();
     for &start in starts {
         debug!("walk_nodes: start={:?} outgoing?={:?}", start, direction == OUTGOING);
@@ -348,18 +344,23 @@ fn walk_nodes<'q>(query: &'q DepGraphQuery,
     set
 }
 
-fn walk_between<'q>(query: &'q DepGraphQuery,
-                    sources: &FxHashSet<&'q DepNode>,
-                    targets: &FxHashSet<&'q DepNode>)
-                    -> FxHashSet<&'q DepNode>
-{
+fn walk_between<'q>(
+    query: &'q DepGraphQuery,
+    sources: &FxHashSet<&'q DepNode>,
+    targets: &FxHashSet<&'q DepNode>,
+) -> FxHashSet<&'q DepNode> {
     // This is a bit tricky. We want to include a node only if it is:
     // (a) reachable from a source and (b) will reach a target. And we
     // have to be careful about cycles etc.  Luckily efficiency is not
     // a big concern!
 
     #[derive(Copy, Clone, PartialEq)]
-    enum State { Undecided, Deciding, Included, Excluded }
+    enum State {
+        Undecided,
+        Deciding,
+        Included,
+        Excluded,
+    }
 
     let mut node_states = vec![State::Undecided; query.graph.len_nodes()];
 
@@ -371,19 +372,16 @@ enum State { Undecided, Deciding, Included, Excluded }
         recurse(query, &mut node_states, source);
     }
 
-    return query.nodes()
-                .into_iter()
-                .filter(|&n| {
-                    let index = query.indices[n];
-                    node_states[index.0] == State::Included
-                })
-                .collect();
-
-    fn recurse(query: &DepGraphQuery,
-               node_states: &mut [State],
-               node: NodeIndex)
-               -> bool
-    {
+    return query
+        .nodes()
+        .into_iter()
+        .filter(|&n| {
+            let index = query.indices[n];
+            node_states[index.0] == State::Included
+        })
+        .collect();
+
+    fn recurse(query: &DepGraphQuery, node_states: &mut [State], node: NodeIndex) -> bool {
         match node_states[node.0] {
             // known to reach a target
             State::Included => return true,
@@ -394,7 +392,7 @@ fn recurse(query: &DepGraphQuery,
             // backedge, not yet known, say false
             State::Deciding => return false,
 
-            State::Undecided => { }
+            State::Undecided => {}
         }
 
         node_states[node.0] = State::Deciding;
@@ -416,12 +414,13 @@ fn recurse(query: &DepGraphQuery,
     }
 }
 
-fn filter_edges<'q>(query: &'q DepGraphQuery,
-                    nodes: &FxHashSet<&'q DepNode>)
-                    -> Vec<(&'q DepNode, &'q DepNode)>
-{
-    query.edges()
-         .into_iter()
-         .filter(|&(source, target)| nodes.contains(source) && nodes.contains(target))
-         .collect()
+fn filter_edges<'q>(
+    query: &'q DepGraphQuery,
+    nodes: &FxHashSet<&'q DepNode>,
+) -> Vec<(&'q DepNode, &'q DepNode)> {
+    query
+        .edges()
+        .into_iter()
+        .filter(|&(source, target)| nodes.contains(source) && nodes.contains(target))
+        .collect()
 }