@@ -159,53 +159,70 @@ where
159
159
. 0 ) ;
160
160
}
161
161
162
+ let mut error_info = None ;
162
163
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) ,
189
200
}
190
201
}
191
- Err ( _) => obligations. push ( obligation) ,
202
+ if !progress {
203
+ infcx. dcx ( ) . span_bug (
204
+ span,
205
+ format ! ( "ambiguity processing {obligations:?} from {self:?}" ) ,
206
+ ) ;
207
+ }
192
208
}
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)
207
210
} ,
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)
210
227
}
211
228
}
0 commit comments