@@ -93,6 +93,18 @@ pub struct OpaqueTypeDecl<'tcx> {
9393 pub origin : hir:: OpaqueTyOrigin ,
9494}
9595
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+
96108impl < ' a , ' tcx > InferCtxt < ' a , ' tcx > {
97109 /// Replaces all opaque types in `value` with fresh inference variables
98110 /// and creates appropriate obligations. For example, given the input:
@@ -315,7 +327,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
315327 debug ! ( "constrain_opaque_types()" ) ;
316328
317329 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+ ) ;
319336 }
320337 }
321338
@@ -324,6 +341,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
324341 & self ,
325342 def_id : DefId ,
326343 opaque_defn : & OpaqueTypeDecl < ' tcx > ,
344+ mode : GenerateMemberConstraints ,
327345 free_region_relations : & FRR ,
328346 ) {
329347 debug ! ( "constrain_opaque_type()" ) ;
@@ -358,6 +376,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
358376 op : |r| self . sub_regions ( infer:: CallReturn ( span) , required_region, r) ,
359377 } ) ;
360378 }
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+ }
361387 return ;
362388 }
363389
@@ -398,13 +424,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
398424 // we will create a "in bound" like `'r in
399425 // ['a, 'b, 'c]`, where `'a..'c` are the
400426 // 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+
401431 return self . generate_member_constraint (
402432 concrete_ty,
403433 opaque_type_generics,
404434 opaque_defn,
405435 def_id,
406- lr,
407- subst_arg,
408436 ) ;
409437 }
410438 }
@@ -414,6 +442,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
414442 let least_region = least_region. unwrap_or ( tcx. lifetimes . re_static ) ;
415443 debug ! ( "constrain_opaque_types: least_region={:?}" , least_region) ;
416444
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+ }
417455 concrete_ty. visit_with ( & mut ConstrainOpaqueTypeRegionVisitor {
418456 tcx : self . tcx ,
419457 op : |r| self . sub_regions ( infer:: CallReturn ( span) , least_region, r) ,
@@ -434,19 +472,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
434472 opaque_type_generics : & ty:: Generics ,
435473 opaque_defn : & OpaqueTypeDecl < ' tcx > ,
436474 opaque_type_def_id : DefId ,
437- conflict1 : ty:: Region < ' tcx > ,
438- conflict2 : ty:: Region < ' tcx > ,
439475 ) {
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-
450476 // Create the set of choice regions: each region in the hidden
451477 // type can be equal to any of the region parameters of the
452478 // opaque type definition.
0 commit comments