@@ -248,64 +248,71 @@ impl<'tcx> InferCtxt<'tcx> {
248248 where
249249 R : Debug + TypeFoldable < TyCtxt < ' tcx > > ,
250250 {
251- let InferOk { value : result_args, mut obligations } = self
252- . query_response_instantiation_guess (
253- cause,
254- param_env,
255- original_values,
256- query_response,
257- ) ?;
251+ let result_args =
252+ self . query_response_instantiation_guess ( cause, original_values, query_response) ;
253+
254+ let mut obligations = vec ! [ ] ;
255+
256+ // Carry all newly resolved opaque types to the caller's scope
257+ for & ( opaque_type_key, hidden_ty) in & query_response. value . opaque_types {
258+ let opaque_type_key = instantiate_value ( self . tcx , & result_args, opaque_type_key) ;
259+ let hidden_ty = instantiate_value ( self . tcx , & result_args, hidden_ty) ;
260+ debug ! ( ?opaque_type_key, ?hidden_ty, "constrain opaque type" ) ;
261+ // We can't use equate here, because the hidden type may have been an inference
262+ // variable that got constrained to the opaque type itself. In that case we want to ensure
263+ // any lifetime differences get recorded in `ouput_query_region_constraints` instead of
264+ // being registered in the `InferCtxt`.
265+ match hidden_ty. kind ( ) {
266+ ty:: Alias ( ty:: Opaque , alias_ty)
267+ if alias_ty. def_id == opaque_type_key. def_id . into ( ) =>
268+ {
269+ assert_eq ! ( alias_ty. args. len( ) , opaque_type_key. args. len( ) ) ;
270+ for ( key_arg, hidden_arg) in
271+ opaque_type_key. args . iter ( ) . zip ( alias_ty. args . iter ( ) )
272+ {
273+ self . equate_generic_arg (
274+ key_arg,
275+ hidden_arg,
276+ output_query_region_constraints,
277+ ConstraintCategory :: OpaqueType ,
278+ & mut obligations,
279+ cause,
280+ param_env,
281+ ) ?;
282+ }
283+ }
284+ _ => {
285+ self . insert_hidden_type (
286+ opaque_type_key,
287+ cause,
288+ param_env,
289+ hidden_ty,
290+ & mut obligations,
291+ ) ?;
292+ }
293+ }
294+ }
258295
259296 // Compute `QueryOutlivesConstraint` values that unify each of
260297 // the original values `v_o` that was canonicalized into a
261298 // variable...
262299
263300 let constraint_category = cause. to_constraint_category ( ) ;
264301
265- for ( index, original_value) in original_values. var_values . iter ( ) . enumerate ( ) {
302+ for ( index, & original_value) in original_values. var_values . iter ( ) . enumerate ( ) {
266303 // ...with the value `v_r` of that variable from the query.
267304 let result_value = query_response. instantiate_projected ( self . tcx , & result_args, |v| {
268305 v. var_values [ BoundVar :: new ( index) ]
269306 } ) ;
270- match ( original_value. unpack ( ) , result_value. unpack ( ) ) {
271- ( GenericArgKind :: Lifetime ( re1) , GenericArgKind :: Lifetime ( re2) )
272- if re1. is_erased ( ) && re2. is_erased ( ) =>
273- {
274- // No action needed.
275- }
276-
277- ( GenericArgKind :: Lifetime ( v_o) , GenericArgKind :: Lifetime ( v_r) ) => {
278- // To make `v_o = v_r`, we emit `v_o: v_r` and `v_r: v_o`.
279- if v_o != v_r {
280- output_query_region_constraints
281- . outlives
282- . push ( ( ty:: OutlivesPredicate ( v_o. into ( ) , v_r) , constraint_category) ) ;
283- output_query_region_constraints
284- . outlives
285- . push ( ( ty:: OutlivesPredicate ( v_r. into ( ) , v_o) , constraint_category) ) ;
286- }
287- }
288-
289- ( GenericArgKind :: Type ( v1) , GenericArgKind :: Type ( v2) ) => {
290- obligations. extend (
291- self . at ( & cause, param_env)
292- . eq ( DefineOpaqueTypes :: Yes , v1, v2) ?
293- . into_obligations ( ) ,
294- ) ;
295- }
296-
297- ( GenericArgKind :: Const ( v1) , GenericArgKind :: Const ( v2) ) => {
298- obligations. extend (
299- self . at ( & cause, param_env)
300- . eq ( DefineOpaqueTypes :: Yes , v1, v2) ?
301- . into_obligations ( ) ,
302- ) ;
303- }
304-
305- _ => {
306- bug ! ( "kind mismatch, cannot unify {:?} and {:?}" , original_value, result_value) ;
307- }
308- }
307+ self . equate_generic_arg (
308+ original_value,
309+ result_value,
310+ output_query_region_constraints,
311+ constraint_category,
312+ & mut obligations,
313+ cause,
314+ param_env,
315+ ) ?;
309316 }
310317
311318 // ...also include the other query region constraints from the query.
@@ -335,6 +342,57 @@ impl<'tcx> InferCtxt<'tcx> {
335342 Ok ( InferOk { value : user_result, obligations } )
336343 }
337344
345+ fn equate_generic_arg (
346+ & self ,
347+ original_value : GenericArg < ' tcx > ,
348+ result_value : GenericArg < ' tcx > ,
349+ output_query_region_constraints : & mut QueryRegionConstraints < ' tcx > ,
350+ constraint_category : ConstraintCategory < ' tcx > ,
351+ obligations : & mut Vec < Obligation < ' tcx , ty:: Predicate < ' tcx > > > ,
352+ cause : & ObligationCause < ' tcx > ,
353+ param_env : ty:: ParamEnv < ' tcx > ,
354+ ) -> Result < ( ) , ty:: error:: TypeError < ' tcx > > {
355+ Ok ( match ( original_value. unpack ( ) , result_value. unpack ( ) ) {
356+ ( GenericArgKind :: Lifetime ( re1) , GenericArgKind :: Lifetime ( re2) )
357+ if re1. is_erased ( ) && re2. is_erased ( ) =>
358+ {
359+ // No action needed.
360+ }
361+
362+ ( GenericArgKind :: Lifetime ( v_o) , GenericArgKind :: Lifetime ( v_r) ) => {
363+ // To make `v_o = v_r`, we emit `v_o: v_r` and `v_r: v_o`.
364+ if v_o != v_r {
365+ output_query_region_constraints
366+ . outlives
367+ . push ( ( ty:: OutlivesPredicate ( v_o. into ( ) , v_r) , constraint_category) ) ;
368+ output_query_region_constraints
369+ . outlives
370+ . push ( ( ty:: OutlivesPredicate ( v_r. into ( ) , v_o) , constraint_category) ) ;
371+ }
372+ }
373+
374+ ( GenericArgKind :: Type ( v1) , GenericArgKind :: Type ( v2) ) => {
375+ obligations. extend (
376+ self . at ( & cause, param_env)
377+ . eq ( DefineOpaqueTypes :: Yes , v1, v2) ?
378+ . into_obligations ( ) ,
379+ ) ;
380+ }
381+
382+ ( GenericArgKind :: Const ( v1) , GenericArgKind :: Const ( v2) ) => {
383+ obligations. extend (
384+ self . at ( & cause, param_env)
385+ . eq ( DefineOpaqueTypes :: Yes , v1, v2) ?
386+ . into_obligations ( ) ,
387+ ) ;
388+ }
389+
390+ _ => {
391+ bug ! ( "kind mismatch, cannot unify {:?} and {:?}" , original_value, result_value) ;
392+ }
393+ } )
394+ }
395+
338396 /// Given the original values and the (canonicalized) result from
339397 /// computing a query, returns an instantiation that can be applied
340398 /// to the query result to convert the result back into the
@@ -360,25 +418,47 @@ impl<'tcx> InferCtxt<'tcx> {
360418 original_values, query_response,
361419 ) ;
362420
363- let mut value = self . query_response_instantiation_guess (
364- cause,
365- param_env,
366- original_values,
367- query_response,
368- ) ?;
421+ let result_args =
422+ self . query_response_instantiation_guess ( cause, original_values, query_response) ;
423+
424+ let mut obligations = vec ! [ ] ;
425+
426+ // Carry all newly resolved opaque types to the caller's scope
427+ for & ( opaque_type_key, hidden_ty) in & query_response. value . opaque_types {
428+ let opaque_type_key = instantiate_value ( self . tcx , & result_args, opaque_type_key) ;
429+ let hidden_ty = instantiate_value ( self . tcx , & result_args, hidden_ty) ;
430+ debug ! ( ?opaque_type_key, ?hidden_ty, "constrain opaque type" ) ;
431+ // We use equate here instead of, for example, just registering the
432+ // opaque type's hidden value directly, because the hidden type may have been an inference
433+ // variable that got constrained to the opaque type itself. In that case we want to equate
434+ // the generic args of the opaque with the generic params of its hidden type version.
435+ obligations. extend (
436+ self . at ( cause, param_env)
437+ . eq (
438+ DefineOpaqueTypes :: Yes ,
439+ Ty :: new_opaque (
440+ self . tcx ,
441+ opaque_type_key. def_id . to_def_id ( ) ,
442+ opaque_type_key. args ,
443+ ) ,
444+ hidden_ty,
445+ ) ?
446+ . obligations ,
447+ ) ;
448+ }
369449
370- value . obligations . extend (
450+ obligations. extend (
371451 self . unify_query_response_instantiation_guess (
372452 cause,
373453 param_env,
374454 original_values,
375- & value . value ,
455+ & result_args ,
376456 query_response,
377457 ) ?
378458 . into_obligations ( ) ,
379459 ) ;
380460
381- Ok ( value)
461+ Ok ( InferOk { value : result_args , obligations } )
382462 }
383463
384464 /// Given the original values and the (canonicalized) result from
@@ -390,14 +470,13 @@ impl<'tcx> InferCtxt<'tcx> {
390470 /// will instantiate fresh inference variables for each canonical
391471 /// variable instead. Therefore, the result of this method must be
392472 /// properly unified
393- #[ instrument( level = "debug" , skip( self , param_env ) ) ]
473+ #[ instrument( level = "debug" , skip( self ) ) ]
394474 fn query_response_instantiation_guess < R > (
395475 & self ,
396476 cause : & ObligationCause < ' tcx > ,
397- param_env : ty:: ParamEnv < ' tcx > ,
398477 original_values : & OriginalQueryValues < ' tcx > ,
399478 query_response : & Canonical < ' tcx , QueryResponse < ' tcx , R > > ,
400- ) -> InferResult < ' tcx , CanonicalVarValues < ' tcx > >
479+ ) -> CanonicalVarValues < ' tcx >
401480 where
402481 R : Debug + TypeFoldable < TyCtxt < ' tcx > > ,
403482 {
@@ -470,7 +549,7 @@ impl<'tcx> InferCtxt<'tcx> {
470549 // Create result arguments: if we found a value for a
471550 // given variable in the loop above, use that. Otherwise, use
472551 // a fresh inference variable.
473- let result_args = CanonicalVarValues {
552+ CanonicalVarValues {
474553 var_values : self . tcx . mk_args_from_iter (
475554 query_response. variables . iter ( ) . enumerate ( ) . map ( |( index, info) | {
476555 if info. universe ( ) != ty:: UniverseIndex :: ROOT {
@@ -495,31 +574,7 @@ impl<'tcx> InferCtxt<'tcx> {
495574 }
496575 } ) ,
497576 ) ,
498- } ;
499-
500- let mut obligations = vec ! [ ] ;
501-
502- // Carry all newly resolved opaque types to the caller's scope
503- for & ( a, b) in & query_response. value . opaque_types {
504- let a = instantiate_value ( self . tcx , & result_args, a) ;
505- let b = instantiate_value ( self . tcx , & result_args, b) ;
506- debug ! ( ?a, ?b, "constrain opaque type" ) ;
507- // We use equate here instead of, for example, just registering the
508- // opaque type's hidden value directly, because the hidden type may have been an inference
509- // variable that got constrained to the opaque type itself. In that case we want to equate
510- // the generic args of the opaque with the generic params of its hidden type version.
511- obligations. extend (
512- self . at ( cause, param_env)
513- . eq (
514- DefineOpaqueTypes :: Yes ,
515- Ty :: new_opaque ( self . tcx , a. def_id . to_def_id ( ) , a. args ) ,
516- b,
517- ) ?
518- . obligations ,
519- ) ;
520577 }
521-
522- Ok ( InferOk { value : result_args, obligations } )
523578 }
524579
525580 /// Given a "guess" at the values for the canonical variables in
0 commit comments