]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_incremental/persist/preds/mod.rs
Rollup merge of #41141 - michaelwoerister:direct-metadata-ich-final, r=nikomatsakis
[rust.git] / src / librustc_incremental / persist / preds / mod.rs
index a80620fbde66fad189b134e9449e3d8c33283951..e769641a4cadf2094e42e6fc14fc3004667e014d 100644 (file)
 
 use rustc::dep_graph::{DepGraphQuery, DepNode};
 use rustc::hir::def_id::DefId;
+use rustc::ich::Fingerprint;
 use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::graph::Graph;
+use rustc_data_structures::graph::{Graph, NodeIndex};
 
 use super::hash::*;
-use ich::Fingerprint;
 
 mod compress;
 
@@ -28,6 +28,14 @@ pub struct Predecessors<'query> {
     // of the graph down.
     pub reduced_graph: Graph<&'query DepNode<DefId>, ()>,
 
+    // These are output nodes that have no incoming edges. We have to
+    // track these specially because, when we load the data back up
+    // again, we want to make sure and recreate these nodes (we want
+    // to recreate the nodes where all incoming edges are clean; but
+    // since we ordinarily just serialize edges, we wind up just
+    // forgetting that bootstrap outputs even exist in that case.)
+    pub bootstrap_outputs: Vec<&'query DepNode<DefId>>,
+
     // For the inputs (hir/foreign-metadata), we include hashes.
     pub hashes: FxHashMap<&'query DepNode<DefId>, Fingerprint>,
 }
@@ -36,16 +44,18 @@ impl<'q> Predecessors<'q> {
     pub fn new(query: &'q DepGraphQuery<DefId>, hcx: &mut HashContext) -> Self {
         let tcx = hcx.tcx;
 
-        let collect_for_metadata = tcx.sess.opts.debugging_opts.incremental_cc ||
-            tcx.sess.opts.debugging_opts.query_dep_graph;
-
         // Find the set of "start nodes". These are nodes that we will
         // possibly query later.
         let is_output = |node: &DepNode<DefId>| -> bool {
             match *node {
                 DepNode::WorkProduct(_) => true,
-                DepNode::MetaData(ref def_id) => collect_for_metadata && def_id.is_local(),
-
+                DepNode::MetaData(ref def_id) => {
+                    // We do *not* create dep-nodes for the current crate's
+                    // metadata anymore, just for metadata that we import/read
+                    // from other crates.
+                    debug_assert!(!def_id.is_local());
+                    false
+                }
                 // if -Z query-dep-graph is passed, save more extended data
                 // to enable better unit testing
                 DepNode::TypeckTables(_) |
@@ -57,7 +67,7 @@ pub fn new(query: &'q DepGraphQuery<DefId>, hcx: &mut HashContext) -> Self {
 
         // Reduce the graph to the most important nodes.
         let compress::Reduction { graph, input_nodes } =
-            compress::reduce_graph(&query.graph, HashContext::is_hashable, is_output);
+            compress::reduce_graph(&query.graph, HashContext::is_hashable, |n| is_output(n));
 
         let mut hashes = FxHashMap();
         for input_index in input_nodes {
@@ -67,8 +77,33 @@ pub fn new(query: &'q DepGraphQuery<DefId>, hcx: &mut HashContext) -> Self {
                   .or_insert_with(|| hcx.hash(input).unwrap());
         }
 
+        if tcx.sess.opts.debugging_opts.query_dep_graph {
+            // Not all inputs might have been reachable from an output node,
+            // but we still want their hash for our unit tests.
+            let hir_nodes = query.graph.all_nodes().iter().filter_map(|node| {
+                match node.data {
+                    DepNode::Hir(_) => Some(&node.data),
+                    _ => None,
+                }
+            });
+
+            for node in hir_nodes {
+                hashes.entry(node)
+                      .or_insert_with(|| hcx.hash(node).unwrap());
+            }
+        }
+
+        let bootstrap_outputs: Vec<&'q DepNode<DefId>> =
+            (0 .. graph.len_nodes())
+            .map(NodeIndex)
+            .filter(|&n| graph.incoming_edges(n).next().is_none())
+            .map(|n| *graph.node_data(n))
+            .filter(|n| is_output(n))
+            .collect();
+
         Predecessors {
             reduced_graph: graph,
+            bootstrap_outputs: bootstrap_outputs,
             hashes: hashes,
         }
     }