@@ -12,26 +12,26 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
12
12
use rustc_data_structures:: stack:: ensure_sufficient_stack;
13
13
use rustc_errors:: { Diag , EmissionGuarantee } ;
14
14
use rustc_hir as hir;
15
- use rustc_hir:: LangItem ;
16
15
use rustc_hir:: def_id:: DefId ;
17
- use rustc_infer:: infer:: BoundRegionConversionTime :: { self , HigherRankedType } ;
18
- use rustc_infer:: infer:: DefineOpaqueTypes ;
16
+ use rustc_hir:: LangItem ;
19
17
use rustc_infer:: infer:: at:: ToTrace ;
20
18
use rustc_infer:: infer:: relate:: TypeRelation ;
19
+ use rustc_infer:: infer:: BoundRegionConversionTime :: { self , HigherRankedType } ;
20
+ use rustc_infer:: infer:: DefineOpaqueTypes ;
21
21
use rustc_infer:: traits:: TraitObligation ;
22
22
use rustc_middle:: bug;
23
- use rustc_middle:: dep_graph:: { DepNodeIndex , dep_kinds } ;
23
+ use rustc_middle:: dep_graph:: { dep_kinds , DepNodeIndex } ;
24
24
use rustc_middle:: mir:: interpret:: ErrorHandled ;
25
25
pub use rustc_middle:: traits:: select:: * ;
26
26
use rustc_middle:: ty:: abstract_const:: NotConstEvaluatable ;
27
27
use rustc_middle:: ty:: error:: TypeErrorToStringExt ;
28
- use rustc_middle:: ty:: print:: { PrintTraitRefExt as _, with_no_trimmed_paths } ;
28
+ use rustc_middle:: ty:: print:: { with_no_trimmed_paths , PrintTraitRefExt as _} ;
29
29
use rustc_middle:: ty:: {
30
30
self , GenericArgsRef , PolyProjectionPredicate , Ty , TyCtxt , TypeFoldable , TypeVisitableExt ,
31
31
Upcast ,
32
32
} ;
33
- use rustc_span:: Symbol ;
34
33
use rustc_span:: symbol:: sym;
34
+ use rustc_span:: Symbol ;
35
35
use tracing:: { debug, instrument, trace} ;
36
36
37
37
use self :: EvaluationResult :: * ;
@@ -40,9 +40,9 @@ use super::coherence::{self, Conflict};
40
40
use super :: project:: ProjectionTermObligation ;
41
41
use super :: util:: closure_trait_ref_and_return_type;
42
42
use super :: {
43
- ImplDerivedCause , Normalized , Obligation , ObligationCause , ObligationCauseCode , Overflow ,
44
- PolyTraitObligation , PredicateObligation , Selection , SelectionError , SelectionResult ,
45
- TraitQueryMode , const_evaluatable , project , util , wf ,
43
+ const_evaluatable , project , util , wf , ImplDerivedCause , Normalized , Obligation ,
44
+ ObligationCause , ObligationCauseCode , Overflow , PolyTraitObligation , PredicateObligation ,
45
+ Selection , SelectionError , SelectionResult , TraitQueryMode ,
46
46
} ;
47
47
use crate :: error_reporting:: InferCtxtErrorExt ;
48
48
use crate :: infer:: { InferCtxt , InferOk , TypeFreshener } ;
@@ -1306,7 +1306,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1306
1306
}
1307
1307
1308
1308
let tcx = self . tcx ( ) ;
1309
- if self . can_use_global_caches ( param_env) {
1309
+ if self . can_use_global_caches ( param_env, trait_pred ) {
1310
1310
if let Some ( res) = tcx. evaluation_cache . get ( & ( param_env, trait_pred) , tcx) {
1311
1311
return Some ( res) ;
1312
1312
}
@@ -1335,7 +1335,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1335
1335
return ;
1336
1336
}
1337
1337
1338
- if self . can_use_global_caches ( param_env) && !trait_pred. has_infer ( ) {
1338
+ if self . can_use_global_caches ( param_env, trait_pred ) && !trait_pred. has_infer ( ) {
1339
1339
debug ! ( ?trait_pred, ?result, "insert_evaluation_cache global" ) ;
1340
1340
// This may overwrite the cache with the same value
1341
1341
// FIXME: Due to #50507 this overwrites the different values
@@ -1479,7 +1479,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1479
1479
}
1480
1480
1481
1481
/// Returns `true` if the global caches can be used.
1482
- fn can_use_global_caches ( & self , param_env : ty:: ParamEnv < ' tcx > ) -> bool {
1482
+ fn can_use_global_caches (
1483
+ & self ,
1484
+ param_env : ty:: ParamEnv < ' tcx > ,
1485
+ pred : ty:: PolyTraitPredicate < ' tcx > ,
1486
+ ) -> bool {
1483
1487
// If there are any inference variables in the `ParamEnv`, then we
1484
1488
// always use a cache local to this particular scope. Otherwise, we
1485
1489
// switch to a global cache.
@@ -1500,7 +1504,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1500
1504
1501
1505
// Avoid using the global cache when we're defining opaque types
1502
1506
// as their hidden type may impact the result of candidate selection.
1503
- if !self . infcx . defining_opaque_types ( ) . is_empty ( ) {
1507
+ //
1508
+ // HACK: This is still theoretically unsound. Goals can indirectly rely
1509
+ // on opaques in the defining scope, and it's easier to do so with TAIT.
1510
+ // However, if we disqualify *all* goals from being cached, perf suffers.
1511
+ // This is likely fixed by better caching in general in the new solver.
1512
+ // See: <https://github.com/rust-lang/rust/issues/132064>.
1513
+ if !self . infcx . defining_opaque_types ( ) . is_empty ( ) && pred. has_opaque_types ( ) {
1504
1514
return false ;
1505
1515
}
1506
1516
@@ -1523,7 +1533,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1523
1533
let tcx = self . tcx ( ) ;
1524
1534
let pred = cache_fresh_trait_pred. skip_binder ( ) ;
1525
1535
1526
- if self . can_use_global_caches ( param_env) {
1536
+ if self . can_use_global_caches ( param_env, cache_fresh_trait_pred ) {
1527
1537
if let Some ( res) = tcx. selection_cache . get ( & ( param_env, pred) , tcx) {
1528
1538
return Some ( res) ;
1529
1539
}
@@ -1580,7 +1590,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1580
1590
return ;
1581
1591
}
1582
1592
1583
- if self . can_use_global_caches ( param_env) {
1593
+ if self . can_use_global_caches ( param_env, cache_fresh_trait_pred ) {
1584
1594
if let Err ( Overflow ( OverflowError :: Canonical ) ) = candidate {
1585
1595
// Don't cache overflow globally; we only produce this in certain modes.
1586
1596
} else if !pred. has_infer ( ) && !candidate. has_infer ( ) {
@@ -1787,7 +1797,11 @@ enum DropVictim {
1787
1797
1788
1798
impl DropVictim {
1789
1799
fn drop_if ( should_drop : bool ) -> DropVictim {
1790
- if should_drop { DropVictim :: Yes } else { DropVictim :: No }
1800
+ if should_drop {
1801
+ DropVictim :: Yes
1802
+ } else {
1803
+ DropVictim :: No
1804
+ }
1791
1805
}
1792
1806
}
1793
1807
@@ -1891,7 +1905,11 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
1891
1905
( ObjectCandidate ( _) | ProjectionCandidate ( _) , ParamCandidate ( victim_cand) ) => {
1892
1906
// Prefer these to a global where-clause bound
1893
1907
// (see issue #50825).
1894
- if is_global ( * victim_cand) { DropVictim :: Yes } else { DropVictim :: No }
1908
+ if is_global ( * victim_cand) {
1909
+ DropVictim :: Yes
1910
+ } else {
1911
+ DropVictim :: No
1912
+ }
1895
1913
}
1896
1914
(
1897
1915
ImplCandidate ( _)
@@ -2450,9 +2468,11 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
2450
2468
} else {
2451
2469
// If this is an ill-formed auto/built-in trait, then synthesize
2452
2470
// new error args for the missing generics.
2453
- let err_args = ty:: GenericArgs :: extend_with_error ( tcx, trait_def_id, & [
2454
- normalized_ty. into ( ) ,
2455
- ] ) ;
2471
+ let err_args = ty:: GenericArgs :: extend_with_error (
2472
+ tcx,
2473
+ trait_def_id,
2474
+ & [ normalized_ty. into ( ) ] ,
2475
+ ) ;
2456
2476
ty:: TraitRef :: new_from_args ( tcx, trait_def_id, err_args)
2457
2477
} ;
2458
2478
@@ -3154,7 +3174,11 @@ impl<'o, 'tcx> TraitObligationStackList<'o, 'tcx> {
3154
3174
}
3155
3175
3156
3176
fn depth ( & self ) -> usize {
3157
- if let Some ( head) = self . head { head. depth } else { 0 }
3177
+ if let Some ( head) = self . head {
3178
+ head. depth
3179
+ } else {
3180
+ 0
3181
+ }
3158
3182
}
3159
3183
}
3160
3184
0 commit comments