@@ -7,6 +7,7 @@ use crate::errors::UnableToConstructConstantValue;
77use crate :: infer:: region_constraints:: { Constraint , RegionConstraintData } ;
88use crate :: infer:: InferCtxt ;
99use crate :: traits:: project:: ProjectAndUnifyResult ;
10+ use rustc_middle:: infer:: canonical:: { Canonical , OriginalQueryValues } ;
1011use rustc_middle:: mir:: interpret:: ErrorHandled ;
1112use rustc_middle:: ty:: fold:: { TypeFolder , TypeSuperFoldable } ;
1213use rustc_middle:: ty:: visit:: TypeVisitable ;
@@ -160,7 +161,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
160161 // SomeTrait' doesn't hold, then we don't need to care about the 'SomeItem = K'
161162 //
162163 // We fix the first assumption by manually clearing out all of the InferCtxt's caches
163- // in between calls to SelectionContext .select. This allows us to keep all of the
164+ // in between calls to `selcx .select` . This allows us to keep all of the
164165 // intermediate types we create bound to the 'tcx lifetime, rather than needing to lift
165166 // them between calls.
166167 //
@@ -233,7 +234,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
233234impl < ' tcx > AutoTraitFinder < ' tcx > {
234235 /// The core logic responsible for computing the bounds for our synthesized impl.
235236 ///
236- /// To calculate the bounds, we call `SelectionContext .select` in a loop. Like
237+ /// To calculate the bounds, we call `selcx .select` in a loop. Like
237238 /// `FulfillmentContext`, we recursively select the nested obligations of predicates we
238239 /// encounter. However, whenever we encounter an `UnimplementedError` involving a type
239240 /// parameter, we add it to our `ParamEnv`. Since our goal is to determine when a particular
@@ -277,7 +278,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
277278 ty : Ty < ' tcx > ,
278279 param_env : ty:: ParamEnv < ' tcx > ,
279280 user_env : ty:: ParamEnv < ' tcx > ,
280- fresh_preds : & mut FxHashSet < ty:: Predicate < ' tcx > > ,
281+ deduplicated_preds : & mut FxHashSet < Canonical < ' tcx , ty:: Predicate < ' tcx > > > ,
281282 only_projections : bool ,
282283 ) -> Option < ( ty:: ParamEnv < ' tcx > , ty:: ParamEnv < ' tcx > ) > {
283284 let tcx = infcx. tcx ;
@@ -286,10 +287,13 @@ impl<'tcx> AutoTraitFinder<'tcx> {
286287 // that are already in the `ParamEnv` (modulo regions): we already
287288 // know that they must hold.
288289 for predicate in param_env. caller_bounds ( ) {
289- fresh_preds. insert ( self . clean_pred ( infcx, predicate) ) ;
290+ deduplicated_preds. insert (
291+ infcx
292+ . canonicalize_query_keep_static ( predicate, & mut OriginalQueryValues :: default ( ) ) ,
293+ ) ;
290294 }
291295
292- let mut select = SelectionContext :: new ( & infcx) ;
296+ let mut selcx = SelectionContext :: new ( & infcx) ;
293297
294298 let mut already_visited = FxHashSet :: default ( ) ;
295299 let mut predicates = VecDeque :: new ( ) ;
@@ -320,7 +324,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
320324 // get rid of any inference variables.
321325 let obligation =
322326 infcx. resolve_vars_if_possible ( Obligation :: new ( dummy_cause. clone ( ) , new_env, pred) ) ;
323- let result = select . select ( & obligation) ;
327+ let result = selcx . select ( & obligation) ;
324328
325329 match result {
326330 Ok ( Some ( ref impl_source) ) => {
@@ -348,9 +352,9 @@ impl<'tcx> AutoTraitFinder<'tcx> {
348352 ty,
349353 obligations,
350354 & mut user_computed_preds,
351- fresh_preds ,
355+ deduplicated_preds ,
352356 & mut predicates,
353- & mut select ,
357+ & mut selcx ,
354358 only_projections,
355359 ) {
356360 return None ;
@@ -403,7 +407,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
403407 }
404408
405409 /// This method is designed to work around the following issue:
406- /// When we compute auto trait bounds, we repeatedly call `SelectionContext .select`,
410+ /// When we compute auto trait bounds, we repeatedly call `selcx .select`,
407411 /// progressively building a `ParamEnv` based on the results we get.
408412 /// However, our usage of `SelectionContext` differs from its normal use within the compiler,
409413 /// in that we capture and re-reprocess predicates from `Unimplemented` errors.
@@ -624,19 +628,22 @@ impl<'tcx> AutoTraitFinder<'tcx> {
624628 ty : Ty < ' _ > ,
625629 nested : impl Iterator < Item = Obligation < ' tcx , ty:: Predicate < ' tcx > > > ,
626630 computed_preds : & mut FxHashSet < ty:: Predicate < ' tcx > > ,
627- fresh_preds : & mut FxHashSet < ty:: Predicate < ' tcx > > ,
631+ deduplicated_preds : & mut FxHashSet < Canonical < ' tcx , ty:: Predicate < ' tcx > > > ,
628632 predicates : & mut VecDeque < ty:: PolyTraitPredicate < ' tcx > > ,
629- select : & mut SelectionContext < ' _ , ' tcx > ,
633+ selcx : & mut SelectionContext < ' _ , ' tcx > ,
630634 only_projections : bool ,
631635 ) -> bool {
632636 let dummy_cause = ObligationCause :: dummy ( ) ;
633637
634638 for obligation in nested {
635639 let is_new_pred =
636- fresh_preds. insert ( self . clean_pred ( select. infcx ( ) , obligation. predicate ) ) ;
640+ deduplicated_preds. insert ( selcx. infcx ( ) . canonicalize_query_keep_static (
641+ obligation. predicate ,
642+ & mut OriginalQueryValues :: default ( ) ,
643+ ) ) ;
637644
638645 // Resolve any inference variables that we can, to help selection succeed
639- let predicate = select . infcx ( ) . resolve_vars_if_possible ( obligation. predicate ) ;
646+ let predicate = selcx . infcx ( ) . resolve_vars_if_possible ( obligation. predicate ) ;
640647
641648 // We only add a predicate as a user-displayable bound if
642649 // it involves a generic parameter, and doesn't contain
@@ -744,7 +751,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
744751 // and turn them into an explicit negative impl for our type.
745752 debug ! ( "Projecting and unifying projection predicate {:?}" , predicate) ;
746753
747- match project:: poly_project_and_unify_type ( select , & obligation. with ( p) ) {
754+ match project:: poly_project_and_unify_type ( selcx , & obligation. with ( p) ) {
748755 ProjectAndUnifyResult :: MismatchedProjectionTypes ( e) => {
749756 debug ! (
750757 "evaluate_nested_obligations: Unable to unify predicate \
@@ -767,9 +774,9 @@ impl<'tcx> AutoTraitFinder<'tcx> {
767774 ty,
768775 v. into_iter ( ) ,
769776 computed_preds,
770- fresh_preds ,
777+ deduplicated_preds ,
771778 predicates,
772- select ,
779+ selcx ,
773780 only_projections,
774781 ) {
775782 return false ;
@@ -792,7 +799,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
792799 }
793800 ty:: PredicateKind :: RegionOutlives ( binder) => {
794801 let binder = bound_predicate. rebind ( binder) ;
795- select . infcx ( ) . region_outlives_predicate ( & dummy_cause, binder)
802+ selcx . infcx ( ) . region_outlives_predicate ( & dummy_cause, binder)
796803 }
797804 ty:: PredicateKind :: TypeOutlives ( binder) => {
798805 let binder = bound_predicate. rebind ( binder) ;
@@ -801,14 +808,14 @@ impl<'tcx> AutoTraitFinder<'tcx> {
801808 binder. map_bound_ref ( |pred| pred. 0 ) . no_bound_vars ( ) ,
802809 ) {
803810 ( None , Some ( t_a) ) => {
804- select . infcx ( ) . register_region_obligation_with_cause (
811+ selcx . infcx ( ) . register_region_obligation_with_cause (
805812 t_a,
806- select . infcx ( ) . tcx . lifetimes . re_static ,
813+ selcx . infcx ( ) . tcx . lifetimes . re_static ,
807814 & dummy_cause,
808815 ) ;
809816 }
810817 ( Some ( ty:: OutlivesPredicate ( t_a, r_b) ) , _) => {
811- select . infcx ( ) . register_region_obligation_with_cause (
818+ selcx . infcx ( ) . register_region_obligation_with_cause (
812819 t_a,
813820 r_b,
814821 & dummy_cause,
@@ -820,13 +827,13 @@ impl<'tcx> AutoTraitFinder<'tcx> {
820827 ty:: PredicateKind :: ConstEquate ( c1, c2) => {
821828 let evaluate = |c : ty:: Const < ' tcx > | {
822829 if let ty:: ConstKind :: Unevaluated ( unevaluated) = c. kind ( ) {
823- match select . infcx ( ) . const_eval_resolve (
830+ match selcx . infcx ( ) . const_eval_resolve (
824831 obligation. param_env ,
825832 unevaluated,
826833 Some ( obligation. cause . span ) ,
827834 ) {
828835 Ok ( Some ( valtree) ) => {
829- Ok ( ty:: Const :: from_value ( select . tcx ( ) , valtree, c. ty ( ) ) )
836+ Ok ( ty:: Const :: from_value ( selcx . tcx ( ) , valtree, c. ty ( ) ) )
830837 }
831838 Ok ( None ) => {
832839 let tcx = self . tcx ;
@@ -847,7 +854,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
847854
848855 match ( evaluate ( c1) , evaluate ( c2) ) {
849856 ( Ok ( c1) , Ok ( c2) ) => {
850- match select
857+ match selcx
851858 . infcx ( )
852859 . at ( & obligation. cause , obligation. param_env )
853860 . eq ( c1, c2)
@@ -874,14 +881,6 @@ impl<'tcx> AutoTraitFinder<'tcx> {
874881 }
875882 true
876883 }
877-
878- pub fn clean_pred (
879- & self ,
880- infcx : & InferCtxt < ' _ , ' tcx > ,
881- p : ty:: Predicate < ' tcx > ,
882- ) -> ty:: Predicate < ' tcx > {
883- infcx. freshen ( p)
884- }
885884}
886885
887886// Replaces all ReVars in a type with ty::Region's, using the provided map
0 commit comments