Skip to content

Commit e5f80f2

Browse files
committed
Auto merge of #49834 - Zoxc:sync-trait-cache, r=nikomatsakis
Make SelectionCache and EvaluationCache thread-safe Split out from #49558 r? @nikomatsakis
2 parents 4725417 + f741ee1 commit e5f80f2

File tree

1 file changed

+17
-10
lines changed

1 file changed

+17
-10
lines changed

src/librustc/traits/select.rs

+17-10
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ use ty::relate::TypeRelation;
4444
use middle::lang_items;
4545
use mir::interpret::{GlobalId};
4646

47+
use rustc_data_structures::sync::Lock;
4748
use rustc_data_structures::bitvec::BitVector;
4849
use std::iter;
49-
use std::cell::RefCell;
5050
use std::cmp;
5151
use std::fmt;
5252
use std::mem;
@@ -148,7 +148,7 @@ struct TraitObligationStack<'prev, 'tcx: 'prev> {
148148

149149
#[derive(Clone)]
150150
pub struct SelectionCache<'tcx> {
151-
hashmap: RefCell<FxHashMap<ty::TraitRef<'tcx>,
151+
hashmap: Lock<FxHashMap<ty::TraitRef<'tcx>,
152152
WithDepNode<SelectionResult<'tcx, SelectionCandidate<'tcx>>>>>,
153153
}
154154

@@ -435,7 +435,7 @@ impl<'tcx> From<OverflowError> for SelectionError<'tcx> {
435435

436436
#[derive(Clone)]
437437
pub struct EvaluationCache<'tcx> {
438-
hashmap: RefCell<FxHashMap<ty::PolyTraitRef<'tcx>, WithDepNode<EvaluationResult>>>
438+
hashmap: Lock<FxHashMap<ty::PolyTraitRef<'tcx>, WithDepNode<EvaluationResult>>>
439439
}
440440

441441
impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
@@ -1015,14 +1015,19 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
10151015
}
10161016

10171017
if self.can_use_global_caches(param_env) {
1018-
let mut cache = self.tcx().evaluation_cache.hashmap.borrow_mut();
10191018
if let Some(trait_ref) = self.tcx().lift_to_global(&trait_ref) {
10201019
debug!(
10211020
"insert_evaluation_cache(trait_ref={:?}, candidate={:?}) global",
10221021
trait_ref,
10231022
result,
10241023
);
1025-
cache.insert(trait_ref, WithDepNode::new(dep_node, result));
1024+
// This may overwrite the cache with the same value
1025+
// FIXME: Due to #50507 this overwrites the different values
1026+
// This should be changed to use HashMapExt::insert_same
1027+
// when that is fixed
1028+
self.tcx().evaluation_cache
1029+
.hashmap.borrow_mut()
1030+
.insert(trait_ref, WithDepNode::new(dep_node, result));
10261031
return;
10271032
}
10281033
}
@@ -1368,15 +1373,17 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
13681373
let tcx = self.tcx();
13691374
let trait_ref = cache_fresh_trait_pred.skip_binder().trait_ref;
13701375
if self.can_use_global_caches(param_env) {
1371-
let mut cache = tcx.selection_cache.hashmap.borrow_mut();
13721376
if let Some(trait_ref) = tcx.lift_to_global(&trait_ref) {
13731377
if let Some(candidate) = tcx.lift_to_global(&candidate) {
13741378
debug!(
13751379
"insert_candidate_cache(trait_ref={:?}, candidate={:?}) global",
13761380
trait_ref,
13771381
candidate,
13781382
);
1379-
cache.insert(trait_ref, WithDepNode::new(dep_node, candidate));
1383+
// This may overwrite the cache with the same value
1384+
tcx.selection_cache
1385+
.hashmap.borrow_mut()
1386+
.insert(trait_ref, WithDepNode::new(dep_node, candidate));
13801387
return;
13811388
}
13821389
}
@@ -3404,7 +3411,7 @@ impl<'tcx> TraitObligation<'tcx> {
34043411
impl<'tcx> SelectionCache<'tcx> {
34053412
pub fn new() -> SelectionCache<'tcx> {
34063413
SelectionCache {
3407-
hashmap: RefCell::new(FxHashMap())
3414+
hashmap: Lock::new(FxHashMap())
34083415
}
34093416
}
34103417

@@ -3416,7 +3423,7 @@ impl<'tcx> SelectionCache<'tcx> {
34163423
impl<'tcx> EvaluationCache<'tcx> {
34173424
pub fn new() -> EvaluationCache<'tcx> {
34183425
EvaluationCache {
3419-
hashmap: RefCell::new(FxHashMap())
3426+
hashmap: Lock::new(FxHashMap())
34203427
}
34213428
}
34223429

@@ -3470,7 +3477,7 @@ impl<'o,'tcx> fmt::Debug for TraitObligationStack<'o,'tcx> {
34703477
}
34713478
}
34723479

3473-
#[derive(Clone)]
3480+
#[derive(Clone, Eq, PartialEq)]
34743481
pub struct WithDepNode<T> {
34753482
dep_node: DepNodeIndex,
34763483
cached_value: T

0 commit comments

Comments
 (0)