@@ -93,6 +93,18 @@ pub struct OpaqueTypeDecl<'tcx> {
93
93
pub origin : hir:: OpaqueTyOrigin ,
94
94
}
95
95
96
+ /// Whether member constraints should be generated for all opaque types
97
+ pub enum GenerateMemberConstraints {
98
+ /// The default, used by typeck
99
+ WhenRequired ,
100
+ /// The borrow checker needs member constraints in any case where we don't
101
+ /// have a `'static` bound. This is because the borrow checker has more
102
+ /// flexibility in the values of regions. For example, given `f<'a, 'b>`
103
+ /// the borrow checker can have an inference variable outlive `'a` and `'b`,
104
+ /// but not be equal to `'static`.
105
+ IfNoStaticBound ,
106
+ }
107
+
96
108
impl < ' a , ' tcx > InferCtxt < ' a , ' tcx > {
97
109
/// Replaces all opaque types in `value` with fresh inference variables
98
110
/// and creates appropriate obligations. For example, given the input:
@@ -315,7 +327,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
315
327
debug ! ( "constrain_opaque_types()" ) ;
316
328
317
329
for ( & def_id, opaque_defn) in opaque_types {
318
- self . constrain_opaque_type ( def_id, opaque_defn, free_region_relations) ;
330
+ self . constrain_opaque_type (
331
+ def_id,
332
+ opaque_defn,
333
+ GenerateMemberConstraints :: WhenRequired ,
334
+ free_region_relations,
335
+ ) ;
319
336
}
320
337
}
321
338
@@ -324,6 +341,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
324
341
& self ,
325
342
def_id : DefId ,
326
343
opaque_defn : & OpaqueTypeDecl < ' tcx > ,
344
+ mode : GenerateMemberConstraints ,
327
345
free_region_relations : & FRR ,
328
346
) {
329
347
debug ! ( "constrain_opaque_type()" ) ;
@@ -358,6 +376,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
358
376
op : |r| self . sub_regions ( infer:: CallReturn ( span) , required_region, r) ,
359
377
} ) ;
360
378
}
379
+ if let GenerateMemberConstraints :: IfNoStaticBound = mode {
380
+ self . generate_member_constraint (
381
+ concrete_ty,
382
+ opaque_type_generics,
383
+ opaque_defn,
384
+ def_id,
385
+ ) ;
386
+ }
361
387
return ;
362
388
}
363
389
@@ -398,13 +424,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
398
424
// we will create a "in bound" like `'r in
399
425
// ['a, 'b, 'c]`, where `'a..'c` are the
400
426
// regions that appear in the impl trait.
427
+
428
+ // For now, enforce a feature gate outside of async functions.
429
+ self . member_constraint_feature_gate ( opaque_defn, def_id, lr, subst_arg) ;
430
+
401
431
return self . generate_member_constraint (
402
432
concrete_ty,
403
433
opaque_type_generics,
404
434
opaque_defn,
405
435
def_id,
406
- lr,
407
- subst_arg,
408
436
) ;
409
437
}
410
438
}
@@ -414,6 +442,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
414
442
let least_region = least_region. unwrap_or ( tcx. lifetimes . re_static ) ;
415
443
debug ! ( "constrain_opaque_types: least_region={:?}" , least_region) ;
416
444
445
+ if let GenerateMemberConstraints :: IfNoStaticBound = mode {
446
+ if least_region != tcx. lifetimes . re_static {
447
+ self . generate_member_constraint (
448
+ concrete_ty,
449
+ opaque_type_generics,
450
+ opaque_defn,
451
+ def_id,
452
+ ) ;
453
+ }
454
+ }
417
455
concrete_ty. visit_with ( & mut ConstrainOpaqueTypeRegionVisitor {
418
456
tcx : self . tcx ,
419
457
op : |r| self . sub_regions ( infer:: CallReturn ( span) , least_region, r) ,
@@ -434,19 +472,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
434
472
opaque_type_generics : & ty:: Generics ,
435
473
opaque_defn : & OpaqueTypeDecl < ' tcx > ,
436
474
opaque_type_def_id : DefId ,
437
- conflict1 : ty:: Region < ' tcx > ,
438
- conflict2 : ty:: Region < ' tcx > ,
439
475
) {
440
- // For now, enforce a feature gate outside of async functions.
441
- if self . member_constraint_feature_gate (
442
- opaque_defn,
443
- opaque_type_def_id,
444
- conflict1,
445
- conflict2,
446
- ) {
447
- return ;
448
- }
449
-
450
476
// Create the set of choice regions: each region in the hidden
451
477
// type can be equal to any of the region parameters of the
452
478
// opaque type definition.
0 commit comments