11use std:: assert_matches:: assert_matches;
22use std:: fmt:: Debug ;
3- use std:: marker:: PhantomData ;
43
54use rustc_data_structures:: stack:: ensure_sufficient_stack;
65use rustc_infer:: infer:: InferCtxt ;
6059/// entered before passing `value` to the function. This is currently needed for
6160/// `normalize_erasing_regions`, which skips binders as it walks through a type.
6261///
63- /// TODO: doc
62+ /// This returns a set of stalled obligations if the typing mode of the underlying infcx
63+ /// has any stalled coroutine def ids.
6464pub fn deeply_normalize_with_skipped_universes_and_ambiguous_goals < ' tcx , T , E > (
6565 at : At < ' _ , ' tcx > ,
6666 value : T ,
@@ -72,24 +72,18 @@ where
7272{
7373 let fulfill_cx = FulfillmentCtxt :: new ( at. infcx ) ;
7474 let mut folder =
75- NormalizationFolder { at, fulfill_cx, depth : 0 , universes, _errors : PhantomData } ;
75+ NormalizationFolder { at, fulfill_cx, depth : 0 , universes, stalled_goals : vec ! [ ] } ;
7676 let value = value. try_fold_with ( & mut folder) ?;
77- let goals = folder
78- . fulfill_cx
79- . drain_stalled_obligations_for_coroutines ( at. infcx )
80- . into_iter ( )
81- . map ( |obl| obl. as_goal ( ) )
82- . collect ( ) ;
8377 let errors = folder. fulfill_cx . select_all_or_error ( at. infcx ) ;
84- if errors. is_empty ( ) { Ok ( ( value, goals ) ) } else { Err ( errors) }
78+ if errors. is_empty ( ) { Ok ( ( value, folder . stalled_goals ) ) } else { Err ( errors) }
8579}
8680
8781struct NormalizationFolder < ' me , ' tcx , E > {
8882 at : At < ' me , ' tcx > ,
8983 fulfill_cx : FulfillmentCtxt < ' tcx , E > ,
9084 depth : usize ,
9185 universes : Vec < Option < UniverseIndex > > ,
92- _errors : PhantomData < E > ,
86+ stalled_goals : Vec < Goal < ' tcx , ty :: Predicate < ' tcx > > > ,
9387}
9488
9589impl < ' tcx , E > NormalizationFolder < ' _ , ' tcx , E >
@@ -130,10 +124,7 @@ where
130124 ) ;
131125
132126 self . fulfill_cx . register_predicate_obligation ( infcx, obligation) ;
133- let errors = self . fulfill_cx . select_where_possible ( infcx) ;
134- if !errors. is_empty ( ) {
135- return Err ( errors) ;
136- }
127+ self . select_all_and_stall_coroutine_predicates ( ) ?;
137128
138129 // Alias is guaranteed to be fully structurally resolved,
139130 // so we can super fold here.
@@ -184,6 +175,27 @@ where
184175 self . depth -= 1 ;
185176 Ok ( result)
186177 }
178+
179+ fn select_all_and_stall_coroutine_predicates ( & mut self ) -> Result < ( ) , Vec < E > > {
180+ let errors = self . fulfill_cx . select_where_possible ( self . at . infcx ) ;
181+ if !errors. is_empty ( ) {
182+ return Err ( errors) ;
183+ }
184+
185+ self . stalled_goals . extend (
186+ self . fulfill_cx
187+ . drain_stalled_obligations_for_coroutines ( self . at . infcx )
188+ . into_iter ( )
189+ . map ( |obl| obl. as_goal ( ) ) ,
190+ ) ;
191+
192+ let errors = self . fulfill_cx . collect_remaining_errors ( self . at . infcx ) ;
193+ if !errors. is_empty ( ) {
194+ return Err ( errors) ;
195+ }
196+
197+ Ok ( ( ) )
198+ }
187199}
188200
189201impl < ' tcx , E > FallibleTypeFolder < TyCtxt < ' tcx > > for NormalizationFolder < ' _ , ' tcx , E >
0 commit comments