diff options
| author | bors <bors@rust-lang.org> | 2017-10-15 14:00:39 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-10-15 14:00:39 +0000 |
| commit | 2689fd2402590961dae32f35369a8685c89022fb (patch) | |
| tree | dbcee88cdfaed1aab6b3266af17f5cdf8f0db5bb /src | |
| parent | df095cefe28f9fc781e8da02f655903600343506 (diff) | |
| parent | d0cb4d09cd4eb7626130cc9e59ef69dbfec04d0e (diff) | |
| download | rust-2689fd2402590961dae32f35369a8685c89022fb.tar.gz rust-2689fd2402590961dae32f35369a8685c89022fb.zip | |
Auto merge of #45228 - theotherjimmy:ensure-query, r=michaelwoerister
incr.comp.: Introduce `ensure` and `ensure` typeck_tables_of
Resolves #45210
In this Pull Request we introduce the `ensure` query/function. `ensure` has the
semantics and type of the function `Q1` below:
```rust
fn Q1::ensure(K){
Q(K);
}
```
Further, `ensure` avoids the need to load the result from disk (or execute the
provider, if we are not storing the results of Q to disk).
@nikomatsakis
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/ty/maps/plumbing.rs | 46 | ||||
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 2 |
2 files changed, 47 insertions, 1 deletions
diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index 3f215303ccb..d6eaf6d1bc4 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -344,6 +344,52 @@ macro_rules! define_maps { } } + /// Ensure that either this query has all green inputs or been executed. + /// Executing query::ensure(D) is considered a read of the dep-node D. + /// + /// This function is particularly useful when executing passes for their + /// side-effects -- e.g., in order to report errors for erroneous programs. + /// + /// Note: The optimization is only available during incr. comp. + pub fn ensure(tcx: TyCtxt<'a, $tcx, 'lcx>, key: $K) -> () { + let dep_node = Self::to_dep_node(tcx, &key); + + // Ensuring an "input" or anonymous query makes no sense + assert!(!dep_node.kind.is_anon()); + assert!(!dep_node.kind.is_input()); + use dep_graph::DepNodeColor; + match tcx.dep_graph.node_color(&dep_node) { + Some(DepNodeColor::Green(dep_node_index)) => { + tcx.dep_graph.read_index(dep_node_index); + } + Some(DepNodeColor::Red) => { + // A DepNodeColor::Red DepNode means that this query was executed + // before. We can not call `dep_graph.read()` here as we don't have + // the DepNodeIndex. Instead, We call the query again to issue the + // appropriate `dep_graph.read()` call. The performance cost this + // introduces should be negligible as we'll immediately hit the + // in-memory cache. + let _ = tcx.$name(key); + } + None => { + // Huh + if !tcx.dep_graph.is_fully_enabled() { + let _ = tcx.$name(key); + return; + } + match tcx.dep_graph.try_mark_green(tcx, &dep_node) { + Some(dep_node_index) => { + debug_assert!(tcx.dep_graph.is_green(dep_node_index)); + tcx.dep_graph.read_index(dep_node_index); + } + None => { + let _ = tcx.$name(key); + } + } + } + } + } + fn compute_result(tcx: TyCtxt<'a, $tcx, 'lcx>, key: $K) -> $V { let provider = tcx.maps.providers[key.map_crate()].$name; provider(tcx.global_tcx(), key) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 3506fc07112..6e263bdb1ad 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -728,7 +728,7 @@ fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum debug_assert!(crate_num == LOCAL_CRATE); Ok(tcx.sess.track_errors(|| { for body_owner_def_id in tcx.body_owners() { - tcx.typeck_tables_of(body_owner_def_id); + ty::maps::queries::typeck_tables_of::ensure(tcx, body_owner_def_id); } })?) } |
