Auto merge of #116849 - oli-obk:error_shenanigans, r=cjgillot
Avoid a `track_errors` by bubbling up most errors from `check_well_formed` I believe `track_errors` is mostly papering over issues that a sufficiently convoluted query graph can hit. I made this change, while the actual change I want to do is to stop bailing out early on errors, and instead use this new `ErrorGuaranteed` to invoke `check_well_formed` for individual items before doing all the `typeck` logic on them. This works towards resolving https://github.com/rust-lang/rust/issues/97477 and various other ICEs, as well as allowing us to use parallel rustc more (which is currently rather limited/bottlenecked due to the very sequential nature in which we do `rustc_hir_analysis::check_crate`) cc `@SparrowLii` `@Zoxc` for the new `try_par_for_each_in` function
This commit is contained in:
commit
a56bd2b944
36 changed files with 425 additions and 310 deletions
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
)
|
||||
})*
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue