@@ -41,6 +41,7 @@ use rustc_middle::ty::fast_reject;
41
41
use rustc_middle:: ty:: print:: with_no_trimmed_paths;
42
42
use rustc_middle:: ty:: relate:: TypeRelation ;
43
43
use rustc_middle:: ty:: subst:: { GenericArgKind , Subst , SubstsRef } ;
44
+ use rustc_middle:: ty:: WithConstness ;
44
45
use rustc_middle:: ty:: { self , PolyProjectionPredicate , ToPolyTraitRef , ToPredicate } ;
45
46
use rustc_middle:: ty:: { Ty , TyCtxt , TypeFoldable } ;
46
47
use rustc_span:: symbol:: sym;
@@ -141,7 +142,7 @@ struct TraitObligationStack<'prev, 'tcx> {
141
142
142
143
/// The trait ref from `obligation` but "freshened" with the
143
144
/// selection-context's freshener. Used to check for recursion.
144
- fresh_trait_ref : ty:: PolyTraitRef < ' tcx > ,
145
+ fresh_trait_ref : ty:: ConstnessAnd < ty :: PolyTraitRef < ' tcx > > ,
145
146
146
147
/// Starts out equal to `depth` -- if, during evaluation, we
147
148
/// encounter a cycle, then we will set this flag to the minimum
@@ -804,7 +805,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
804
805
// terms of `Fn` etc, but we could probably make this more
805
806
// precise still.
806
807
let unbound_input_types =
807
- stack. fresh_trait_ref . skip_binder ( ) . substs . types ( ) . any ( |ty| ty. is_fresh ( ) ) ;
808
+ stack. fresh_trait_ref . value . skip_binder ( ) . substs . types ( ) . any ( |ty| ty. is_fresh ( ) ) ;
808
809
// This check was an imperfect workaround for a bug in the old
809
810
// intercrate mode; it should be removed when that goes away.
810
811
if unbound_input_types && self . intercrate {
@@ -925,7 +926,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
925
926
fn check_evaluation_cache (
926
927
& self ,
927
928
param_env : ty:: ParamEnv < ' tcx > ,
928
- trait_ref : ty:: PolyTraitRef < ' tcx > ,
929
+ trait_ref : ty:: ConstnessAnd < ty :: PolyTraitRef < ' tcx > > ,
929
930
) -> Option < EvaluationResult > {
930
931
let tcx = self . tcx ( ) ;
931
932
if self . can_use_global_caches ( param_env) {
@@ -939,7 +940,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
939
940
fn insert_evaluation_cache (
940
941
& mut self ,
941
942
param_env : ty:: ParamEnv < ' tcx > ,
942
- trait_ref : ty:: PolyTraitRef < ' tcx > ,
943
+ trait_ref : ty:: ConstnessAnd < ty :: PolyTraitRef < ' tcx > > ,
943
944
dep_node : DepNodeIndex ,
944
945
result : EvaluationResult ,
945
946
) {
@@ -1024,18 +1025,26 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1024
1025
let tcx = self . tcx ( ) ;
1025
1026
// Respect const trait obligations
1026
1027
if let hir:: Constness :: Const = obligation. predicate . skip_binder ( ) . constness {
1027
- match candidate {
1028
- // const impl
1029
- ImplCandidate ( def_id) if tcx. impl_constness ( def_id) == hir:: Constness :: Const => { }
1030
- // const param
1031
- ParamCandidate ( ty:: ConstnessAnd { constness : hir:: Constness :: Const , .. } ) => { }
1032
- // auto trait impl
1033
- AutoImplCandidate ( ..) => { }
1034
- // FIXME check if this is right, but this would allow Sized impls
1035
- // BuiltinCandidate { .. } => {}
1036
- _ => {
1037
- // reject all other types of candidates
1038
- return Err ( Unimplemented ) ;
1028
+ if Some ( obligation. predicate . skip_binder ( ) . trait_ref . def_id )
1029
+ != tcx. lang_items ( ) . sized_trait ( )
1030
+ // const Sized bounds are skipped
1031
+ {
1032
+ match candidate {
1033
+ // const impl
1034
+ ImplCandidate ( def_id)
1035
+ if tcx. impl_constness ( def_id) == hir:: Constness :: Const => { }
1036
+ // const param
1037
+ ParamCandidate ( ty:: ConstnessAnd {
1038
+ constness : hir:: Constness :: Const , ..
1039
+ } ) => { }
1040
+ // auto trait impl
1041
+ AutoImplCandidate ( ..) => { }
1042
+ // FIXME check if this is right, but this would allow Sized impls
1043
+ // BuiltinCandidate { .. } => {}
1044
+ _ => {
1045
+ // reject all other types of candidates
1046
+ return Err ( Unimplemented ) ;
1047
+ }
1039
1048
}
1040
1049
}
1041
1050
}
@@ -1121,13 +1130,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1121
1130
cache_fresh_trait_pred : ty:: PolyTraitPredicate < ' tcx > ,
1122
1131
) -> Option < SelectionResult < ' tcx , SelectionCandidate < ' tcx > > > {
1123
1132
let tcx = self . tcx ( ) ;
1124
- let trait_ref = & cache_fresh_trait_pred. skip_binder ( ) . trait_ref ;
1133
+ let pred = & cache_fresh_trait_pred. skip_binder ( ) ;
1134
+ let trait_ref = pred. trait_ref ;
1125
1135
if self . can_use_global_caches ( param_env) {
1126
- if let Some ( res) = tcx. selection_cache . get ( & param_env. and ( * trait_ref) , tcx) {
1136
+ if let Some ( res) = tcx
1137
+ . selection_cache
1138
+ . get ( & param_env. and ( trait_ref) . with_constness ( pred. constness ) , tcx)
1139
+ {
1127
1140
return Some ( res) ;
1128
1141
}
1129
1142
}
1130
- self . infcx . selection_cache . get ( & param_env. and ( * trait_ref) , tcx)
1143
+ self . infcx
1144
+ . selection_cache
1145
+ . get ( & param_env. and ( trait_ref) . with_constness ( pred. constness ) , tcx)
1131
1146
}
1132
1147
1133
1148
/// Determines whether can we safely cache the result
@@ -1164,7 +1179,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1164
1179
candidate : SelectionResult < ' tcx , SelectionCandidate < ' tcx > > ,
1165
1180
) {
1166
1181
let tcx = self . tcx ( ) ;
1167
- let trait_ref = cache_fresh_trait_pred. skip_binder ( ) . trait_ref ;
1182
+ let pred = cache_fresh_trait_pred. skip_binder ( ) ;
1183
+ let trait_ref = pred. trait_ref ;
1168
1184
1169
1185
if !self . can_cache_candidate ( & candidate) {
1170
1186
debug ! ( ?trait_ref, ?candidate, "insert_candidate_cache - candidate is not cacheable" ) ;
@@ -1178,14 +1194,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1178
1194
if !candidate. needs_infer ( ) {
1179
1195
debug ! ( ?trait_ref, ?candidate, "insert_candidate_cache global" ) ;
1180
1196
// This may overwrite the cache with the same value.
1181
- tcx. selection_cache . insert ( param_env. and ( trait_ref) , dep_node, candidate) ;
1197
+ tcx. selection_cache . insert (
1198
+ param_env. and ( trait_ref) . with_constness ( pred. constness ) ,
1199
+ dep_node,
1200
+ candidate,
1201
+ ) ;
1182
1202
return ;
1183
1203
}
1184
1204
}
1185
1205
}
1186
1206
1187
1207
debug ! ( ?trait_ref, ?candidate, "insert_candidate_cache local" ) ;
1188
- self . infcx . selection_cache . insert ( param_env. and ( trait_ref) , dep_node, candidate) ;
1208
+ self . infcx . selection_cache . insert (
1209
+ param_env. and ( trait_ref) . with_constness ( pred. constness ) ,
1210
+ dep_node,
1211
+ candidate,
1212
+ ) ;
1189
1213
}
1190
1214
1191
1215
/// Matches a predicate against the bounds of its self type.
@@ -2015,8 +2039,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
2015
2039
2016
2040
fn match_fresh_trait_refs (
2017
2041
& self ,
2018
- previous : ty:: PolyTraitRef < ' tcx > ,
2019
- current : ty:: PolyTraitRef < ' tcx > ,
2042
+ previous : ty:: ConstnessAnd < ty :: PolyTraitRef < ' tcx > > ,
2043
+ current : ty:: ConstnessAnd < ty :: PolyTraitRef < ' tcx > > ,
2020
2044
param_env : ty:: ParamEnv < ' tcx > ,
2021
2045
) -> bool {
2022
2046
let mut matcher = ty:: _match:: Match :: new ( self . tcx ( ) , param_env) ;
@@ -2028,8 +2052,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
2028
2052
previous_stack : TraitObligationStackList < ' o , ' tcx > ,
2029
2053
obligation : & ' o TraitObligation < ' tcx > ,
2030
2054
) -> TraitObligationStack < ' o , ' tcx > {
2031
- let fresh_trait_ref =
2032
- obligation. predicate . to_poly_trait_ref ( ) . fold_with ( & mut self . freshener ) ;
2055
+ let fresh_trait_ref = obligation
2056
+ . predicate
2057
+ . to_poly_trait_ref ( )
2058
+ . fold_with ( & mut self . freshener )
2059
+ . with_constness ( obligation. predicate . skip_binder ( ) . constness ) ;
2033
2060
2034
2061
let dfn = previous_stack. cache . next_dfn ( ) ;
2035
2062
let depth = previous_stack. depth ( ) + 1 ;
@@ -2308,7 +2335,7 @@ struct ProvisionalEvaluationCache<'tcx> {
2308
2335
/// - then we determine that `E` is in error -- we will then clear
2309
2336
/// all cache values whose DFN is >= 4 -- in this case, that
2310
2337
/// means the cached value for `F`.
2311
- map : RefCell < FxHashMap < ty:: PolyTraitRef < ' tcx > , ProvisionalEvaluation > > ,
2338
+ map : RefCell < FxHashMap < ty:: ConstnessAnd < ty :: PolyTraitRef < ' tcx > > , ProvisionalEvaluation > > ,
2312
2339
}
2313
2340
2314
2341
/// A cache value for the provisional cache: contains the depth-first
@@ -2340,7 +2367,7 @@ impl<'tcx> ProvisionalEvaluationCache<'tcx> {
2340
2367
/// `reached_depth` (from the returned value).
2341
2368
fn get_provisional (
2342
2369
& self ,
2343
- fresh_trait_ref : ty:: PolyTraitRef < ' tcx > ,
2370
+ fresh_trait_ref : ty:: ConstnessAnd < ty :: PolyTraitRef < ' tcx > > ,
2344
2371
) -> Option < ProvisionalEvaluation > {
2345
2372
debug ! (
2346
2373
?fresh_trait_ref,
@@ -2358,7 +2385,7 @@ impl<'tcx> ProvisionalEvaluationCache<'tcx> {
2358
2385
& self ,
2359
2386
from_dfn : usize ,
2360
2387
reached_depth : usize ,
2361
- fresh_trait_ref : ty:: PolyTraitRef < ' tcx > ,
2388
+ fresh_trait_ref : ty:: ConstnessAnd < ty :: PolyTraitRef < ' tcx > > ,
2362
2389
result : EvaluationResult ,
2363
2390
) {
2364
2391
debug ! ( ?from_dfn, ?fresh_trait_ref, ?result, "insert_provisional" ) ;
@@ -2436,7 +2463,7 @@ impl<'tcx> ProvisionalEvaluationCache<'tcx> {
2436
2463
fn on_completion (
2437
2464
& self ,
2438
2465
dfn : usize ,
2439
- mut op : impl FnMut ( ty:: PolyTraitRef < ' tcx > , EvaluationResult ) ,
2466
+ mut op : impl FnMut ( ty:: ConstnessAnd < ty :: PolyTraitRef < ' tcx > > , EvaluationResult ) ,
2440
2467
) {
2441
2468
debug ! ( ?dfn, "on_completion" ) ;
2442
2469
0 commit comments