@@ -68,10 +68,11 @@ use crate::infer::{
68
68
} ;
69
69
use crate :: traits:: { ObligationCause , ObligationCauseCode } ;
70
70
use rustc_data_structures:: undo_log:: UndoLogs ;
71
+ use rustc_hir:: def_id:: DefId ;
71
72
use rustc_hir:: def_id:: LocalDefId ;
72
73
use rustc_middle:: mir:: ConstraintCategory ;
73
74
use rustc_middle:: ty:: subst:: GenericArgKind ;
74
- use rustc_middle:: ty:: { self , Region , Ty , TyCtxt , TypeVisitable } ;
75
+ use rustc_middle:: ty:: { self , Region , SubstsRef , Ty , TyCtxt , TypeVisitable } ;
75
76
use smallvec:: smallvec;
76
77
77
78
impl < ' cx , ' tcx > InferCtxt < ' cx , ' tcx > {
@@ -283,6 +284,9 @@ where
283
284
Component :: Param ( param_ty) => {
284
285
self . param_ty_must_outlive ( origin, region, * param_ty) ;
285
286
}
287
+ Component :: Opaque ( def_id, substs) => {
288
+ self . opaque_must_outlive ( * def_id, substs, origin, region)
289
+ }
286
290
Component :: Projection ( projection_ty) => {
287
291
self . projection_must_outlive ( origin, region, * projection_ty) ;
288
292
}
@@ -314,17 +318,69 @@ where
314
318
) ;
315
319
316
320
let generic = GenericKind :: Param ( param_ty) ;
317
- let verify_bound = self . verify_bound . generic_bound ( generic ) ;
321
+ let verify_bound = self . verify_bound . param_bound ( param_ty ) ;
318
322
self . delegate . push_verify ( origin, generic, region, verify_bound) ;
319
323
}
320
324
325
+ #[ instrument( level = "debug" , skip( self ) ) ]
326
+ fn opaque_must_outlive (
327
+ & mut self ,
328
+ def_id : DefId ,
329
+ substs : SubstsRef < ' tcx > ,
330
+ origin : infer:: SubregionOrigin < ' tcx > ,
331
+ region : ty:: Region < ' tcx > ,
332
+ ) {
333
+ self . generic_must_outlive (
334
+ origin,
335
+ region,
336
+ GenericKind :: Opaque ( def_id, substs) ,
337
+ def_id,
338
+ substs,
339
+ true ,
340
+ |ty| match * ty. kind ( ) {
341
+ ty:: Opaque ( def_id, substs) => ( def_id, substs) ,
342
+ _ => bug ! ( "expected only projection types from env, not {:?}" , ty) ,
343
+ } ,
344
+ ) ;
345
+ }
346
+
321
347
#[ instrument( level = "debug" , skip( self ) ) ]
322
348
fn projection_must_outlive (
323
349
& mut self ,
324
350
origin : infer:: SubregionOrigin < ' tcx > ,
325
351
region : ty:: Region < ' tcx > ,
326
352
projection_ty : ty:: ProjectionTy < ' tcx > ,
327
353
) {
354
+ self . generic_must_outlive (
355
+ origin,
356
+ region,
357
+ GenericKind :: Projection ( projection_ty) ,
358
+ projection_ty. item_def_id ,
359
+ projection_ty. substs ,
360
+ false ,
361
+ |ty| match ty. kind ( ) {
362
+ ty:: Projection ( projection_ty) => ( projection_ty. item_def_id , projection_ty. substs ) ,
363
+ _ => bug ! ( "expected only projection types from env, not {:?}" , ty) ,
364
+ } ,
365
+ ) ;
366
+ }
367
+
368
+ #[ instrument( level = "debug" , skip( self , filter) ) ]
369
+ fn generic_must_outlive (
370
+ & mut self ,
371
+ origin : infer:: SubregionOrigin < ' tcx > ,
372
+ region : ty:: Region < ' tcx > ,
373
+ generic : GenericKind < ' tcx > ,
374
+ def_id : DefId ,
375
+ substs : SubstsRef < ' tcx > ,
376
+ is_opaque : bool ,
377
+ filter : impl Fn ( Ty < ' tcx > ) -> ( DefId , SubstsRef < ' tcx > ) ,
378
+ ) {
379
+ // An optimization for a common case with opaque types.
380
+ if substs. is_empty ( ) {
381
+ return ;
382
+ }
383
+
328
384
// This case is thorny for inference. The fundamental problem is
329
385
// that there are many cases where we have choice, and inference
330
386
// doesn't like choice (the current region inference in
@@ -343,16 +399,15 @@ where
343
399
// These are guaranteed to apply, no matter the inference
344
400
// results.
345
401
let trait_bounds: Vec < _ > =
346
- self . verify_bound . projection_declared_bounds_from_trait ( projection_ty ) . collect ( ) ;
402
+ self . verify_bound . declared_region_bounds ( def_id , substs ) . collect ( ) ;
347
403
348
404
debug ! ( ?trait_bounds) ;
349
405
350
406
// Compute the bounds we can derive from the environment. This
351
407
// is an "approximate" match -- in some cases, these bounds
352
408
// may not apply.
353
- let mut approx_env_bounds =
354
- self . verify_bound . projection_approx_declared_bounds_from_env ( projection_ty) ;
355
- debug ! ( "projection_must_outlive: approx_env_bounds={:?}" , approx_env_bounds) ;
409
+ let mut approx_env_bounds = self . verify_bound . approx_declared_bounds_from_env ( generic) ;
410
+ debug ! ( ?approx_env_bounds) ;
356
411
357
412
// Remove outlives bounds that we get from the environment but
358
413
// which are also deducible from the trait. This arises (cc
@@ -366,14 +421,8 @@ where
366
421
// If the declaration is `trait Trait<'b> { type Item: 'b; }`, then `projection_declared_bounds_from_trait`
367
422
// will be invoked with `['b => ^1]` and so we will get `^1` returned.
368
423
let bound = bound_outlives. skip_binder ( ) ;
369
- match * bound. 0 . kind ( ) {
370
- ty:: Projection ( projection_ty) => self
371
- . verify_bound
372
- . projection_declared_bounds_from_trait ( projection_ty)
373
- . all ( |r| r != bound. 1 ) ,
374
-
375
- _ => panic ! ( "expected only projection types from env, not {:?}" , bound. 0 ) ,
376
- }
424
+ let ( def_id, substs) = filter ( bound. 0 ) ;
425
+ self . verify_bound . declared_region_bounds ( def_id, substs) . all ( |r| r != bound. 1 )
377
426
} ) ;
378
427
379
428
// If declared bounds list is empty, the only applicable rule is
@@ -390,29 +439,11 @@ where
390
439
// the problem is to add `T: 'r`, which isn't true. So, if there are no
391
440
// inference variables, we use a verify constraint instead of adding
392
441
// edges, which winds up enforcing the same condition.
393
- let needs_infer = projection_ty. needs_infer ( ) ;
394
- if approx_env_bounds. is_empty ( ) && trait_bounds. is_empty ( ) && needs_infer {
395
- debug ! ( "projection_must_outlive: no declared bounds" ) ;
396
-
397
- let constraint = origin. to_constraint_category ( ) ;
398
- for k in projection_ty. substs {
399
- match k. unpack ( ) {
400
- GenericArgKind :: Lifetime ( lt) => {
401
- self . delegate . push_sub_region_constraint (
402
- origin. clone ( ) ,
403
- region,
404
- lt,
405
- constraint,
406
- ) ;
407
- }
408
- GenericArgKind :: Type ( ty) => {
409
- self . type_must_outlive ( origin. clone ( ) , ty, region, constraint) ;
410
- }
411
- GenericArgKind :: Const ( _) => {
412
- // Const parameters don't impose constraints.
413
- }
414
- }
415
- }
442
+ let needs_infer = substs. needs_infer ( ) ;
443
+ if approx_env_bounds. is_empty ( ) && trait_bounds. is_empty ( ) && ( needs_infer || is_opaque) {
444
+ debug ! ( "no declared bounds" ) ;
445
+
446
+ self . substs_must_outlive ( substs, origin, region) ;
416
447
417
448
return ;
418
449
}
@@ -442,8 +473,8 @@ where
442
473
. all ( |b| b == Some ( trait_bounds[ 0 ] ) )
443
474
{
444
475
let unique_bound = trait_bounds[ 0 ] ;
445
- debug ! ( "projection_must_outlive: unique trait bound = {:?}" , unique_bound) ;
446
- debug ! ( "projection_must_outlive: unique declared bound appears in trait ref" ) ;
476
+ debug ! ( ? unique_bound) ;
477
+ debug ! ( "unique declared bound appears in trait ref" ) ;
447
478
let category = origin. to_constraint_category ( ) ;
448
479
self . delegate . push_sub_region_constraint ( origin, region, unique_bound, category) ;
449
480
return ;
@@ -454,11 +485,42 @@ where
454
485
// projection outlive; in some cases, this may add insufficient
455
486
// edges into the inference graph, leading to inference failures
456
487
// even though a satisfactory solution exists.
457
- let generic = GenericKind :: Projection ( projection_ty) ;
458
- let verify_bound = self . verify_bound . generic_bound ( generic) ;
488
+ let verify_bound = self . verify_bound . projection_opaque_bounds (
489
+ generic,
490
+ def_id,
491
+ substs,
492
+ & mut Default :: default ( ) ,
493
+ ) ;
459
494
debug ! ( "projection_must_outlive: pushing {:?}" , verify_bound) ;
460
495
self . delegate . push_verify ( origin, generic, region, verify_bound) ;
461
496
}
497
+
498
+ fn substs_must_outlive (
499
+ & mut self ,
500
+ substs : SubstsRef < ' tcx > ,
501
+ origin : infer:: SubregionOrigin < ' tcx > ,
502
+ region : ty:: Region < ' tcx > ,
503
+ ) {
504
+ let constraint = origin. to_constraint_category ( ) ;
505
+ for k in substs {
506
+ match k. unpack ( ) {
507
+ GenericArgKind :: Lifetime ( lt) => {
508
+ self . delegate . push_sub_region_constraint (
509
+ origin. clone ( ) ,
510
+ region,
511
+ lt,
512
+ constraint,
513
+ ) ;
514
+ }
515
+ GenericArgKind :: Type ( ty) => {
516
+ self . type_must_outlive ( origin. clone ( ) , ty, region, constraint) ;
517
+ }
518
+ GenericArgKind :: Const ( _) => {
519
+ // Const parameters don't impose constraints.
520
+ }
521
+ }
522
+ }
523
+ }
462
524
}
463
525
464
526
impl < ' cx , ' tcx > TypeOutlivesDelegate < ' tcx > for & ' cx InferCtxt < ' cx , ' tcx > {
0 commit comments