+ /// Registers a read in the dependency graph of the AST node with
+ /// the given `id`. This needs to be called each time a public
+ /// function returns the HIR for a node -- in other words, when it
+ /// "reveals" the content of a node to the caller (who might not
+ /// otherwise have had access to those contents, and hence needs a
+ /// read recorded). If the function just returns a DefId or
+ /// NodeId, no actual content was returned, so no read is needed.
+ fn read(&self, id: NodeId) {
+ self.dep_graph.read(self.dep_node(id));
+ }
+
+ fn dep_node(&self, id0: NodeId) -> DepNode {
+ let map = self.map.borrow();
+ let mut id = id0;
+ loop {
+ match map[id as usize] {
+ EntryItem(_, item) => {
+ let def_id = self.local_def_id(item.id);
+ // NB ^~~~~~~
+ //
+ // You would expect that `item.id == id`, but this
+ // is not always the case. In particular, for
+ // ViewPath like `use self::{mem, foo}`, we record
+ // map the ids for `mem` and `foo` to the
+ // enclosing view path item. This seems mega super
+ // ultra wrong, but then who am I to
+ // judge. -nmatsakis
+ return DepNode::Hir(def_id);
+ }
+
+ EntryForeignItem(p, _) |
+ EntryTraitItem(p, _) |
+ EntryImplItem(p, _) |
+ EntryVariant(p, _) |
+ EntryExpr(p, _) |
+ EntryStmt(p, _) |
+ EntryLocal(p, _) |
+ EntryPat(p, _) |
+ EntryBlock(p, _) |
+ EntryStructCtor(p, _) |
+ EntryLifetime(p, _) |
+ EntryTyParam(p, _) =>
+ id = p,
+
+ RootCrate |
+ RootInlinedParent(_) => // FIXME(#2369) clarify story about cross-crate dep tracking
+ return DepNode::Krate,
+
+ NotPresent =>
+ panic!("Walking parents from `{}` led to `NotPresent` at `{}`", id0, id),
+ }
+ }
+ }
+