@@ -41,6 +41,7 @@ use rustc_middle::ty::fast_reject;
4141use rustc_middle:: ty:: print:: with_no_trimmed_paths;
4242use rustc_middle:: ty:: relate:: TypeRelation ;
4343use rustc_middle:: ty:: subst:: { GenericArgKind , Subst , SubstsRef } ;
44+ use rustc_middle:: ty:: WithConstness ;
4445use rustc_middle:: ty:: { self , PolyProjectionPredicate , ToPolyTraitRef , ToPredicate } ;
4546use rustc_middle:: ty:: { Ty , TyCtxt , TypeFoldable } ;
4647use rustc_span:: symbol:: sym;
@@ -141,7 +142,7 @@ struct TraitObligationStack<'prev, 'tcx> {
141142
142143 /// The trait ref from `obligation` but "freshened" with the
143144 /// 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 > > ,
145146
146147 /// Starts out equal to `depth` -- if, during evaluation, we
147148 /// encounter a cycle, then we will set this flag to the minimum
@@ -804,7 +805,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
804805 // terms of `Fn` etc, but we could probably make this more
805806 // precise still.
806807 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 ( ) ) ;
808809 // This check was an imperfect workaround for a bug in the old
809810 // intercrate mode; it should be removed when that goes away.
810811 if unbound_input_types && self . intercrate {
@@ -925,7 +926,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
925926 fn check_evaluation_cache (
926927 & self ,
927928 param_env : ty:: ParamEnv < ' tcx > ,
928- trait_ref : ty:: PolyTraitRef < ' tcx > ,
929+ trait_ref : ty:: ConstnessAnd < ty :: PolyTraitRef < ' tcx > > ,
929930 ) -> Option < EvaluationResult > {
930931 let tcx = self . tcx ( ) ;
931932 if self . can_use_global_caches ( param_env) {
@@ -939,7 +940,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
939940 fn insert_evaluation_cache (
940941 & mut self ,
941942 param_env : ty:: ParamEnv < ' tcx > ,
942- trait_ref : ty:: PolyTraitRef < ' tcx > ,
943+ trait_ref : ty:: ConstnessAnd < ty :: PolyTraitRef < ' tcx > > ,
943944 dep_node : DepNodeIndex ,
944945 result : EvaluationResult ,
945946 ) {
@@ -1024,18 +1025,26 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
10241025 let tcx = self . tcx ( ) ;
10251026 // Respect const trait obligations
10261027 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+ }
10391048 }
10401049 }
10411050 }
@@ -1121,13 +1130,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11211130 cache_fresh_trait_pred : ty:: PolyTraitPredicate < ' tcx > ,
11221131 ) -> Option < SelectionResult < ' tcx , SelectionCandidate < ' tcx > > > {
11231132 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 ;
11251135 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+ {
11271140 return Some ( res) ;
11281141 }
11291142 }
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)
11311146 }
11321147
11331148 /// Determines whether can we safely cache the result
@@ -1164,7 +1179,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11641179 candidate : SelectionResult < ' tcx , SelectionCandidate < ' tcx > > ,
11651180 ) {
11661181 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 ;
11681184
11691185 if !self . can_cache_candidate ( & candidate) {
11701186 debug ! ( ?trait_ref, ?candidate, "insert_candidate_cache - candidate is not cacheable" ) ;
@@ -1178,14 +1194,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11781194 if !candidate. needs_infer ( ) {
11791195 debug ! ( ?trait_ref, ?candidate, "insert_candidate_cache global" ) ;
11801196 // 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+ ) ;
11821202 return ;
11831203 }
11841204 }
11851205 }
11861206
11871207 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+ ) ;
11891213 }
11901214
11911215 /// Matches a predicate against the bounds of its self type.
@@ -2015,8 +2039,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
20152039
20162040 fn match_fresh_trait_refs (
20172041 & 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 > > ,
20202044 param_env : ty:: ParamEnv < ' tcx > ,
20212045 ) -> bool {
20222046 let mut matcher = ty:: _match:: Match :: new ( self . tcx ( ) , param_env) ;
@@ -2028,8 +2052,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
20282052 previous_stack : TraitObligationStackList < ' o , ' tcx > ,
20292053 obligation : & ' o TraitObligation < ' tcx > ,
20302054 ) -> 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 ) ;
20332060
20342061 let dfn = previous_stack. cache . next_dfn ( ) ;
20352062 let depth = previous_stack. depth ( ) + 1 ;
@@ -2308,7 +2335,7 @@ struct ProvisionalEvaluationCache<'tcx> {
23082335 /// - then we determine that `E` is in error -- we will then clear
23092336 /// all cache values whose DFN is >= 4 -- in this case, that
23102337 /// means the cached value for `F`.
2311- map : RefCell < FxHashMap < ty:: PolyTraitRef < ' tcx > , ProvisionalEvaluation > > ,
2338+ map : RefCell < FxHashMap < ty:: ConstnessAnd < ty :: PolyTraitRef < ' tcx > > , ProvisionalEvaluation > > ,
23122339}
23132340
23142341/// A cache value for the provisional cache: contains the depth-first
@@ -2340,7 +2367,7 @@ impl<'tcx> ProvisionalEvaluationCache<'tcx> {
23402367 /// `reached_depth` (from the returned value).
23412368 fn get_provisional (
23422369 & self ,
2343- fresh_trait_ref : ty:: PolyTraitRef < ' tcx > ,
2370+ fresh_trait_ref : ty:: ConstnessAnd < ty :: PolyTraitRef < ' tcx > > ,
23442371 ) -> Option < ProvisionalEvaluation > {
23452372 debug ! (
23462373 ?fresh_trait_ref,
@@ -2358,7 +2385,7 @@ impl<'tcx> ProvisionalEvaluationCache<'tcx> {
23582385 & self ,
23592386 from_dfn : usize ,
23602387 reached_depth : usize ,
2361- fresh_trait_ref : ty:: PolyTraitRef < ' tcx > ,
2388+ fresh_trait_ref : ty:: ConstnessAnd < ty :: PolyTraitRef < ' tcx > > ,
23622389 result : EvaluationResult ,
23632390 ) {
23642391 debug ! ( ?from_dfn, ?fresh_trait_ref, ?result, "insert_provisional" ) ;
@@ -2436,7 +2463,7 @@ impl<'tcx> ProvisionalEvaluationCache<'tcx> {
24362463 fn on_completion (
24372464 & self ,
24382465 dfn : usize ,
2439- mut op : impl FnMut ( ty:: PolyTraitRef < ' tcx > , EvaluationResult ) ,
2466+ mut op : impl FnMut ( ty:: ConstnessAnd < ty :: PolyTraitRef < ' tcx > > , EvaluationResult ) ,
24402467 ) {
24412468 debug ! ( ?dfn, "on_completion" ) ;
24422469
0 commit comments