Skip to content

Commit 57a28d8

Browse files
committed
Poison queries which panic
1 parent dd075c9 commit 57a28d8

File tree

3 files changed

+52
-19
lines changed

3 files changed

+52
-19
lines changed

src/Cargo.lock

Lines changed: 16 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/librustc/ty/maps/job.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,5 @@ impl<'tcx> QueryJob<'tcx> {
6565
pub(super) enum QueryResult<'tcx, T> {
6666
Started(Lrc<QueryJob<'tcx>>),
6767
Complete(T),
68+
Poisoned,
6869
}

src/librustc/ty/maps/plumbing.rs

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,12 @@ macro_rules! define_maps {
179179
use dep_graph::DepNodeIndex;
180180
use rustc_data_structures::sync::{Lock, LockGuard};
181181
use std::iter;
182+
use std::mem;
183+
use std::panic;
182184
use errors::Diagnostic;
183185
use ty::maps::plumbing::QUERY_DEPTH;
184186
use std::sync::atomic::Ordering;
187+
use rayon_core;
185188

186189
define_map_struct! {
187190
tcx: $tcx,
@@ -281,6 +284,9 @@ macro_rules! define_maps {
281284
tcx.dep_graph.read_index(value.index);
282285
return Ok((&value.value).clone());
283286
},
287+
QueryResult::Poisoned => {
288+
panic::resume_unwind(Box::new(rayon_core::PoisonedJob))
289+
},
284290
}
285291
} else {
286292
break
@@ -465,9 +471,35 @@ macro_rules! define_maps {
465471
.or_insert(QueryResult::Started(job.clone()));
466472
}
467473

468-
let r = ty::tls::enter(tcx.with_query(&*job), |new_tcx| {
469-
compute(new_tcx)
470-
});
474+
struct OnPanic<F: Fn()>(F);
475+
476+
impl<F: Fn()> Drop for OnPanic<F> {
477+
fn drop(&mut self) {
478+
(self.0)();
479+
}
480+
}
481+
482+
let r = {
483+
let on_panic = OnPanic(|| {
484+
// Poison the query so jobs waiting on it panics
485+
tcx.maps
486+
.$name
487+
.borrow_mut()
488+
.map
489+
.insert(key, QueryResult::Poisoned);
490+
// Also signal the completion of the job, so waiters
491+
// will continue execution
492+
job.signal_complete();
493+
});
494+
495+
let r = ty::tls::enter(tcx.with_query(&*job), |new_tcx| {
496+
compute(new_tcx)
497+
});
498+
499+
mem::forget(on_panic);
500+
501+
r
502+
};
471503

472504
if *LOG {
473505
println!("ending query {:?}", query.clone());

0 commit comments

Comments
 (0)