diff options
Diffstat (limited to 'compiler/rustc_middle/src')
| -rw-r--r-- | compiler/rustc_middle/src/hir/map/mod.rs | 15 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/hir/mod.rs | 32 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/query/mod.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/query/plumbing.rs | 58 |
4 files changed, 97 insertions, 18 deletions
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 3ca26ec98c6..58c0c6bab49 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -6,7 +6,7 @@ use rustc_ast as ast; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::svh::Svh; -use rustc_data_structures::sync::{par_for_each_in, DynSend, DynSync}; +use rustc_data_structures::sync::{par_for_each_in, try_par_for_each_in, DynSend, DynSync}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash}; @@ -16,7 +16,7 @@ use rustc_index::Idx; use rustc_middle::hir::nested_filter; use rustc_span::def_id::StableCrateId; use rustc_span::symbol::{kw, sym, Ident, Symbol}; -use rustc_span::Span; +use rustc_span::{ErrorGuaranteed, Span}; use rustc_target::spec::abi::Abi; #[inline] @@ -632,6 +632,17 @@ impl<'hir> Map<'hir> { }) } + #[inline] + pub fn try_par_for_each_module( + self, + f: impl Fn(LocalModDefId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync, + ) -> Result<(), ErrorGuaranteed> { + let crate_items = self.tcx.hir_crate_items(()); + try_par_for_each_in(&crate_items.submodules[..], |module| { + f(LocalModDefId::new_unchecked(module.def_id)) + }) + } + /// Returns an iterator for the nodes in the ancestor tree of the `current_id` /// until the crate root is reached. Prefer this over your own loop using `parent_id`. #[inline] diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 0da8fe9cca7..f28ec771169 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -9,12 +9,12 @@ pub mod place; use crate::query::Providers; use crate::ty::{EarlyBinder, ImplSubject, TyCtxt}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_data_structures::sync::{par_for_each_in, DynSend, DynSync}; +use rustc_data_structures::sync::{try_par_for_each_in, DynSend, DynSync}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId}; use rustc_hir::*; use rustc_query_system::ich::StableHashingContext; -use rustc_span::{ExpnId, DUMMY_SP}; +use rustc_span::{ErrorGuaranteed, ExpnId, DUMMY_SP}; /// Top-level HIR node for current owner. This only contains the node for which /// `HirId::local_id == 0`, and excludes bodies. @@ -78,20 +78,32 @@ impl ModuleItems { self.owners().map(|id| id.def_id) } - pub fn par_items(&self, f: impl Fn(ItemId) + DynSend + DynSync) { - par_for_each_in(&self.items[..], |&id| f(id)) + pub fn par_items( + &self, + f: impl Fn(ItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync, + ) -> Result<(), ErrorGuaranteed> { + try_par_for_each_in(&self.items[..], |&id| f(id)) } - pub fn par_trait_items(&self, f: impl Fn(TraitItemId) + DynSend + DynSync) { - par_for_each_in(&self.trait_items[..], |&id| f(id)) + pub fn par_trait_items( + &self, + f: impl Fn(TraitItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync, + ) -> Result<(), ErrorGuaranteed> { + try_par_for_each_in(&self.trait_items[..], |&id| f(id)) } - pub fn par_impl_items(&self, f: impl Fn(ImplItemId) + DynSend + DynSync) { - par_for_each_in(&self.impl_items[..], |&id| f(id)) + pub fn par_impl_items( + &self, + f: impl Fn(ImplItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync, + ) -> Result<(), ErrorGuaranteed> { + try_par_for_each_in(&self.impl_items[..], |&id| f(id)) } - pub fn par_foreign_items(&self, f: impl Fn(ForeignItemId) + DynSend + DynSync) { - par_for_each_in(&self.foreign_items[..], |&id| f(id)) + pub fn par_foreign_items( + &self, + f: impl Fn(ForeignItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync, + ) -> Result<(), ErrorGuaranteed> { + try_par_for_each_in(&self.foreign_items[..], |&id| f(id)) } } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index cd5206a837f..23d77a1ebe4 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -25,7 +25,9 @@ use crate::mir::interpret::{ use crate::mir::interpret::{LitToConstError, LitToConstInput}; use crate::mir::mono::CodegenUnit; use crate::query::erase::{erase, restore, Erase}; -use crate::query::plumbing::{query_ensure, query_get_at, CyclePlaceholder, DynamicQuery}; +use crate::query::plumbing::{ + query_ensure, query_ensure_error_guaranteed, query_get_at, CyclePlaceholder, DynamicQuery, +}; use crate::thir; use crate::traits::query::{ CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal, @@ -965,8 +967,9 @@ rustc_queries! { desc { |tcx| "checking that impls are well-formed in {}", describe_as_module(key, tcx) } } - query check_mod_type_wf(key: LocalModDefId) -> () { + query check_mod_type_wf(key: LocalModDefId) -> Result<(), ErrorGuaranteed> { desc { |tcx| "checking that types are well-formed in {}", describe_as_module(key, tcx) } + ensure_forwards_result_if_red } query collect_mod_item_types(key: LocalModDefId) -> () { @@ -1499,8 +1502,9 @@ rustc_queries! { feedable } - query check_well_formed(key: hir::OwnerId) -> () { + query check_well_formed(key: hir::OwnerId) -> Result<(), ErrorGuaranteed> { desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key) } + ensure_forwards_result_if_red } // The `DefId`s of all non-generic functions and statics in the given crate diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 34e5b02ba5b..f4a8ada8f68 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -173,6 +173,45 @@ pub fn query_ensure<'tcx, Cache>( } } +#[inline] +pub fn query_ensure_error_guaranteed<'tcx, Cache>( + tcx: TyCtxt<'tcx>, + execute_query: fn(TyCtxt<'tcx>, Span, Cache::Key, QueryMode) -> Option<Cache::Value>, + query_cache: &Cache, + key: Cache::Key, + check_cache: bool, +) -> Result<(), ErrorGuaranteed> +where + Cache: QueryCache<Value = super::erase::Erase<Result<(), ErrorGuaranteed>>>, +{ + let key = key.into_query_param(); + if let Some(res) = try_get_cached(tcx, query_cache, &key) { + super::erase::restore(res) + } else { + execute_query(tcx, DUMMY_SP, key, QueryMode::Ensure { check_cache }) + .map(super::erase::restore) + // Either we actually executed the query, which means we got a full `Result`, + // or we can just assume the query succeeded, because it was green in the + // incremental cache. If it is green, that means that the previous compilation + // that wrote to the incremental cache compiles successfully. That is only + // possible if the cache entry was `Ok(())`, so we emit that here, without + // actually encoding the `Result` in the cache or loading it from there. + .unwrap_or(Ok(())) + } +} + +macro_rules! query_ensure { + ([]$($args:tt)*) => { + query_ensure($($args)*) + }; + ([(ensure_forwards_result_if_red) $($rest:tt)*]$($args:tt)*) => { + query_ensure_error_guaranteed($($args)*) + }; + ([$other:tt $($modifiers:tt)*]$($args:tt)*) => { + query_ensure!([$($modifiers)*]$($args)*) + }; +} + macro_rules! query_helper_param_ty { (DefId) => { impl IntoQueryParam<DefId> }; (LocalDefId) => { impl IntoQueryParam<LocalDefId> }; @@ -220,6 +259,18 @@ macro_rules! separate_provide_extern_decl { }; } +macro_rules! ensure_result { + ([][$ty:ty]) => { + () + }; + ([(ensure_forwards_result_if_red) $($rest:tt)*][$ty:ty]) => { + Result<(), ErrorGuaranteed> + }; + ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => { + ensure_result!([$($modifiers)*][$($args)*]) + }; +} + macro_rules! separate_provide_extern_default { ([][$name:ident]) => { () @@ -343,14 +394,15 @@ macro_rules! define_callbacks { impl<'tcx> TyCtxtEnsure<'tcx> { $($(#[$attr])* #[inline(always)] - pub fn $name(self, key: query_helper_param_ty!($($K)*)) { - query_ensure( + pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> ensure_result!([$($modifiers)*][$V]) { + query_ensure!( + [$($modifiers)*] self.tcx, self.tcx.query_system.fns.engine.$name, &self.tcx.query_system.caches.$name, key.into_query_param(), false, - ); + ) })* } |
