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