Skip to content

Commit bff405c

Browse files
committed
Change value_from_cycle_error signature.
Currently if a cycle error occurs the error is created, then handled according to `CycleErrorHandling` (which comes from the `cycle_*` query modifers), and then `value_from_cycle_error` is called. This commit changes things so the error is created and then just passed to `value_from_cycle_error`. This gives `value_from_cycle_error` full control over how it's handled, eliminating the need for `CycleErrorHandling`. This makes things simpler overall.
1 parent a5267ba commit bff405c

9 files changed

Lines changed: 61 additions & 130 deletions

File tree

compiler/rustc_macros/src/query.rs

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,6 @@ struct QueryModifiers {
143143
anon: Option<Ident>,
144144
arena_cache: Option<Ident>,
145145
cache_on_disk_if: Option<CacheOnDiskIf>,
146-
cycle_delay_bug: Option<Ident>,
147-
cycle_stash: Option<Ident>,
148146
depth_limit: Option<Ident>,
149147
desc: Desc,
150148
eval_always: Option<Ident>,
@@ -158,8 +156,6 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
158156
let mut arena_cache = None;
159157
let mut cache_on_disk_if = None;
160158
let mut desc = None;
161-
let mut cycle_delay_bug = None;
162-
let mut cycle_stash = None;
163159
let mut no_hash = None;
164160
let mut anon = None;
165161
let mut eval_always = None;
@@ -193,10 +189,6 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
193189
try_insert!(cache_on_disk_if = CacheOnDiskIf { modifier, block });
194190
} else if modifier == "arena_cache" {
195191
try_insert!(arena_cache = modifier);
196-
} else if modifier == "cycle_delay_bug" {
197-
try_insert!(cycle_delay_bug = modifier);
198-
} else if modifier == "cycle_stash" {
199-
try_insert!(cycle_stash = modifier);
200192
} else if modifier == "no_hash" {
201193
try_insert!(no_hash = modifier);
202194
} else if modifier == "anon" {
@@ -220,8 +212,6 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
220212
arena_cache,
221213
cache_on_disk_if,
222214
desc,
223-
cycle_delay_bug,
224-
cycle_stash,
225215
no_hash,
226216
anon,
227217
eval_always,
@@ -256,8 +246,6 @@ fn make_modifiers_stream(query: &Query) -> proc_macro2::TokenStream {
256246
anon,
257247
arena_cache,
258248
cache_on_disk_if,
259-
cycle_delay_bug,
260-
cycle_stash,
261249
depth_limit,
262250
desc: _,
263251
eval_always,
@@ -270,15 +258,6 @@ fn make_modifiers_stream(query: &Query) -> proc_macro2::TokenStream {
270258
let anon = anon.is_some();
271259
let arena_cache = arena_cache.is_some();
272260
let cache_on_disk = cache_on_disk_if.is_some();
273-
274-
let cycle_error_handling = if cycle_delay_bug.is_some() {
275-
quote! { DelayBug }
276-
} else if cycle_stash.is_some() {
277-
quote! { Stash }
278-
} else {
279-
quote! { Error }
280-
};
281-
282261
let depth_limit = depth_limit.is_some();
283262
let eval_always = eval_always.is_some();
284263
let feedable = feedable.is_some();
@@ -297,7 +276,6 @@ fn make_modifiers_stream(query: &Query) -> proc_macro2::TokenStream {
297276
anon: #anon,
298277
arena_cache: #arena_cache,
299278
cache_on_disk: #cache_on_disk,
300-
cycle_error_handling: #cycle_error_handling,
301279
depth_limit: #depth_limit,
302280
eval_always: #eval_always,
303281
feedable: #feedable,
@@ -410,8 +388,6 @@ fn add_to_analyzer_stream(query: &Query, analyzer_stream: &mut proc_macro2::Toke
410388

411389
doc_link!(
412390
arena_cache,
413-
cycle_delay_bug,
414-
cycle_stash,
415391
no_hash,
416392
anon,
417393
eval_always,

compiler/rustc_middle/src/queries.rs

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@
3232
//! - `arena_cache`: Use an arena for in-memory caching of the query result.
3333
//! - `cache_on_disk_if { ... }`: Cache the query result to disk if the provided block evaluates to
3434
//! true. The query key identifier is available for use within the block, as is `tcx`.
35-
//! - `cycle_delay_bug`: If a dependency cycle is detected, emit a delayed bug instead of aborting immediately.
36-
//! - `cycle_stash`: If a dependency cycle is detected, stash the error for later handling.
3735
//! - `no_hash`: Do not hash the query result for incremental compilation; just mark as dirty if recomputed.
3836
//! - `anon`: Make the query anonymous in the dependency graph (no dep node is created).
3937
//! - `eval_always`: Always evaluate the query, ignoring its dependencies and cached results.
@@ -354,7 +352,6 @@ rustc_queries! {
354352
"computing type of opaque `{path}`",
355353
path = tcx.def_path_str(key),
356354
}
357-
cycle_stash
358355
}
359356
query type_of_opaque_hir_typeck(key: LocalDefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
360357
desc {
@@ -588,14 +585,13 @@ rustc_queries! {
588585
}
589586

590587
/// Checks whether a type is representable or infinitely sized
588+
//
589+
// Infinitely sized types will cause a cycle. The `value_from_cycle_error` impl will print
590+
// a custom error about the infinite size and then abort compilation. (In the past we
591+
// recovered and continued, but in practice that leads to confusing subsequent error
592+
// messages about cycles that then abort.)
591593
query check_representability(key: LocalDefId) {
592594
desc { "checking if `{}` is representable", tcx.def_path_str(key) }
593-
// njn: update comment
594-
// Infinitely sized types will cause a cycle. The custom `FromCycleError` impl for
595-
// `Representability` will print a custom error about the infinite size and then abort
596-
// compilation. (In the past we recovered and continued, but in practice that leads to
597-
// confusing subsequent error messages about cycles that then abort.)
598-
cycle_delay_bug
599595
// We don't want recursive representability calls to be forced with
600596
// incremental compilation because, if a cycle occurs, we need the
601597
// entire cycle to be in memory for diagnostics. This means we can't
@@ -607,7 +603,6 @@ rustc_queries! {
607603
/// details, particularly on the modifiers.
608604
query check_representability_adt_ty(key: Ty<'tcx>) {
609605
desc { "checking if `{}` is representable", key }
610-
cycle_delay_bug
611606
anon
612607
}
613608

@@ -1052,7 +1047,6 @@ rustc_queries! {
10521047
desc { "computing the variances of `{}`", tcx.def_path_str(def_id) }
10531048
cache_on_disk_if { def_id.is_local() }
10541049
separate_provide_extern
1055-
cycle_delay_bug
10561050
}
10571051

10581052
/// Gets a map with the inferred outlives-predicates of every item in the local crate.
@@ -1185,7 +1179,6 @@ rustc_queries! {
11851179
desc { "computing function signature of `{}`", tcx.def_path_str(key) }
11861180
cache_on_disk_if { key.is_local() }
11871181
separate_provide_extern
1188-
cycle_delay_bug
11891182
}
11901183

11911184
/// Performs lint checking for the module.
@@ -1776,8 +1769,6 @@ rustc_queries! {
17761769
) -> Result<ty::layout::TyAndLayout<'tcx>, &'tcx ty::layout::LayoutError<'tcx>> {
17771770
depth_limit
17781771
desc { "computing layout of `{}`", key.value }
1779-
// we emit our own error during query cycle handling
1780-
cycle_delay_bug
17811772
}
17821773

17831774
/// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers.

compiler/rustc_middle/src/query/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ pub use self::caches::{DefIdCache, DefaultCache, QueryCache, SingleCache, VecCac
44
pub use self::job::{QueryInfo, QueryJob, QueryJobId, QueryLatch, QueryWaiter};
55
pub use self::keys::{AsLocalQueryKey, LocalCrate, QueryKey};
66
pub use self::plumbing::{
7-
ActiveKeyStatus, CycleError, CycleErrorHandling, EnsureMode, IntoQueryParam, QueryMode,
8-
QueryState, TyCtxtAt, TyCtxtEnsureDone, TyCtxtEnsureOk, TyCtxtEnsureResult,
7+
ActiveKeyStatus, CycleError, EnsureMode, IntoQueryParam, QueryMode, QueryState, TyCtxtAt,
8+
TyCtxtEnsureDone, TyCtxtEnsureOk, TyCtxtEnsureResult,
99
};
1010
pub use self::stack::{QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra};
1111
pub use crate::queries::Providers;

compiler/rustc_middle/src/query/modifiers.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,6 @@ pub(crate) struct arena_cache;
2323
/// Cache the query to disk if the `Block` returns true.
2424
pub(crate) struct cache_on_disk_if;
2525

26-
/// # `cycle_delay_bug` query modifier
27-
///
28-
/// A cycle error results in a delay_bug call
29-
pub(crate) struct cycle_delay_bug;
30-
31-
/// # `cycle_stash` query modifier
32-
///
33-
/// A cycle error results in a stashed cycle error that can be unstashed and canceled later
34-
pub(crate) struct cycle_stash;
35-
3626
/// # `depth_limit` query modifier
3727
///
3828
/// Whether the query has a call depth limit

compiler/rustc_middle/src/query/plumbing.rs

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use rustc_data_structures::fingerprint::Fingerprint;
55
use rustc_data_structures::hash_table::HashTable;
66
use rustc_data_structures::sharded::Sharded;
77
use rustc_data_structures::sync::{AtomicU64, WorkerLocal};
8+
use rustc_errors::Diag;
89
use rustc_hir::def_id::{DefId, LocalDefId};
910
use rustc_hir::hir_id::OwnerId;
1011
use rustc_macros::HashStable;
@@ -50,17 +51,6 @@ pub enum ActiveKeyStatus<'tcx> {
5051
Poisoned,
5152
}
5253

53-
/// How a particular query deals with query cycle errors.
54-
///
55-
/// Inspected by the code that actually handles cycle errors, to decide what
56-
/// approach to use.
57-
#[derive(Copy, Clone)]
58-
pub enum CycleErrorHandling {
59-
Error,
60-
DelayBug,
61-
Stash,
62-
}
63-
6454
#[derive(Clone, Debug)]
6555
pub struct CycleError<I = QueryStackFrameExtra> {
6656
/// The query and related span that uses the cycle.
@@ -109,8 +99,6 @@ pub struct QueryVTable<'tcx, C: QueryCache> {
10999
pub feedable: bool,
110100

111101
pub dep_kind: DepKind,
112-
/// How this query deals with query cycle errors.
113-
pub cycle_error_handling: CycleErrorHandling,
114102
pub state: QueryState<'tcx, C::Key>,
115103
pub cache: C,
116104

@@ -138,8 +126,12 @@ pub struct QueryVTable<'tcx, C: QueryCache> {
138126
/// For `no_hash` queries, this function pointer is None.
139127
pub hash_value_fn: Option<fn(&mut StableHashingContext<'_>, &C::Value) -> Fingerprint>,
140128

129+
/// Function pointer that handles a cycle error. `error` must be consumed, e.g. with `emit` (if
130+
/// it should be emitted) or `delay_as_bug` (if it need not be emitted because an alternative
131+
/// error is created and emitted).
141132
pub value_from_cycle_error:
142-
fn(tcx: TyCtxt<'tcx>, cycle_error: CycleError, guar: ErrorGuaranteed) -> C::Value,
133+
fn(tcx: TyCtxt<'tcx>, cycle_error: CycleError, error: Diag<'_>) -> C::Value,
134+
143135
pub format_value: fn(&C::Value) -> String,
144136

145137
/// Formats a human-readable description of this query and its key, as
@@ -306,7 +298,6 @@ macro_rules! define_callbacks {
306298
anon: $anon:literal,
307299
arena_cache: $arena_cache:literal,
308300
cache_on_disk: $cache_on_disk:literal,
309-
cycle_error_handling: $cycle_error_handling:ident,
310301
depth_limit: $depth_limit:literal,
311302
eval_always: $eval_always:literal,
312303
feedable: $feedable:literal,

compiler/rustc_query_impl/src/dep_kind_vtables.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,6 @@ macro_rules! define_dep_kind_vtables {
136136
anon: $anon:literal,
137137
arena_cache: $arena_cache:literal,
138138
cache_on_disk: $cache_on_disk:literal,
139-
cycle_error_handling: $cycle_error_handling:ident,
140139
depth_limit: $depth_limit:literal,
141140
eval_always: $eval_always:literal,
142141
feedable: $feedable:literal,

compiler/rustc_query_impl/src/execution.rs

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ use rustc_data_structures::hash_table::{Entry, HashTable};
55
use rustc_data_structures::stack::ensure_sufficient_stack;
66
use rustc_data_structures::sync::{DynSend, DynSync};
77
use rustc_data_structures::{outline, sharded, sync};
8-
use rustc_errors::{FatalError, StashKey};
8+
use rustc_errors::FatalError;
99
use rustc_middle::dep_graph::{DepGraphData, DepNodeKey, SerializedDepNodeIndex};
1010
use rustc_middle::query::plumbing::QueryVTable;
1111
use rustc_middle::query::{
12-
ActiveKeyStatus, CycleError, CycleErrorHandling, EnsureMode, QueryCache, QueryJob, QueryJobId,
13-
QueryKey, QueryLatch, QueryMode, QueryState,
12+
ActiveKeyStatus, CycleError, EnsureMode, QueryCache, QueryJob, QueryJobId, QueryKey,
13+
QueryLatch, QueryMode, QueryState,
1414
};
1515
use rustc_middle::ty::TyCtxt;
1616
use rustc_middle::verify_ich::incremental_verify_ich;
@@ -101,26 +101,7 @@ fn mk_cycle<'tcx, C: QueryCache>(
101101
cycle_error: CycleError,
102102
) -> C::Value {
103103
let error = report_cycle(tcx.sess, &cycle_error);
104-
match query.cycle_error_handling {
105-
CycleErrorHandling::Error => {
106-
let guar = error.emit();
107-
(query.value_from_cycle_error)(tcx, cycle_error, guar)
108-
}
109-
CycleErrorHandling::DelayBug => {
110-
let guar = error.delay_as_bug();
111-
(query.value_from_cycle_error)(tcx, cycle_error, guar)
112-
}
113-
CycleErrorHandling::Stash => {
114-
let guar = if let Some(root) = cycle_error.cycle.first()
115-
&& let Some(span) = root.frame.info.span
116-
{
117-
error.stash(span, StashKey::Cycle).unwrap()
118-
} else {
119-
error.emit()
120-
};
121-
(query.value_from_cycle_error)(tcx, cycle_error, guar)
122-
}
123-
}
104+
(query.value_from_cycle_error)(tcx, cycle_error, error)
124105
}
125106

126107
/// Guard object representing the responsibility to execute a query job and

0 commit comments

Comments
 (0)