@@ -2,6 +2,7 @@ use std::marker::PhantomData;
22use std:: mem;
33use std:: ops:: ControlFlow ;
44
5+ use rustc_data_structures:: fx:: FxHashSet ;
56use rustc_data_structures:: thinvec:: ExtractIf ;
67use rustc_hir:: def_id:: LocalDefId ;
78use rustc_infer:: infer:: InferCtxt ;
@@ -19,7 +20,7 @@ use rustc_next_trait_solver::solve::{
1920} ;
2021use rustc_span:: Span ;
2122use thin_vec:: ThinVec ;
22- use tracing:: instrument;
23+ use tracing:: { debug , instrument} ;
2324
2425use self :: derive_errors:: * ;
2526use super :: Certainty ;
@@ -57,6 +58,7 @@ pub struct FulfillmentCtxt<'tcx, E: 'tcx> {
5758
5859#[ derive( Default , Debug ) ]
5960struct ObligationStorage < ' tcx > {
61+ dedup : FxHashSet < ( ty:: ParamEnv < ' tcx > , ty:: Predicate < ' tcx > ) > ,
6062 /// Obligations which resulted in an overflow in fulfillment itself.
6163 ///
6264 /// We cannot eagerly return these as error so we instead store them here
@@ -67,7 +69,14 @@ struct ObligationStorage<'tcx> {
6769}
6870
6971impl < ' tcx > ObligationStorage < ' tcx > {
70- fn register (
72+ fn register ( & mut self , obligation : PredicateObligation < ' tcx > ) {
73+ if self . dedup . insert ( ( obligation. param_env , obligation. predicate ) ) {
74+ self . pending . push ( ( obligation, None ) ) ;
75+ } else {
76+ debug ! ( "skipping already registered obligation: {obligation:?}" ) ;
77+ }
78+ }
79+ fn readd_pending (
7180 & mut self ,
7281 obligation : PredicateObligation < ' tcx > ,
7382 stalled_on : Option < GoalStalledOn < TyCtxt < ' tcx > > > ,
@@ -161,7 +170,7 @@ where
161170 obligation : PredicateObligation < ' tcx > ,
162171 ) {
163172 assert_eq ! ( self . usable_in_snapshot, infcx. num_open_snapshots( ) ) ;
164- self . obligations . register ( obligation, None ) ;
173+ self . obligations . register ( obligation) ;
165174 }
166175
167176 fn collect_remaining_errors ( & mut self , infcx : & InferCtxt < ' tcx > ) -> Vec < E > {
@@ -205,7 +214,7 @@ where
205214 // Only goals proven via the trait solver should be region dependent.
206215 Certainty :: Yes => { }
207216 Certainty :: Maybe ( _) => {
208- self . obligations . register ( obligation, None ) ;
217+ self . obligations . readd_pending ( obligation, None ) ;
209218 }
210219 }
211220 continue ;
@@ -256,7 +265,7 @@ where
256265 infcx. push_hir_typeck_potentially_region_dependent_goal ( obligation) ;
257266 }
258267 }
259- Certainty :: Maybe ( _) => self . obligations . register ( obligation, stalled_on) ,
268+ Certainty :: Maybe ( _) => self . obligations . readd_pending ( obligation, stalled_on) ,
260269 }
261270 }
262271
0 commit comments