@@ -95,6 +95,18 @@ pub struct OpaqueTypeDecl<'tcx> {
9595 pub origin : hir:: OpaqueTyOrigin ,
9696}
9797
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+
98110impl < ' a , ' tcx > InferCtxt < ' a , ' tcx > {
99111 /// Replaces all opaque types in `value` with fresh inference variables
100112 /// and creates appropriate obligations. For example, given the input:
@@ -317,7 +329,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
317329 debug ! ( "constrain_opaque_types()" ) ;
318330
319331 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+ ) ;
321338 }
322339 }
323340
@@ -326,6 +343,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
326343 & self ,
327344 def_id : DefId ,
328345 opaque_defn : & OpaqueTypeDecl < ' tcx > ,
346+ mode : GenerateMemberConstraints ,
329347 free_region_relations : & FRR ,
330348 ) {
331349 debug ! ( "constrain_opaque_type()" ) ;
@@ -360,6 +378,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
360378 op : |r| self . sub_regions ( infer:: CallReturn ( span) , required_region, r) ,
361379 } ) ;
362380 }
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+ }
363389 return ;
364390 }
365391
@@ -400,13 +426,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
400426 // we will create a "in bound" like `'r in
401427 // ['a, 'b, 'c]`, where `'a..'c` are the
402428 // 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+
403433 return self . generate_member_constraint (
404434 concrete_ty,
405435 opaque_type_generics,
406436 opaque_defn,
407437 def_id,
408- lr,
409- subst_arg,
410438 ) ;
411439 }
412440 }
@@ -416,6 +444,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
416444 let least_region = least_region. unwrap_or ( tcx. lifetimes . re_static ) ;
417445 debug ! ( "constrain_opaque_types: least_region={:?}" , least_region) ;
418446
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+ }
419457 concrete_ty. visit_with ( & mut ConstrainOpaqueTypeRegionVisitor {
420458 tcx : self . tcx ,
421459 op : |r| self . sub_regions ( infer:: CallReturn ( span) , least_region, r) ,
@@ -436,19 +474,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
436474 opaque_type_generics : & ty:: Generics ,
437475 opaque_defn : & OpaqueTypeDecl < ' tcx > ,
438476 opaque_type_def_id : DefId ,
439- conflict1 : ty:: Region < ' tcx > ,
440- conflict2 : ty:: Region < ' tcx > ,
441477 ) {
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-
452478 // Create the set of choice regions: each region in the hidden
453479 // type can be equal to any of the region parameters of the
454480 // opaque type definition.
0 commit comments