Skip to content

Instantly share code, notes, and snippets.

@nikomatsakis
Created March 22, 2017 21:39
Show Gist options
  • Save nikomatsakis/181cf637ca36af9e28819a33462d8d96 to your computer and use it in GitHub Desktop.
Save nikomatsakis/181cf637ca36af9e28819a33462d8d96 to your computer and use it in GitHub Desktop.

Wants anonymous nodes

  • src/librustc/traits/select.rs:413: let _task = tcx.dep_graph.in_task(dep_node);
    • Trait selection. This really wants to use the "anonymous nodes"

New queries

  • src/librustc_privacy/lib.rs:1187: let _task = tcx.dep_graph.in_task(DepNode::Privacy);
    • this wants to become an AccessLevels query
  • src/librustc/middle/reachable.rs:365: let _task = tcx.dep_graph.in_task(DepNode::Reachability);
    • query would be ReachableSet, yielding type NodeSet
    • it can then request access_levels (see previous)
  • src/librustc_borrowck/borrowck/mod.rs:68: tcx.dep_graph.with_task(DepNode::BorrowCheck(body_owner_def_id)
    • writes to used_mut_nodes, so probably wants to return this set
    • the lint would be modified to request the borrowck query for the current function
  • src/librustc/middle/region.rs:1260: let _task = map.dep_graph.in_task(DepNode::RegionResolveCrate);
    • returns a RegionMaps

The following tasks currently execute before a tcx is built, but they could be easily converted into queries that are requested after tcx is built. The main reason they are the way they are was to avoid a gratuitious refcell (but using the refcell map seems fine):

  • src/librustc/middle/entry.rs:60: let _task = hir_map.dep_graph.in_task(DepNode::EntryPoint);
  • src/librustc/middle/resolve_lifetime.rs:262: let _task = hir_map.dep_graph.in_task(DepNode::ResolveLifetimes);
  • src/librustc/middle/lang_items.rs:239: let _task = map.dep_graph.in_task(DepNode::CollectLanguageItems);

Lints

Lints are bit complex, because currently lints are pushed into a shared, mutable data structure via add_lint. We have to remove every call to that. @eddyb has proposed restructuring lints, which I think is probably a good idea. The idea would be to do a single sweep that creates a map which tells us, for any point in the crate, what the "allow/warn/deny" level is for each lint. When we wish to issue a lint of kind L at id X, then, we would invoke a routine which:

  • queries the map;
  • determines the level of the lint;
  • issues the appropriate diagnostic as a result.

This has several advantages. Among other things, it removes the need to treat lints distinct from other diagnostics, but also it means we will issue lints at the same time as other related checks.

  • src/librustc/lint/context.rs:1236: let _task = tcx.dep_graph.in_task(DepNode::LateLintCheck);

Stability

  • The stability index is somewhat complex:
    • src/librustc/middle/stability.rs:386: let _task = tcx.dep_graph.in_task(DepNode::StabilityIndex);
    • src/librustc/middle/stability.rs:400: let _task = hir_map.dep_graph.in_task(DepNode::StabilityIndex);
    • src/librustc/middle/stability.rs:664: let _task = tcx.dep_graph.in_task(DepNode::StabilityIndex);
  • From what I can tell, what we do is to construct a Stability::Index for the current crate early on, store this in the tcx in a RefCell, and then gradually grow it to cache the results from other crates
  • Two possible translations:
    • each crate has a stability index, and you can query for stability_index(krate)
    • have very granular queries like stability(def_id), deprecation(def_id), and deprecation_entry(def_id)
      • for the local crate, these would request the stability-index, extract the relevant data
        • good example for uncached queries
      • for the extern crate, we'd go to metadata and cache it in the DepTrackingMap or something?

Just plain remove

I think these tasks are not needed anymore:

  • src/librustc_typeck/collect.rs:171: self.tcx.dep_graph.with_task(DepNode::CollectItemSig(def_id), self.tcx, id, op);
    • since type collection is now fully on-demand, the "isolation" of dependencies that we wanted will happen quite naturally

"Always execute" passes; probably want anonymous nodes

These are all handled in the same way. Much like rust-lang/rust#40540, we will add a task with () result.

"Blocking" issue: How should we handle the reads that result? Do we want a root "compile" task?

  • src/librustc_passes/loops.rs:53: let _task = map.dep_graph.in_task(DepNode::CheckLoops);
  • src/librustc_passes/static_recursion.rs:91: let _task = hir_map.dep_graph.in_task(DepNode::CheckStaticRecursion);
  • src/librustc_borrowck/borrowck/mod.rs:64: tcx.dep_graph.with_task(DepNode::BorrowCheckKrate, tcx, (), check_crate_task);
  • src/librustc/middle/effect.rs:244: let _task = tcx.dep_graph.in_task(DepNode::EffectCheck);
  • src/librustc/middle/liveness.rs:199: let _task = tcx.dep_graph.in_task(DepNode::Liveness);
  • src/librustc_typeck/check_unused.rs:65: let _task = tcx.dep_graph.in_task(DepNode::UnusedTraitCheck);
  • src/librustc/middle/dead.rs:597: let _task = tcx.dep_graph.in_task(DepNode::DeadCheck);
    • this would use the AccessLevels query described elsewhere
  • src/librustc_typeck/coherence/mod.rs:135: let _task = tcx.dep_graph.in_task(DepNode::Coherence);
  • src/librustc_typeck/coherence/overlap.rs:42: tcx.dep_graph.in_task(DepNode::CoherenceOverlapCheck(trait_def_id));

Internal graph manipulation

  • src/librustc_incremental/persist/load.rs:439: let _task = tcx.dep_graph.in_task(target_node);
  • src/librustc_incremental/persist/load.rs:195: tcx.dep_graph.with_task(n, (), (), create_node);
  • src/librustc/dep_graph/dep_tracking_map.rs:134: let _task = graph.in_task(M::to_dep_node(&key));
  • src/librustc/dep_graph/graph.rs:110: let _task = self.in_task(key);
  • src/librustc/ty/maps.rs:271: let _task = tcx.dep_graph.in_task(Self::to_dep_node(&key));

Visitor stuff

  • src/librustc/dep_graph/visit.rs:41: let _task = self.tcx.dep_graph.in_task(task_id.clone());
  • src/librustc/dep_graph/visit.rs:51: let _task = self.tcx.dep_graph.in_task(task_id.clone());
  • src/librustc/dep_graph/visit.rs:61: let _task = self.tcx.dep_graph.in_task(task_id.clone());

Docs that will need to be rewritten or deleted

  • src/librustc/dep_graph/README.md:67:You set the current task by calling dep_graph.in_task(node). For example:
  • src/librustc/dep_graph/README.md:70:let _task = tcx.dep_graph.in_task(DepNode::Privacy);
  • src/librustc/dep_graph/README.md:83:let _n1 = tcx.dep_graph.in_task(DepNode::N1);
  • src/librustc/dep_graph/README.md:84:let _n2 = tcx.dep_graph.in_task(DepNode::N2);
  • src/librustc/dep_graph/README.md:102:let _n1 = tcx.dep_graph.in_task(DepNode::N1);
  • src/librustc/dep_graph/README.md:104:let _n2 = tcx.dep_graph.in_task(DepNode::N2);
  • src/librustc/dep_graph/README.md:167: let task = tcx.dep_graph.in_task(DepNode::ItemSignature(def_id));

Uncategorized

  • src/librustc_typeck/check/mod.rs:543: tcx.dep_graph.with_task(DepNode::TypeckBodiesKrate, tcx, (), check_item_bodies_task);
  • src/librustc_mir/mir_map.rs:43: tcx.dep_graph.with_task(DepNode::MirKrate, tcx, (), build_mir_for_crate_task);
  • src/librustc_trans/base.rs:1125: tcx.dep_graph.with_task(dep_node,
  • src/librustc_trans/base.rs:1146: tcx.dep_graph.with_task(dep_node,
  • src/librustc/ty/mod.rs:1655: let _task = tcx.dep_graph.in_task(DepNode::SizedConstraint(self.did));
  • src/librustc_typeck/lib.rs:277: let _task = tcx.dep_graph.in_task(DepNode::CheckEntryFn);
  • src/librustc/mir/transform.rs:123: let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
  • src/librustc_mir/transform/qualify_consts.rs:969: let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
  • src/librustc_mir/transform/inline.rs:65: let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
  • src/librustc_mir/transform/inline.rs:89: let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
  • src/librustc_mir/transform/inline.rs:187: let _task = self.tcx.dep_graph.in_task(DepNode::Mir(callsite.caller));
  • src/librustc_mir/transform/inline.rs:256: let _task = self.tcx.dep_graph.in_task(DepNode::Mir(def_id));
  • src/librustc_mir/transform/inline.rs:433: let _task = self.tcx.dep_graph.in_task(DepNode::Mir(callsite.caller));
  • src/librustc_driver/derive_registrar.rs:19: let _task = hir_map.dep_graph.in_task(DepNode::PluginRegistrar);
  • src/librustc_plugin/build.rs:47: let _task = hir_map.dep_graph.in_task(DepNode::PluginRegistrar);
  • src/librustc_trans/trans_item.rs:77: let _task = ccx.tcx().dep_graph.in_task(DepNode::TransCrateItem(def_id)); // (*)
  • src/librustc_trans/trans_item.rs:93: let _task = ccx.tcx().dep_graph.in_task(
  • src/librustc_trans/base.rs:1034: let _task = tcx.dep_graph.in_task(DepNode::TransCrate);
  • src/librustc_trans/back/link.rs:199: let _task = sess.dep_graph.in_task(DepNode::LinkBinary);
  • src/librustc_metadata/index_builder.rs:121: let _task = self.tcx.dep_graph.in_task(DepNode::MetaData(id));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment