@@ -159,53 +159,70 @@ where
159159 . 0 ) ;
160160 }
161161
162+ let mut error_info = None ;
162163 let mut region_constraints = QueryRegionConstraints :: default ( ) ;
163- let ( output, error_info, mut obligations, _) =
164- Q :: fully_perform_into ( self , infcx, & mut region_constraints, span) . map_err ( |_| {
165- infcx. dcx ( ) . span_delayed_bug ( span, format ! ( "error performing {self:?}" ) )
166- } ) ?;
167-
168- // Typically, instantiating NLL query results does not
169- // create obligations. However, in some cases there
170- // are unresolved type variables, and unify them *can*
171- // create obligations. In that case, we have to go
172- // fulfill them. We do this via a (recursive) query.
173- while !obligations. is_empty ( ) {
174- trace ! ( "{:#?}" , obligations) ;
175- let mut progress = false ;
176- for obligation in std:: mem:: take ( & mut obligations) {
177- let obligation = infcx. resolve_vars_if_possible ( obligation) ;
178- match ProvePredicate :: fully_perform_into (
179- obligation. param_env . and ( ProvePredicate :: new ( obligation. predicate ) ) ,
180- infcx,
181- & mut region_constraints,
182- span,
183- ) {
184- Ok ( ( ( ) , _, new, certainty) ) => {
185- obligations. extend ( new) ;
186- progress = true ;
187- if let Certainty :: Ambiguous = certainty {
188- obligations. push ( obligation) ;
164+
165+ // HACK(type_alias_impl_trait): When moving an opaque type to hidden type mapping from the query to the current inferctxt,
166+ // we sometimes end up with `Opaque<'a> = Opaque<'b>` instead of an actual hidden type. In that case we don't register a
167+ // hidden type but just equate the lifetimes. Thus we need to scrape the region constraints even though we're also manually
168+ // collecting region constraints via `region_constraints`.
169+ let ( mut output, _) = scrape_region_constraints (
170+ infcx,
171+ |_ocx| {
172+ let ( output, ei, mut obligations, _) =
173+ Q :: fully_perform_into ( self , infcx, & mut region_constraints, span) ?;
174+ error_info = ei;
175+
176+ // Typically, instantiating NLL query results does not
177+ // create obligations. However, in some cases there
178+ // are unresolved type variables, and unify them *can*
179+ // create obligations. In that case, we have to go
180+ // fulfill them. We do this via a (recursive) query.
181+ while !obligations. is_empty ( ) {
182+ trace ! ( "{:#?}" , obligations) ;
183+ let mut progress = false ;
184+ for obligation in std:: mem:: take ( & mut obligations) {
185+ let obligation = infcx. resolve_vars_if_possible ( obligation) ;
186+ match ProvePredicate :: fully_perform_into (
187+ obligation. param_env . and ( ProvePredicate :: new ( obligation. predicate ) ) ,
188+ infcx,
189+ & mut region_constraints,
190+ span,
191+ ) {
192+ Ok ( ( ( ) , _, new, certainty) ) => {
193+ obligations. extend ( new) ;
194+ progress = true ;
195+ if let Certainty :: Ambiguous = certainty {
196+ obligations. push ( obligation) ;
197+ }
198+ }
199+ Err ( _) => obligations. push ( obligation) ,
189200 }
190201 }
191- Err ( _) => obligations. push ( obligation) ,
202+ if !progress {
203+ infcx. dcx ( ) . span_bug (
204+ span,
205+ format ! ( "ambiguity processing {obligations:?} from {self:?}" ) ,
206+ ) ;
207+ }
192208 }
193- }
194- if !progress {
195- infcx
196- . dcx ( )
197- . span_bug ( span, format ! ( "ambiguity processing {obligations:?} from {self:?}" ) ) ;
198- }
199- }
200-
201- Ok ( TypeOpOutput {
202- output,
203- constraints : if region_constraints. is_empty ( ) {
204- None
205- } else {
206- Some ( infcx. tcx . arena . alloc ( region_constraints) )
209+ Ok ( output)
207210 } ,
208- error_info,
209- } )
211+ "fully_perform" ,
212+ span,
213+ ) ?;
214+ output. error_info = error_info;
215+ if let Some ( constraints) = output. constraints {
216+ region_constraints
217+ . member_constraints
218+ . extend ( constraints. member_constraints . iter ( ) . cloned ( ) ) ;
219+ region_constraints. outlives . extend ( constraints. outlives . iter ( ) . cloned ( ) ) ;
220+ }
221+ output. constraints = if region_constraints. is_empty ( ) {
222+ None
223+ } else {
224+ Some ( infcx. tcx . arena . alloc ( region_constraints) )
225+ } ;
226+ Ok ( output)
210227 }
211228}
0 commit comments