Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 5c92971

Browse files
authoredSep 7, 2022
Rollup merge of rust-lang#101303 - jyn514:jnelson/handle-cycle-enum, r=cjgillot
Make `HandleCycleError` an enum instead of a macro-generated closure Helps with rust-lang#96524. Based on rust-lang#100943 to avoid merge conflicts, so it looks larger than it is (only the last commit is relevant). cc https://rust-lang.zulipchat.com/#narrow/stream/241847-t-compiler.2Fwg-incr-comp/topic/Moving.20.60Value.60.20to.20rustc_query_system.20.2396524 r? `@cjgillot`
2 parents 8fd49fe + 4856aff commit 5c92971

File tree

9 files changed

+86
-43
lines changed

9 files changed

+86
-43
lines changed
 

‎compiler/rustc_middle/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ pub mod mir;
9696
pub mod thir;
9797
pub mod traits;
9898
pub mod ty;
99+
mod values;
99100

100101
pub mod util {
101102
pub mod bug;

‎compiler/rustc_query_impl/src/values.rs ‎compiler/rustc_middle/src/values.rs

+11-22
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,28 @@
1-
use super::QueryCtxt;
2-
use rustc_middle::ty::{self, AdtSizedConstraint, Ty};
1+
use rustc_middle::ty::{self, AdtSizedConstraint, Ty, TyCtxt};
2+
use rustc_query_system::Value;
33

4-
pub(super) trait Value<'tcx>: Sized {
5-
fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self;
6-
}
7-
8-
impl<'tcx, T> Value<'tcx> for T {
9-
default fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> T {
10-
tcx.sess.abort_if_errors();
11-
bug!("Value::from_cycle_error called without errors");
12-
}
13-
}
14-
15-
impl<'tcx> Value<'tcx> for Ty<'_> {
16-
fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self {
4+
impl<'tcx> Value<TyCtxt<'tcx>> for Ty<'_> {
5+
fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self {
176
// SAFETY: This is never called when `Self` is not `Ty<'tcx>`.
187
// FIXME: Represent the above fact in the trait system somehow.
198
unsafe { std::mem::transmute::<Ty<'tcx>, Ty<'_>>(tcx.ty_error()) }
209
}
2110
}
2211

23-
impl<'tcx> Value<'tcx> for ty::SymbolName<'_> {
24-
fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self {
12+
impl<'tcx> Value<TyCtxt<'tcx>> for ty::SymbolName<'_> {
13+
fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self {
2514
// SAFETY: This is never called when `Self` is not `SymbolName<'tcx>`.
2615
// FIXME: Represent the above fact in the trait system somehow.
2716
unsafe {
2817
std::mem::transmute::<ty::SymbolName<'tcx>, ty::SymbolName<'_>>(ty::SymbolName::new(
29-
*tcx, "<error>",
18+
tcx, "<error>",
3019
))
3120
}
3221
}
3322
}
3423

