@@ -7,6 +7,7 @@ use crate::errors::UnableToConstructConstantValue;
7
7
use crate :: infer:: region_constraints:: { Constraint , RegionConstraintData } ;
8
8
use crate :: infer:: InferCtxt ;
9
9
use crate :: traits:: project:: ProjectAndUnifyResult ;
10
+ use rustc_middle:: infer:: canonical:: { Canonical , OriginalQueryValues } ;
10
11
use rustc_middle:: mir:: interpret:: ErrorHandled ;
11
12
use rustc_middle:: ty:: fold:: { TypeFolder , TypeSuperFoldable } ;
12
13
use rustc_middle:: ty:: visit:: TypeVisitable ;
@@ -160,7 +161,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
160
161
// SomeTrait' doesn't hold, then we don't need to care about the 'SomeItem = K'
161
162
//
162
163
// 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
164
165
// intermediate types we create bound to the 'tcx lifetime, rather than needing to lift
165
166
// them between calls.
166
167
//
@@ -233,7 +234,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
233
234
impl < ' tcx > AutoTraitFinder < ' tcx > {
234
235
/// The core logic responsible for computing the bounds for our synthesized impl.
235
236
///
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
237
238
/// `FulfillmentContext`, we recursively select the nested obligations of predicates we
238
239
/// encounter. However, whenever we encounter an `UnimplementedError` involving a type
239
240
/// parameter, we add it to our `ParamEnv`. Since our goal is to determine when a particular
@@ -277,7 +278,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
277
278
ty : Ty < ' tcx > ,
278
279
param_env : ty:: ParamEnv < ' tcx > ,
279
280
user_env : ty:: ParamEnv < ' tcx > ,
280
- fresh_preds : & mut FxHashSet < ty:: Predicate < ' tcx > > ,
281
+ deduplicated_preds : & mut FxHashSet < Canonical < ' tcx , ty:: Predicate < ' tcx > > > ,
281
282
only_projections : bool ,
282
283
) -> Option < ( ty:: ParamEnv < ' tcx > , ty:: ParamEnv < ' tcx > ) > {
283
284
let tcx = infcx. tcx ;
@@ -286,10 +287,13 @@ impl<'tcx> AutoTraitFinder<'tcx> {
286
287
// that are already in the `ParamEnv` (modulo regions): we already
287
288
// know that they must hold.
288
289
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
+ ) ;
290
294
}
291
295
292
- let mut select = SelectionContext :: new ( & infcx) ;
296
+ let mut selcx = SelectionContext :: new ( & infcx) ;
293
297
294
298
let mut already_visited = FxHashSet :: default ( ) ;
295
299
let mut predicates = VecDeque :: new ( ) ;
@@ -320,7 +324,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
320
324
// get rid of any inference variables.
321
325
let obligation =
322
326
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) ;
324
328
325
329
match result {
326
330
Ok ( Some ( ref impl_source) ) => {
@@ -348,9 +352,9 @@ impl<'tcx> AutoTraitFinder<'tcx> {
348
352
ty,
349
353
obligations,
350
354
& mut user_computed_preds,
351
- fresh_preds ,
355
+ deduplicated_preds ,
352
356
& mut predicates,
353
- & mut select ,
357
+ & mut selcx ,
354
358
only_projections,
355
359
) {
356
360
return None ;
@@ -403,7 +407,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
403
407
}
404
408
405
409
/// 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`,
407
411
/// progressively building a `ParamEnv` based on the results we get.
408
412
/// However, our usage of `SelectionContext` differs from its normal use within the compiler,
409
413
/// in that we capture and re-reprocess predicates from `Unimplemented` errors.
@@ -624,19 +628,22 @@ impl<'tcx> AutoTraitFinder<'tcx> {
624
628
ty : Ty < ' _ > ,
625
629
nested : impl Iterator < Item = Obligation < ' tcx , ty:: Predicate < ' tcx > > > ,
626
630
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 > > > ,
628
632
predicates : & mut VecDeque < ty:: PolyTraitPredicate < ' tcx > > ,
629
- select : & mut SelectionContext < ' _ , ' tcx > ,
633
+ selcx : & mut SelectionContext < ' _ , ' tcx > ,
630
634
only_projections : bool ,
631
635
) -> bool {
632
636
let dummy_cause = ObligationCause :: dummy ( ) ;
633
637
634
638
for obligation in nested {
635
639
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
+ ) ) ;
637
644
638
645
// 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 ) ;
640
647
641
648
// We only add a predicate as a user-displayable bound if
642
649
// it involves a generic parameter, and doesn't contain
@@ -744,7 +751,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
744
751
// and turn them into an explicit negative impl for our type.
745
752
debug ! ( "Projecting and unifying projection predicate {:?}" , predicate) ;
746
753
747
- match project:: poly_project_and_unify_type ( select , & obligation. with ( p) ) {
754
+ match project:: poly_project_and_unify_type ( selcx , & obligation. with ( p) ) {
748
755
ProjectAndUnifyResult :: MismatchedProjectionTypes ( e) => {
749
756
debug ! (
750
757
"evaluate_nested_obligations: Unable to unify predicate \
@@ -767,9 +774,9 @@ impl<'tcx> AutoTraitFinder<'tcx> {
767
774
ty,
768
775
v. into_iter ( ) ,
769
776
computed_preds,
770
- fresh_preds ,
777
+ deduplicated_preds ,
771
778
predicates,
772
- select ,
779
+ selcx ,
773
780
only_projections,
774
781
) {
775
782
return false ;
@@ -792,7 +799,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
792
799
}
793
800
ty:: PredicateKind :: RegionOutlives ( binder) => {
794
801
let binder = bound_predicate. rebind ( binder) ;
795
- select . infcx ( ) . region_outlives_predicate ( & dummy_cause, binder)
802
+ selcx . infcx ( ) . region_outlives_predicate ( & dummy_cause, binder)
796
803
}
797
804
ty:: PredicateKind :: TypeOutlives ( binder) => {
798
805
let binder = bound_predicate. rebind ( binder) ;
@@ -801,14 +808,14 @@ impl<'tcx> AutoTraitFinder<'tcx> {
801
808
binder. map_bound_ref ( |pred| pred. 0 ) . no_bound_vars ( ) ,
802
809
) {
803
810
( None , Some ( t_a) ) => {
804
- select . infcx ( ) . register_region_obligation_with_cause (
811
+ selcx . infcx ( ) . register_region_obligation_with_cause (
805
812
t_a,
806
- select . infcx ( ) . tcx . lifetimes . re_static ,
813
+ selcx . infcx ( ) . tcx . lifetimes . re_static ,
807
814
& dummy_cause,
808
815
) ;
809
816
}
810
817
( Some ( ty:: OutlivesPredicate ( t_a, r_b) ) , _) => {
811
- select . infcx ( ) . register_region_obligation_with_cause (
818
+ selcx . infcx ( ) . register_region_obligation_with_cause (
812
819
t_a,
813
820
r_b,
814
821
& dummy_cause,
@@ -820,13 +827,13 @@ impl<'tcx> AutoTraitFinder<'tcx> {
820
827
ty:: PredicateKind :: ConstEquate ( c1, c2) => {
821
828
let evaluate = |c : ty:: Const < ' tcx > | {
822
829
if let ty:: ConstKind :: Unevaluated ( unevaluated) = c. kind ( ) {
823
- match select . infcx ( ) . const_eval_resolve (
830
+ match selcx . infcx ( ) . const_eval_resolve (
824
831
obligation. param_env ,
825
832
unevaluated,
826
833
Some ( obligation. cause . span ) ,
827
834
) {
828
835
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 ( ) ) )
830
837
}
831
838
Ok ( None ) => {
832
839
let tcx = self . tcx ;
@@ -847,7 +854,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
847
854
848
855
match ( evaluate ( c1) , evaluate ( c2) ) {
849
856
( Ok ( c1) , Ok ( c2) ) => {
850
- match select
857
+ match selcx
851
858
. infcx ( )
852
859
. at ( & obligation. cause , obligation. param_env )
853
860
. eq ( c1, c2)
@@ -874,14 +881,6 @@ impl<'tcx> AutoTraitFinder<'tcx> {
874
881
}
875
882
true
876
883
}
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
- }
885
884
}
886
885
887
886
// Replaces all ReVars in a type with ty::Region's, using the provided map
0 commit comments