@@ -248,64 +248,71 @@ impl<'tcx> InferCtxt<'tcx> {
248
248
where
249
249
R : Debug + TypeFoldable < TyCtxt < ' tcx > > ,
250
250
{
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
+ }
258
295
259
296
// Compute `QueryOutlivesConstraint` values that unify each of
260
297
// the original values `v_o` that was canonicalized into a
261
298
// variable...
262
299
263
300
let constraint_category = cause. to_constraint_category ( ) ;
264
301
265
- for ( index, original_value) in original_values. var_values . iter ( ) . enumerate ( ) {
302
+ for ( index, & original_value) in original_values. var_values . iter ( ) . enumerate ( ) {
266
303
// ...with the value `v_r` of that variable from the query.
267
304
let result_value = query_response. instantiate_projected ( self . tcx , & result_args, |v| {
268
305
v. var_values [ BoundVar :: new ( index) ]
269
306
} ) ;
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
+ ) ?;
309
316
}
310
317
311
318
// ...also include the other query region constraints from the query.
@@ -335,6 +342,57 @@ impl<'tcx> InferCtxt<'tcx> {
335
342
Ok ( InferOk { value : user_result, obligations } )
336
343
}
337
344
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
+
338
396
/// Given the original values and the (canonicalized) result from
339
397
/// computing a query, returns an instantiation that can be applied
340
398
/// to the query result to convert the result back into the
@@ -360,25 +418,47 @@ impl<'tcx> InferCtxt<'tcx> {
360
418
original_values, query_response,
361
419
) ;
362
420
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
+ }
369
449
370
- value . obligations . extend (
450
+ obligations. extend (
371
451
self . unify_query_response_instantiation_guess (
372
452
cause,
373
453
param_env,
374
454
original_values,
375
- & value . value ,
455
+ & result_args ,
376
456
query_response,
377
457
) ?
378
458
. into_obligations ( ) ,
379
459
) ;
380
460
381
- Ok ( value)
461
+ Ok ( InferOk { value : result_args , obligations } )
382
462
}
383
463
384
464
/// Given the original values and the (canonicalized) result from
@@ -390,14 +470,13 @@ impl<'tcx> InferCtxt<'tcx> {
390
470
/// will instantiate fresh inference variables for each canonical
391
471
/// variable instead. Therefore, the result of this method must be
392
472
/// properly unified
393
- #[ instrument( level = "debug" , skip( self , param_env ) ) ]
473
+ #[ instrument( level = "debug" , skip( self ) ) ]
394
474
fn query_response_instantiation_guess < R > (
395
475
& self ,
396
476
cause : & ObligationCause < ' tcx > ,
397
- param_env : ty:: ParamEnv < ' tcx > ,
398
477
original_values : & OriginalQueryValues < ' tcx > ,
399
478
query_response : & Canonical < ' tcx , QueryResponse < ' tcx , R > > ,
400
- ) -> InferResult < ' tcx , CanonicalVarValues < ' tcx > >
479
+ ) -> CanonicalVarValues < ' tcx >
401
480
where
402
481
R : Debug + TypeFoldable < TyCtxt < ' tcx > > ,
403
482
{
@@ -470,7 +549,7 @@ impl<'tcx> InferCtxt<'tcx> {
470
549
// Create result arguments: if we found a value for a
471
550
// given variable in the loop above, use that. Otherwise, use
472
551
// a fresh inference variable.
473
- let result_args = CanonicalVarValues {
552
+ CanonicalVarValues {
474
553
var_values : self . tcx . mk_args_from_iter (
475
554
query_response. variables . iter ( ) . enumerate ( ) . map ( |( index, info) | {
476
555
if info. universe ( ) != ty:: UniverseIndex :: ROOT {
@@ -495,31 +574,7 @@ impl<'tcx> InferCtxt<'tcx> {
495
574
}
496
575
} ) ,
497
576
) ,
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
- ) ;
520
577
}
521
-
522
- Ok ( InferOk { value : result_args, obligations } )
523
578
}
524
579
525
580
/// Given a "guess" at the values for the canonical variables in
0 commit comments