35-
impl<'tcx> Value<'tcx> for AdtSizedConstraint<'_> {
36-
fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self {
24+
impl<'tcx> Value<TyCtxt<'tcx>> for AdtSizedConstraint<'_> {
25+
fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self {
3726
// SAFETY: This is never called when `Self` is not `AdtSizedConstraint<'tcx>`.
3827
// FIXME: Represent the above fact in the trait system somehow.
3928
unsafe {
@@ -44,8 +33,8 @@ impl<'tcx> Value<'tcx> for AdtSizedConstraint<'_> {
4433
}
4534
}
4635

47-
impl<'tcx> Value<'tcx> for ty::Binder<'_, ty::FnSig<'_>> {
48-
fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self {
36+
impl<'tcx> Value<TyCtxt<'tcx>> for ty::Binder<'_, ty::FnSig<'_>> {
37+
fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self {
4938
let err = tcx.ty_error();
5039
// FIXME(compiler-errors): It would be nice if we could get the
5140
// query key, so we could at least generate a fn signature that

‎compiler/rustc_query_impl/src/lib.rs

-3
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@ pub use rustc_query_system::query::{deadlock, QueryContext};
3434
mod keys;
3535
use keys::Key;
3636

37-
mod values;
38-
use self::values::Value;
39-
4037
pub use rustc_query_system::query::QueryConfig;
4138
pub(crate) use rustc_query_system::query::{QueryDescription, QueryVTable};
4239

‎compiler/rustc_query_impl/src/plumbing.rs

+11-13
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use rustc_query_system::query::{
1818
force_query, QueryConfig, QueryContext, QueryDescription, QueryJobId, QueryMap,
1919
QuerySideEffects, QueryStackFrame,
2020
};
21+
use rustc_query_system::Value;
2122
use std::any::Any;
2223
use std::num::NonZeroU64;
2324
use thin_vec::ThinVec;
@@ -174,21 +175,17 @@ impl<'tcx> QueryCtxt<'tcx> {
174175
}
175176

176177
macro_rules! handle_cycle_error {
177-
([][$tcx: expr, $error:expr]) => {{
178-
$error.emit();
179-
Value::from_cycle_error($tcx)
178+
([]) => {{
179+
rustc_query_system::HandleCycleError::Error
180180
}};
181-
([(fatal_cycle) $($rest:tt)*][$tcx:expr, $error:expr]) => {{
182-
$error.emit();
183-
$tcx.sess.abort_if_errors();
184-
unreachable!()
181+
([(fatal_cycle) $($rest:tt)*]) => {{
182+
rustc_query_system::HandleCycleError::Fatal
185183
}};
186-
([(cycle_delay_bug) $($rest:tt)*][$tcx:expr, $error:expr]) => {{
187-
$error.delay_as_bug();
188-
Value::from_cycle_error($tcx)
184+
([(cycle_delay_bug) $($rest:tt)*]) => {{
185+
rustc_query_system::HandleCycleError::DelayBug
189186
}};
190-
([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
191-
handle_cycle_error!([$($modifiers)*][$($args)*])
187+
([$other:tt $($modifiers:tt)*]) => {
188+
handle_cycle_error!([$($modifiers)*])
192189
};
193190
}
194191

@@ -320,6 +317,7 @@ fn force_from_dep_node<'tcx, Q>(tcx: TyCtxt<'tcx>, dep_node: DepNode) -> bool
320317
where
321318
Q: QueryDescription<QueryCtxt<'tcx>>,
322319
Q::Key: DepNodeParams<TyCtxt<'tcx>>,
320+
Q::Value: Value<TyCtxt<'tcx>>,
323321
{
324322
if let Some(key) = Q::Key::recover(tcx, &dep_node) {
325323
#[cfg(debug_assertions)]
@@ -418,7 +416,7 @@ macro_rules! define_queries {
418416
depth_limit: depth_limit!([$($modifiers)*]),
419417
dep_kind: dep_graph::DepKind::$name,
420418
hash_result: hash_result!([$($modifiers)*]),
421-
handle_cycle_error: |tcx, mut error| handle_cycle_error!([$($modifiers)*][tcx, error]),
419+
handle_cycle_error: handle_cycle_error!([$($modifiers)*]),
422420
compute,
423421
cache_on_disk,
424422
try_load_from_disk: Self::TRY_LOAD_FROM_DISK,

‎compiler/rustc_query_system/src/error.rs

+7
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ impl AddSubdiagnostic for CycleStack {
1212
}
1313
}
1414

15+
#[derive(Copy, Clone)]
16+
pub enum HandleCycleError {
17+
Error,
18+
Fatal,
19+
DelayBug,
20+
}
21+
1522
#[derive(SessionSubdiagnostic)]
1623
pub enum StackCount {
1724
#[note(query_system::cycle_stack_single)]

‎compiler/rustc_query_system/src/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,7 @@ pub mod dep_graph;
2020
mod error;
2121
pub mod ich;
2222
pub mod query;
23+
mod values;
24+
25+
pub use error::HandleCycleError;
26+
pub use values::Value;

‎compiler/rustc_query_system/src/query/config.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
33
use crate::dep_graph::DepNode;
44
use crate::dep_graph::SerializedDepNodeIndex;
5+
use crate::error::HandleCycleError;
56
use crate::ich::StableHashingContext;
67
use crate::query::caches::QueryCache;
78
use crate::query::{QueryContext, QueryState};
89

910
use rustc_data_structures::fingerprint::Fingerprint;
10-
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
1111
use std::fmt::Debug;
1212
use std::hash::Hash;
1313

@@ -19,6 +19,7 @@ pub trait QueryConfig {
1919
type Stored: Clone;
2020
}
2121

22+
#[derive(Copy, Clone)]
2223
pub struct QueryVTable<CTX: QueryContext, K, V> {
2324
pub anon: bool,
2425
pub dep_kind: CTX::DepKind,
@@ -28,7 +29,7 @@ pub struct QueryVTable<CTX: QueryContext, K, V> {
2829

2930
pub compute: fn(CTX::DepContext, K) -> V,
3031
pub hash_result: Option<fn(&mut StableHashingContext<'_>, &V) -> Fingerprint>,
31-
pub handle_cycle_error: fn(CTX, DiagnosticBuilder<'_, ErrorGuaranteed>) -> V,
32+
pub handle_cycle_error: HandleCycleError,
3233
pub try_load_from_disk: Option<fn(CTX, SerializedDepNodeIndex) -> Option<V>>,
3334
}
3435

‎compiler/rustc_query_system/src/query/plumbing.rs

+35-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use crate::query::caches::QueryCache;
77
use crate::query::config::{QueryDescription, QueryVTable};
88
use crate::query::job::{report_cycle, QueryInfo, QueryJob, QueryJobId, QueryJobInfo};
99
use crate::query::{QueryContext, QueryMap, QuerySideEffects, QueryStackFrame};
10+
use crate::values::Value;
11+
use crate::HandleCycleError;
1012
use rustc_data_structures::fingerprint::Fingerprint;
1113
use rustc_data_structures::fx::FxHashMap;
1214
#[cfg(parallel_compiler)]
@@ -118,19 +120,46 @@ where
118120
fn mk_cycle<CTX, V, R>(
119121
tcx: CTX,
120122
error: CycleError,
121-
handle_cycle_error: fn(CTX, DiagnosticBuilder<'_, ErrorGuaranteed>) -> V,
123+
handler: HandleCycleError,
122124
cache: &dyn crate::query::QueryStorage<Value = V, Stored = R>,
123125
) -> R
124126
where
125127
CTX: QueryContext,
126-
V: std::fmt::Debug,
128+
V: std::fmt::Debug + Value<CTX::DepContext>,
127129
R: Clone,
128130
{
129131
let error = report_cycle(tcx.dep_context().sess(), error);
130-
let value = handle_cycle_error(tcx, error);
132+
let value = handle_cycle_error(*tcx.dep_context(), error, handler);
131133
cache.store_nocache(value)
132134
}
133135

136+
fn handle_cycle_error<CTX, V>(
137+
tcx: CTX,
138+
mut error: DiagnosticBuilder<'_, ErrorGuaranteed>,
139+
handler: HandleCycleError,
140+
) -> V
141+
where
142+
CTX: DepContext,
143+
V: Value<CTX>,
144+
{
145+
use HandleCycleError::*;
146+
match handler {
147+
Error => {
148+
error.emit();
149+
Value::from_cycle_error(tcx)
150+
}
151+
Fatal => {
152+
error.emit();
153+
tcx.sess().abort_if_errors();
154+
unreachable!()
155+
}
156+
DelayBug => {
157+
error.delay_as_bug();
158+
Value::from_cycle_error(tcx)
159+
}
160+
}
161+
}
162+
134163
impl<'tcx, K> JobOwner<'tcx, K>
135164
where
136165
K: Eq + Hash + Clone,
@@ -336,6 +365,7 @@ fn try_execute_query<CTX, C>(
336365
where
337366
C: QueryCache,
338367
C::Key: Clone + DepNodeParams<CTX::DepContext>,
368+
C::Value: Value<CTX::DepContext>,
339369
CTX: QueryContext,
340370
{
341371
match JobOwner::<'_, C::Key>::try_start(&tcx, state, span, key.clone()) {
@@ -686,6 +716,7 @@ pub fn get_query<Q, CTX>(tcx: CTX, span: Span, key: Q::Key, mode: QueryMode) ->
686716
where
687717
Q: QueryDescription<CTX>,
688718
Q::Key: DepNodeParams<CTX::DepContext>,
719+
Q::Value: Value<CTX::DepContext>,
689720
CTX: QueryContext,
690721
{
691722
let query = Q::make_vtable(tcx, &key);
@@ -718,6 +749,7 @@ pub fn force_query<Q, CTX>(tcx: CTX, key: Q::Key, dep_node: DepNode<CTX::DepKind
718749
where
719750
Q: QueryDescription<CTX>,
720751
Q::Key: DepNodeParams<CTX::DepContext>,
752+
Q::Value: Value<CTX::DepContext>,
721753
CTX: QueryContext,
722754
{
723755
// We may be concurrently trying both execute and force a query.
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
use crate::dep_graph::DepContext;
2+
3+
pub trait Value<CTX: DepContext>: Sized {
4+
fn from_cycle_error(tcx: CTX) -> Self;
5+
}
6+
7+
impl<CTX: DepContext, T> Value<CTX> for T {
8+
default fn from_cycle_error(tcx: CTX) -> T {
9+
tcx.sess().abort_if_errors();
10+
// Ideally we would use `bug!` here. But bug! is only defined in rustc_middle, and it's
11+
// non-trivial to define it earlier.
12+
panic!("Value::from_cycle_error called without errors");
13+
}
14+
}

0 commit comments

Comments
 (0)
Please sign in to comment.