@@ -49,13 +49,17 @@ use rustc_middle::ty::{self, EarlyBinder, PolyProjectionPredicate, ToPolyTraitRe
49
49
use rustc_middle:: ty:: { Ty , TyCtxt , TypeFoldable , TypeVisitable } ;
50
50
use rustc_span:: symbol:: sym;
51
51
52
+ use rustc_data_structures:: fingerprint:: Fingerprint ;
53
+ use rustc_data_structures:: stable_hasher:: StableHasher ;
52
54
use std:: cell:: { Cell , RefCell } ;
53
55
use std:: cmp;
54
56
use std:: fmt:: { self , Display } ;
57
+ use std:: hash:: Hash ;
55
58
use std:: iter;
56
59
57
60
pub use rustc_middle:: traits:: select:: * ;
58
61
use rustc_middle:: ty:: print:: with_no_trimmed_paths;
62
+ use rustc_query_system:: dep_graph:: TaskDeps ;
59
63
60
64
mod candidate_assembly;
61
65
mod confirmation;
@@ -1017,7 +1021,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1017
1021
return Ok ( cycle_result) ;
1018
1022
}
1019
1023
1020
- let ( result, dep_node) = self . in_task ( |this| this. evaluate_stack ( & stack) ) ;
1024
+ let ( result, dep_node) = if cfg ! ( parallel_compiler) {
1025
+ self . in_task_with_hash (
1026
+ |this| this. evaluate_stack ( & stack) ,
1027
+ |_| {
1028
+ let mut hasher = StableHasher :: new ( ) ;
1029
+ ( param_env, fresh_trait_pred) . hash ( & mut hasher) ;
1030
+ hasher. finish ( )
1031
+ } ,
1032
+ )
1033
+ } else {
1034
+ self . in_task ( |this| this. evaluate_stack ( & stack) )
1035
+ } ;
1036
+
1021
1037
let result = result?;
1022
1038
1023
1039
if !result. must_apply_modulo_regions ( ) {
@@ -1263,17 +1279,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1263
1279
if self . can_use_global_caches ( param_env) {
1264
1280
if !trait_pred. needs_infer ( ) {
1265
1281
debug ! ( ?trait_pred, ?result, "insert_evaluation_cache global" ) ;
1266
- // This may overwrite the cache with the same value
1267
- // FIXME: Due to #50507 this overwrites the different values
1268
- // This should be changed to use HashMapExt::insert_same
1269
- // when that is fixed
1270
- self . tcx ( ) . evaluation_cache . insert ( ( param_env, trait_pred) , dep_node, result) ;
1282
+ self . tcx ( ) . evaluation_cache . insert_same ( ( param_env, trait_pred) , dep_node, result) ;
1271
1283
return ;
1272
1284
}
1273
1285
}
1274
1286
1275
1287
debug ! ( ?trait_pred, ?result, "insert_evaluation_cache" ) ;
1276
- self . infcx . evaluation_cache . insert ( ( param_env, trait_pred) , dep_node, result) ;
1288
+ self . infcx . evaluation_cache . insert_same ( ( param_env, trait_pred) , dep_node, result) ;
1277
1289
}
1278
1290
1279
1291
/// For various reasons, it's possible for a subobligation
@@ -1344,6 +1356,21 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1344
1356
( result, dep_node)
1345
1357
}
1346
1358
1359
+ fn in_task_with_hash < OP , R , H > ( & mut self , op : OP , hash : H ) -> ( R , DepNodeIndex )
1360
+ where
1361
+ OP : FnOnce ( & mut Self ) -> R ,
1362
+ H : FnOnce ( & TaskDeps < DepKind > ) -> Fingerprint ,
1363
+ {
1364
+ let ( result, dep_node) = self . tcx ( ) . dep_graph . with_hash_task (
1365
+ self . tcx ( ) ,
1366
+ DepKind :: TraitSelect ,
1367
+ || op ( self ) ,
1368
+ hash,
1369
+ ) ;
1370
+ self . tcx ( ) . dep_graph . read_index ( dep_node) ;
1371
+ ( result, dep_node)
1372
+ }
1373
+
1347
1374
/// filter_impls filters constant trait obligations and candidates that have a positive impl
1348
1375
/// for a negative goal and a negative impl for a positive goal
1349
1376
#[ instrument( level = "debug" , skip( self , candidates) ) ]
0 commit comments