diff options
| author | Camille GILLOT <gillot.camille@gmail.com> | 2022-11-26 13:54:45 +0000 |
|---|---|---|
| committer | Camille GILLOT <gillot.camille@gmail.com> | 2022-11-29 18:43:00 +0000 |
| commit | 731c002b2754bb028fcd28019a441cd962313f82 (patch) | |
| tree | 56b587c9d24cbaefe6b01be21882559ccddf46cd | |
| parent | 9f2c6b0b09c1f93f922f6fcd46649c3e2110f42b (diff) | |
| download | rust-731c002b2754bb028fcd28019a441cd962313f82.tar.gz rust-731c002b2754bb028fcd28019a441cd962313f82.zip | |
Only allow feeding a value to newly created definitions.
| -rw-r--r-- | compiler/rustc_ast_lowering/src/lib.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/definitions.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/lib.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/query/mod.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/context.rs | 47 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/query.rs | 20 |
6 files changed, 47 insertions, 33 deletions
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index ad6e72d0156..266d653b46d 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -497,7 +497,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.tcx.hir().def_key(self.local_def_id(node_id)), ); - let def_id = self.tcx.create_def(parent, data); + let def_id = self.tcx.create_def(parent, data).def_id; debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id); self.resolver.node_id_to_def_id.insert(node_id, def_id); diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index d85ac960f9b..dd37efb6983 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -368,10 +368,6 @@ impl Definitions { LocalDefId { local_def_index: self.table.allocate(key, def_path_hash) } } - pub fn iter_local_def_id(&self) -> impl Iterator<Item = LocalDefId> + '_ { - self.table.def_path_hashes.indices().map(|local_def_index| LocalDefId { local_def_index }) - } - #[inline(always)] pub fn local_def_path_hash_to_def_id( &self, @@ -389,6 +385,10 @@ impl Definitions { pub fn def_path_hash_to_def_index_map(&self) -> &DefPathHashMap { &self.table.def_path_hash_to_index } + + pub fn num_definitions(&self) -> usize { + self.table.def_path_hashes.len() + } } #[derive(Copy, Clone, PartialEq, Debug)] diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 6bdf591fdd7..7e4063c2ffd 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -30,8 +30,10 @@ #![feature(core_intrinsics)] #![feature(discriminant_kind)] #![feature(exhaustive_patterns)] +#![feature(generators)] #![feature(get_mut_unchecked)] #![feature(if_let_guard)] +#![feature(iter_from_generator)] #![feature(negative_impls)] #![feature(never_type)] #![feature(extern_types)] diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index f94fc34ec47..38b72ec9231 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -165,7 +165,6 @@ rustc_queries! { } cache_on_disk_if { key.is_local() } separate_provide_extern - feedable } query collect_trait_impl_trait_tys(key: DefId) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 3590aae51c3..60e600f22a2 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -53,6 +53,7 @@ use rustc_hir::{ use rustc_index::vec::{Idx, IndexVec}; use rustc_macros::HashStable; use rustc_middle::mir::FakeReadCause; +use rustc_query_system::dep_graph::DepNodeIndex; use rustc_query_system::ich::StableHashingContext; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder}; use rustc_session::config::{CrateType, OutputFilenames}; @@ -1009,6 +1010,14 @@ pub struct FreeRegionInfo { pub is_impl_item: bool, } +#[derive(Copy, Clone)] +pub struct TyCtxtFeed<'tcx> { + pub tcx: TyCtxt<'tcx>, + pub def_id: LocalDefId, + /// This struct should only be created by `create_def`. + _priv: (), +} + /// The central data structure of the compiler. It stores references /// to the various **arenas** and also houses the results of the /// various **compiler queries** that have been performed. See the @@ -1471,12 +1480,15 @@ impl<'tcx> TyCtxt<'tcx> { } /// Create a new definition within the incr. comp. engine. - pub fn create_def(self, parent: LocalDefId, data: hir::definitions::DefPathData) -> LocalDefId { + pub fn create_def( + self, + parent: LocalDefId, + data: hir::definitions::DefPathData, + ) -> TyCtxtFeed<'tcx> { // This function modifies `self.definitions` using a side-effect. // We need to ensure that these side effects are re-run by the incr. comp. engine. // Depending on the forever-red node will tell the graph that the calling query // needs to be re-evaluated. - use rustc_query_system::dep_graph::DepNodeIndex; self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE); // The following call has the side effect of modifying the tables inside `definitions`. @@ -1493,23 +1505,38 @@ impl<'tcx> TyCtxt<'tcx> { // This is fine because: // - those queries are `eval_always` so we won't miss their result changing; // - this write will have happened before these queries are called. - self.definitions.write().create_def(parent, data) + let def_id = self.definitions.write().create_def(parent, data); + + TyCtxtFeed { tcx: self, def_id, _priv: () } } pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> + 'tcx { - // Create a dependency to the crate to be sure we re-execute this when the amount of + // Create a dependency to the red node to be sure we re-execute this when the amount of // definitions change. - self.ensure().hir_crate(()); - // Leak a read lock once we start iterating on definitions, to prevent adding new ones - // while iterating. If some query needs to add definitions, it should be `ensure`d above. - let definitions = self.definitions.leak(); - definitions.iter_local_def_id() + self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE); + + let definitions = &self.definitions; + std::iter::from_generator(|| { + let mut i = 0; + + // Recompute the number of definitions each time, because our caller may be creating + // new ones. + while i < { definitions.read().num_definitions() } { + let local_def_index = rustc_span::def_id::DefIndex::from_usize(i); + yield LocalDefId { local_def_index }; + i += 1; + } + + // Leak a read lock once we finish iterating on definitions, to prevent adding new ones. + definitions.leak(); + }) } pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable { // Create a dependency to the crate to be sure we re-execute this when the amount of // definitions change. - self.ensure().hir_crate(()); + self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE); + // Leak a read lock once we start iterating on definitions, to prevent adding new ones // while iterating. If some query needs to add definitions, it should be `ensure`d above. let definitions = self.definitions.leak(); diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index f44039879a6..ba85d5c8498 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/ty/query.rs @@ -28,6 +28,7 @@ use crate::traits::query::{ }; use crate::traits::specialization_graph; use crate::traits::{self, ImplSource}; +use crate::ty::context::TyCtxtFeed; use crate::ty::fast_reject::SimplifiedType; use crate::ty::layout::TyAndLayout; use crate::ty::subst::{GenericArg, SubstsRef}; @@ -85,11 +86,6 @@ pub struct TyCtxtEnsure<'tcx> { pub tcx: TyCtxt<'tcx>, } -#[derive(Copy, Clone)] -pub struct TyCtxtFeed<'tcx> { - pub tcx: TyCtxt<'tcx>, -} - impl<'tcx> TyCtxt<'tcx> { /// Returns a transparent wrapper for `TyCtxt`, which ensures queries /// are executed instead of just returning their results. @@ -98,12 +94,6 @@ impl<'tcx> TyCtxt<'tcx> { TyCtxtEnsure { tcx: self } } - /// Returns a transparent wrapper for `TyCtxt`, for setting a result into a query. - #[inline(always)] - pub fn feed(self) -> TyCtxtFeed<'tcx> { - TyCtxtFeed { tcx: self } - } - /// Returns a transparent wrapper for `TyCtxt` which uses /// `span` as the location of queries performed through it. #[inline(always)] @@ -355,12 +345,8 @@ macro_rules! define_feedable { impl<'tcx> TyCtxtFeed<'tcx> { $($(#[$attr])* #[inline(always)] - pub fn $name( - self, - key: query_helper_param_ty!($($K)*), - value: $V, - ) -> query_stored::$name<'tcx> { - let key = key.into_query_param(); + pub fn $name(self, value: $V) -> query_stored::$name<'tcx> { + let key = self.def_id.into_query_param(); opt_remap_env_constness!([$($modifiers)*][key]); let tcx = self.tcx; |
